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