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