Update AG and HF agent codes from wearable product
[platform/core/connectivity/bluetooth-agent.git] / ag-agent / bluetooth-ag-agent.c
1 /*
2  * Bluetooth-ag-agent
3  *
4  * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:     Hocheol Seo <hocheol.seo@samsung.com>
7  *              Chethan T N <chethan.tn@samsung.com>
8  *              Chanyeol Park <chanyeol.park@samsung.com>
9  *              Rakesh MK <rakesh.mk@samsung.com>
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *              http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <signal.h>
27 #include <stdbool.h>
28 #include <sys/poll.h>
29 #include <gio/gunixfdlist.h>
30 #include <bundle_internal.h>
31 #include "bluetooth-ag-agent.h"
32 #include "bluetooth-ag-handler.h"
33 #include "bluetooth-agent-profile.h"
34
35 #include <bluetooth.h>
36 #include <bluetooth_internal.h>
37
38 #include <TapiUtility.h>
39 #include <ITapiSim.h>
40 #include <ITapiModem.h>
41 #include <ITapiCall.h>
42 #include <TelNetwork.h>
43 #include <TelCall.h>
44 #include <app.h>
45 #include <aul.h>
46 #include <system_info.h>
47
48 #include "contacts.h"
49 #include "appsvc.h"
50 #include <device-error.h>
51 #include <device/battery.h>
52 #include <device/callback.h>
53
54 static GMainLoop *gmain_loop;
55 static GDBusProxy *profile_gproxy;
56 static guint interface_added_sig_id;
57 static guint interface_removed_sig_id;
58 static guint proterty_changed_sig_id;
59 static guint name_owner_sig_id;
60 GDBusConnection *ag_dbus_conn = NULL;
61 gchar *remote_dev_path = NULL;
62 gboolean wbs_en;
63 uint16_t hfp_ver;
64 uint16_t hsp_ver;
65 static TapiHandle *tapi_handle[3];
66 int sim1;
67 int sim2;
68 static TapiHandle *tapi_handle_preferred_sim;
69 extern wbs_options wbs_opts;
70 GSList *active_devices = NULL;
71 static gchar *local_addr;
72 static gboolean call_launch_requested = FALSE;
73 static gchar* sco_owner;
74 static guint sco_open_timer_id;
75 static gboolean sco_open_request;
76 static guint hf_bluez_id;
77 static guint hs_bluez_id;
78 static guint app_id;
79 static guint device_property_id;
80 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
81 static guint media_sig_id;
82 static guint media_state_sig_id;
83 static bt_ag_media_transport_state_t transport_state;
84 #endif
85 static int last_speaker_gain = 9;
86
87 #define GET_TAPI_HANDLE \
88         (tapi_handle_preferred_sim != NULL) ? tapi_handle_preferred_sim : \
89                 ((sim1 == 1) ? tapi_handle[0] : tapi_handle[1])
90
91 #define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb"
92 #define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb"
93 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
94 #define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb"
95 #endif
96 #define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0"
97 #define VCONF_KEY_BT_LUNAR_ENABLED "db/wms/bt_loop_device_hfp_connected"
98
99 #define CALL_ALIAS_APP_ID "tizen.call"
100
101 #if defined(TIZEN_SUPPORT_DUAL_HF)
102 #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
103 #define MAX_CONNECTED_DEVICES 2
104 #else
105 #define MAX_CONNECTED_DEVICES 1
106 #endif
107
108 #define BT_AG_SIG_NUM 3
109 static struct sigaction bt_ag_sigoldact[BT_AG_SIG_NUM];
110 static int bt_ag_sig_to_handle[] = { SIGABRT, SIGSEGV, SIGTERM };
111
112 /*Below Inrospection data is exposed to bluez from agent*/
113 static const gchar ag_agent_bluez_introspection_xml[] =
114 "<node name='/'>"
115 " <interface name='org.bluez.Profile1'>"
116 "     <method name='NewConnection'>"
117 "          <arg type='o' name='device' direction='in'/>"
118 "          <arg type='h' name='fd' direction='in'/>"
119 "          <arg type='a{sv}' name='options' direction='in'/>"
120 "     </method>"
121 "     <method name='RequestDisconnection'>"
122 "          <arg type='o' name='device' direction='in'/>"
123 "     </method>"
124 "    <method name='ReplyAuthorize'>"
125 "      <arg type='u' name='accept' direction='in'/>"
126 "    </method>"
127 " </interface>"
128 "</node>";
129
130 /*Below Introspection data is exposed to application from agent*/
131 static const gchar ag_agent_app_introspection_xml[] =
132 "<node name='/'>"
133 "  <interface name='Org.Hfp.App.Interface'>"
134 "     <method name='RegisterApplication'>"
135 "          <arg type='s' name='path' direction='in'/>"
136 "          <arg type='s' name='address' direction='in'/>"
137 "     </method>"
138 "     <method name='UnregisterApplication'>"
139 "          <arg type='s' name='path' direction='in'/>"
140 "     </method>"
141 "     <method name='IncomingCall'>"
142 "          <arg type='s' name='path' direction='in'/>"
143 "          <arg type='s' name='number' direction='in'/>"
144 "          <arg type='i' name='id' direction='in'/>"
145 "     </method>"
146 "     <method name='OutgoingCall'>"
147 "          <arg type='s' name='path' direction='in'/>"
148 "          <arg type='s' name='number' direction='in'/>"
149 "          <arg type='i' name='id' direction='in'/>"
150 "     </method>"
151 "     <method name='ChangeCallStatus'>"
152 "          <arg type='s' name='path' direction='in'/>"
153 "          <arg type='s' name='number' direction='in'/>"
154 "          <arg type='i' name='status' direction='in'/>"
155 "          <arg type='i' name='id' direction='in'/>"
156 "     </method>"
157 "     <method name='GetProperties'>"
158 "               <arg type='a{sv}' name='properties' direction='out'/>"
159 "     </method>"
160 "       <method name='Disconnect'>"
161 "       </method>"
162 "       <method name='IsConnected'>"
163 "               <arg type='b' name='connected' direction='out'/>"
164 "       </method>"
165 "       <method name='IndicateCall'>"
166 "       </method>"
167 "       <method name='CancelCall'>"
168 "       </method>"
169 "       <method name='Play'>"
170 "       </method>"
171 "       <method name='Stop'>"
172 "       </method>"
173 "       <method name='IsPlaying'>"
174 "       <arg type='b' name='playing' direction='out'/>"
175 "       </method>"
176 "       <method name='GetSpeakerGain'>"
177 "               <arg type='q' name='gain' direction='out'/>"
178 "       </method>"
179 "       <method name='GetMicrophoneGain'>"
180 "               <arg type='q' name='gain' direction='out'/>"
181 "       </method>"
182 "       <method name='SetSpeakerGain'>"
183 "               <arg type='q' name='gain' direction='in'/>"
184 "       </method>"
185 "       <method name='SetMicrophoneGain'>"
186 "               <arg type='q' name='gain' direction='in'/>"
187 "       </method>"
188 "       <method name='SetVoiceDial'>"
189 "               <arg type='b' name='enable' direction='in'/>"
190 "       </method>"
191 "       <method name='CheckPrivilege'>"
192 "       </method>"
193 "     <method name='SwapHeadset'>"
194 "          <arg type='s' name='remote_addr' direction='in'/>"
195 "     </method>"
196 "  </interface>"
197 "</node>";
198
199 struct event {
200         const char *cmd;
201         int (*callback)(bt_ag_info_t *hs, const char *buf);
202 };
203
204 struct sco_socket_addr {
205         sa_family_t     sco_family;
206         bt_addr         sco_bdaddr;
207 };
208
209 typedef struct {
210         uint16_t setting;
211 } bt_voice;
212
213 bt_ag_status_t ag = {
214         .telephony_ready = FALSE,
215         .features = 0,
216         .er_mode = 3,
217         .er_ind = 0,
218         .rh = BT_RSP_HOLD_NOT_SUPPORTED,
219         .number = NULL,
220         .number_type = 0,
221         .ring_timer = 0,
222         .sdp_features = 0,
223 };
224 static void __bt_ag_agent_sigterm_handler(int signo);
225 static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
226                                                 const gchar *object_path);
227 static gboolean __bt_ag_agent_connection_release(bt_ag_info_t *hs);
228 static gboolean __bt_ag_event_handler(GIOChannel *channel, GIOCondition cond,
229         void *user_data);
230 static int __bt_ag_sco_connect(bt_ag_info_t *hs);
231 void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state);
232 static void __bt_ag_agent_reg_sim_event(TapiHandle *handle, void *user_data);
233 static void __bt_ag_agent_dereg_sim_event(TapiHandle *handle);
234 static uint32_t __bt_ag_agent_get_ag_features(void);
235 static void  __bt_ag_agent_tel_cb(TapiHandle *handle, int result, void *data, void *user_data);
236 static void __bt_ag_agent_subscribe_tapi_updates(TapiHandle *handle);
237 static void __bt_ag_agent_unsubscribe_tapi_updates(TapiHandle *handle);
238 static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection,
239                                         const gchar *sender_name,
240                                         const gchar *object_path,
241                                         const gchar *interface_name,
242                                         const gchar *signal_name,
243                                         GVariant *parameters,
244                                         gpointer user_data);
245 static GError *__bt_ag_agent_set_error(bt_hfp_agent_error_t error);
246
247 static void __bt_convert_addr_type_to_rev_string(char *address,
248                                 unsigned char *addr)
249 {
250         ret_if(address == NULL);
251         ret_if(addr == NULL);
252
253         g_snprintf(address, BT_ADDRESS_STRING_SIZE,
254                         "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
255                         addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
256 }
257
258 static GDBusProxy *__bt_ag_gdbus_init_profile_proxy(void)
259 {
260         FN_START;
261
262         GDBusProxy *proxy;
263         GError *err = NULL;
264
265         if (ag_dbus_conn == NULL)
266                 ag_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
267
268         if (!ag_dbus_conn) {
269                 if (err) {
270                         ERR("Unable to connect to gdbus: %s", err->message);
271                         g_clear_error(&err);
272                 }
273                 return NULL;
274         }
275
276         proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
277                         G_DBUS_PROXY_FLAGS_NONE, NULL,
278                         BLUEZ_SERVICE_NAME, "/org/bluez",
279                         BLUEZ_PROFILE_MGMT_INTERFACE, NULL, &err);
280         if (!proxy) {
281                 if (err) {
282                         ERR("Unable to create proxy: %s", err->message);
283                         g_clear_error(&err);
284                 }
285                 return NULL;
286         }
287
288         profile_gproxy = proxy;
289
290         FN_END;
291         return proxy;
292 }
293
294 static GDBusProxy *__bt_ag_gdbus_get_app_proxy(const gchar *service,
295                                 const gchar *path, const gchar *interface)
296 {
297         FN_START;
298
299         GDBusProxy *proxy;
300         GError *err = NULL;
301
302         if (ag_dbus_conn == NULL)
303                 ag_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
304
305         if (!ag_dbus_conn) {
306                 if (err) {
307                         ERR("Unable to connect to gdbus: %s", err->message);
308                         g_clear_error(&err);
309                 }
310                 return NULL;
311         }
312
313         DBG("%s %s %s", service, path, interface);
314
315         proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
316                         G_DBUS_PROXY_FLAGS_NONE, NULL,
317                         service, path,
318                         interface, NULL, &err);
319
320         if (!proxy) {
321                 if (err) {
322                         ERR("Unable to create proxy: %s", err->message);
323                         g_clear_error(&err);
324                 }
325                 return NULL;
326         }
327
328         FN_END;
329         return proxy;
330 }
331
332 static int __bt_ag_agent_gdbus_method_send(const char *service,
333                                 const gchar *path, const char *interface,
334                                 const char *method, gboolean response,
335                                 GVariant *parameters)
336 {
337         FN_START;
338
339         GVariant *ret;
340         GDBusProxy *proxy;
341         GError *error = NULL;
342
343         proxy = __bt_ag_gdbus_get_app_proxy(service, path, interface);
344         if (!proxy)
345                 return BT_HFP_AGENT_ERROR_INTERNAL;
346
347         if (response) {
348                 ret = g_dbus_proxy_call_sync(proxy,
349                                         method, parameters,
350                                         G_DBUS_CALL_FLAGS_NONE, -1,
351                                         NULL, &error);
352                 if (ret == NULL) {
353                         /* dBUS-RPC is failed */
354                         ERR("dBUS-RPC is failed");
355                         if (error != NULL) {
356                                 /* dBUS gives error cause */
357                                 ERR("D-Bus API failure: errCode[%x], message[%s]",
358                                         error->code, error->message);
359
360                                 g_clear_error(&error);
361                         }
362                         g_object_unref(proxy);
363                         return BT_HFP_AGENT_ERROR_INTERNAL;
364                 }
365
366                 g_variant_unref(ret);
367         } else {
368                 g_dbus_proxy_call(proxy,
369                                         method, parameters,
370                                         G_DBUS_CALL_FLAGS_NONE, 2000,
371                                         NULL, NULL, NULL);
372         }
373         g_object_unref(proxy);
374
375         return BT_HFP_AGENT_ERROR_NONE;
376 }
377
378 gboolean _bt_ag_agent_emit_signal(
379                                 GDBusConnection *connection,
380                                 const char *path,
381                                 const char *interface,
382                                 const char *name,
383                                 GVariant *property)
384 {
385         FN_START;
386
387         GError *error = NULL;
388         gboolean ret;
389         ret =  g_dbus_connection_emit_signal(connection,
390                                 NULL, path, interface,
391                                 name, property,
392                                 &error);
393         if (!ret) {
394                 if (error != NULL) {
395                         /* dBUS gives error cause */
396                         ERR("D-Bus API failure: errCode[%x], message[%s]",
397                                 error->code, error->message);
398                         g_clear_error(&error);
399                 }
400         }
401         INFO_C("Emit Signal done = [%s]", name);
402
403         FN_END;
404         return ret;
405 }
406
407 gboolean _bt_ag_agent_emit_property_changed(
408                                 GDBusConnection *connection,
409                                 const char *path,
410                                 const char *interface,
411                                 const char *name,
412                                 GVariant *property)
413 {
414         FN_START;
415
416         gboolean ret;
417         GVariant *var_data;
418
419         var_data = g_variant_new("(sv)",        name, property);
420
421         ret =  _bt_ag_agent_emit_signal(connection,
422                                 path, interface,
423                                 "PropertyChanged", var_data);
424         FN_END;
425         return ret;
426 }
427
428 static void __bt_ag_agent_start_watch(bt_ag_info_t *bt_ag_info)
429 {
430         bt_ag_info->watch_id = g_io_add_watch(bt_ag_info->io_chan,
431                         G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
432                         (GIOFunc) __bt_ag_event_handler, bt_ag_info);
433 }
434
435 static void __bt_ag_agent_remove_watch(guint *watch_id)
436 {
437         DBG("Remove IO watch ID %d", *watch_id);
438         if (*watch_id > 0) {
439                 g_source_remove(*watch_id);
440                 *watch_id = 0;
441         }
442 }
443
444 #if defined(TIZEN_SUPPORT_DUAL_HF)
445 gboolean __bt_ag_agent_is_companion_device(const char *addr)
446 {
447         if (TIZEN_PROFILE_WEARABLE) {
448                 char *host_device_address = NULL;
449                 host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
450
451                 if (!host_device_address) {
452                         INFO("Failed to get a companion device address");
453                         return FALSE;
454                 }
455
456                 if (g_strcmp0(host_device_address, addr) == 0) {
457                         INFO("addr[%s] is companion device", addr);
458                                 free(host_device_address);
459                         return TRUE;
460                 }
461                 free(host_device_address);
462                 return FALSE;
463         }
464         return FALSE;
465 }
466
467 void __bt_convert_device_path_to_address(const gchar *device_path,
468                                                 char *device_address)
469 {
470         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
471         char *dev_addr;
472
473         ret_if(device_path == NULL);
474         ret_if(device_address == NULL);
475
476         dev_addr = strstr(device_path, "dev_");
477         if (dev_addr != NULL) {
478                 char *pos = NULL;
479                 dev_addr += 4;
480                 g_strlcpy(address, dev_addr, sizeof(address));
481
482                 while ((pos = strchr(address, '_')) != NULL)
483                         *pos = ':';
484
485                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
486         }
487 }
488
489 static gboolean  __bt_ag_agent_is_companion_device_connected(void)
490 {
491         GSList *l;
492
493         for (l = active_devices ; l; l = l->next) {
494                 bt_ag_info_t *data = l->data;
495
496                 if (data->is_companion_device) {
497                         DBG("Companion device found");
498                         return TRUE;
499                 }
500         }
501
502         return FALSE;
503 }
504
505 gboolean __bt_ag_agent_check_dual_hf_condition(const gchar *device_path)
506 {
507         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
508         gboolean is_companion_device;
509
510         __bt_convert_device_path_to_address(device_path, device_address);
511         is_companion_device = __bt_ag_agent_is_companion_device(device_address);
512
513         DBG_SECURE(" device_address[%s]", device_address);
514         DBG(" is_companion_device[%d]", is_companion_device);
515
516         if (__bt_ag_agent_is_companion_device_connected()) {
517                 if (is_companion_device)
518                         return FALSE;
519         } else {
520                 if (!is_companion_device)
521                         return FALSE;
522         }
523         return TRUE;
524 }
525 #endif /* TIZEN_SUPPORT_DUAL_HF */
526
527 static gboolean __bt_is_phone_locked(int *phone_lock_state)
528 {
529         FN_START;
530         int ret;
531
532         if (NULL == phone_lock_state)
533                 return FALSE;
534
535         ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, phone_lock_state);
536         if (ret != 0) {
537                 ERR("Failed to read  [%s]\n", VCONFKEY_IDLE_LOCK_STATE);
538                 return FALSE;
539         }
540
541         FN_END;
542         return TRUE;
543 }
544
545 static gboolean __bt_get_outgoing_callapp_type(int *callapp_type)
546 {
547         FN_START;
548
549         if (NULL == callapp_type)
550                 return FALSE;
551
552         *callapp_type = BT_VOICE_CALL;
553         FN_END;
554         return TRUE;
555 }
556
557 static gboolean __bt_get_outgoing_call_condition(int *condition)
558 {
559         FN_START;
560
561         if (NULL == condition)
562                 return FALSE;
563
564         *condition = BT_MO_ONLY_UNLOCKED;
565         FN_END;
566         return TRUE;
567 }
568
569 static gboolean  __bt_ag_agent_launch_call_app(const char *number)
570 {
571         FN_START;
572         bundle *b;
573
574         DBG_SECURE("number(%s)", number);
575
576         b = bundle_create();
577         if (NULL == b) {
578                 ERR("bundle_create() Failed");
579                 return FALSE;
580         }
581
582         bundle_add(b, "launch-type", "MO");
583         bundle_add(b, "dial-type", "HEADSET");
584
585         if (strlen(number) != 0)
586                 bundle_add(b, "number", number);
587
588         aul_launch_app_async(CALL_ALIAS_APP_ID, b);
589         bundle_free(b);
590
591         FN_END;
592         return TRUE;
593 }
594
595 static gboolean __bt_ag_agent_launch_call_req(void *arg)
596 {
597         FN_START;
598         bundle *b = (bundle *)arg;
599
600         if (appsvc_run_service(b, 0, NULL, NULL) < 0)
601                 ERR("Unable to run app svc");
602         bundle_free(b);
603         call_launch_requested = FALSE;
604         FN_END;
605         return FALSE;
606 }
607
608 static gboolean __bt_ag_agent_make_call(const char *number)
609 {
610         FN_START;
611
612         char telnum[BT_MAX_TEL_NUM_STRING];
613         bundle *b;
614
615         if (TIZEN_PROFILE_WEARABLE)
616                 return __bt_ag_agent_launch_call_app(number);
617
618         if (call_launch_requested == TRUE) {
619                 DBG("Launch request is in progress");
620                 return TRUE;
621         }
622
623         b = bundle_create();
624         if (NULL == b)
625                 return FALSE;
626
627         appsvc_set_operation(b, APPSVC_OPERATION_CALL);
628         snprintf(telnum, sizeof(telnum), "tel:%s", number);
629         appsvc_set_uri(b, telnum);
630         appsvc_add_data(b, "ctindex", "-1");
631
632         call_launch_requested = TRUE;
633         g_idle_add(__bt_ag_agent_launch_call_req, b);
634
635         FN_END;
636         return TRUE;
637 }
638
639 static gboolean __bt_ag_agent_make_video_call(const char *mo_number)
640 {
641         FN_START;
642         bundle *kb;
643
644         kb = bundle_create();
645         if (NULL == kb)
646                 return FALSE;
647
648         bundle_add(kb, "KEY_CALL_TYPE", "MO");
649         bundle_add(kb, "number", mo_number);
650         aul_launch_app("org.tizen.vtmain", kb);
651         bundle_free(kb);
652
653         FN_END;
654         return TRUE;
655 }
656
657 gboolean _bt_ag_agent_answer_call(unsigned int call_id,
658                                 const gchar *path, const gchar *sender)
659 {
660         FN_START;
661
662         if (path == NULL || sender == NULL) {
663                 DBG("Invalid Arguments");
664                 return FALSE;
665         }
666
667         DBG("Application path = %s", path);
668         DBG("Call Id = %d", call_id);
669         DBG("Sender = %s", sender);
670
671         _bt_ag_agent_emit_signal(ag_dbus_conn, path,
672                                         BT_AG_SERVICE_NAME, "Answer",
673                                         g_variant_new("(u)", call_id));
674         FN_END;
675         return TRUE;
676 }
677
678 gboolean _bt_ag_agent_reject_call(unsigned int call_id,
679                                 const gchar *path, const gchar *sender)
680 {
681         FN_START;
682
683         if (path == NULL || sender == NULL) {
684                 DBG("Invalid Arguments");
685                 return FALSE;
686         }
687
688         DBG("Application path = %s", path);
689         DBG("Call Id = %d", call_id);
690         DBG("Sender = %s", sender);
691
692         _bt_ag_agent_emit_signal(ag_dbus_conn, path,
693                                         BT_AG_SERVICE_NAME, "Reject",
694                                         g_variant_new("(u)", call_id));
695         FN_END;
696         return TRUE;
697 }
698
699 gboolean _bt_ag_agent_release_call(unsigned int call_id,
700                                 const gchar *path, const gchar *sender)
701 {
702         FN_START;
703
704         if (path == NULL || sender == NULL) {
705                 DBG("Invalid Arguments");
706                 return FALSE;
707         }
708
709         DBG("Application path = %s", path);
710         DBG("Call Id = %d", call_id);
711         DBG("Sender = %s", sender);
712
713         _bt_ag_agent_emit_signal(ag_dbus_conn, path,
714                                         BT_AG_SERVICE_NAME, "Release",
715                                         g_variant_new("(u)", call_id));
716
717         FN_END;
718         return TRUE;
719 }
720
721 bt_hfp_agent_error_t _bt_ag_agent_dial_num(const gchar *number, guint flags)
722 {
723         bt_hfp_agent_error_t error_code = BT_HFP_AGENT_ERROR_NONE;
724         int callapp_type;
725         int phone_lock_state;
726         int condition;
727
728         FN_START;
729
730         if (number == NULL) {
731                 ERR("Invalid Argument");
732                 error_code = BT_HFP_AGENT_ERROR_INVALID_PARAM;
733                 goto fail;
734         }
735
736         DBG_SECURE("Number = %s", number);
737         DBG("flags = %d", flags);
738
739         if (!__bt_is_phone_locked(&phone_lock_state)) {
740                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
741                 goto fail;
742         }
743
744         if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
745                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
746                 goto fail;
747         }
748
749         if (!__bt_get_outgoing_call_condition(&condition)) {
750                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
751                 goto fail;
752         }
753
754         if (condition == BT_MO_ONLY_UNLOCKED && phone_lock_state ==
755                 VCONFKEY_IDLE_LOCK) {
756                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
757                 goto fail;
758         }
759
760         if (callapp_type == BT_VIDEO_CALL) {
761                 if (!__bt_ag_agent_make_video_call(number)) {
762                         ERR("Problem launching application");
763                         error_code = BT_HFP_AGENT_ERROR_INTERNAL;
764                         goto fail;
765                 }
766         } else {
767                 if (!__bt_ag_agent_make_call(number)) {
768                         ERR("Problem launching application");
769                         error_code = BT_HFP_AGENT_ERROR_INTERNAL;
770                         goto fail;
771                 }
772         }
773
774 fail:
775         FN_END;
776         return error_code;
777 }
778
779 bt_hfp_agent_error_t _bt_ag_agent_dial_memory(unsigned int location)
780 {
781         bt_hfp_agent_error_t error_code = BT_HFP_AGENT_ERROR_NONE;
782         char *number = NULL;
783         contacts_filter_h filter = NULL;
784         contacts_query_h query = NULL;
785         contacts_list_h list = NULL;
786         contacts_record_h record = NULL;
787         unsigned int projections[] = {
788                 _contacts_speeddial.number,
789         };
790
791         FN_START;
792
793         DBG("location = %d", location);
794
795         /*Get number from contacts location*/
796         if (contacts_connect() != CONTACTS_ERROR_NONE) {
797                 ERR(" contacts_connect failed");
798                 return BT_HFP_AGENT_ERROR_INTERNAL;
799         }
800
801         contacts_filter_create(_contacts_speeddial._uri, &filter);
802
803         if (filter == NULL)
804                 goto done;
805
806         if (contacts_filter_add_int(filter,
807                 _contacts_speeddial.speeddial_number,
808                 CONTACTS_MATCH_EQUAL, location) !=
809                 CONTACTS_ERROR_NONE) {
810                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
811                 goto done;
812         }
813
814         contacts_query_create(_contacts_speeddial._uri, &query);
815
816         if (query == NULL)
817                 goto done;
818
819         contacts_query_set_filter(query, filter);
820
821         if (contacts_query_set_projection(query, projections,
822                                 sizeof(projections)/sizeof(unsigned int)) !=
823                                 CONTACTS_ERROR_NONE) {
824                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
825                 goto done;
826         }
827
828         if (contacts_db_get_records_with_query(query, 0, 1, &list) !=
829                                 CONTACTS_ERROR_NONE) {
830                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
831                 goto done;
832         }
833
834         if (contacts_list_first(list) != CONTACTS_ERROR_NONE) {
835                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
836                 goto done;
837         }
838
839         if (contacts_list_get_current_record_p(list, &record) !=
840                                 CONTACTS_ERROR_NONE) {
841                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
842                 goto done;
843         }
844
845         if (record == NULL)
846                 goto done;
847
848         if (contacts_record_get_str(record, _contacts_speeddial.number, &number)
849                 != CONTACTS_ERROR_NONE) {
850                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
851                 goto done;
852         }
853
854         if (number == NULL) {
855                 ERR("No number at the location");
856                 error_code = BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX;
857                 goto done;
858         }
859
860         DBG_SECURE("number %s", number);
861
862         /*Make Voice call*/
863         if (!__bt_ag_agent_make_call(number)) {
864                 ERR("Problem launching application");
865                 error_code = BT_HFP_AGENT_ERROR_INTERNAL;
866         }
867
868         g_free(number);
869 done:
870         if (list != NULL)
871                 contacts_list_destroy(list, TRUE);
872
873         if (filter != NULL)
874                 contacts_filter_destroy(filter);
875
876         if (query != NULL)
877                 contacts_query_destroy(query);
878
879         contacts_disconnect();
880
881         FN_END;
882
883         return error_code;
884 }
885
886 bt_hfp_agent_error_t _bt_ag_agent_send_dtmf(const gchar *dtmf,
887                                 const gchar *path, const gchar *sender)
888 {
889         bt_hfp_agent_error_t ret;
890
891         FN_START;
892
893         if (dtmf == NULL || path == NULL || sender == NULL) {
894                 ERR("Invalid Argument");
895                 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
896         }
897
898         DBG("Dtmf = %s", dtmf);
899         DBG("Application path = %s", path);
900         DBG("Sender = %s", sender);
901
902         ret = __bt_ag_agent_gdbus_method_send(sender,
903                                 path, TELEPHONY_APP_INTERFACE,
904                                 "SendDtmf", FALSE,
905                                 g_variant_new("(s)", dtmf));
906
907         return ret;
908 }
909
910 gboolean _bt_ag_agent_threeway_call(unsigned int chld_value,
911                                 const gchar *path, const gchar *sender)
912 {
913         FN_START;
914
915         if (path == NULL || sender == NULL) {
916                 DBG("Invalid Arguments");
917                 return FALSE;
918         }
919
920         DBG("Application path = %s", path);
921         DBG("Value = %d", chld_value);
922         DBG("Sender = %s", sender);
923
924         if (TIZEN_PROFILE_WEARABLE) {
925                 /* Check if AG supports (i.e. ag_chld_str = "0,1,2") the requested CHLD;
926                 if not return FALSE */
927                 if (chld_value != 0 && chld_value != 1 && chld_value != 2)
928                         return FALSE;
929         } else {
930         if (chld_value != 0 && chld_value != 1 && chld_value != 2 &&
931                                 chld_value != 3)
932                 return FALSE;
933         }
934
935         _bt_ag_agent_emit_signal(ag_dbus_conn, path,
936                                         BT_AG_SERVICE_NAME, "Threeway",
937                                         g_variant_new("(u)", chld_value));
938         FN_END;
939         return TRUE;
940 }
941
942 bt_hfp_agent_error_t _bt_ag_agent_dial_last_num(void *device)
943 {
944         bt_hfp_agent_error_t err_code = BT_HFP_AGENT_ERROR_NONE;
945         char *last_num = NULL;
946         int type;
947         int callapp_type;
948         int phone_lock_state;
949         int condition;
950         contacts_list_h list = NULL;
951         contacts_query_h query = NULL;
952         contacts_filter_h filter = NULL;
953         contacts_record_h record = NULL;
954         unsigned int projections[] = {
955                 _contacts_phone_log.address,
956                 _contacts_phone_log.log_type,
957         };
958
959         FN_START;
960
961         if (contacts_connect() != CONTACTS_ERROR_NONE) {
962                 ERR(" contacts_connect failed");
963                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
964                 return err_code;
965         }
966
967         contacts_filter_create(_contacts_phone_log._uri, &filter);
968
969         if (filter == NULL)
970                 goto done;
971
972         if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
973                                 CONTACTS_MATCH_EQUAL,
974                                 CONTACTS_PLOG_TYPE_VOICE_OUTGOING) !=
975                                 CONTACTS_ERROR_NONE) {
976                 ERR(" contacts_filter_add_int failed");
977                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
978                 goto done;
979         }
980
981         if (contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR) !=
982                                 CONTACTS_ERROR_NONE) {
983                 ERR(" contacts_filter_add_operator failed");
984                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
985                 goto done;
986         }
987
988         if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
989                                 CONTACTS_MATCH_EQUAL,
990                                 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) !=
991                                 CONTACTS_ERROR_NONE) {
992                 ERR(" contacts_filter_add_int failed");
993                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
994                 goto done;
995         }
996
997         contacts_query_create(_contacts_phone_log._uri, &query);
998
999         if (query == NULL)
1000                 goto done;
1001
1002         contacts_query_set_filter(query, filter);
1003
1004         if (contacts_query_set_projection(query, projections,
1005                                 sizeof(projections)/sizeof(unsigned int)) !=
1006                                 CONTACTS_ERROR_NONE) {
1007                 ERR(" contacts_query_set_projection failed");
1008                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1009                 goto done;
1010         }
1011
1012         if (contacts_query_set_sort(query, _contacts_phone_log.log_time, false)
1013                 != CONTACTS_ERROR_NONE) {
1014                 ERR(" contacts_query_set_sort failed");
1015                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1016                 goto done;
1017         }
1018
1019         if (contacts_db_get_records_with_query(query, 0, 1, &list)  !=
1020                                 CONTACTS_ERROR_NONE) {
1021                 ERR(" contacts_db_get_records_with_query failed");
1022                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1023                 goto done;
1024         }
1025
1026         if (contacts_list_first(list)  != CONTACTS_ERROR_NONE) {
1027                 ERR(" contacts_list_first failed");
1028                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1029                 goto done;
1030         }
1031
1032         if (contacts_list_get_current_record_p(list, &record)  !=
1033                                 CONTACTS_ERROR_NONE) {
1034                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1035                 goto done;
1036         }
1037
1038         if (record == NULL)
1039                 goto done;
1040
1041         if (contacts_record_get_str(record, _contacts_phone_log.address,
1042                                 &last_num) != CONTACTS_ERROR_NONE) {
1043                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1044                 goto done;
1045         }
1046
1047         if (last_num == NULL) {
1048                 ERR("No last number");
1049                 err_code = BT_HFP_AGENT_ERROR_NO_CALL_LOGS;
1050                 goto done;
1051         }
1052
1053         if (!__bt_is_phone_locked(&phone_lock_state)) {
1054                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1055                 goto done;
1056         }
1057
1058         if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
1059                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1060                 goto done;
1061         }
1062
1063         if (!__bt_get_outgoing_call_condition(&condition)) {
1064                 ERR(" Failed to get the call condition");
1065                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1066                 goto done;
1067         }
1068
1069         if (condition == BT_MO_ONLY_UNLOCKED &&
1070                 phone_lock_state == VCONFKEY_IDLE_LOCK) {
1071                 ERR(" call condition and phone lock state check fail");
1072                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1073                 goto done;
1074         }
1075
1076         switch (callapp_type) {
1077         case BT_VOICE_CALL:
1078                 if (!__bt_ag_agent_make_call(last_num)) {
1079                         ERR("Problem launching application");
1080                         err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1081                 }
1082                 break;
1083         case BT_VIDEO_CALL:
1084                 if (!__bt_ag_agent_make_video_call(last_num)) {
1085                         ERR("Problem launching application");
1086                         err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1087                 }
1088                 break;
1089         case BT_FOLLOW_CALL_LOG:
1090                 if (contacts_record_get_int(record,
1091                         _contacts_phone_log.log_type,
1092                         &type) != CONTACTS_ERROR_NONE) {
1093                         err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1094                         break;
1095                 }
1096                 if (type == CONTACTS_PLOG_TYPE_VOICE_OUTGOING) {
1097                         if (!__bt_ag_agent_make_call(last_num)) {
1098                                 ERR("Problem launching application");
1099                                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1100                         }
1101                 } else if (type == CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) {
1102                         if (!__bt_ag_agent_make_video_call(last_num)) {
1103                                 ERR("Problem launching application");
1104                                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1105                         }
1106                 } else {
1107                                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1108                 }
1109                 break;
1110         default:
1111                 err_code = BT_HFP_AGENT_ERROR_INTERNAL;
1112                 break;
1113         }
1114
1115 done:
1116
1117         if (list != NULL)
1118                 contacts_list_destroy(list, TRUE);
1119
1120         if (filter != NULL)
1121                 contacts_filter_destroy(filter);
1122
1123         if (query != NULL)
1124                 contacts_query_destroy(query);
1125
1126         contacts_disconnect();
1127
1128         if (last_num != NULL)
1129                 g_free(last_num);
1130
1131         FN_END;
1132
1133         return err_code;
1134 }
1135
1136 bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd,
1137                 const gchar *path, const gchar *sender)
1138 {
1139         bt_hfp_agent_error_t ret;
1140
1141         FN_START;
1142
1143         if (cmd == NULL || path == NULL || sender == NULL) {
1144                 ERR("Invalid Argument");
1145                 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
1146         }
1147
1148         DBG("cmd = %s", cmd);
1149         DBG("Application path = %s", path);
1150         DBG("Sender = %s", sender);
1151
1152         ret = __bt_ag_agent_gdbus_method_send(sender,
1153                                 path, TELEPHONY_APP_INTERFACE,
1154                                 "VendorCmd", FALSE,
1155                                 g_variant_new("(s)", cmd));
1156         FN_END;
1157         return ret;
1158 }
1159
1160 gboolean _bt_ag_agent_get_signal_quality(void *device)
1161 {
1162         int rssi;
1163         int ret;
1164
1165         FN_START;
1166         ret = tel_get_property_int(GET_TAPI_HANDLE,
1167                                 TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, &rssi);
1168         if (ret != TAPI_API_SUCCESS) {
1169                 ERR("Get signal status failed err = %d\n", ret);
1170                 goto fail;
1171         }
1172
1173         DBG("RSSI : %d", rssi);
1174
1175         _bt_hfp_signal_quality_reply(rssi, BT_SIGNAL_QUALITY_BER,
1176                 device);
1177
1178         FN_END;
1179         return TRUE;
1180 fail:
1181         FN_END;
1182         _bt_hfp_signal_quality_reply(-1, -1, device);
1183         return FALSE;
1184 }
1185
1186 gboolean _bt_ag_agent_get_battery_status(void *device)
1187 {
1188         bool battery_chrg_status;
1189         int battery_capacity;
1190         int ret;
1191
1192         FN_START;
1193
1194         ret = device_battery_is_charging(&battery_chrg_status);
1195         if (ret != DEVICE_ERROR_NONE) {
1196                 ERR("Get battery charge status failed. Err = %d\n", ret);
1197                 goto fail;
1198         }
1199
1200         DBG("Status : %d\n", battery_chrg_status);
1201
1202         ret = device_battery_get_percent(&battery_capacity);
1203         if (ret != DEVICE_ERROR_NONE) {
1204                 ERR("Get battery capacity status failed. Err = %d\n", ret);
1205                 goto fail;
1206         }
1207
1208         DBG("Capacity : %d\n", battery_capacity);
1209
1210         _bt_hfp_battery_property_reply(device,
1211                 battery_chrg_status, battery_capacity);
1212         FN_END;
1213         return TRUE;
1214
1215 fail:
1216         _bt_hfp_battery_property_reply(device, -1, -1);
1217         FN_END;
1218         return FALSE;
1219 }
1220
1221 gboolean _bt_ag_agent_get_operator_name(void *device)
1222 {
1223         char *operator_name = NULL;
1224         int ret;
1225         FN_START;
1226
1227         ret = tel_get_property_string(GET_TAPI_HANDLE,
1228                                         TAPI_PROP_NETWORK_NETWORK_NAME, &operator_name);
1229         if (NULL == operator_name) {
1230                 DBG("TAPI_PROP_NETWORK_NETWORK_NAME failed (%d)", ret);
1231                 _bt_hfp_operator_reply(NULL, device);
1232                 return FALSE;
1233         }
1234
1235         DBG("operator_name  = [%s]", operator_name);
1236
1237         _bt_hfp_operator_reply(operator_name, device);
1238
1239         free(operator_name);
1240
1241         FN_END;
1242         return TRUE;
1243 }
1244
1245 gboolean _bt_hfp_agent_nrec_status(gboolean status,
1246                         void *t_device)
1247 {
1248         FN_START;
1249         bt_ag_info_t *hs = (bt_ag_info_t *)t_device;
1250
1251         DBG("NREC status = %d", status);
1252         if (status)
1253                 hs->nrec_status = FALSE;
1254         else
1255                 hs->nrec_status = TRUE;
1256
1257         _bt_ag_agent_emit_signal(ag_dbus_conn, hs->path,
1258                                         BT_AG_SERVICE_NAME, "NrecStatusChanged",
1259                                         g_variant_new("(b)", hs->nrec_status));
1260         FN_END;
1261         return TRUE;
1262 }
1263
1264 gboolean _bt_ag_agent_get_imei_number(void *device)
1265 {
1266         FN_START;
1267         char *imei_number;
1268
1269         imei_number = tel_get_misc_me_imei_sync(GET_TAPI_HANDLE);
1270         if (NULL == imei_number) {
1271                 ERR("tel_get_misc_me_imei_sync for imei_number failed");
1272                 goto fail;
1273         }
1274
1275         if (!g_utf8_validate(imei_number, -1, NULL)) {
1276                 free(imei_number);
1277                 ERR("get_imei_number : invalid UTF8");
1278                 goto fail;
1279         }
1280
1281         DBG_SECURE("imei_number  = [%s]", imei_number);
1282         _bt_hfp_get_imei_number_reply(imei_number, device);
1283         free(imei_number);
1284         FN_END;
1285         return TRUE;
1286
1287 fail:
1288         _bt_hfp_get_imei_number_reply(NULL, device);
1289         FN_END;
1290         return FALSE;
1291 }
1292
1293 void _bt_ag_agent_get_manufacturer_name(void *device)
1294 {
1295         FN_START;
1296         char *manufacturer_name;
1297         int ret;
1298
1299         ret = system_info_get_platform_string("http://tizen.org/system/manufacturer",
1300                                                 &manufacturer_name);
1301         if (SYSTEM_INFO_ERROR_NONE != ret) {
1302                 ERR("Get manufacturer_name failed : %d", ret);
1303                 if (NULL != manufacturer_name)
1304                         free(manufacturer_name);
1305
1306                 manufacturer_name = g_strdup("Unknown");
1307         } else if (!g_utf8_validate(manufacturer_name, -1, NULL)) {
1308                 free(manufacturer_name);
1309                 manufacturer_name = g_strdup("Unknown");
1310                 ERR("get_manufacturer_name : invalid UTF8");
1311         }
1312
1313         DBG_SECURE("manufacturer_name  = [%s]", manufacturer_name);
1314         _bt_hfp_get_device_manufacturer_reply(manufacturer_name, device);
1315         free(manufacturer_name);
1316         FN_END;
1317 }
1318
1319 void _bt_ag_agent_get_imsi(void *device)
1320 {
1321         FN_START;
1322         TelSimImsiInfo_t imsi;
1323         memset(&imsi, 0, sizeof(TelSimImsiInfo_t));
1324         if (tel_get_sim_imsi(GET_TAPI_HANDLE, &imsi) != TAPI_API_SUCCESS) {
1325                 ERR("tel_get_sim_imsi failed");
1326                 goto fail;
1327         }
1328         DBG_SECURE("tapi values %s %s %s", imsi.szMcc, imsi.szMnc, imsi.szMsin);
1329
1330         _bt_hfp_get_imsi_reply(imsi.szMcc, imsi.szMnc, imsi.szMsin, device);
1331         FN_END;
1332         return;
1333 fail:
1334         _bt_hfp_get_imsi_reply(NULL, NULL, NULL, device);
1335         FN_END;
1336 }
1337
1338 int _bt_ag_agent_registration_status_convert(int result)
1339 {
1340         switch (result) {
1341         case TAPI_NETWORK_SERVICE_LEVEL_NO:
1342                 return BT_AGENT_NETWORK_REG_STATUS_NOT_REGISTER;
1343         case TAPI_NETWORK_SERVICE_LEVEL_EMERGENCY:
1344                 return BT_AGENT_NETWORK_REG_STATUS_EMERGENCY;
1345         case TAPI_NETWORK_SERVICE_LEVEL_FULL:
1346                 return BT_AGENT_NETWORK_REG_STATUS_REGISTER_HOME_NETWORK;
1347         case TAPI_NETWORK_SERVICE_LEVEL_SEARCH:
1348                 return BT_AGENT_NETWORK_REG_STATUS_SEARCH;
1349         default:
1350                 return BT_AGENT_NETWORK_REG_STATUS_UNKNOWN;
1351         }
1352         return result;
1353 }
1354
1355 void _bt_ag_agent_get_creg_status(void *device)
1356 {
1357         FN_START;
1358         int result = 0;
1359         int ret = 0;
1360         int n = 1;
1361         int registration_status = 0;
1362         int roam_status = 0;
1363
1364         ret = tel_get_property_int(GET_TAPI_HANDLE,
1365                                 TAPI_PROP_NETWORK_CIRCUIT_STATUS, &result);
1366         if (ret != TAPI_API_SUCCESS) {
1367                 ERR("tel_get_property_int failed");
1368                 return;
1369         }
1370         registration_status =
1371                         _bt_ag_agent_registration_status_convert(result);
1372
1373         DBG_SECURE("Registration status %d", result);
1374         DBG_SECURE("Mapped Status %d", registration_status);
1375         if (registration_status ==
1376                         BT_AGENT_NETWORK_REG_STATUS_REGISTER_HOME_NETWORK) {
1377                 ret = tel_get_property_int(GET_TAPI_HANDLE,
1378                                 TAPI_PROP_NETWORK_ROAMING_STATUS, &roam_status);
1379                 if (ret != TAPI_API_SUCCESS) {
1380                         ERR("Get roaming status failed err = %d\n", ret);
1381                         return;
1382                 }
1383                 DBG_SECURE("Roam status %d", roam_status);
1384                 if (roam_status == 1) {
1385                         registration_status =
1386                                         BT_AGENT_NETWORK_REG_STATUS_REGISTERED_ROAMING;
1387                 }
1388         }
1389
1390         _bt_hfp_get_creg_status_reply(n, registration_status, device);
1391
1392         FN_END;
1393         return;
1394 }
1395
1396 void _bt_ag_agent_get_model_name(void *device)
1397 {
1398         FN_START;
1399         char *model_name;
1400         int ret;
1401
1402         ret = system_info_get_platform_string("http://tizen.org/system/model_name", &model_name);
1403         if (SYSTEM_INFO_ERROR_NONE != ret) {
1404                 ERR("Get model_name failed: %d", ret);
1405                 if (NULL != model_name)
1406                         free(model_name);
1407
1408                 model_name = g_strdup("Unknown");
1409         } else if (!g_utf8_validate(model_name, -1, NULL)) {
1410                 free(model_name);
1411                 model_name = g_strdup("Unknown");
1412                 ERR("get_model_name : invalid UTF8");
1413         }
1414
1415         DBG_SECURE("model_name  = [%s]", model_name);
1416         _bt_hfp_get_model_info_reply(model_name, device);
1417         free(model_name);
1418         FN_END;
1419 }
1420
1421 void _bt_ag_agent_get_revision_information(void *device)
1422 {
1423         FN_START;
1424         char *revision_info;
1425         int ret;
1426
1427         ret = system_info_get_platform_string("http://tizen.org/system/build.string",
1428                                 &revision_info);
1429         if (SYSTEM_INFO_ERROR_NONE != ret) {
1430                 ERR("Get revision_info failed: %d", ret);
1431                 if (NULL != revision_info)
1432                         free(revision_info);
1433
1434                 revision_info = g_strdup("Unknown");
1435         } else if (!g_utf8_validate(revision_info, -1, NULL)) {
1436                         free(revision_info);
1437                         revision_info = g_strdup("Unknown");
1438                         ERR("get_revision_info: invalid UTF8");
1439                 }
1440
1441         DBG_SECURE("revision_info  = [%s]", revision_info);
1442         _bt_hfp_get_revision_info_reply(revision_info, device);
1443         free(revision_info);
1444         FN_END;
1445 }
1446
1447 void _bt_ag_agent_set_last_speaker_gain(int gain)
1448 {
1449         last_speaker_gain = gain;
1450 }
1451
1452 static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate)
1453 {
1454         FN_START;
1455         if (TIZEN_PROFILE_WEARABLE) {
1456                 bundle *b;
1457
1458                 b = bundle_create();
1459                 if (NULL == b) {
1460                         ERR("bundle_create() Failed");
1461                         return FALSE;
1462                 }
1463
1464                 bundle_add(b, "domain", "bt_headset");
1465                 if (!activate)
1466                         bundle_add(b, "action_type", "deactivate");
1467
1468                 aul_launch_app_async("org.tizen.svoice", b);
1469                 bundle_free(b);
1470                 FN_END;
1471                 return TRUE;
1472         } else {
1473                 app_control_h service = NULL;
1474
1475                 app_control_create(&service);
1476
1477                 if (service == NULL) {
1478                         ERR("Service create failed");
1479                         return FALSE;
1480                 }
1481
1482                 app_control_set_app_id(service, "org.tizen.svoice");
1483                 app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT);
1484                 if (app_control_add_extra_data(service, "domain", "bt_headset")
1485                                         != APP_CONTROL_ERROR_NONE) {
1486                         ERR("app_control_add_extra_data failed");
1487                         app_control_destroy(service);
1488                         return FALSE;
1489                 }
1490
1491                 if (!activate)
1492                         if (app_control_add_extra_data(service, "action_type", "deactivate")
1493                                         != APP_CONTROL_ERROR_NONE) {
1494                                 ERR("app_control_add_extra_data failed");
1495                                 app_control_destroy(service);
1496                                 return FALSE;
1497                         }
1498
1499                 if (app_control_send_launch_request(service, NULL, NULL) !=
1500                                                 APP_CONTROL_ERROR_NONE) {
1501                         ERR("launch failed");
1502                         app_control_destroy(service);
1503                         return FALSE;
1504                 }
1505
1506                 app_control_destroy(service);
1507                 FN_END;
1508                 return TRUE;
1509         }
1510 }
1511
1512 gboolean _bt_ag_agent_voice_dial(gboolean activate)
1513 {
1514         DBG("Activate = %d", activate);
1515
1516         return __bt_ag_agent_launch_voice_dial(activate);
1517 }
1518
1519 static void __bt_ag_codec_negotiation_info_reset(bt_ag_info_t *hs,
1520                                         gboolean reset)
1521 {
1522         hs->codec_info.is_negotiating = FALSE;
1523         hs->codec_info.requested_by_hf = FALSE;
1524         hs->codec_info.sending_codec = 0;
1525         g_free(hs->codec_info.status);
1526         hs->codec_info.status = NULL;
1527
1528         if (reset) {
1529                 hs->codec_info.remote_codecs = 0;
1530                 hs->codec_info.final_codec = 0;
1531                 hs->nrec_status = FALSE;
1532         }
1533
1534         if (hs->codec_info.nego_timer) {
1535                 g_source_remove(hs->codec_info.nego_timer);
1536                 hs->codec_info.nego_timer = 0;
1537         }
1538         wbs_opts.wbs_enable = wbs_en;
1539 }
1540
1541 static gboolean __bt_ag_codec_negotiation_finished(gpointer user_data)
1542 {
1543         bt_ag_info_t *hs = (bt_ag_info_t *)user_data;
1544
1545         if (g_strcmp0(hs->codec_info.status, "finish") == 0) {
1546                 DBG("Codec negotiation finished");
1547                 __bt_ag_sco_connect(hs);
1548                 __bt_ag_codec_negotiation_info_reset(hs, FALSE);
1549                 return TRUE;
1550         } else if (g_strcmp0(hs->codec_info.status, "timeout") == 0) {
1551                 ERR("Timeout is occured in codec negotiation");
1552                 /* Codec negotiation is timedout fall back to default NB */
1553                 hs->codec = BT_CVSD_CODEC_ID;
1554                 hs->codec_info.final_codec = BT_CVSD_CODEC_ID;
1555         }
1556
1557         if (hs->codec_info.requested_by_hf) {
1558                 __bt_ag_codec_negotiation_info_reset(hs, FALSE);
1559         } else {
1560                 __bt_ag_sco_connect(hs);
1561                 __bt_ag_codec_negotiation_info_reset(hs, FALSE);
1562         }
1563
1564         return FALSE;
1565 }
1566
1567 static bt_hfp_agent_error_t __bt_ag_set_codec(void *device, char *method)
1568 {
1569         GDBusProxy *proxy;
1570         GVariant *ret;
1571         GError *err = NULL;
1572         bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)device;
1573
1574         proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
1575                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1576                         BLUEZ_SERVICE_NAME, DEFAULT_ADAPTER_OBJECT_PATH,
1577                         BT_ADAPTER_INTERFACE, NULL, &err);
1578
1579         if (!proxy) {
1580                 if (err) {
1581                         ERR("Unable to create proxy: %s", err->message);
1582                         g_clear_error(&err);
1583                 }
1584                 return BT_HFP_AGENT_ERROR_INTERNAL;
1585         }
1586
1587         ret = g_dbus_proxy_call_sync(proxy, method,
1588                         g_variant_new("(ss)", "Gateway", bt_ag_info->remote_addr),
1589                         G_DBUS_CALL_FLAGS_NONE, -1,
1590                         NULL, &err);
1591         if (ret == NULL) {
1592                 /* dBUS-RPC is failed */
1593                 ERR("dBUS-RPC is failed");
1594                 if (err != NULL) {
1595                         /* dBUS gives error cause */
1596                         ERR("D-Bus API failure: errCode[%x], message[%s]",
1597                                err->code, err->message);
1598
1599                         g_clear_error(&err);
1600                 }
1601                 g_object_unref(proxy);
1602                 return BT_HFP_AGENT_ERROR_INTERNAL;
1603         }
1604         g_variant_unref(ret);
1605         g_object_unref(proxy);
1606
1607         return BT_HFP_AGENT_ERROR_NONE;
1608 }
1609
1610 static bt_hfp_agent_error_t __bt_ag_codec_selection_setup(bt_ag_info_t *hs,
1611                         uint32_t codec)
1612 {
1613         bt_hfp_agent_error_t err = BT_HFP_AGENT_ERROR_NONE;
1614
1615         DBG("Codec setup [%x]", codec);
1616
1617         /* 1. Compare sending codec & recieved code */
1618         if (hs->codec_info.sending_codec != codec)
1619                 err = BT_HFP_AGENT_ERROR_INTERNAL;
1620
1621         /* 2. Send WB or NB command */
1622         switch (codec) {
1623         case BT_CVSD_CODEC_ID:
1624                 err = __bt_ag_set_codec(hs, "SetNbParameters");
1625                 break;
1626         case BT_MSBC_CODEC_ID:
1627                 err = __bt_ag_set_codec(hs, "SetWbsParameters");
1628                 break;
1629         default:
1630                 err = BT_HFP_AGENT_ERROR_INTERNAL;
1631                 break;
1632         }
1633
1634         /* If the vendor specific calling returns error or codec is not correct,
1635          * we send CVSD Codec parameter to MM module. and also returns
1636          * normal value to HF
1637         */
1638         if (err != BT_HFP_AGENT_ERROR_NONE)
1639                 codec = BT_CVSD_CODEC_ID;
1640
1641         hs->codec_info.final_codec = codec;
1642
1643         return err;
1644 }
1645
1646 static bt_hfp_agent_error_t __bt_hfp_send_bcs_command(bt_ag_info_t *hs,
1647                         gboolean init_by_hf)
1648 {
1649         uint32_t codec;
1650
1651 #ifdef TIZEN_FEATURE_BT_SCO_WIDEBAND
1652         if (hs->codec_info.remote_codecs & BT_MSBC_CODEC_MASK)
1653                 codec = BT_MSBC_CODEC_ID;
1654         else
1655                 codec = BT_CVSD_CODEC_ID;
1656 #else
1657         codec = BT_CVSD_CODEC_ID;
1658 #endif
1659
1660         if (wbs_opts.wbs_enable == FALSE)
1661                 codec = BT_CVSD_CODEC_ID;
1662
1663         hs->codec = codec;
1664
1665         if (_bt_ag_send_at(hs, "\r\n+BCS: %d\r\n", codec) < 0)
1666                 return BT_HFP_AGENT_ERROR_INTERNAL;
1667         else
1668                 DBG("Send +BCS:%d\n", codec);
1669
1670         /* Send +BCS command to HF, and wait some times */
1671         hs->codec_info.is_negotiating = TRUE;
1672         hs->codec_info.sending_codec = codec;
1673         hs->codec_info.requested_by_hf = init_by_hf;
1674         hs->codec_info.final_codec = codec;
1675         hs->codec_info.status = g_strdup("timeout");
1676
1677         hs->codec_info.nego_timer = g_timeout_add_seconds(
1678                         HFP_CODEC_NEGOTIATION_TIMEOUT,
1679                         (GSourceFunc)__bt_ag_codec_negotiation_finished,
1680                         hs);
1681
1682         return BT_HFP_AGENT_ERROR_NONE;
1683 }
1684
1685
1686 static bt_hfp_agent_error_t __bt_hfp_codec_connection_setup(
1687                                 bt_ag_info_t *hs, gboolean init_by_hf)
1688 {
1689         DBG("Request to codec connection by %s", init_by_hf ? "HF" : "AG");
1690
1691         if (hs->state < HEADSET_STATE_CONNECTED)
1692                 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
1693
1694         if (hs->codec_info.is_negotiating == TRUE) {
1695                 /* In codec negotiation, return and wait */
1696                 ERR("Codec nogotiation is in progress");
1697                 return BT_HFP_AGENT_ERROR_BUSY;
1698         }
1699
1700         /* Not support Codec Negotiation or Not recieved BAC command */
1701         if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) ||
1702                                 hs->codec_info.remote_codecs == 0) {
1703                 ERR("No support for Codec Negotiation or receive BAC command");
1704                 if (init_by_hf) {
1705                         return BT_HFP_AGENT_ERROR_INTERNAL;
1706                 } else {
1707                         __bt_ag_sco_connect(hs);
1708                         return BT_HFP_AGENT_ERROR_INTERNAL;
1709                 }
1710         }
1711
1712         /* If HF initiated codec connection setup, it should send OK command
1713          * before +BCS command transmission.
1714          */
1715         if (init_by_hf)
1716                 return HFP_STATE_MNGR_ERR_NONE;
1717         else
1718                 return __bt_hfp_send_bcs_command(hs, init_by_hf);
1719 }
1720
1721
1722 static int __hfp_parse_available_codecs(const char *cmd, uint32_t *codecs)
1723 {
1724         char *str = NULL;
1725         *codecs = 0x00000000;
1726
1727         str = strchr(cmd, '=');
1728         if (str == NULL)
1729                 return -EINVAL;
1730
1731         while (str != NULL) {
1732                 str++;
1733
1734                 if (atoi(str) == BT_CVSD_CODEC_ID)
1735                         *codecs |= BT_CVSD_CODEC_MASK;
1736                 else if (atoi(str) == BT_MSBC_CODEC_ID)
1737                         *codecs |= BT_MSBC_CODEC_MASK;
1738
1739                 str = strchr(str, ',');
1740         }
1741
1742         if (*codecs == 0x00000000)
1743                 return -EINVAL;
1744
1745         return 0;
1746 }
1747
1748 /* AT+BAC (Bluetooth Available Codecs) */
1749 static int __bt_hfp_available_codecs(bt_ag_info_t *hs, const char *buf)
1750 {
1751         uint32_t codecs = 0x00000000;
1752         hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1753
1754         if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION)) {
1755                 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1756         } else if (__hfp_parse_available_codecs(buf, &codecs) < 0) {
1757                 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1758         } else {
1759                 DBG("Update remote available codecs [%x]", codecs);
1760                 hs->codec_info.remote_codecs = codecs;
1761         }
1762
1763         _bt_ag_send_response(hs, err);
1764
1765         /* Reset codec information and
1766          * restart codec connection setup by AG
1767          */
1768         hs->codec_info.final_codec = 0;
1769         if (hs->codec_info.nego_timer) {
1770                 hs->codec_info.is_negotiating = FALSE;
1771                 hs->codec_info.requested_by_hf = FALSE;
1772                 hs->codec_info.sending_codec = 0;
1773                 g_free(hs->codec_info.status);
1774                 hs->codec_info.status = NULL;
1775                 g_source_remove(hs->codec_info.nego_timer);
1776                 __bt_hfp_codec_connection_setup(hs, FALSE);
1777         }
1778
1779         return 0;
1780 }
1781
1782 /* AT+BCC (Bluetooth Codec Connection) */
1783 static int __bt_hfp_codec_connection(bt_ag_info_t *hs, const char *buf)
1784 {
1785         hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1786
1787         err = __bt_hfp_codec_connection_setup(hs, TRUE);
1788
1789         _bt_ag_send_response(hs, err);
1790
1791         if (err == HFP_STATE_MNGR_ERR_NONE)
1792                 err = __bt_hfp_send_bcs_command(hs, TRUE);
1793
1794         if (err != HFP_STATE_MNGR_ERR_NONE)
1795                 ERR("Fail to request codec connection setup");
1796
1797         return 0;
1798 }
1799
1800 /* AT+BCS (Bluetooth Codec Selection) */
1801 static int __bt_hfp_codec_selection(bt_ag_info_t *hs, const char *buf)
1802 {
1803         uint32_t codec = 0x00000000;
1804         hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1805
1806         /* Timer reset */
1807         if (hs->codec_info.nego_timer) {
1808                 g_source_remove(hs->codec_info.nego_timer);
1809                 hs->codec_info.nego_timer = 0;
1810                 g_free(hs->codec_info.status);
1811                 hs->codec_info.status = NULL;
1812         }
1813
1814         if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION))
1815                 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1816         else if (__hfp_parse_available_codecs(buf, &codec) < 0)
1817                 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1818         else if (__bt_ag_codec_selection_setup(hs, codec) !=
1819                                         BT_HFP_AGENT_ERROR_NONE)
1820                 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1821
1822         hs->codec_info.status = g_strdup("finish");
1823         _bt_ag_send_response(hs, err);
1824         __bt_ag_codec_negotiation_finished(hs);
1825
1826         return 0;
1827 }
1828
1829 static void __bt_ag_str2ba(const char *str, bt_addr *ba)
1830 {
1831         int i;
1832         for (i = 5; i >= 0; i--, str += 3)
1833                 ba->b[i] = strtol(str, NULL, 16);
1834 }
1835
1836 static const char *__bt_ag_state2str(hs_state_t state)
1837 {
1838         switch (state) {
1839         case HEADSET_STATE_DISCONNECTED:
1840                 return "disconnected";
1841         case HEADSET_STATE_CONNECTING:
1842                 return "connecting";
1843         case HEADSET_STATE_CONNECTED:
1844                 return "connected";
1845         case HEADSET_STATE_PLAY_IN_PROGRESS:
1846                 return "Play In Progress";
1847         case HEADSET_STATE_ON_CALL:
1848                 return "On Call";
1849         }
1850
1851         return NULL;
1852 }
1853
1854 static void __bt_convert_addr_string_to_type_rev(unsigned char *addr,
1855                 const char *address)
1856 {
1857         int i;
1858         char *ptr = NULL;
1859
1860         ret_if(address == NULL);
1861         ret_if(addr == NULL);
1862
1863         for (i = 0; i < 6; i++) {
1864                 addr[5 - i] = strtol(address, &ptr, 16);
1865                 if (ptr[0] != '\0') {
1866                         if (ptr[0] != ':')
1867                                 return;
1868
1869                         address = ptr + 1;
1870                 }
1871         }
1872 }
1873
1874 static gboolean __bt_ag_check_nval(GIOChannel *chan)
1875 {
1876         struct pollfd file_desc;
1877
1878         memset(&file_desc, 0, sizeof(file_desc));
1879         file_desc.fd = g_io_channel_unix_get_fd(chan);
1880         file_desc.events = POLLNVAL;
1881
1882         if (poll(&file_desc, 1, 0) > 0 && (POLLNVAL & file_desc.revents))
1883                 return TRUE;
1884
1885         return FALSE;
1886 }
1887
1888 static int __bt_ag_sco_connect(bt_ag_info_t *hs)
1889 {
1890         struct sco_socket_addr sco_addr;
1891         int err;
1892         GIOChannel *io;
1893         int sco_skt;
1894         bt_voice bt_vo;
1895         bt_ag_slconn_t *slconn = hs->slc;
1896         /*guint watch_id;*/
1897
1898         if (hs->state == HEADSET_STATE_ON_CALL)
1899                 return BT_HFP_AGENT_ERROR_ALREADY_CONNECTED;
1900
1901         if (hs->state != HEADSET_STATE_CONNECTED)
1902                 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
1903 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
1904         _bt_ag_agent_check_transport_state();
1905 #endif
1906
1907         /* Create Sco socket */
1908         sco_skt = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BT_SCO_PRTCL);
1909         if (sco_skt < 0) {
1910                 ERR("ERROR: Create socket failed.\n");
1911                 return BT_HFP_AGENT_ERROR_INTERNAL;
1912         }
1913
1914         /* Bind Sco Socket to Local BD addr */
1915         memset(&sco_addr, 0, sizeof(sco_addr));
1916         sco_addr.sco_family = AF_BLUETOOTH;
1917
1918         if (local_addr) {
1919                 __bt_ag_str2ba(local_addr, &sco_addr.sco_bdaddr);
1920                 DBG_SECURE("Local BD address: %s", local_addr);
1921         } else {
1922                 ERR("Local address is NULL");
1923                 ERR("Close SCO skt");
1924                 close(sco_skt);
1925                 return BT_HFP_AGENT_ERROR_INTERNAL;
1926         }
1927
1928
1929         err = bind(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr));
1930         if (err < 0) {
1931                 ERR("ERROR: sco socket binding failed");
1932                 ERR("Close SCO skt");
1933                 close(sco_skt);
1934                 return BT_HFP_AGENT_ERROR_INTERNAL;
1935         }
1936
1937         DBG_SECURE("Socket FD : %d", sco_skt);
1938
1939         io = g_io_channel_unix_new(sco_skt);
1940         g_io_channel_set_close_on_unref(io, TRUE);
1941         /*g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
1942         g_io_channel_set_buffered(io, FALSE);
1943         g_io_channel_set_encoding(io, NULL, NULL);*/
1944
1945         if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
1946                 (slconn && (slconn->hs_features &
1947                         BT_HF_FEATURE_CODEC_NEGOTIATION)) &&
1948                         wbs_opts.wbs_enable == TRUE) {
1949                 bt_vo.setting = (hs->codec == BT_MSBC_CODEC_ID) ?
1950                                 BT_HFP_MSBC_VOICE : BT_HFP_CVSD_VOICE;
1951
1952                 DBG("set Bluetooth voice: %d", bt_vo.setting);
1953                 err = setsockopt(sco_skt, BT_SOCKET_LEVEL,
1954                                         BT_VOICE_NUM, &bt_vo, sizeof(bt_vo));
1955                 if (err < 0) {
1956                         ERR("ERROR: sco socket set socket option failed");
1957                         ERR("Close SCO skt");
1958                         g_io_channel_unref(io);
1959                         close(sco_skt);
1960                         return BT_HFP_AGENT_ERROR_INTERNAL;
1961                 }
1962         } else {
1963                 DBG("Set NB codec parameter");
1964                 __bt_ag_set_codec(hs, "SetNbParameters");
1965         }
1966
1967         memset(&sco_addr, 0, sizeof(sco_addr));
1968         sco_addr.sco_family = AF_BLUETOOTH;
1969         __bt_ag_str2ba(hs->remote_addr, &sco_addr.sco_bdaddr);
1970         DBG_SECURE("remotel BD address: %s", hs->remote_addr);
1971
1972         err = connect(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr));
1973         if (err < 0 && !(errno == EINPROGRESS || errno == EAGAIN)) {
1974                 err = -errno;
1975                 ERR("sco socket connect failed : %s (%d)", strerror(-err), -err);
1976                 ERR("Close SCO skt");
1977                 g_io_channel_unref(io);
1978                 close(sco_skt);
1979                 return BT_HFP_AGENT_ERROR_INTERNAL;
1980         }
1981
1982         /* Disabling the watch since SCO is connected */
1983         /*watch_id = __bt_ag_set_watch(io,
1984                         (GIOFunc) __bt_ag_sco_connect_cb, hs);
1985         if (watch_id)
1986                 DBG("SCO watch set Success");*/
1987
1988         hs->sco = io;
1989
1990         _bt_ag_set_headset_state(hs, HEADSET_STATE_ON_CALL);
1991         return BT_HFP_AGENT_ERROR_NONE;
1992 }
1993
1994 static void __bt_ag_close_sco(bt_ag_info_t *hs)
1995 {
1996         DBG("");
1997         if (hs->sco) {
1998                 int sock = g_io_channel_unix_get_fd(hs->sco);
1999                 shutdown(sock, SHUT_RDWR);
2000                 g_io_channel_unref(hs->sco);
2001                 hs->sco = NULL;
2002         }
2003
2004         if (hs->sco_id)
2005                 __bt_ag_agent_remove_watch(&hs->sco_id);
2006
2007         if (hs->sco_incoming_id)
2008                 __bt_ag_agent_remove_watch(&hs->sco_incoming_id);
2009 }
2010
2011 static gboolean __bt_ag_sco_server_conn_cb(GIOChannel *chan,
2012                                 GIOCondition cond, gpointer user_data)
2013 {
2014         bt_ag_info_t *ag_info = user_data;
2015
2016         DBG("");
2017         if (cond & G_IO_NVAL)
2018                 return FALSE;
2019
2020         if (cond & (G_IO_HUP | G_IO_ERR)) {
2021                 ag_info->sco = NULL;
2022                 if (ag_info->sco_id)
2023                         __bt_ag_agent_remove_watch(&ag_info->sco_id);
2024
2025                 if (ag_info->sco_incoming_id)
2026                         __bt_ag_agent_remove_watch(&ag_info->sco_incoming_id);
2027
2028                 if (ag_info->watch_id)
2029                         _bt_ag_set_headset_state(ag_info, HEADSET_STATE_CONNECTED);
2030                 return FALSE;
2031         }
2032         return TRUE;
2033 }
2034
2035 static gboolean __bt_ag_sco_server_cb(GIOChannel *chan,
2036                                 GIOCondition cond, gpointer user_data)
2037 {
2038         bt_ag_info_t *ag_info = user_data;
2039         int sco_skt;
2040         int cli_sco_sock;
2041         GIOChannel *sco_io;
2042         bt_ag_slconn_t *slconn = ag_info->slc;
2043         bt_voice bt_vo;
2044         int err;
2045
2046         if ((cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) ||
2047                                 __bt_ag_check_nval(chan)) {
2048                 ERR("cond or chan is not valid");
2049                 return FALSE;
2050         }
2051
2052         INFO_C("Incoming SCO....");
2053
2054         if (ag_info->state < HEADSET_STATE_CONNECTED)
2055                 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
2056
2057         sco_skt = g_io_channel_unix_get_fd(chan);
2058
2059         cli_sco_sock = accept(sco_skt, NULL, NULL);
2060         if (cli_sco_sock < 0) {
2061                 ERR("accept is failed");
2062                 return TRUE;
2063         }
2064
2065         sco_io = g_io_channel_unix_new(cli_sco_sock);
2066         g_io_channel_set_close_on_unref(sco_io, TRUE);
2067         g_io_channel_set_encoding(sco_io, NULL, NULL);
2068         g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
2069         g_io_channel_set_buffered(sco_io, FALSE);
2070
2071         if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
2072                 (slconn && (slconn->hs_features &
2073                         BT_HF_FEATURE_CODEC_NEGOTIATION)) &&
2074                         wbs_opts.wbs_enable == TRUE) {
2075                 bt_vo.setting = (ag_info->codec == BT_MSBC_CODEC_ID) ?
2076                                 BT_HFP_MSBC_VOICE : BT_HFP_CVSD_VOICE;
2077
2078                 DBG("set Bluetooth voice: %d", bt_vo.setting);
2079                 err = setsockopt(cli_sco_sock, BT_SOCKET_LEVEL,
2080                                         BT_VOICE_NUM, &bt_vo, sizeof(bt_vo));
2081                 if (err < 0) {
2082                         ERR("Sco socket set socket option failed");
2083                         g_io_channel_unref(sco_io);
2084                         close(cli_sco_sock);
2085                         return FALSE;
2086                 }
2087         }
2088
2089         ag_info->sco = sco_io;
2090         ag_info->sco_incoming_id = g_io_add_watch(sco_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
2091                                         __bt_ag_sco_server_conn_cb, ag_info);
2092
2093         if (remote_dev_path)
2094                 g_free(remote_dev_path);
2095
2096         remote_dev_path = g_strdup(ag_info->path);
2097
2098         _bt_ag_set_headset_state(ag_info, HEADSET_STATE_ON_CALL);
2099
2100         return TRUE;
2101 }
2102
2103 static int __bt_ag_start_sco_server(bt_ag_info_t *hs)
2104 {
2105         DBG("Start SCO server");
2106         struct sco_socket_addr addr;
2107         GIOChannel *sco_io;
2108         int sco_skt;
2109         bdaddr_t bd_addr = {{0},};
2110
2111         if (hs->sco_server_started) {
2112                 DBG("Already exsist");
2113                 return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
2114         }
2115
2116         /* Create socket */
2117         sco_skt = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BT_SCO_PRTCL);
2118         if (sco_skt < 0) {
2119                 ERR("Can't create socket:\n");
2120                 return BT_HFP_AGENT_ERROR_INTERNAL;
2121         }
2122
2123         /* Bind to local address */
2124         memset(&addr, 0, sizeof(addr));
2125         addr.sco_family = AF_BLUETOOTH;
2126
2127         __bt_convert_addr_string_to_type_rev(bd_addr.b, hs->remote_addr);
2128         DBG_SECURE("Bind to address %s", hs->remote_addr);
2129         memcpy(&addr.sco_bdaddr, &bd_addr, sizeof(bdaddr_t));
2130
2131         if (bind(sco_skt, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
2132                 ERR("Can't bind socket:\n");
2133                 goto error;
2134         }
2135
2136         if (listen(sco_skt, 1)) {
2137                 ERR("Can not listen on the socket:\n");
2138                 goto error;
2139         }
2140
2141         sco_io = g_io_channel_unix_new(sco_skt);
2142         g_io_channel_set_close_on_unref(sco_io, TRUE);
2143         g_io_channel_set_encoding(sco_io, NULL, NULL);
2144         g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
2145         g_io_channel_set_buffered(sco_io, FALSE);
2146
2147         hs->sco_server = sco_io;
2148         hs->sco_watch_id = g_io_add_watch(sco_io,
2149                         G_IO_IN | G_IO_HUP | G_IO_ERR |
2150                         G_IO_NVAL, __bt_ag_sco_server_cb, hs);
2151
2152         hs->sco_server_started = TRUE;
2153         return BT_HFP_AGENT_ERROR_NONE;
2154
2155 error:
2156         close(sco_skt);
2157         return BT_HFP_AGENT_ERROR_INTERNAL;
2158 }
2159
2160 void __bt_ag_stop_sco_server(bt_ag_info_t *hs)
2161 {
2162         DBG("Stop SCO server");
2163         if (hs->sco_server) {
2164                 g_io_channel_shutdown(hs->sco_server, TRUE, NULL);
2165                 g_io_channel_unref(hs->sco_server);
2166                 hs->sco_server = NULL;
2167         }
2168         __bt_ag_agent_remove_watch(&hs->sco_watch_id);
2169         hs->sco_server_started = FALSE;
2170 }
2171
2172 static int __bt_ag_headset_close_rfcomm(bt_ag_info_t *hs)
2173 {
2174         GIOChannel *rfcomm = hs->rfcomm;
2175
2176         if (rfcomm) {
2177                 g_io_channel_shutdown(rfcomm, TRUE, NULL);
2178                 g_io_channel_unref(rfcomm);
2179                 hs->rfcomm = NULL;
2180         }
2181
2182         g_free(hs->slc);
2183         hs->slc = NULL;
2184
2185         return 0;
2186 }
2187
2188 static gboolean __bt_ag_sco_cb(GIOChannel *chan, GIOCondition cond,
2189                         bt_ag_info_t *hs)
2190 {
2191         if (cond & G_IO_NVAL)
2192                 return FALSE;
2193
2194         if (name_owner_sig_id)
2195                 g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
2196                                         name_owner_sig_id);
2197         name_owner_sig_id = 0;
2198         g_free(sco_owner);
2199         sco_owner = NULL;
2200
2201         DBG("Audio connection disconnected");
2202         _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
2203
2204         return FALSE;
2205 }
2206
2207 void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
2208 {
2209         bt_ag_slconn_t *slconn = hs->slc;
2210         const char *hs_state;
2211         hs_state_t org_state = hs->state;
2212         gboolean val = FALSE;
2213
2214         if (org_state == state)
2215                 return;
2216
2217         hs_state = __bt_ag_state2str(state);
2218
2219         switch (state) {
2220         case HEADSET_STATE_CONNECTING:
2221                 _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2222                                         hs->path,
2223                                         BT_HEADSET_INTERFACE, "State",
2224                                         g_variant_new("s", hs_state));
2225                 hs->state = state;
2226                 active_devices = g_slist_append(active_devices, hs);
2227                 break;
2228
2229         case HEADSET_STATE_CONNECTED:
2230                 if (hs->state != HEADSET_STATE_PLAY_IN_PROGRESS)
2231                         _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2232                                         hs->path,
2233                                         BT_HEADSET_INTERFACE, "State",
2234                                         g_variant_new("s", hs_state));
2235
2236                 if (hs->state < state) {
2237                         val = TRUE;
2238                         if (!g_slist_find(active_devices, hs))
2239                         active_devices = g_slist_append(active_devices, hs);
2240                         _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2241                                                 hs->path,
2242                                                 BT_HEADSET_INTERFACE,
2243                                                 "Connected",
2244                                                 g_variant_new("b", val));
2245
2246                         DBG_SECURE("Device %s connected", hs->remote_addr);
2247
2248                         /* update remote dev path to last connected device. */
2249                         if (remote_dev_path)
2250                                 g_free(remote_dev_path);
2251                         remote_dev_path = g_strdup(hs->path);
2252
2253 #if defined(TIZEN_SUPPORT_DUAL_HF)
2254                          if (!hs->is_companion_device)
2255                                 __bt_ag_start_sco_server(hs);
2256 #else
2257                         __bt_ag_start_sco_server(hs);
2258 #endif
2259
2260                         /* Set default code as Gateway NB */
2261                         __bt_ag_set_codec(hs, "SetNbParameters");
2262                 } else if (hs->state == HEADSET_STATE_ON_CALL) {
2263                         val = FALSE;
2264                         _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2265                                                 hs->path,
2266                                                 BT_HEADSET_INTERFACE,
2267                                                 "Playing",
2268                                                 g_variant_new("b", val));
2269                 }
2270                 hs->state = state;
2271                 break;
2272
2273         case HEADSET_STATE_DISCONNECTED:
2274                 if (sco_open_timer_id > 0) {
2275                         g_source_remove(sco_open_timer_id);
2276                         sco_open_timer_id = 0;
2277                         if (hs->invocation) {
2278                                 INFO("Disconnected before SCO Connection");
2279                                 /* Reply with error */
2280                                 GError *err = NULL;
2281                                 err = __bt_ag_agent_set_error(BT_HFP_AGENT_ERROR_NOT_CONNECTED);
2282                                 g_dbus_method_invocation_return_gerror(hs->invocation, err);
2283                                 hs->invocation = NULL;
2284                                 g_error_free(err);
2285                         }
2286                 }
2287
2288                 __bt_ag_close_sco(hs);
2289                 __bt_ag_headset_close_rfcomm(hs);
2290
2291                 if (hs->state == HEADSET_STATE_ON_CALL) {
2292                         val = FALSE;
2293                         _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2294                                                 hs->path,
2295                                                 BT_HEADSET_INTERFACE,
2296                                                 "Playing",
2297                                                 g_variant_new("b", val));
2298                 }
2299
2300                 val = FALSE;
2301                 _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2302                                 hs->path,
2303                                 BT_HEADSET_INTERFACE,
2304                                 "Connected",
2305                                 g_variant_new("b", val));
2306                 if (hs->state > HEADSET_STATE_CONNECTING)
2307                         _bt_hfp_device_disconnected(hs);
2308
2309                 active_devices = g_slist_remove(active_devices, hs);
2310
2311                 __bt_ag_codec_negotiation_info_reset(hs, TRUE);
2312 #if 0 /* SCO is crashed if below is called when SCO is opened by hf-agent */
2313                 __bt_ag_set_codec(hs, "SetNbParameters");
2314 #endif
2315                 hs->codec = 0;
2316
2317                 /* Since SCO server is binded on remote address */
2318                 /* Need to stop SCO server once heasdet disconencted*/
2319                 if (hs->sco_server_started)
2320                         __bt_ag_stop_sco_server(hs);
2321
2322                 g_free(hs->remote_addr);
2323                 g_free(hs->slc);
2324                 g_free(hs);
2325                 break;
2326
2327         case HEADSET_STATE_PLAY_IN_PROGRESS:
2328         case HEADSET_STATE_ON_CALL:
2329                 val = TRUE;
2330                 _bt_ag_agent_emit_property_changed(ag_dbus_conn,
2331                                         hs->path,
2332                                         BT_HEADSET_INTERFACE, "State",
2333                                         g_variant_new("s", hs_state));
2334
2335                 /*add watch for sco data */
2336                 hs->sco_id = g_io_add_watch(hs->sco,
2337                                         G_IO_ERR | G_IO_NVAL,
2338                                         (GIOFunc) __bt_ag_sco_cb, hs);
2339
2340                 _bt_ag_agent_emit_property_changed(
2341                                 ag_dbus_conn, hs->path,
2342                                 BT_HEADSET_INTERFACE, "Playing",
2343                                 g_variant_new("b", val));
2344
2345                 if (slconn->microphone_gain >= 0 &&
2346                                         !slconn->is_voice_recognition_running)
2347                         _bt_ag_send_at(hs, "\r\n+VGM=%u\r\n",
2348                                 slconn->microphone_gain);
2349
2350                 if (slconn->speaker_gain >= 0 &&
2351                                         !slconn->is_voice_recognition_running)
2352                         _bt_ag_send_at(hs, "\r\n+VGS=%u\r\n",
2353                                 slconn->speaker_gain);
2354
2355                 hs->state = state;
2356                 break;
2357
2358         default:
2359                 hs->state = state;
2360                 break;
2361         }
2362
2363         INFO("STATE CHANGED from [%s(%d)] to [%s(%d)]",
2364                 __bt_ag_state2str(org_state), org_state, __bt_ag_state2str(state), state);
2365 }
2366
2367 static struct event at_event_callbacks[] = {
2368         { "AT+BRSF", _bt_hfp_supported_features },
2369         { "AT+CIND", _bt_hfp_report_indicators },
2370         { "AT+CMER", _bt_hfp_enable_indicators },
2371         { "AT+CHLD", _bt_hfp_call_hold },
2372         { "ATA", _bt_hfp_answer_call },
2373         { "ATD", _bt_hfp_dial_number },
2374         { "AT+VG", _bt_hfp_signal_gain_setting },
2375         { "AT+CHUP", _bt_hfp_terminate_call },
2376         { "AT+CKPD", _bt_hfp_key_press },
2377         { "AT+CLIP", _bt_hfp_cli_notification },
2378         { "AT+BTRH", _bt_hfp_response_and_hold },
2379         { "AT+BLDN", _bt_hfp_last_dialed_number },
2380         { "AT+VTS", _bt_hfp_dtmf_tone },
2381         { "AT+CNUM", _bt_hfp_subscriber_number },
2382         { "AT+CLCC", _bt_hfp_list_current_calls },
2383         { "AT+CMEE", _bt_hfp_extended_errors },
2384         { "AT+CCWA", _bt_hfp_call_waiting_notify },
2385         { "AT+COPS", _bt_hfp_operator_selection },
2386         { "AT+NREC", _bt_hfp_nr_and_ec },
2387         { "AT+BVRA", _bt_hfp_voice_dial },
2388         { "AT+XAPL", _bt_hfp_apl_command },
2389         { "AT+IPHONEACCEV", _bt_hfp_apl_command },
2390         { "AT+BIA", _bt_hfp_indicators_activation },
2391         { "AT+CPBS", _bt_hfp_select_pb_memory },
2392         { "AT+CPBR", _bt_hfp_read_pb_entries},
2393         { "AT+CPBF", _bt_hfp_find_pb_entires },
2394         { "AT+CSCS", _bt_hfp_select_character_set },
2395         { "AT+CSQ", _bt_hfp_get_signal_quality },
2396         { "AT+CBC", _bt_hfp_get_battery_charge_status },
2397         { "AT+CPAS", _bt_hfp_get_activity_status },
2398         { "AT+CGSN", _bt_hfp_get_equipment_identity },
2399         { "AT+CGMM", _bt_hfp_get_model_information },
2400         { "AT+CGMI", _bt_hfp_get_device_manufacturer },
2401         { "AT+CGMR", _bt_hfp_get_revision_information },
2402         { "AT+BAC", __bt_hfp_available_codecs },
2403         { "AT+BCC", __bt_hfp_codec_connection },
2404         { "AT+BCS", __bt_hfp_codec_selection },
2405         { "AT+XSAT", _bt_hfp_vendor_cmd },
2406         { "AT+CIMI", _bt_hfp_get_imsi },
2407         { "AT+CREG", _bt_hfp_get_creg_status },
2408         { 0 }
2409 };
2410
2411 int num_of_secure_command = 4;
2412 static const char* secure_command[] = {"CLCC", "CLIP", "CPBR", "CCWA"};
2413
2414 static void __bt_ag_agent_print_at_buffer(char *message, const char *buf)
2415 {
2416
2417         int i = 0;
2418         char s[MAX_BUFFER_SIZE] = {0, };
2419         gboolean hide = FALSE;
2420
2421         gboolean is_security_command = FALSE;
2422         char *xsat_ptr;
2423
2424         strncpy(s, buf, MAX_BUFFER_SIZE - 1);
2425
2426         for (i = 0; i < num_of_secure_command; i++) {
2427                 if (strstr(buf, secure_command[i])) {
2428                         is_security_command = TRUE;
2429                         break;
2430                 }
2431         }
2432
2433         /* +XSAT: 11,DISC */
2434         xsat_ptr =  strstr(s, "11,DISC,");
2435         if (xsat_ptr) {
2436                 xsat_ptr = xsat_ptr + 8;
2437                 int x = 0;
2438                 while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
2439                         xsat_ptr[x] = 'X';
2440                         x++;
2441                 }
2442         }
2443
2444         /* AT+XSAT=11,Q_CT,X,XXXX */
2445         xsat_ptr =  strstr(s, "11,Q_CT,");
2446         if (xsat_ptr) {
2447                 xsat_ptr = xsat_ptr + 8;
2448                 int x = 0;
2449                 while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
2450                         if (x > 1) /* ignore 0 and 1 position */
2451                                 xsat_ptr[x] = 'X';
2452                         x++;
2453                 }
2454         }
2455
2456         i = 0;
2457         while (s[i] != '\0') {
2458                 if (s[i] == '\r' || s[i] == '\n') {
2459                         s[i] = '.';
2460                 } else {
2461                         if (s[i] == '\"')
2462                                 hide = hide ? FALSE : TRUE;
2463                         else if (is_security_command && hide) {
2464                                 if (i % 2)
2465                                         s[i] = 'X';
2466                         }
2467                 }
2468                 i++;
2469         }
2470         if (message)
2471                 INFO("%s Buffer = [%s], Len(%d)", message, s, strlen(s));
2472         else
2473                 INFO("[%s]", s);
2474 }
2475
2476 static int __bt_ag_at_handler(bt_ag_info_t *hs, const char *buf)
2477 {
2478         struct event *ev;
2479
2480         __bt_ag_agent_print_at_buffer("[AG AT CMD][RCVD] :", buf);
2481
2482         for (ev = at_event_callbacks; ev->cmd; ev++) {
2483                 if (!strncmp(buf, ev->cmd, strlen(ev->cmd)))
2484                         return ev->callback(hs, buf);
2485         }
2486
2487         return -EINVAL;
2488 }
2489
2490 static int __bt_ag_send_at_valist(bt_ag_info_t *hdset, va_list list,
2491                         char *list_format)
2492 {
2493         ssize_t final_written, count;
2494         char rsp_buffer[MAX_BUFFER_SIZE];
2495         int fd;
2496         int err;
2497
2498         count = vsnprintf(rsp_buffer, sizeof(rsp_buffer), list_format, list);
2499         if (count < 0) {
2500                 ERR("count is %d", count);
2501                 return -EINVAL;
2502         }
2503
2504         if (!hdset->io_chan) {
2505                 ERR("__bt_ag_send_at_valist: headset not connected");
2506                 return -EIO;
2507         }
2508
2509         final_written = 0;
2510
2511         fd = g_io_channel_unix_get_fd(hdset->io_chan);
2512
2513         if (fd != 0) {
2514                 while (final_written < count) {
2515                         ssize_t written;
2516
2517                         do {
2518                                 written = write(fd, rsp_buffer + final_written,
2519                                                 count - final_written);
2520                         } while (written < 0 && errno == EINTR);
2521
2522                         if (written < 0) {
2523                                 err = -errno;
2524                                 ERR("write failed : %s (%d)", strerror(-err), -err);
2525                                 return -errno;
2526                         }
2527
2528                         final_written += written;
2529                 }
2530
2531                 /* Synchronize the sending buffer */
2532 #if 0
2533                 /* Don't do sync call as it may block process untill all buffers are cleared
2534                 * On Z300F device this issue is reproduciable just connect with meacap
2535                 * select phonebook and call CPBR when we call CPBR multiple times it is
2536                 * blocking for 5 seconds.*/
2537                 sync();
2538 #endif
2539                 fsync(fd);
2540         } else {
2541                 ERR_SECURE("FD is 0. remote_addr : %s", hdset->remote_addr);
2542                 return -1;
2543         }
2544
2545         __bt_ag_agent_print_at_buffer("[AG AT CMD][SENT]", rsp_buffer);
2546
2547         return 0;
2548 }
2549
2550 int __attribute__((format(printf, 2, 3)))
2551                         _bt_ag_send_at(bt_ag_info_t *hs, char *format, ...)
2552 {
2553         va_list ap;
2554         int ret;
2555
2556         va_start(ap, format);
2557         ret = __bt_ag_send_at_valist(hs, ap, format);
2558         va_end(ap);
2559
2560         return ret;
2561 }
2562
2563 void __attribute__((format(printf, 3, 4)))
2564                 _bt_ag_send_foreach_headset(GSList *devices,
2565                                 int (*cmp) (bt_ag_info_t *hs),
2566                                 char *format, ...)
2567 {
2568         GSList *l;
2569         va_list ap;
2570
2571         for (l = devices; l != NULL; l = l->next) {
2572                 bt_ag_info_t *hs = l->data;
2573                 int ret;
2574
2575                 if (cmp && cmp(hs) != 0)
2576                         continue;
2577
2578                 va_start(ap, format);
2579                 ret = __bt_ag_send_at_valist(hs, ap, format);
2580                 if (ret < 0)
2581                         ERR("Failed to send to headset: %s (%d)",
2582                                         strerror(-ret), -ret);
2583                 va_end(ap);
2584         }
2585 }
2586
2587 int _bt_ag_send_response(bt_ag_info_t *hs, hfp_state_manager_err_t err)
2588 {
2589         if ((err != HFP_STATE_MNGR_ERR_NONE) && hs->slc->is_cme_enabled)
2590                 return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n", err);
2591
2592         switch (err) {
2593         case HFP_STATE_MNGR_ERR_NONE:
2594                 return _bt_ag_send_at(hs, "\r\nOK\r\n");
2595         case HFP_STATE_MNGR_ERR_NO_NETWORK_SERVICE:
2596                 return _bt_ag_send_at(hs, "\r\nNO CARRIER\r\n");
2597         default:
2598                 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
2599         }
2600 }
2601
2602 static gboolean __bt_ag_event_handler(GIOChannel *channel,
2603                                 GIOCondition cond, void *user_data)
2604 {
2605         bt_ag_slconn_t *slconn;
2606         unsigned char event_buf[MAX_BUFFER_SIZE];
2607         ssize_t len;
2608         size_t available_buffer;
2609         int fd;
2610         bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)user_data;
2611         int err_return = 0;
2612
2613
2614         if (cond & G_IO_NVAL)
2615                 return FALSE;
2616
2617         slconn = bt_ag_info->slc;
2618         if (cond & (G_IO_ERR | G_IO_HUP)) {
2619                 if (bt_ag_info->watch_id)
2620                         __bt_ag_agent_remove_watch(&bt_ag_info->watch_id);
2621
2622                 ERR("ERR or HUP on RFCOMM socket");
2623                 INFO_C("Disconnected [AG role] [Terminated by remote dev]");
2624                 goto failed;
2625         }
2626
2627         fd = g_io_channel_unix_get_fd(channel);
2628         len = read(fd, event_buf, sizeof(event_buf) - 1);
2629
2630         if (len < 0)
2631                 return FALSE;
2632         available_buffer = sizeof(slconn->buffer) - (slconn->start) -
2633                                 (slconn->length) - 1;
2634         if (available_buffer < (size_t) len) {
2635                 ERR("Buffer over flow");
2636                 goto failed;
2637         }
2638
2639         memcpy(&slconn->buffer[slconn->start + slconn->length], event_buf, len);
2640         slconn->length += len;
2641
2642         slconn->buffer[slconn->start + slconn->length] = '\0';
2643
2644         while (slconn->length > 0) {
2645                 char *get_cr;
2646                 int err;
2647                 off_t cmd_len;
2648
2649                 get_cr = strchr(&slconn->buffer[slconn->start], '\r');
2650                 if (!get_cr) {
2651                         ERR("Broken AT command received, break");
2652                         break;
2653                 }
2654
2655                 cmd_len = 1 + (off_t) get_cr -
2656                         (off_t) &slconn->buffer[slconn->start];
2657                 *get_cr = '\0';
2658
2659                 if (cmd_len > 1) {
2660                         DBG("Call AT handler");
2661                         err = __bt_ag_at_handler(bt_ag_info,
2662                                         &slconn->buffer[slconn->start]);
2663                 } else {
2664                         ERR("Failed to call AT handler");
2665                         err = 0;
2666                 }
2667
2668                 if (err < 0) {
2669                         switch (err) {
2670                         case -EINVAL:
2671                                 err_return = HFP_STATE_MNGR_ERR_NOT_SUPPORTED;
2672                                 break;
2673                         case -EACCES:
2674                                 err_return = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
2675                                 break;
2676                         default:
2677                                 err_return = HFP_STATE_MNGR_ERR_NOT_SUPPORTED;
2678                                 break;
2679                         }
2680                         ERR("Error handling command %s: %s (%d)",
2681                                                 &slconn->buffer[slconn->start],
2682                                                 strerror(-err), -err);
2683                         err = _bt_ag_send_response(bt_ag_info,
2684                                         err_return);
2685                         if (err < 0)
2686                                 goto failed;
2687                 }
2688
2689                 slconn->start += cmd_len;
2690                 slconn->length -= cmd_len;
2691
2692                 if (slconn->length <= 0)
2693                         slconn->start = 0;
2694         }
2695         return TRUE;
2696 failed:
2697         ERR("Failed in event handler - SLC Disconnect");
2698         _bt_ag_set_headset_state(bt_ag_info,
2699                                         HEADSET_STATE_DISCONNECTED);
2700         return FALSE;
2701 }
2702
2703 static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
2704                                                 const gchar *object_path)
2705 {
2706         GIOFlags flags;
2707
2708         bt_ag_info_t *bt_ag_info = g_new0(bt_ag_info_t, 1);
2709         struct sockaddr_remote address;
2710         socklen_t address_len;
2711
2712         INFO_C("Connected [AG role]");
2713         bt_ag_info->rfcomm = NULL;
2714         bt_ag_info->slc = NULL;
2715         bt_ag_info->hfp_active = TRUE;
2716         bt_ag_info->vr_blacklisted = FALSE;
2717         bt_ag_info->state = HEADSET_STATE_DISCONNECTED;
2718         bt_ag_info->sco_server_started = FALSE;
2719         __bt_ag_codec_negotiation_info_reset(bt_ag_info, TRUE);
2720
2721         bt_ag_info->path = device_path;
2722         DBG_SECURE("device_path = [%s]", device_path);
2723
2724         address_len = sizeof(address);
2725         if (getpeername(fd, (struct sockaddr *) &address, &address_len) != 0)
2726                 ERR("BD_ADDR is NULL");
2727
2728         DBG("RFCOMM connection for HFP/HSP is completed. Fd = [%d]", fd);
2729         bt_ag_info->fd = fd;
2730         bt_ag_info->io_chan = g_io_channel_unix_new(bt_ag_info->fd);
2731         flags = g_io_channel_get_flags(bt_ag_info->io_chan);
2732
2733         flags &= ~G_IO_FLAG_NONBLOCK;
2734         flags &= G_IO_FLAG_MASK;
2735         g_io_channel_set_flags(bt_ag_info->io_chan, flags, NULL);
2736         g_io_channel_set_encoding(bt_ag_info->io_chan, NULL, NULL);
2737         g_io_channel_set_buffered(bt_ag_info->io_chan, FALSE);
2738
2739         bt_ag_info->rfcomm = g_io_channel_ref(bt_ag_info->io_chan);
2740
2741         bt_ag_info->remote_addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
2742         __bt_convert_addr_type_to_rev_string(bt_ag_info->remote_addr,
2743                                                 address.remote_bdaddr.b);
2744
2745 #if defined(TIZEN_SUPPORT_DUAL_HF)
2746         bt_ag_info->is_companion_device =
2747                         __bt_ag_agent_is_companion_device(bt_ag_info->remote_addr);
2748 #endif
2749
2750         DBG_SECURE("remote Device Address = [%s]", bt_ag_info->remote_addr);
2751
2752         if (g_strcmp0(object_path, BT_HS_AG_AGENT_OBJECT_PATH) == 0) {
2753                 DBG("HSP connection completed");
2754                 _bt_ag_set_headset_state(bt_ag_info,
2755                                                 HEADSET_STATE_CONNECTED);
2756         } else {
2757                 DBG("HFP connection connecting");
2758                 _bt_ag_set_headset_state(bt_ag_info,
2759                                                 HEADSET_STATE_CONNECTING);
2760         }
2761
2762         __bt_ag_agent_start_watch(bt_ag_info);
2763
2764         bt_ag_info->slc = g_new0(bt_ag_slconn_t, 1);
2765         bt_ag_info->slc->speaker_gain = last_speaker_gain;
2766         bt_ag_info->slc->microphone_gain = 9;
2767         bt_ag_info->slc->is_nrec = TRUE;
2768
2769         return TRUE;
2770 }
2771
2772 static gboolean __bt_ag_agent_is_device_vr_blacklisted(const char *lap_addr)
2773 {
2774         char *buffer;
2775         FILE *fp;
2776         long size;
2777         size_t result;
2778         char *token;
2779         char *saveptr;
2780
2781         fp = fopen(AGENT_VR_BLACKLIST_FILE, "r");
2782
2783         if (fp == NULL) {
2784                 ERR("Unable to open VR blacklist file");
2785                 return FALSE;
2786         }
2787
2788         fseek(fp, 0, SEEK_END);
2789         size = ftell(fp);
2790         if (size <= 0) {
2791                 ERR("size is not a positive number");
2792                 fclose(fp);
2793                 return FALSE;
2794         }
2795
2796         rewind(fp);
2797
2798         buffer = g_malloc0(sizeof(char) * size);
2799         if (buffer == NULL) {
2800                 ERR("g_malloc0 is failed");
2801                 fclose(fp);
2802                 return FALSE;
2803         }
2804         result = fread((char *)buffer, 1, size, fp);
2805         fclose(fp);
2806         if (result != size) {
2807                 ERR("Read Error");
2808                 g_free(buffer);
2809                 return FALSE;
2810         }
2811
2812         token = strtok_r(buffer, "=", &saveptr);
2813         if (token == NULL) {
2814                 g_free(buffer);
2815                 return FALSE;
2816         }
2817
2818         while ((token = strtok_r(NULL, ",", &saveptr))) {
2819                 if (strlen(token) > 8)
2820                         token[8] = '\0';
2821                 if (0 == g_strcmp0(token, lap_addr)) {
2822                         INFO("Voice Recognition blacklisted");
2823                         g_free(buffer);
2824                         return TRUE;
2825                 }
2826         }
2827         g_free(buffer);
2828         return FALSE;
2829 }
2830
2831 static gboolean __bt_sco_open_delay_timeout_cb(gpointer user_data)
2832 {
2833         bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)user_data;
2834         sco_open_timer_id = 0;
2835         DBG("sco_open_request (%d)", sco_open_request);
2836
2837         if (sco_open_request && bt_ag_info->state == HEADSET_STATE_CONNECTED) {
2838                 bt_ag_slconn_t *slconn = bt_ag_info->slc;
2839
2840                 INFO("try to open SCO");
2841                 sco_open_request = FALSE;
2842
2843                 if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
2844                                 (slconn && (slconn->hs_features &
2845                                         BT_HF_FEATURE_CODEC_NEGOTIATION))) {
2846                         switch (bt_ag_info->codec_info.final_codec) {
2847                         case BT_CVSD_CODEC_ID:
2848                                 __bt_ag_set_codec(bt_ag_info, "SetNbParameters");
2849                                 __bt_ag_sco_connect(bt_ag_info);
2850                                 break;
2851                         case BT_MSBC_CODEC_ID:
2852                                 __bt_ag_set_codec(bt_ag_info, "SetWbsParameters");
2853                                 __bt_ag_sco_connect(bt_ag_info);
2854                                 break;
2855                         default:
2856                                 __bt_hfp_codec_connection_setup(bt_ag_info, FALSE);
2857                                 break;
2858                         }
2859                 } else
2860                         __bt_ag_sco_connect(bt_ag_info);
2861
2862                 DBG("Dbus Reply for SCO Connection request");
2863                 g_dbus_method_invocation_return_value(bt_ag_info->invocation, NULL);
2864         }
2865
2866         return FALSE;
2867 }
2868
2869 /*
2870 * Service level connection complete
2871 * indication and state management
2872 */
2873 void _bt_ag_slconn_complete(bt_ag_info_t *hs)
2874 {
2875         char lap_address[BT_LOWER_ADDRESS_LENGTH];
2876
2877         DBG("HFP Service Level Connection established\n");
2878
2879         /* Check device Voice Recognition blacklist status */
2880         g_strlcpy(lap_address, hs->remote_addr, sizeof(lap_address));
2881         hs->vr_blacklisted =
2882                 __bt_ag_agent_is_device_vr_blacklisted(lap_address);
2883
2884         if (sco_open_timer_id > 0) {
2885                 g_source_remove(sco_open_timer_id);
2886                 sco_open_timer_id = 0;
2887         }
2888
2889         sco_open_request = FALSE;
2890         sco_open_timer_id = g_timeout_add(BT_SCO_OPEN_DELAY_TIMER,
2891                                                 __bt_sco_open_delay_timeout_cb, hs);
2892
2893         _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
2894 }
2895
2896 static gboolean __bt_ag_agent_connection_release(bt_ag_info_t *hs)
2897 {
2898
2899         g_io_channel_shutdown(hs->io_chan, TRUE, NULL);
2900         g_io_channel_unref(hs->io_chan);
2901         hs->io_chan = NULL;
2902
2903         if (hs->sco) {
2904                 __bt_ag_close_sco(hs);
2905                 _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
2906         }
2907         __bt_ag_agent_remove_watch(&hs->watch_id);
2908
2909         _bt_ag_set_headset_state(hs, HEADSET_STATE_DISCONNECTED);
2910         return TRUE;
2911 }
2912
2913 static GQuark __bt_ag_agent_error_quark(void)
2914 {
2915         FN_START;
2916
2917         static GQuark quark = 0;
2918         if (!quark)
2919                 quark = g_quark_from_static_string("ag-agent");
2920
2921         FN_END;
2922         return quark;
2923 }
2924
2925 static GError *__bt_ag_agent_set_error(bt_hfp_agent_error_t error)
2926 {
2927         FN_START;
2928         ERR("error[%d]\n", error);
2929
2930         switch (error) {
2931         case BT_HFP_AGENT_ERROR_NOT_AVAILABLE:
2932                 return g_error_new(BT_AG_AGENT_ERROR, error,
2933                                         BT_ERROR_NOT_AVAILABLE);
2934         case BT_HFP_AGENT_ERROR_NOT_CONNECTED:
2935         return g_error_new(BT_AG_AGENT_ERROR, error,
2936                                         BT_ERROR_NOT_CONNECTED);
2937         case BT_HFP_AGENT_ERROR_BUSY:
2938                 return g_error_new(BT_AG_AGENT_ERROR, error,
2939                                                 BT_ERROR_BUSY);
2940         case BT_HFP_AGENT_ERROR_INVALID_PARAM:
2941                 return g_error_new(BT_AG_AGENT_ERROR, error,
2942                                                 BT_ERROR_INVALID_PARAM);
2943         case BT_HFP_AGENT_ERROR_ALREADY_EXSIST:
2944                 return g_error_new(BT_AG_AGENT_ERROR, error,
2945                                                 BT_ERROR_ALREADY_EXSIST);
2946         case BT_HFP_AGENT_ERROR_ALREADY_CONNECTED:
2947                 return g_error_new(BT_AG_AGENT_ERROR, error,
2948                                                 BT_ERROR_ALREADY_CONNECTED);
2949         case BT_HFP_AGENT_ERROR_NO_MEMORY:
2950                 return g_error_new(BT_AG_AGENT_ERROR, error,
2951                                                 BT_ERROR_NO_MEMORY);
2952         case BT_HFP_AGENT_ERROR_I_O_ERROR:
2953                 return g_error_new(BT_AG_AGENT_ERROR, error,
2954                                                 BT_ERROR_I_O_ERROR);
2955         case BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE:
2956                 return g_error_new(BT_AG_AGENT_ERROR, error,
2957                                         BT_ERROR_OPERATION_NOT_AVAILABLE);
2958         case BT_HFP_AGENT_ERROR_BATTERY_STATUS:
2959                 return g_error_new(BT_AG_AGENT_ERROR, error,
2960                                         BT_ERROR_BATTERY);
2961         case BT_HFP_AGENT_ERROR_SIGNAL_STATUS:
2962                 return g_error_new(BT_AG_AGENT_ERROR, error,
2963                                         BT_ERROR_SIGNAL);
2964         case BT_HFP_AGENT_ERROR_NO_CALL_LOGS:
2965                 return g_error_new(BT_AG_AGENT_ERROR, error,
2966                                         BT_ERROR_NO_CALL_LOG);
2967         case BT_HFP_AGENT_ERROR_INTERNAL:
2968         default:
2969                 return g_error_new(BT_AG_AGENT_ERROR, error,
2970                                                 BT_ERROR_INTERNAL);
2971         }
2972         FN_END;
2973 }
2974
2975 static bt_ag_info_t *__bt_get_active_headset(const gchar *device_path)
2976 {
2977         GSList *l;
2978
2979         for (l = active_devices ; l; l = l->next) {
2980                 bt_ag_info_t *data = l->data;
2981                 if (device_path == NULL) /*just to avoid crash incase of "play" when dailed from device[NEEDS TO BE CHANGED]*/
2982                         return data;
2983                 if (g_strcmp0(data->path, device_path) == 0) {
2984                         INFO("Active device found");
2985                         return data;
2986                 }
2987         }
2988
2989         INFO("Active device not found");
2990         return NULL;
2991 }
2992
2993 static void __bt_ag_agent_method(GDBusConnection *connection,
2994                         const gchar *sender,
2995                         const gchar *object_path,
2996                         const gchar *interface_name,
2997                         const gchar *method_name,
2998                         GVariant *parameters,
2999                         GDBusMethodInvocation *invocation,
3000                         gpointer user_data)
3001 {
3002         FN_START;
3003
3004         INFO("method %s", method_name);
3005         INFO("object_path %s", object_path);
3006         int ret = BT_HFP_AGENT_ERROR_NONE;
3007         GError *err = NULL;
3008         const gchar *device_path = NULL;
3009         GSList *l;
3010
3011         if (g_strcmp0(method_name, "NewConnection") == 0) {
3012                 gint32 fd;
3013                 int index = 0;
3014                 GDBusMessage *msg;
3015                 GUnixFDList *fd_list;
3016                 GVariant *options = NULL;
3017                 int device_count = 0;
3018
3019                 device_count = g_slist_length(active_devices);
3020
3021                 INFO("device_count %d", device_count);
3022
3023                 if (device_count >= MAX_CONNECTED_DEVICES) {
3024                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3025                         goto fail;
3026                 }
3027
3028                 g_variant_get(parameters, "(oha{sv})",
3029                                                 &device_path, &index, &options);
3030 #if defined(TIZEN_SUPPORT_DUAL_HF)
3031                 if (TIZEN_PROFILE_WEARABLE) {
3032                         /*
3033                          * Below code is not required for dual HF support for
3034                          * mobile devices
3035                          */
3036                         if (device_count &&
3037                                 __bt_ag_agent_check_dual_hf_condition(device_path) == FALSE) {
3038                                 INFO("not allow to connect 2nd HF connection");
3039                                 ret = BT_HFP_AGENT_ERROR_INTERNAL;
3040                                 goto fail;
3041                         }
3042                 }
3043 #endif
3044                 msg = g_dbus_method_invocation_get_message(invocation);
3045                 fd_list = g_dbus_message_get_unix_fd_list(msg);
3046                 if (fd_list == NULL) {
3047                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3048                         goto fail;
3049                 }
3050
3051                 fd = g_unix_fd_list_get(fd_list, index, NULL);
3052                 if (fd == -1) {
3053                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3054                         goto fail;
3055                 }
3056
3057                 DBG_SECURE("FD is = [%d], device_path = [%s]\n", fd, device_path);
3058
3059                 if (!__bt_ag_agent_connection(fd, device_path, object_path)) {
3060                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3061                         goto fail;
3062                 }
3063
3064                 g_dbus_method_invocation_return_value(invocation, NULL);
3065         } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
3066
3067                 g_variant_get(parameters, "(o)", &device_path);
3068                 INFO_SECURE("device_path %s", device_path);
3069
3070                 for (l = active_devices; l; l = l->next) {
3071                         bt_ag_info_t *data = l->data;
3072
3073                         INFO_SECURE("data->path %s", data->path);
3074                         if (g_strcmp0(data->path, device_path) == 0) {
3075                                 if (!__bt_ag_agent_connection_release(data)) {
3076                                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3077                                         goto fail;
3078                                 }
3079                                 INFO_C("Disconnected [AG role] [Terminated by local host]");
3080                                 g_dbus_method_invocation_return_value(invocation, NULL);
3081                         }
3082                 }
3083         } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
3084                 const guint accept;
3085                 bt_ag_info_t *data;
3086                 g_variant_get(parameters, "(u)", &accept);
3087                 INFO("Accept: %d", accept);
3088
3089                 l = active_devices;
3090                 data = l->data;
3091                 INFO_SECURE("data->path %s", data->path);
3092                 data->pbap_trusted = accept;
3093
3094                 _bt_hfp_select_phonebook_memory_status_reply(data);
3095
3096                 INFO("pbap_trusted %d", data->pbap_trusted);
3097
3098                 if (data->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) {
3099                         /* Allow Access update this to bluez */
3100                         bt_device_set_profile_trusted(data->remote_addr,
3101                                 1, TRUE);
3102                 } else if (data->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) {
3103                         /* Blocked Access update this to bluez */
3104                         bt_device_set_profile_trusted(data->remote_addr,
3105                                 1, FALSE);
3106                 }
3107         } else if (g_strcmp0(method_name, "RegisterApplication") == 0) {
3108                 gchar *path = NULL;
3109                 gchar *address = NULL;
3110                 g_variant_get(parameters, "(&s&s)", &path, &address);
3111                 /*local_addr = malloc(strlen(address));
3112                 memcpy(local_addr, address, strlen(address));*/
3113
3114                 DBG("Sender = %s, Application path = %s\n", sender, path);
3115                 ret = _bt_hfp_register_telephony_agent(TRUE, path, sender);
3116                 if (ret)
3117                         goto fail;
3118
3119                 g_free(local_addr);
3120                 local_addr = g_strdup(address);
3121                 DBG_SECURE("Address = %s\n", local_addr);
3122                 g_dbus_method_invocation_return_value(invocation, NULL);
3123         } else if (g_strcmp0(method_name, "UnregisterApplication") == 0) {
3124                 gchar *path = NULL;
3125                 g_variant_get(parameters, "(&s)", &path);
3126
3127                 DBG("Application path = %s\n", path);
3128                 DBG("Sender = %s\n", sender);
3129
3130                 ret = _bt_hfp_register_telephony_agent(FALSE, path, sender);
3131                 if (ret)
3132                         goto fail;
3133
3134                 g_dbus_method_invocation_return_value(invocation, NULL);
3135         } else if (g_strcmp0(method_name, "IncomingCall") == 0) {
3136                 gchar *path = NULL;
3137                 gchar *number = NULL;
3138                 gint call_id = 0;
3139
3140                 g_variant_get(parameters, "(&s&si)", &path, &number, &call_id);
3141
3142                 DBG("Application path = %s", path);
3143                 DBG_SECURE("Phone number = %s", number);
3144                 DBG("Call id = %d", call_id);
3145
3146                 DBG("Sender = %s", sender);
3147
3148                 ret = _bt_hfp_incoming_call(path, number, call_id, sender);
3149                 if (ret)
3150                         goto fail;
3151                 g_dbus_method_invocation_return_value(invocation, NULL);
3152         } else if (g_strcmp0(method_name, "OutgoingCall") == 0) {
3153                 gchar *path = NULL;
3154                 gchar *number = NULL;
3155                 gint call_id = 0;
3156
3157                 g_variant_get(parameters, "(&s&si)", &path, &number, &call_id);
3158
3159                 DBG("Application path = %s", path);
3160                 DBG_SECURE("Phone number = %s", number);
3161                 DBG("Call id = %d", call_id);
3162
3163                 DBG("Sender = %s", sender);
3164
3165                 ret = _bt_hfp_outgoing_call(path, number, call_id, sender);
3166                 if (ret)
3167                         goto fail;
3168                 g_dbus_method_invocation_return_value(invocation, NULL);
3169         } else if (g_strcmp0(method_name, "ChangeCallStatus") == 0) {
3170                 gchar *path = NULL;
3171                 gchar *number = NULL;
3172                 gint status = 0;
3173                 gint call_id = 0;
3174                 GSList *l;
3175
3176                 g_variant_get(parameters, "(&s&sii)",
3177                                         &path, &number, &status, &call_id);
3178                 DBG("Application path = %s\n", path);
3179                 DBG_SECURE("Number = %s\n", number);
3180                 DBG("Status = %d\n", status);
3181                 DBG("Call id = %d\n", call_id);
3182                 DBG("Sender = %s\n", sender);
3183
3184                 ret = _bt_hfp_change_call_status(path,
3185                                         number, status, call_id, sender);
3186
3187                 if (_bt_hfp_is_call_exist() == FALSE) {
3188                         for (l = active_devices; l; l = l->next) {
3189                                 bt_ag_info_t *data = l->data;
3190
3191                                 if (data->state == HEADSET_STATE_ON_CALL) {
3192                                         __bt_ag_close_sco(data);
3193                                         _bt_ag_set_headset_state(data,
3194                                                 HEADSET_STATE_CONNECTED);
3195                                 }
3196                         }
3197                 }
3198
3199                 if (ret)
3200                         goto fail;
3201                 g_dbus_method_invocation_return_value(invocation, NULL);
3202         } else if (g_strcmp0(method_name, "GetProperties") == 0) {
3203                 GVariantBuilder *builder;
3204                 GVariant *var_data;
3205                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3206
3207                 if (bt_ag_info) {
3208                         gchar *codec = g_strdup("codec");
3209                         gchar *nrec = g_strdup("nrec");
3210
3211                         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
3212
3213                         g_variant_builder_add(builder, "{sv}",
3214                                         codec, g_variant_new("u", bt_ag_info->codec_info.final_codec));
3215                         g_variant_builder_add(builder, "{sv}",
3216                                         nrec, g_variant_new("b", bt_ag_info->nrec_status));
3217
3218                         var_data = g_variant_new("(a{sv})", builder);
3219                         g_variant_builder_unref(builder);
3220                         g_dbus_method_invocation_return_value(invocation, var_data);
3221
3222                         g_free(codec);
3223                         g_free(nrec);
3224                 } else {
3225                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3226                         goto fail;
3227                 }
3228         } else if (g_strcmp0(method_name, "Disconnect") == 0) {
3229                 char hdset_address[18] = { 0, };
3230
3231                 for (l = active_devices; l; l = l->next) {
3232                         bt_ag_info_t *data = l->data;
3233
3234                         __bt_convert_addr_type_to_rev_string(hdset_address,
3235                                         (unsigned char *)data->remote_addr);
3236
3237                         DBG_SECURE("Disconnect Headset %s, %s\n",
3238                                                 hdset_address, data->path);
3239                         _bt_ag_set_headset_state(data,
3240                                                 HEADSET_STATE_DISCONNECTED);
3241                 }
3242                 g_dbus_method_invocation_return_value(invocation, NULL);
3243         } else if (g_strcmp0(method_name, "IsConnected") == 0) {
3244                 gboolean is_connected = FALSE;
3245
3246                 for (l = active_devices; l; l = l->next) {
3247                         bt_ag_info_t *data = l->data;
3248
3249                         if (data->state >= HEADSET_STATE_CONNECTED)
3250                                 is_connected = TRUE;
3251                 }
3252                 DBG("is_connected : %s",
3253                                 is_connected ? "Connected" : "Disconnected");
3254
3255                 g_dbus_method_invocation_return_value(invocation,
3256                                 g_variant_new("(b)", is_connected));
3257         } else if (g_strcmp0(method_name, "IndicateCall") == 0) {
3258
3259                 if (0 == g_slist_length(active_devices)) {
3260                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3261                         goto fail;
3262                 }
3263
3264                 if (ag.ring_timer) {
3265                         DBG("IndicateCall received when already indicating");
3266                         g_dbus_method_invocation_return_value(invocation, NULL);
3267                 }
3268
3269                 for (l = active_devices; l; l = l->next) {
3270                         bt_ag_info_t *data = l->data;
3271
3272                         if (data->state >= HEADSET_STATE_CONNECTED)
3273                                 _bt_ag_send_at(data, "\r\nRING\r\n");
3274                 }
3275
3276                 __bt_ring_timer_cb(NULL);
3277                 ag.ring_timer = g_timeout_add(AG_RING_INTERVAL,
3278                                 __bt_ring_timer_cb, NULL);
3279                 g_dbus_method_invocation_return_value(invocation, NULL);
3280         } else if (g_strcmp0(method_name, "CancelCall") == 0) {
3281                 if (0 == g_slist_length(active_devices)) {
3282                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3283                         goto fail;
3284                 }
3285
3286                 if (ag.ring_timer) {
3287                         g_source_remove(ag.ring_timer);
3288                         ag.ring_timer = 0;
3289                 } else
3290                         DBG("Got CancelCall method call but no call is active");
3291
3292                 g_dbus_method_invocation_return_value(invocation, NULL);
3293         } else if (g_strcmp0(method_name, "Play") == 0) {
3294                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3295                 bt_ag_slconn_t *slconn = NULL;
3296
3297                 if (bt_ag_info) {
3298                         slconn = bt_ag_info->slc;
3299                 } else {
3300                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3301                         goto fail;
3302                 }
3303
3304 #ifndef __TIZEN_OPEN__
3305 #ifdef MDM_PHASE_2
3306                 int mode;
3307                 if (slconn && FALSE == slconn->is_voice_recognition_running &&
3308                                 mdm_get_service() == MDM_RESULT_SUCCESS) {
3309                         mode = mdm_get_allow_bluetooth_outgoing_call();
3310                         mdm_release_service();
3311
3312                         if (mode == MDM_RESTRICTED) {
3313                                 ERR("[MDM] Not allow the outgoing call");
3314                                 ret = BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE;
3315                                 goto fail;
3316                         }
3317                 }
3318 #endif
3319 #endif
3320
3321                 switch (bt_ag_info->state) {
3322                 case HEADSET_STATE_CONNECTING:
3323                 case HEADSET_STATE_DISCONNECTED:
3324                         ERR("HEADSET_STATE  ERROR");
3325                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3326                         break;
3327                 case HEADSET_STATE_CONNECTED:
3328                         break;
3329                 case HEADSET_STATE_PLAY_IN_PROGRESS:
3330                         ERR("Play In Progress");
3331                         ret = BT_HFP_AGENT_ERROR_BUSY;
3332                         break;
3333                 case HEADSET_STATE_ON_CALL:
3334                         ERR("SCO is already established");
3335                         ret = BT_HFP_AGENT_ERROR_ALREADY_CONNECTED;
3336                         break;
3337                 default:
3338                         break;
3339                 }
3340                 if (ret)
3341                         goto fail;
3342
3343                 if (sco_open_timer_id > 0) {
3344                         INFO("SCO open delay");
3345                         sco_open_request = TRUE;
3346                         bt_ag_info->invocation = invocation;
3347                         return;
3348                 }
3349
3350                 if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
3351                                 (slconn && (slconn->hs_features &
3352                                         BT_HF_FEATURE_CODEC_NEGOTIATION))) {
3353                         switch (bt_ag_info->codec_info.final_codec) {
3354                         case BT_CVSD_CODEC_ID:
3355                                 __bt_ag_set_codec(bt_ag_info, "SetNbParameters");
3356                                 ret = __bt_ag_sco_connect(bt_ag_info);
3357                                 break;
3358                         case BT_MSBC_CODEC_ID:
3359                                 __bt_ag_set_codec(bt_ag_info, "SetWbsParameters");
3360                                 ret = __bt_ag_sco_connect(bt_ag_info);
3361                                 break;
3362                         default:
3363                                 ret = __bt_hfp_codec_connection_setup(bt_ag_info, FALSE);
3364                                 break;
3365                         }
3366                 } else
3367                         ret = __bt_ag_sco_connect(bt_ag_info);
3368
3369                 if (ret)
3370                         goto fail;
3371
3372                 g_free(sco_owner);
3373                 sco_owner = g_strdup(sender);
3374
3375                 g_dbus_method_invocation_return_value(invocation, NULL);
3376
3377                 if (name_owner_sig_id == 0)
3378                         name_owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
3379                                         NULL, NULL, "NameOwnerChanged", NULL, NULL, 0,
3380                                         __bt_ag_name_owner_changed_cb, NULL, NULL);
3381         } else if (g_strcmp0(method_name, "Stop") == 0) {
3382
3383                 for (l = active_devices; l; l = l->next) {
3384                         bt_ag_info_t *data = l->data;
3385
3386                         if (data->state > HEADSET_STATE_CONNECTED) {
3387                                 __bt_ag_close_sco(data);
3388                                 _bt_ag_set_headset_state(data,
3389                                         HEADSET_STATE_CONNECTED);
3390                         }
3391                 }
3392
3393                 g_dbus_method_invocation_return_value(invocation, NULL);
3394         } else if (g_strcmp0(method_name, "IsPlaying") == 0) {
3395                 gboolean is_playing = FALSE;
3396
3397                 for (l = active_devices; l; l = l->next) {
3398                         bt_ag_info_t *data = l->data;
3399
3400                         if (data->state == HEADSET_STATE_ON_CALL)
3401                                 is_playing = TRUE;
3402                 }
3403                 DBG("is_playing : %s", is_playing ? "Playing" : "Not Playing");
3404
3405                 g_dbus_method_invocation_return_value(invocation,
3406                                 g_variant_new("(b)", is_playing));
3407         } else if (g_strcmp0(method_name, "GetSpeakerGain") == 0) {
3408                 bt_ag_slconn_t *slconn = NULL;
3409                 guint16 gain_value = 0;
3410                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3411
3412                 if (bt_ag_info == NULL ||
3413                         bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3414                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3415                         goto fail;
3416                 }
3417
3418                 slconn = bt_ag_info->slc;
3419                 if (slconn)
3420                         gain_value = (guint16) slconn->speaker_gain;
3421
3422                 g_dbus_method_invocation_return_value(invocation,
3423                                 g_variant_new("(q)", gain_value));
3424         } else if (g_strcmp0(method_name, "SetSpeakerGain") == 0) {
3425                 guint16 gain = 0;
3426                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3427                 if (bt_ag_info == NULL ||
3428                         bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3429                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3430                         goto fail;
3431                 }
3432
3433                 g_variant_get(parameters, "(q)", &gain);
3434                 DBG("Speaker gain = %d\n", gain);
3435
3436                 ret = _bt_hfp_set_speaker_gain(bt_ag_info, gain);
3437                 if (ret)
3438                         goto fail;
3439                 g_dbus_method_invocation_return_value(invocation, NULL);
3440         } else if (g_strcmp0(method_name, "GetMicrophoneGain") == 0) {
3441                 bt_ag_slconn_t *slconn = NULL;
3442                 guint16 gain_value = 0;
3443                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3444
3445                 if (bt_ag_info == NULL ||
3446                         bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3447                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3448                         goto fail;
3449                 }
3450
3451                 if (bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3452                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3453                         goto fail;
3454                 }
3455
3456                 slconn = bt_ag_info->slc;
3457                 if (slconn)
3458                         gain_value = (guint16) slconn->microphone_gain;
3459
3460                 g_dbus_method_invocation_return_value(invocation,
3461                                 g_variant_new("(q)", gain_value));
3462         } else if (g_strcmp0(method_name, "SetMicrophoneGain") == 0) {
3463                 guint16 gain = 0;
3464                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3465                 if (bt_ag_info == NULL ||
3466                         bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3467                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3468                         goto fail;
3469                 }
3470
3471                 g_variant_get(parameters, "(q)", &gain);
3472                 DBG("Microphone gain = %d\n", gain);
3473
3474                 ret = _bt_hfp_set_microphone_gain(bt_ag_info, gain);
3475                 if (ret)
3476                         goto fail;
3477                 g_dbus_method_invocation_return_value(invocation, NULL);
3478         } else if (g_strcmp0(method_name, "SetVoiceDial") == 0) {
3479                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3480                 if (bt_ag_info == NULL ||
3481                         bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3482                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3483                         goto fail;
3484                 }
3485
3486                 bt_ag_slconn_t *slconn = bt_ag_info->slc;
3487                 gboolean enable;
3488
3489                 g_variant_get(parameters, "(b)", &enable);
3490                 DBG("VoiceDail enable = %d\n", enable);
3491
3492                 if ((slconn && !(slconn->hs_features &
3493                                         BT_HF_FEATURE_VOICE_RECOGNITION)))
3494                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3495                 else if (bt_ag_info->vr_blacklisted)
3496                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3497                 else
3498                         ret = _bt_hfp_set_voice_dial(bt_ag_info, enable);
3499
3500                 if (slconn)
3501                         slconn->is_voice_recognition_running = enable;
3502
3503                 if (ret)
3504                         goto fail;
3505                 g_dbus_method_invocation_return_value(invocation, NULL);
3506         } else if (g_strcmp0(method_name, "SendVendorAtCmd") == 0) {
3507                 gchar *cmd;
3508                 bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
3509                 if (bt_ag_info == NULL ||
3510                         bt_ag_info->state < HEADSET_STATE_CONNECTED) {
3511                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3512                         goto fail;
3513                 }
3514
3515                 g_variant_get(parameters, "(&s)", &cmd);
3516                 if (cmd == NULL) {
3517                         ret = BT_HFP_AGENT_ERROR_INVALID_PARAM;
3518                         goto fail;
3519                 }
3520
3521                 DBG("vendor cmd = %s", cmd);
3522
3523                 ret = _bt_hfp_send_vendor_cmd(bt_ag_info, cmd);
3524                 if (ret)
3525                         goto fail;
3526                 g_dbus_method_invocation_return_value(invocation, NULL);
3527         } else if (g_strcmp0(method_name, "CheckPrivilege") == 0) {
3528                 DBG("Already pass dbus SMACK for bt-service::platform");
3529                 /* Return success */
3530                 g_dbus_method_invocation_return_value(invocation, NULL);
3531         }  else if (g_strcmp0(method_name, "SwapHeadset") == 0) {
3532                 GSList *l;
3533                 gchar *addr = NULL;
3534                 char address[BT_ADDRESS_STRING_SIZE];
3535                 char remote_addr[BT_ADDRESS_STRING_SIZE];
3536                 gboolean device_found = FALSE;
3537
3538                 g_variant_get(parameters, "(s)", &addr);
3539                 g_strlcpy(address, addr, sizeof(address));
3540                 DBG("Sender = %s", sender);
3541
3542                 /* Loop through connected headset list
3543                  * If found, update the remote_dev_path.
3544                  */
3545                 for (l = active_devices ; l; l = l->next) {
3546                         bt_ag_info_t *data = l->data;
3547                         g_strlcpy(remote_addr, data->remote_addr, sizeof(remote_addr));
3548                         if (g_strcmp0(remote_addr, address) == 0) {
3549                                 DBG("Active device found");
3550                                 if (data->path == NULL) {
3551                                         DBG("device path is null");
3552                                         ret = BT_HFP_AGENT_ERROR_INTERNAL;
3553                                         goto fail;
3554                                 }
3555                                 remote_dev_path = g_strdup(data->path);
3556                                 DBG("Setting device path %s as active device path", remote_dev_path);
3557                                 device_found = TRUE;
3558                                 break;
3559                         }
3560                 }
3561
3562                 if (!device_found) {
3563                         ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
3564                         goto fail;
3565                 }
3566
3567                 g_dbus_method_invocation_return_value(invocation, NULL);
3568         }
3569
3570         INFO("-");
3571         return;
3572
3573 fail:
3574         err = __bt_ag_agent_set_error(ret);
3575         g_dbus_method_invocation_return_gerror(invocation, err);
3576         g_error_free(err);
3577         INFO("-");
3578 }
3579
3580 static const GDBusInterfaceVTable method_table = {
3581         __bt_ag_agent_method,
3582         NULL,
3583         NULL,
3584 };
3585
3586 static GDBusNodeInfo *__bt_ag_create_method_node_info
3587                                         (const gchar *introspection_data)
3588 {
3589         GError *err = NULL;
3590         GDBusNodeInfo *node_info = NULL;
3591
3592         if (introspection_data == NULL)
3593                 return NULL;
3594
3595         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
3596
3597         if (err) {
3598                 ERR("Unable to create node: %s", err->message);
3599                 g_clear_error(&err);
3600         }
3601         return node_info;
3602 }
3603
3604 static GDBusConnection *__bt_ag_get_gdbus_connection(void)
3605 {
3606         FN_START;
3607
3608         GError *err = NULL;
3609
3610         if (ag_dbus_conn == NULL)
3611                 ag_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
3612
3613         if (!ag_dbus_conn) {
3614                 if (err) {
3615                         ERR("Unable to connect to dbus: %s", err->message);
3616                         g_clear_error(&err);
3617                 }
3618                 return NULL;
3619         }
3620         FN_END;
3621
3622         return ag_dbus_conn;
3623 }
3624
3625 static gboolean __bt_ag_register_profile_methods(void)
3626 {
3627         FN_START;
3628         GError *error = NULL;
3629         guint owner_id;
3630         GDBusNodeInfo *node_info = NULL;
3631         gchar *path;
3632
3633         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
3634                                 BT_AG_SERVICE_NAME,
3635                                 G_BUS_NAME_OWNER_FLAGS_NONE,
3636                                 NULL, NULL, NULL,
3637                                 NULL, NULL);
3638
3639         DBG("owner_id is [%d]", owner_id);
3640
3641         node_info = __bt_ag_create_method_node_info(
3642                                 ag_agent_bluez_introspection_xml);
3643         if (node_info == NULL)
3644                 return FALSE;
3645
3646         path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
3647         DBG("path is [%s]", path);
3648
3649         hf_bluez_id = g_dbus_connection_register_object(ag_dbus_conn, path,
3650                                         node_info->interfaces[0],
3651                                         &method_table,
3652                                         NULL, NULL, &error);
3653         if (hf_bluez_id == 0) {
3654                 ERR("Failed to register: %s", error->message);
3655                 g_error_free(error);
3656                 g_free(path);
3657                 g_dbus_node_info_unref(node_info);
3658                 return FALSE;
3659         }
3660         g_free(path);
3661
3662         /* Ag register profile methods for HSP*/
3663
3664         path = g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
3665         DBG("path is [%s]", path);
3666
3667         hs_bluez_id = g_dbus_connection_register_object(ag_dbus_conn, path,
3668                                         node_info->interfaces[0],
3669                                         &method_table,
3670                                         NULL, NULL, &error);
3671         if (hs_bluez_id == 0) {
3672                 ERR("Failed to register: %s", error->message);
3673                 g_error_free(error);
3674                 g_free(path);
3675                 g_dbus_node_info_unref(node_info);
3676                 return FALSE;
3677         }
3678         g_free(path);
3679         g_dbus_node_info_unref(node_info);
3680
3681         node_info = __bt_ag_create_method_node_info
3682                                 (ag_agent_app_introspection_xml);
3683         if (node_info == NULL)
3684                 return FALSE;
3685
3686         path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
3687         DBG("path is [%s]", path);
3688
3689         app_id = g_dbus_connection_register_object(ag_dbus_conn, path,
3690                                                 node_info->interfaces[0],
3691                                                 &method_table,
3692                                                 NULL, NULL, &error);
3693         if (app_id == 0) {
3694                 ERR("Failed to register: %s", error->message);
3695                 g_error_free(error);
3696                 g_free(path);
3697                 g_dbus_node_info_unref(node_info);
3698                 return FALSE;
3699         }
3700         g_free(path);
3701         g_dbus_node_info_unref(node_info);
3702
3703         FN_END;
3704         return TRUE;
3705 }
3706
3707 static void __bt_ag_unregister_profile_methods(void)
3708 {
3709         DBG("");
3710
3711         if (hf_bluez_id > 0) {
3712                 g_dbus_connection_unregister_object(ag_dbus_conn,
3713                                                         hf_bluez_id);
3714                 hf_bluez_id = 0;
3715         }
3716
3717         if (hs_bluez_id > 0) {
3718                 g_dbus_connection_unregister_object(ag_dbus_conn,
3719                                                         hs_bluez_id);
3720                 hs_bluez_id = 0;
3721         }
3722
3723         if (app_id > 0) {
3724                 g_dbus_connection_unregister_object(ag_dbus_conn,
3725                                                         app_id);
3726                 app_id = 0;
3727         }
3728 }
3729
3730 static GDBusProxy *__bt_ag_gdbus_get_profile_proxy(void)
3731 {
3732         return (profile_gproxy) ? profile_gproxy :
3733                                   __bt_ag_gdbus_init_profile_proxy();
3734 }
3735
3736 static void __bt_ag_agent_register(gchar *path, uint16_t profile_version,
3737                                 char *profile_uuid, const char* profile_name)
3738 {
3739         FN_START;
3740         GDBusProxy *proxy;
3741         GVariant *ret;
3742         GError *error = NULL;
3743         GVariantBuilder *builder;
3744
3745         proxy = __bt_ag_gdbus_get_profile_proxy();
3746         if (proxy == NULL)
3747                 return;
3748
3749         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
3750
3751         g_variant_builder_add(builder, "{sv}",
3752                         "Name", g_variant_new("s",
3753                         profile_name));
3754         g_variant_builder_add(builder, "{sv}",
3755                         "Version", g_variant_new("q", profile_version));
3756         /*g_variant_builder_add(builder, "{sv}",
3757                         "Role", g_variant_new("s","client"));*/
3758         if (g_strcmp0(path, BT_AG_AGENT_OBJECT_PATH) == 0) {
3759                 g_variant_builder_add(builder, "{sv}",
3760                                 "features", g_variant_new("q", ag.sdp_features));
3761         }
3762
3763         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
3764                                         g_variant_new("(osa{sv})", path,
3765                                                         profile_uuid, builder),
3766                                         G_DBUS_CALL_FLAGS_NONE, -1,
3767                                         NULL, &error);
3768         g_variant_builder_unref(builder);
3769         /* set the name and role for the profile*/
3770         if (ret == NULL) {
3771                 /* dBUS-RPC is failed */
3772                 ERR("dBUS-RPC is failed");
3773
3774                 if (error != NULL) {
3775                         /* dBUS gives error cause */
3776                         ERR("D-Bus API failure: errCode[%x], message[%s]",
3777                                         error->code, error->message);
3778
3779                         g_clear_error(&error);
3780                 }
3781                 g_free(path);
3782                 return;
3783         }
3784         g_variant_unref(ret);
3785         g_free(path);
3786
3787         FN_END;
3788         return;
3789 }
3790
3791 static void __bt_ag_agent_unregister(gchar *path)
3792 {
3793         FN_START;
3794         GDBusProxy *proxy;
3795         GVariant *ret;
3796         GError *error = NULL;
3797
3798         proxy = __bt_ag_gdbus_get_profile_proxy();
3799         if (proxy == NULL)
3800                 return;
3801
3802         ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
3803                                         g_variant_new("(o)", path),
3804                                         G_DBUS_CALL_FLAGS_NONE, 100,
3805                                         NULL, &error);
3806         g_free(path);
3807         /* set the name and role for the profile*/
3808         if (ret == NULL) {
3809                 /* dBUS-RPC is failed */
3810                 ERR("dBUS-RPC is failed");
3811
3812                 if (error != NULL) {
3813                         /* dBUS gives error cause */
3814                         ERR("D-Bus API failure: errCode[%x], message[%s]",
3815                                         error->code, error->message);
3816
3817                         g_clear_error(&error);
3818                 }
3819                 return;
3820         }
3821         g_variant_unref(ret);
3822
3823         if (local_addr) {
3824                 g_free(local_addr);
3825                 local_addr = NULL;
3826         }
3827         FN_END;
3828         return;
3829 }
3830
3831 static void __bt_ag_agent_battery_status_cb(device_callback_e type,
3832                                                 void *value, void *user_data)
3833 {
3834         int batt_cap;
3835         if (type == DEVICE_CALLBACK_BATTERY_CAPACITY) {
3836                 device_battery_get_percent(&batt_cap);
3837                 _bt_hfp_set_property_value("BatteryBarsChanged", batt_cap);
3838         }
3839 }
3840
3841 static void __bt_ag_agent_network_signal_status_cb(TapiHandle *handle,
3842                 const char *noti_id, void *data, void *user_data)
3843 {
3844         int *signal_bar = data;
3845
3846         BT_CHECK_SIGNAL_STRENGTH(*signal_bar);
3847         _bt_hfp_set_property_value("SignalBarsChanged", *signal_bar);
3848 }
3849
3850 static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node)
3851 {
3852         gboolean status = vconf_keynode_get_bool(node);
3853         GSList *l;
3854         DBG("status = %d", status);
3855
3856         if (status == TRUE) {
3857                 for (l = active_devices; l; l = l->next) {
3858                         bt_ag_info_t *data = l->data;
3859                         _bt_ag_send_at(data, "\r\n+BSIR:1\r\n");
3860                 }
3861         }
3862 }
3863
3864 static void __bt_ag_agent_call_preferred_voice_subscription_cb(TapiHandle *handle,
3865                 const char *noti_id, void *data, void *user_data)
3866 {
3867         TelCallPreferredVoiceSubsNoti_t *noti_data = (TelCallPreferredVoiceSubsNoti_t *)data;
3868         uint32_t ag_features;
3869         int tapi_result;
3870         if (!noti_data) {
3871                 ERR("Error happen during voice subscription data noti");
3872                 return;
3873         }
3874
3875         INFO("TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION = Value %d",
3876                                                 noti_data->preferred_subs);
3877         ag_features = __bt_ag_agent_get_ag_features();
3878         switch (noti_data->preferred_subs) {
3879         case TAPI_CALL_PREFERRED_VOICE_SUBS_SIM1:
3880         case TAPI_CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS:
3881                 if (tapi_handle_preferred_sim == tapi_handle[0]) {
3882                         INFO("No handler change. Preferred sim is same as SIM1");
3883                         break;
3884                 }
3885                 __bt_ag_agent_unsubscribe_tapi_updates(tapi_handle_preferred_sim);
3886                 tapi_handle_preferred_sim = tapi_handle[0];
3887                 _bt_hfp_initialize_telephony_manager(ag_features, tapi_handle_preferred_sim);
3888                 __bt_ag_agent_subscribe_tapi_updates(tapi_handle_preferred_sim);
3889                 tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL);
3890                 if (tapi_result != TAPI_API_SUCCESS)
3891                         ERR("Fail to get sim info: %d", tapi_result);
3892                 break;
3893         case TAPI_CALL_PREFERRED_VOICE_SUBS_SIM2:
3894                 if (tapi_handle_preferred_sim == tapi_handle[1]) {
3895                         INFO("No handler change. Preferred sim is same as SIM2");
3896                         break;
3897                 }
3898                 __bt_ag_agent_unsubscribe_tapi_updates(tapi_handle_preferred_sim);
3899                 tapi_handle_preferred_sim = tapi_handle[1];
3900                 _bt_hfp_initialize_telephony_manager(ag_features, tapi_handle_preferred_sim);
3901                 __bt_ag_agent_subscribe_tapi_updates(tapi_handle_preferred_sim);
3902                 tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL);
3903                 if (tapi_result != TAPI_API_SUCCESS)
3904                         ERR("Fail to get sim info: %d", tapi_result);
3905
3906                 break;
3907
3908         case TAPI_CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK:
3909         case TAPI_CALL_PREFERRED_VOICE_SUBS_UNKNOWN:
3910         default:
3911                 break;
3912         }
3913 }
3914
3915 static void __bt_ag_agent_network_register_status_cb(TapiHandle *handle,
3916                 const char *noti_id, void *data, void *user_data)
3917 {
3918         int service;
3919         bt_hfp_agent_network_registration_status_t network_service;
3920         int roam_status;
3921         int ret;
3922
3923         int *service_type = data;
3924
3925         DBG("Network service type changed = [%d]", *service_type);
3926
3927         switch (*service_type) {
3928         case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN:
3929         case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE:
3930         case TAPI_NETWORK_SERVICE_TYPE_SEARCH:
3931                 service = 0;
3932                 break;
3933         default:
3934                 service = 1;
3935                 break;
3936         }
3937
3938         ret = tel_get_property_int(GET_TAPI_HANDLE,
3939                         TAPI_PROP_NETWORK_ROAMING_STATUS, &roam_status);
3940         if (ret != TAPI_API_SUCCESS) {
3941                 ERR("Get roaming status failed err = %d\n", ret);
3942                 return;
3943         }
3944
3945         if (roam_status == 0 && service == 1)
3946                 network_service = BT_AGENT_NETWORK_REG_STATUS_HOME;
3947         else if (roam_status == 1 && service == 1)
3948                 network_service = BT_AGENT_NETWORK_REG_STATUS_ROAMING;
3949         else
3950                 network_service = BT_AGENT_NETWORK_REG_STATUS_UNKOWN;
3951
3952         _bt_hfp_set_property_value("RegistrationChanged", network_service);
3953 }
3954
3955 static void __bt_ag_agent_subscribe_vconf_updates(void)
3956 {
3957         int ret;
3958
3959         DBG("\n");
3960         ret = device_add_callback(DEVICE_CALLBACK_BATTERY_CAPACITY,
3961                                 __bt_ag_agent_battery_status_cb, NULL);
3962         if (ret != DEVICE_ERROR_NONE) {
3963                 ERR("Subscription to battery status failed err =  [%d]\n", ret);
3964         }
3965
3966         if (TIZEN_PROFILE_WEARABLE) {
3967                 ret = vconf_notify_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
3968                                 (void *)__bt_ag_agent_lunar_connection_status_cb, NULL);
3969                 if (0 != ret)
3970                         ERR("Subsrciption to lunar connection failed err =  [%d]\n", ret);
3971         }
3972 }
3973
3974 static void __bt_ag_agent_release_vconf_updates(void)
3975 {
3976         int ret;
3977
3978         DBG("\n");
3979         ret = device_remove_callback(DEVICE_CALLBACK_BATTERY_CAPACITY,
3980                                         __bt_ag_agent_battery_status_cb);
3981         if (ret != DEVICE_ERROR_NONE) {
3982                 ERR("Unsubscription to battery status failed err =  [%d]\n", ret);
3983         }
3984
3985         if (TIZEN_PROFILE_WEARABLE) {
3986                 ret = vconf_ignore_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
3987                                 (void *)__bt_ag_agent_lunar_connection_status_cb);
3988                 if (0 != ret)
3989                         ERR("Subsrciption to lunar connection failed err =  [%d]\n", ret);
3990         }
3991 }
3992
3993 static gboolean __bt_ag_agent_send_subscriber_number_changed(
3994                                                         const char *number)
3995 {
3996         const char *property = g_strdup("SubscriberNumberChanged");
3997
3998         FN_START;
3999
4000         DBG_SECURE("Number is %s", number);
4001
4002         if (!_bt_hfp_set_property_name(property, number)) {
4003                 DBG("Error- set property for subscriber no change  - ERROR\n");
4004                 g_free((void *)property);
4005                 return FALSE;
4006         }
4007         g_free((void *)property);
4008         FN_END;
4009         return TRUE;
4010 }
4011 static void __bt_ag_agent_sigterm_handler(int signo)
4012 {
4013         int i;
4014         GSList *l;
4015
4016         ERR_C("***** Signal handler came with signal %d *****", signo);
4017
4018         for (l = active_devices ; l; l = l->next) {
4019                 bt_ag_info_t *data = l->data;
4020                 if (!__bt_ag_agent_connection_release(data))
4021                         ERR("__bt_ag_agent_connection_release failed");
4022         }
4023         if (ag_dbus_conn)
4024                 g_dbus_connection_flush(ag_dbus_conn, NULL, NULL, NULL);
4025
4026         if (gmain_loop) {
4027                 g_main_loop_quit(gmain_loop);
4028                 DBG("Exiting");
4029                 gmain_loop = NULL;
4030         } else {
4031                 INFO("Terminating AG agent");
4032                 exit(0);
4033         }
4034
4035         if (signo == SIGTERM)
4036                 return;
4037
4038         for (i = 0; i < BT_AG_SIG_NUM; i++)
4039                 sigaction(bt_ag_sig_to_handle[i], &(bt_ag_sigoldact[i]), NULL);
4040
4041         raise(signo);
4042 }
4043
4044 static void  __bt_ag_agent_tel_cb(TapiHandle *handle,
4045                                 int result,
4046                                 void *data,
4047                                 void *user_data)
4048 {
4049         TelSimMsisdnList_t *number;
4050         gchar *subscriber_number;
4051
4052         ERR("*********** Result =%d **********", result);
4053
4054         if (result == TAPI_ERROR_OPERATION_FAILED ||
4055                         result == TAPI_ERROR_ACCESS_DENIED ||
4056                                 result == TAPI_ERROR_OPERATION_NOT_SUPPORTED) {
4057                 ERR("SIM has limited capabilities");
4058                 __bt_ag_agent_send_subscriber_number_changed("");
4059                 return;
4060         }
4061
4062         if (result == TAPI_API_SIM_LOCKED ||
4063                 result == TAPI_API_SIM_NOT_INITIALIZED ||
4064                 result == TAPI_API_SERVICE_NOT_READY) {
4065                 DBG("initializing the tapi event for SIM status");
4066                 __bt_ag_agent_reg_sim_event(handle, user_data);
4067                 return;
4068         }
4069
4070         if (data == NULL)
4071                 return;
4072
4073         number = (TelSimMsisdnList_t *)data;
4074         subscriber_number = g_strdup(number->list[0].num);
4075         __bt_ag_agent_send_subscriber_number_changed(subscriber_number);
4076         g_free(subscriber_number);
4077 }
4078
4079 static void __bt_ag_agent_on_noti_sim_status(TapiHandle *handle,
4080                 const char *noti_id, void *data, void *user_data)
4081 {
4082         TelSimCardStatus_t *status = data;
4083         int tapi_result;
4084
4085         DBG("event TAPI_NOTI_SIM_STATUS received!! status[%d]", *status);
4086
4087         if (*status == TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
4088                 __bt_ag_agent_dereg_sim_event(handle);
4089                 tapi_result = tel_get_sim_msisdn(handle, __bt_ag_agent_tel_cb,
4090                                         user_data);
4091                 if (tapi_result != TAPI_API_SUCCESS)
4092                         ERR("Fail to get sim info: %d", tapi_result);
4093         }
4094 }
4095
4096 static void __bt_ag_agent_reg_sim_event(TapiHandle *handle, void *user_data)
4097 {
4098         int ret;
4099         ret = tel_register_noti_event(handle, TAPI_NOTI_SIM_STATUS,
4100                 __bt_ag_agent_on_noti_sim_status, user_data);
4101
4102         if (ret != TAPI_API_SUCCESS)
4103                 ERR("event register failed(%d)", ret);
4104 }
4105
4106 static void __bt_ag_agent_dereg_sim_event(TapiHandle *handle)
4107 {
4108         int ret;
4109         ret = tel_deregister_noti_event(handle, TAPI_NOTI_SIM_STATUS);
4110
4111         if (ret != TAPI_API_SUCCESS)
4112                 ERR("event deregister failed(%d)", ret);
4113 }
4114
4115 static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection,
4116                                         const gchar *sender_name,
4117                                         const gchar *object_path,
4118                                         const gchar *interface_name,
4119                                         const gchar *signal_name,
4120                                         GVariant *parameters,
4121                                         gpointer user_data)
4122 {
4123         FN_START;
4124         char *name_owner = NULL;
4125         char *old_owner = NULL;
4126         char *new_owner = NULL;
4127
4128         if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
4129                 GSList *l;
4130
4131                 g_variant_get(parameters, "(sss)", &name_owner, &old_owner, &new_owner);
4132
4133                 _bt_hfp_release_all_calls_by_sender(name_owner);
4134
4135                 if (sco_owner == NULL)
4136                         return;
4137
4138                 if (strcasecmp(name_owner, sco_owner) == 0) {
4139                         if (name_owner_sig_id)
4140                                 g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4141                                                         name_owner_sig_id);
4142                         name_owner_sig_id = 0;
4143                         g_free(sco_owner);
4144                         sco_owner = NULL;
4145
4146                         for (l = active_devices ; l; l = l->next) {
4147                                 bt_ag_info_t *data = l->data;
4148
4149                                 if (data->sco) {
4150                                         __bt_ag_close_sco(data);
4151                                         _bt_ag_set_headset_state(data,
4152                                                 HEADSET_STATE_CONNECTED);
4153                                 }
4154                         }
4155                 }
4156         }
4157 }
4158
4159 static void __bt_ag_agent_bluez_interface_signal_cb(GDBusConnection *connection,
4160                                         const gchar *sender_name,
4161                                         const gchar *object_path,
4162                                         const gchar *interface_name,
4163                                         const gchar *signal_name,
4164                                         GVariant *parameters,
4165                                         gpointer user_data)
4166 {
4167         FN_START;
4168         char *path = NULL;
4169         GVariant *optional_param = NULL;
4170
4171         if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
4172
4173                 g_variant_get(parameters, "(&o@a{sa{sv}})",
4174                                                         &path, &optional_param);
4175                 if (!path) {
4176                         if (optional_param)
4177                                 g_variant_unref(optional_param);
4178                         ERR("Invalid adapter path");
4179                         return;
4180                 }
4181
4182                 INFO_SECURE("Adapter Path = [%s]", path);
4183                 if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
4184                         gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
4185                         __bt_ag_agent_register(path, hfp_ver,
4186                                  HFP_AG_UUID, "Hands-Free Audio Gateway");
4187
4188                         path =  g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
4189                         __bt_ag_agent_register(path, hsp_ver,
4190                                 HSP_AG_UUID, "Headset Audio Gateway");
4191                 }
4192         } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
4193                 g_variant_get(parameters, "(&o@as)", &path, &optional_param);
4194                 if (!path) {
4195                         if (optional_param)
4196                                 g_variant_unref(optional_param);
4197                         ERR("Invalid adapter path");
4198                         return;
4199                 }
4200
4201                 INFO_SECURE("Adapter Path = [%s]", path);
4202                 if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
4203                         gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
4204                         __bt_ag_agent_unregister(path);
4205
4206                         path =  g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
4207                         __bt_ag_agent_unregister(path);
4208                 }
4209         }
4210
4211         if (optional_param)
4212                 g_variant_unref(optional_param);
4213
4214         FN_END;
4215 }
4216
4217 static void __bt_ag_agent_bluez_property_changed_cb(GDBusConnection *connection,
4218                                         const gchar *sender_name,
4219                                         const gchar *object_path,
4220                                         const gchar *interface_name,
4221                                         const gchar *signal_name,
4222                                         GVariant *parameters,
4223                                         gpointer user_data)
4224 {
4225         GVariant *optional_param = NULL;
4226         char *inter = NULL;
4227         GVariant *dict_param = NULL;
4228
4229         if (strcasecmp(signal_name, BT_PROPERTY_CHANGED) == 0) {
4230                 if (g_strcmp0(g_variant_get_type_string(parameters),
4231                         "(sa{sv}as)")) {
4232                         ERR("Incorrect parameters\n");
4233                         return;
4234                 }
4235                 g_variant_get(parameters, "(&s@a{sv}@as)",
4236                                 &inter, &dict_param, &optional_param);
4237                 if (strcasecmp(inter, BLUEZ_DEVICE_INTERFACE) == 0) {
4238                         GVariantDict dict;
4239                         int trusted = 0;
4240                         g_variant_dict_init(&dict, dict_param);
4241                         if (g_variant_dict_lookup(
4242                                 &dict, "TrustedProfiles", "u", &trusted)) {
4243                                 GSList *l;
4244                                 for (l = active_devices ; l; l = l->next) {
4245                                         bt_ag_info_t *data = l->data;
4246                                         if (g_strcmp0(data->path, object_path) != 0)
4247                                                 continue;
4248                                         if (trusted == BT_PROFILE_SUPPORTED_TRUSTED) {
4249                                                 data->pbap_trusted =
4250                                                         BT_AG_FEATURE_PBAP_ALLOWED;
4251                                                 DBG("[%s] PBAP is TRUSTED", object_path);
4252                                         } else if (trusted == BT_PROFILE_SUPPORTED_BLOCKED) {
4253                                                 data->pbap_trusted =
4254                                                         BT_AG_FEATURE_PBAP_BLOCKED;
4255                                                 DBG("[%s] PBAP is BLOCKED", object_path);
4256                                         }
4257                                 }
4258                         }
4259                         g_variant_dict_end(&dict);
4260                 }
4261                 if (dict_param)
4262                         g_variant_unref(dict_param);
4263         }
4264
4265         if (optional_param)
4266                 g_variant_unref(optional_param);
4267 }
4268
4269 static void __bt_ag_agent_dbus_deinit(void)
4270 {
4271         if (profile_gproxy) {
4272                 g_object_unref(profile_gproxy);
4273                 profile_gproxy = NULL;
4274         }
4275
4276         if (ag_dbus_conn) {
4277                 __bt_ag_unregister_profile_methods();
4278
4279                 if (interface_added_sig_id)
4280                         g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4281                                                 interface_added_sig_id);
4282
4283                 if (interface_removed_sig_id)
4284                         g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4285                                                 interface_removed_sig_id);
4286
4287                 if (proterty_changed_sig_id)
4288                         g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4289                                                 proterty_changed_sig_id);
4290
4291                 if (name_owner_sig_id)
4292                         g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4293                                                 name_owner_sig_id);
4294 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
4295                 if (media_sig_id)
4296                         g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4297                                                 media_sig_id);
4298
4299                 media_sig_id = 0;
4300 #endif
4301                 if (device_property_id)
4302                         g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
4303                                                 device_property_id);
4304
4305                 device_property_id = 0;
4306                 interface_added_sig_id = 0;
4307                 interface_removed_sig_id = 0;
4308                 proterty_changed_sig_id = 0;
4309                 name_owner_sig_id = 0;
4310                 g_free(sco_owner);
4311                 sco_owner = NULL;
4312
4313                 g_object_unref(ag_dbus_conn);
4314                 ag_dbus_conn = NULL;
4315         }
4316 }
4317
4318 static int __bt_ag_agent_get_adapter_path(GDBusConnection *conn, char *path)
4319 {
4320         GError *err = NULL;
4321         GDBusProxy *manager_proxy = NULL;
4322         GVariant *result = NULL;
4323         char *adapter_path = NULL;
4324
4325         if (conn == NULL)
4326                 return BT_HFP_AGENT_ERROR_INTERNAL;
4327
4328         manager_proxy =  g_dbus_proxy_new_sync(conn,
4329                         G_DBUS_PROXY_FLAGS_NONE, NULL,
4330                         BLUEZ_SERVICE_NAME,
4331                         "/",
4332                         BT_MANAGER_INTERFACE,
4333                         NULL, &err);
4334
4335         if (!manager_proxy) {
4336                 ERR("Unable to create proxy: %s", err->message);
4337                 goto fail;
4338         }
4339
4340         result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
4341                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
4342         if (!result) {
4343                 if (err != NULL)
4344                         ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
4345                 else
4346                         ERR("Fail to get DefaultAdapter");
4347
4348                 goto fail;
4349         }
4350
4351         if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
4352                 ERR("Incorrect result\n");
4353                 goto fail;
4354         }
4355
4356         g_variant_get(result, "(&o)", &adapter_path);
4357
4358         if (adapter_path == NULL ||
4359                 strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) {
4360                 ERR("Adapter path is inproper\n");
4361                 goto fail;
4362         }
4363
4364         if (path)
4365                 g_strlcpy(path, adapter_path, BT_ADAPTER_OBJECT_PATH_MAX);
4366
4367         g_variant_unref(result);
4368         g_object_unref(manager_proxy);
4369
4370         return 0;
4371
4372 fail:
4373         g_clear_error(&err);
4374
4375         if (result)
4376                 g_variant_unref(result);
4377
4378         if (manager_proxy)
4379                 g_object_unref(manager_proxy);
4380
4381         return BT_HFP_AGENT_ERROR_INTERNAL;
4382
4383 }
4384
4385 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
4386 void _bt_ag_agent_check_transport_state(void)
4387 {
4388         FN_START;
4389
4390         if (transport_state == MEDIA_TRANSPORT_STATE_PLAYING) {
4391                 GDBusProxy *proxy;
4392                 GError *err = NULL;
4393
4394                 proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
4395                                 G_DBUS_PROXY_FLAGS_NONE, NULL,
4396                                 "org.PulseAudio2", A2DP_SOURCE_ENDPOINT,
4397                                 BLUEZ_MEDIA_ENDPOINT_INTERFACE, NULL, &err);
4398
4399                 if (!proxy) {
4400                         if (err) {
4401                                 ERR("Unable to create proxy: %s", err->message);
4402                                 g_clear_error(&err);
4403                         }
4404                         return;
4405                 }
4406                 INFO_C("SuspendMedia initiated");
4407
4408                 g_dbus_proxy_call(proxy,
4409                                         "SuspendMedia", NULL,
4410                                         G_DBUS_CALL_FLAGS_NONE, 2000,
4411                                         NULL, NULL, NULL);
4412                 transport_state = MEDIA_TRANSPORT_STATE_IDLE;
4413                 g_object_unref(proxy);
4414         }
4415
4416         FN_END;
4417 }
4418
4419 static void __bt_ag_agent_transport_state_update(const char *value)
4420 {
4421
4422         if (!g_strcmp0(value, "idle"))
4423                 transport_state = MEDIA_TRANSPORT_STATE_IDLE;
4424         else if (!g_strcmp0(value, "pending") || !g_strcmp0(value, "active"))
4425                 transport_state = MEDIA_TRANSPORT_STATE_PLAYING;
4426         else
4427                 transport_state =  MEDIA_TRANSPORT_STATE_DISCONNECTED;
4428
4429         INFO_C("transport_state %d", transport_state);
4430 }
4431
4432 static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection,
4433                                         const gchar *sender_name,
4434                                         const gchar *object_path,
4435                                         const gchar *interface_name,
4436                                         const gchar *signal_name,
4437                                         GVariant *parameters,
4438                                         gpointer user_data)
4439 {
4440         FN_START;
4441         char *inter = NULL;
4442         GVariant *dict_param = NULL;
4443         GVariant *optional_param = NULL;
4444         GSList *l;
4445         if (strcasecmp(signal_name, "PropertiesChanged") == 0) {
4446                 if (g_strcmp0(g_variant_get_type_string(parameters),
4447                                                         "(sa{sv}as)")) {
4448                         ERR("Incorrect parameters\n");
4449                         return;
4450                 }
4451
4452                 g_variant_get(parameters, "(&s@a{sv}@as)",
4453                                         &inter, &dict_param, &optional_param);
4454                 if (dict_param && (!g_strcmp0(inter,
4455                                 BLUEZ_MEDIA_TRANSPORT_INTERFACE))){
4456                         GVariantIter *iter = NULL;
4457                         const gchar *key = NULL;
4458                         GVariant *value_var = NULL;
4459                         const gchar *value = NULL;
4460                         g_variant_get(dict_param, "a{sv}", &iter);
4461                         while (g_variant_iter_loop(
4462                                         iter, "{sv}", &key, &value_var)) {
4463                                 DBG("key %s", key);
4464                                 if (g_strcmp0(key, "State") == 0) {
4465                                         value = (gchar *)g_variant_get_string(
4466                                                                 value_var,
4467                                                                 NULL);
4468                                         DBG("value %s", value);
4469                                         __bt_ag_agent_transport_state_update(value);
4470                                         break;
4471                                 }
4472                         }
4473                         g_variant_iter_free(iter);
4474                 }
4475         } else if (strcasecmp(signal_name, "ProfileStateChanged") == 0) {
4476                 char *profile_uuid = NULL;
4477                 int state = 0;
4478
4479                 g_variant_get(parameters, "(&si)", &profile_uuid, &state);
4480                 if ((g_strcmp0(profile_uuid, A2DP_SINK_UUID) == 0)  &&
4481                         (state == BT_PROFILE_STATE_DISCONNECTED)) {
4482                         DBG("Updating the transport state");
4483                         __bt_ag_agent_transport_state_update("Disconnect");
4484                 }
4485         }
4486
4487         if (dict_param)
4488                 g_variant_unref(dict_param);
4489
4490         if (optional_param)
4491                 g_variant_unref(optional_param);
4492
4493         FN_END;
4494 }
4495 #endif
4496 static void __bt_ag_agent_dbus_init(void)
4497 {
4498         FN_START;
4499
4500         if (__bt_ag_get_gdbus_connection() == NULL) {
4501                 ERR("Error in creating the gdbus connection\n");
4502                 return;
4503         }
4504         if (!__bt_ag_register_profile_methods()) {
4505                 ERR("Error in HFP / HSP register_profile_methods\n");
4506                 return;
4507         }
4508
4509         if (!__bt_ag_agent_get_adapter_path(ag_dbus_conn , NULL)) {
4510
4511                 gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
4512                 __bt_ag_agent_register(path, hfp_ver,
4513                          HFP_AG_UUID, "Hands-Free Audio Gateway");
4514
4515                 path = g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
4516                 __bt_ag_agent_register(path, hsp_ver,
4517                         HSP_AG_UUID, "Headset Audio Gateway");
4518         }
4519
4520         interface_added_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
4521                                 NULL, BT_MANAGER_INTERFACE,
4522                                 BT_INTERFACES_ADDED, NULL, NULL, 0,
4523                                 __bt_ag_agent_bluez_interface_signal_cb, NULL, NULL);
4524
4525         interface_removed_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
4526                                 NULL, BT_MANAGER_INTERFACE,
4527                                 BT_INTERFACES_REMOVED, NULL, NULL, 0,
4528                                 __bt_ag_agent_bluez_interface_signal_cb, NULL, NULL);
4529
4530         proterty_changed_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
4531                                 NULL, BT_MANAGER_INTERFACE,
4532                                 BT_PROPERTY_CHANGED, NULL, NULL, 0,
4533                                 __bt_ag_agent_bluez_property_changed_cb, NULL, NULL);
4534
4535 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
4536         media_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
4537                                 NULL, BT_PROPERTIES_INTERFACE, NULL, NULL,
4538                                 NULL, 0, __bt_ag_agent_media_filter_cb,
4539                                 NULL, NULL);
4540
4541         media_state_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
4542                                 NULL, BLUEZ_DEVICE_INTERFACE, NULL, NULL,
4543                                 NULL, 0, __bt_ag_agent_media_filter_cb,
4544                                 NULL, NULL);
4545
4546         transport_state = MEDIA_TRANSPORT_STATE_DISCONNECTED;
4547 #endif
4548         device_property_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
4549                                 NULL, BT_PROPERTIES_INTERFACE, BT_PROPERTY_CHANGED, NULL,
4550                                 NULL, 0, __bt_ag_agent_bluez_property_changed_cb,
4551                                 NULL, NULL);
4552         FN_END;
4553         return;
4554 }
4555
4556 static void __bt_ag_agent_subscribe_tapi_updates(TapiHandle *handle)
4557 {
4558         int ret;
4559
4560         DBG("\nSubscribe tapi update for handler %p", handle);
4561
4562         ret = tel_register_noti_event(handle, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL,
4563                 __bt_ag_agent_network_signal_status_cb, NULL);
4564         if (ret != TAPI_API_SUCCESS) {
4565                 ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
4566         }
4567
4568         ret = tel_register_noti_event(handle, TAPI_PROP_NETWORK_SERVICE_TYPE,
4569                 __bt_ag_agent_network_register_status_cb, NULL);
4570         if (ret != TAPI_API_SUCCESS) {
4571                 ERR("Subsrciption to network failed err =  [%d]\n", ret);
4572         }
4573
4574         ret = tel_register_noti_event(handle, TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION,
4575                 __bt_ag_agent_call_preferred_voice_subscription_cb, NULL);
4576         if (ret != TAPI_API_SUCCESS) {
4577                 ERR("Subsrciption to preferred voice err =  [%d]\n", ret);
4578         }
4579
4580 }
4581
4582 static void __bt_ag_agent_unsubscribe_tapi_updates(TapiHandle *handle)
4583 {
4584         int ret;
4585
4586         DBG("\nUnsubscribe tapi update for handler %p", handle);
4587
4588         ret = tel_deregister_noti_event(handle, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL);
4589         if (ret != TAPI_API_SUCCESS) {
4590                 ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
4591         }
4592
4593         ret = tel_deregister_noti_event(handle, TAPI_PROP_NETWORK_SERVICE_TYPE);
4594         if (ret != TAPI_API_SUCCESS) {
4595                 ERR("Subsrciption to network failed err =  [%d]\n", ret);
4596         }
4597
4598         ret = tel_deregister_noti_event(handle, TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION);
4599         if (ret != TAPI_API_SUCCESS) {
4600                 ERR("Subsrciption to preferred voice err =  [%d]\n", ret);
4601         }
4602 }
4603
4604 static uint32_t __bt_ag_agent_get_ag_features(void)
4605 {
4606
4607         uint32_t ag_features = BT_AG_FEATURE_EC_AND_NR |
4608                                 BT_AG_FEATURE_REJECT_CALL |
4609                                 BT_AG_FEATURE_ENHANCED_CALL_STATUS |
4610                                 BT_AG_FEATURE_THREE_WAY_CALL |
4611 #if !defined(TIZEN_FEATURE_BT_VENDOR_SPRD)
4612                                 BT_AG_FEATURE_VOICE_RECOGNITION |
4613 #endif
4614                                 BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
4615
4616 #ifdef TIZEN_FEATURE_BT_SCO_WIDEBAND
4617         wbs_en = TRUE;
4618 #else
4619         wbs_en = FALSE;
4620 #endif
4621
4622         hfp_ver = HFP_VERSION_1_7;
4623         hsp_ver = HSP_VERSION_1_2;
4624
4625         if (hfp_ver > HFP_VERSION_1_5)
4626                 ag_features |= BT_AG_FEATURE_CODEC_NEGOTIATION;
4627         if (hfp_ver == HFP_VERSION_1_7)
4628                 ag_features |= BT_AG_FEATURE_ESCO_S4_T2_SUPPORT;
4629
4630         return ag_features;
4631 }
4632
4633 static void __bt_ag_agent_tel_get_preferred_sim(TapiHandle *handler)
4634 {
4635         TelCallPreferredVoiceSubs_t preferredSubscription;
4636         int err_code = tel_get_call_preferred_voice_subscription(handler, &preferredSubscription);
4637         if (err_code == TAPI_API_SUCCESS) {
4638                 if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_SIM1) {
4639                         tapi_handle_preferred_sim = tapi_handle[0];
4640                         INFO("Preferred SIM 1");
4641                 } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_SIM2) {
4642                         tapi_handle_preferred_sim = tapi_handle[1];
4643                         INFO("Preferred SIM 2");
4644                 } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK) {
4645                         INFO("Preferred SIM Current Network");
4646                 } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS) {
4647                         tapi_handle_preferred_sim = tapi_handle[0];
4648                         INFO("Preferred SIM Always Ask");
4649                 } else {
4650                         ERR("Unknown Preferred voice subscription");
4651                 }
4652         }
4653 }
4654
4655 static void __bt_ag_agent_tel_init_multisim(void)
4656 {
4657         INFO_C("Initializing the telephony multi sim info");
4658
4659         char **cp_list = NULL;
4660         unsigned int modem_num = 0;
4661         int err_code;
4662         TelSimCardStatus_t simStatus = 0;
4663         int card_changed = 0;
4664
4665
4666
4667         /* Get CP name list ? cp_list */
4668         cp_list = tel_get_cp_name_list();
4669         if (cp_list == NULL) {
4670                 ERR("tel_get_cp_name_list() Failed");
4671                 return;
4672         }
4673
4674         while (cp_list[modem_num]) {
4675                 /* Initialize TAPI handle */
4676                 tapi_handle[modem_num] = tel_init(cp_list[modem_num]);
4677
4678                 if (tapi_handle[modem_num] == NULL) {
4679                         /* TAPI initialization ? Failure */
4680                         ERR_SECURE("tel_init failed for Modem SIM number = %d", modem_num);
4681                 } else {
4682                         /* TAPI initialization ? Success */
4683                         DBG_SECURE("Success for Modem SIM number = %d, handler = %p",
4684                                         modem_num, tapi_handle[modem_num]);
4685                          err_code = tel_get_sim_init_info(tapi_handle[modem_num],
4686                                                 &simStatus, &card_changed);
4687                          INFO_SECURE("Sim number = %d SIM status = %d", modem_num, simStatus);
4688                           if ((TAPI_API_SUCCESS == err_code) &&
4689                                         (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == simStatus)) {
4690                                 if (modem_num == 0)
4691                                         sim1 = 1;
4692                                 else
4693                                         sim2 = 1;
4694                           }
4695                 }
4696
4697                 /* Move to next CP Name in cp_list */
4698                 modem_num++;
4699         }
4700
4701         tapi_handle[modem_num] = NULL;
4702
4703         g_strfreev(cp_list);
4704 }
4705
4706 static void __bt_ag_agent_tel_deinit_multisim(void)
4707 {
4708         INFO_C("DeInitializing the telephony multi sim info");
4709
4710         char **cp_list = NULL;
4711         unsigned int modem_num = 0;
4712         int result;
4713
4714         cp_list = tel_get_cp_name_list();
4715         if (cp_list == NULL) {
4716                 ERR("tel_get_cp_name_list() Failed");
4717                 return;
4718         }
4719
4720          while (cp_list[modem_num]) {
4721                 result = tel_deinit(tapi_handle[modem_num]);
4722                 if (result != TAPI_API_SUCCESS)
4723                         ERR("Fail to tel_deinit");
4724                  /* Move to next CP Name in cp_list */
4725                  modem_num++;
4726         }
4727
4728         g_strfreev(cp_list);
4729 }
4730
4731 gboolean __bt_ag_agent_telephony_init(void *arg)
4732 {
4733         int tapi_result;
4734         uint32_t ag_features = *((uint32_t *)arg);
4735
4736         INFO_C("Initializing the telephony info");
4737         __bt_ag_agent_tel_init_multisim();
4738         __bt_ag_agent_tel_get_preferred_sim(GET_TAPI_HANDLE);
4739         _bt_hfp_initialize_telephony_manager(ag_features, GET_TAPI_HANDLE);
4740         __bt_ag_agent_subscribe_tapi_updates(GET_TAPI_HANDLE);
4741         __bt_ag_agent_subscribe_vconf_updates();
4742         tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb,
4743                                         NULL);
4744         if (tapi_result != TAPI_API_SUCCESS)
4745                 ERR("Fail to get sim info: %d", tapi_result);
4746         return FALSE;
4747 }
4748
4749 int main(void)
4750 {
4751         int i;
4752         uint32_t ag_features;
4753         struct sigaction sa;
4754
4755         INFO_C("### Starting Bluetooth AG agent");
4756
4757 #if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_36
4758         g_type_init();
4759 #endif
4760         ag_features = __bt_ag_agent_get_ag_features();
4761
4762         ag.sdp_features = (uint16_t) ag_features & 0x1F;
4763
4764         if (hfp_ver >= HFP_VERSION_1_6 && wbs_en == TRUE)
4765                 ag.sdp_features |= BT_AG_FEATURE_SDP_WIDEBAND_SPEECH;
4766
4767         __bt_ag_agent_dbus_init();
4768
4769         g_idle_add(__bt_ag_agent_telephony_init, &ag_features);
4770
4771         memset(&sa, 0, sizeof(sa));
4772         sa.sa_flags = SA_NOCLDSTOP;
4773         sa.sa_handler = __bt_ag_agent_sigterm_handler;
4774
4775         for (i = 0; i < BT_AG_SIG_NUM; i++)
4776                 sigaction(bt_ag_sig_to_handle[i], &sa, &(bt_ag_sigoldact[i]));
4777
4778         gmain_loop = g_main_loop_new(NULL, FALSE);
4779
4780         if (gmain_loop == NULL) {
4781                 ERR("GMainLoop create failed");
4782                 return EXIT_FAILURE;
4783         }
4784
4785         g_main_loop_run(gmain_loop);
4786
4787         DBG("Cleaning up");
4788
4789         __bt_ag_agent_dbus_deinit();
4790         _bt_hfp_deinitialize_telephony_manager();
4791         __bt_ag_agent_release_vconf_updates();
4792         __bt_ag_agent_unsubscribe_tapi_updates(GET_TAPI_HANDLE);
4793         __bt_ag_agent_tel_deinit_multisim();
4794         if (remote_dev_path)
4795                 g_free(remote_dev_path);
4796
4797         if (gmain_loop)
4798                 g_main_loop_unref(gmain_loop);
4799
4800         INFO_C("### Terminating Bluetooth AG agent");
4801         return 0;
4802 }