remove syspopup dependency
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-audio.c
1 /*
2  * bluetooth-frwk
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
26 #include <syspopup_caller.h>
27 #endif
28
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
31
32 #include "bt-service-audio.h"
33 #include "bt-service-adapter.h"
34 #include "bt-service-common.h"
35 #include "bt-service-event.h"
36 #include "bt-service-util.h"
37
38 typedef struct {
39         unsigned int type;
40         int device_state;
41         char device_address[BT_ADDRESS_STRING_SIZE + 1];
42 } bt_connected_headset_data_t;
43
44 static GList *g_connected_list;
45
46 static bt_headset_wait_t *g_wait_data;
47
48 static void __bt_remove_device_from_wait_list();
49
50 static void __bt_free_wait_data();
51
52 static void __bt_audio_request_cb(DBusGProxy *proxy, DBusGProxyCall *call,
53                                     gpointer user_data)
54 {
55         GError *g_error = NULL;
56         GArray *out_param1 = NULL;
57         GArray *out_param2 = NULL;
58         int result = BLUETOOTH_ERROR_NONE;
59         bt_function_data_t *func_data;
60         request_info_t *req_info;
61
62         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
63
64         g_object_unref(proxy);
65
66         func_data = user_data;
67
68         if (func_data == NULL) {
69                 /* Send reply */
70                 BT_ERR("func_data == NULL");
71                 goto done;
72         }
73
74         req_info = _bt_get_request_info(func_data->req_id);
75         if (req_info == NULL) {
76                 BT_ERR("req_info == NULL");
77                 goto done;
78         }
79
80         if (g_error == NULL)
81                 goto dbus_return;
82
83         BT_ERR("Audio Connect Dbus Call Error: %s\n", g_error->message);
84
85         result = BLUETOOTH_ERROR_INTERNAL;
86
87         /* Remove the device from the list */
88         _bt_remove_headset_from_list(BT_AUDIO_ALL, func_data->address);
89
90         /* Error, check if any waiting device is there */
91         if (g_wait_data == NULL)
92                 goto dbus_return;
93
94         if (g_strcmp0(g_wait_data->address, func_data->address) != 0) {
95                 bluetooth_device_address_t device_address;
96                 _bt_convert_addr_string_to_type(device_address.addr,
97                                                         g_wait_data->address);
98                 _bt_audio_connect(g_wait_data->req_id, g_wait_data->type,
99                                 &device_address, g_wait_data->out_param1);
100         }
101
102         /* Event will be sent by the event reciever */
103 dbus_return:
104         if (req_info->context == NULL)
105                 goto done;
106
107         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
108         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
109
110         g_array_append_vals(out_param1, func_data->address,
111                                 BT_ADDRESS_STR_LEN);
112         g_array_append_vals(out_param2, &result, sizeof(int));
113
114         dbus_g_method_return(req_info->context, out_param1, out_param2);
115
116         g_array_free(out_param1, TRUE);
117         g_array_free(out_param2, TRUE);
118
119         _bt_delete_request_list(req_info->req_id);
120 done:
121         if (g_error)
122                 g_error_free(g_error);
123
124         if (func_data) {
125                 g_free(func_data->address);
126                 g_free(func_data);
127         }
128 }
129
130 static char *__bt_get_audio_path(bluetooth_device_address_t *address)
131 {
132
133         char *object_path = NULL;
134         char addr_str[BT_ADDRESS_STRING_SIZE + 1] = { 0 };
135         DBusGProxy *audio_proxy;
136         DBusGProxy *adapter_proxy;
137         DBusGConnection *g_conn;
138         GError *error = NULL;
139
140         retv_if(address == NULL, NULL);
141
142         g_conn = _bt_get_system_gconn();
143         retv_if(g_conn == NULL, NULL);
144
145         adapter_proxy = _bt_get_adapter_proxy();
146         retv_if(adapter_proxy == NULL, NULL);
147
148         _bt_convert_addr_type_to_string(addr_str, address->addr);
149
150         object_path = _bt_get_device_object_path(addr_str);
151
152         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_FOUND);
153
154         audio_proxy = dbus_g_proxy_new_for_name(g_conn,
155                                         BT_BLUEZ_NAME,
156                                         object_path,
157                                         BT_HFP_AGENT_INTERFACE);
158
159         retv_if(audio_proxy == NULL, NULL);
160
161         g_object_unref(audio_proxy);
162
163         return object_path;
164 }
165
166 static char *__bt_get_connected_audio_path(void)
167 {
168         int i;
169         guint size;
170         char *audio_path = NULL;
171         GArray *device_list;
172         bluetooth_device_info_t info;
173
174         /* allocate the g_pointer_array */
175         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
176
177         if (_bt_get_bonded_devices(&device_list)
178                                         != BLUETOOTH_ERROR_NONE) {
179                 g_array_free(device_list, TRUE);
180                 return NULL;
181         }
182
183         size = device_list->len;
184         size = (device_list->len) / sizeof(bluetooth_device_info_t);
185
186         for (i = 0; i < size; i++) {
187
188                 info = g_array_index(device_list,
189                                 bluetooth_device_info_t, i);
190
191                 if (info.connected == TRUE) {
192                         audio_path = __bt_get_audio_path(&info.device_address);
193                         if (audio_path)
194                                 break;
195                 }
196         }
197
198         g_array_free(device_list, TRUE);
199
200         return audio_path;
201 }
202
203 static void __bt_free_wait_data()
204 {
205         if (g_wait_data != NULL) {
206                 g_free(g_wait_data->address);
207                 g_free(g_wait_data);
208                 g_wait_data = NULL;
209         }
210 }
211
212 static void __bt_remove_device_from_wait_list()
213 {
214         /* Before deleting the request update the UI */
215         GArray *out_param_1 = NULL;
216         GArray *out_param_2 = NULL;
217         int result = BLUETOOTH_ERROR_INTERNAL;
218         request_info_t *req_info;
219
220         req_info = _bt_get_request_info(g_wait_data->req_id);
221         if (req_info == NULL) {
222                 BT_ERR("req_info == NULL");
223                 return;
224         }
225
226         out_param_1 = g_array_new(FALSE, FALSE, sizeof(gchar));
227         out_param_2 = g_array_new(FALSE, FALSE, sizeof(gchar));
228         g_array_append_vals(out_param_1, g_wait_data->address,
229                                 BT_ADDRESS_STR_LEN);
230         g_array_append_vals(out_param_2, &result, sizeof(int));
231         dbus_g_method_return(req_info->context,
232                                 out_param_1, out_param_2);
233         g_array_free(out_param_1, TRUE);
234         g_array_free(out_param_2, TRUE);
235         _bt_delete_request_list(g_wait_data->req_id);
236 }
237
238 static void __bt_set_headset_disconnection_type(const char *address)
239 {
240         bt_connected_headset_data_t *connected_device;
241         GList *node;
242
243         BT_DBG("__bt_set_headset_disconnection_type \n");
244
245         node = g_list_first(g_connected_list);
246         while (node != NULL) {
247                 connected_device = node->data;
248                 if (g_strcmp0(connected_device->device_address, address) == 0) {
249                         g_wait_data->disconnection_type = connected_device->type;
250                         return;
251                 }
252                 node = g_list_next(node);
253         }
254 }
255
256 gboolean _bt_is_headset_type_connected(int type, char *address)
257 {
258         GList *node;
259
260         BT_DBG("_bt_is_headset_type_connected \n");
261
262         node = g_list_first(g_connected_list);
263         while (node != NULL) {
264                 bt_connected_headset_data_t *connected_device = node->data;
265
266                 if (connected_device->type & type) {
267                         if (address != NULL)
268                                 g_strlcpy(address, connected_device->device_address,
269                                                 BT_ADDRESS_STRING_SIZE + 1);
270                         return TRUE;
271                 }
272
273                 node = g_list_next(node);
274         }
275         return FALSE;
276 }
277
278 static gboolean __bt_is_headset_connected(int type, int req_id,
279                                 const char *address, GArray **out_param1)
280 {
281         gboolean connected;
282         char connected_address[BT_ADDRESS_STRING_SIZE + 1];
283         bluetooth_device_address_t device_address;
284
285         BT_DBG("__bt_is_headset_connected \n");
286
287         /* Check if any other headset is connected */
288         connected = _bt_is_headset_type_connected(type, connected_address);
289
290         if (!connected)
291                 return FALSE;
292
293         /* If already one device is waiting, remove current waiting device and add new */
294         if (g_wait_data != NULL) {
295                 if (g_strcmp0(g_wait_data->address, address) != 0) {
296                         __bt_remove_device_from_wait_list();
297                         __bt_free_wait_data();
298                 }
299         }
300
301         if (g_wait_data == NULL) {
302                 g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
303                 g_wait_data->address = g_strdup(address);
304                 g_wait_data->req_id = req_id;
305                 g_wait_data->type = type;
306                 g_wait_data->ag_flag = FALSE;
307                 g_wait_data->out_param1 = out_param1;
308
309                 /* Set disconnection type */
310                 __bt_set_headset_disconnection_type(connected_address);
311         }
312
313         /* Convert BD adress from string type */
314         _bt_convert_addr_string_to_type(device_address.addr, connected_address);
315         _bt_audio_disconnect(0, type, &device_address, NULL);
316         return TRUE;
317 }
318
319 void _bt_set_audio_wait_data_flag(gboolean flag)
320 {
321         BT_DBG("_bt_set_audio_wait_data_flag \n");
322         g_wait_data->ag_flag = flag;
323 }
324
325 bt_headset_wait_t *_bt_get_audio_wait_data(void)
326 {
327         BT_DBG("_bt_get_audio_wait_data \n");
328         return g_wait_data;
329 }
330
331 void _bt_add_headset_to_list(int type, int status, const char *address)
332 {
333         bt_connected_headset_data_t *connected_device;
334         bt_connected_headset_data_t *device;
335         GList *node;
336
337         BT_DBG("_bt_add_headset_to_list \n");
338
339         node = g_list_first(g_connected_list);
340         while (node != NULL) {
341                 device = (bt_connected_headset_data_t *)node->data;
342
343                 if (g_strcmp0(device->device_address, address) == 0) {
344                         BT_DBG("Address match, update connection type \n");
345                         device->type |= type;
346                         device->device_state = status;
347                         return;
348                 }
349                 node = g_list_next(node);
350         }
351
352         connected_device = g_malloc0(sizeof(bt_connected_headset_data_t));
353         connected_device->type |= type;
354         connected_device->device_state = status;
355         g_strlcpy(connected_device->device_address, address,
356                                 sizeof(connected_device->device_address));
357         g_connected_list = g_list_append(g_connected_list, connected_device);
358 }
359
360 void _bt_remove_headset_from_list(int type, const char *address)
361 {
362         GList *node;
363
364         BT_DBG("_bt_remove_headset_from_list \n");
365
366         node = g_list_first(g_connected_list);
367         while (node != NULL) {
368                 bt_connected_headset_data_t *connected_device = node->data;
369
370                 if (g_strcmp0(connected_device->device_address, address) != 0) {
371                         node = g_list_next(node);
372                         continue;
373                 }
374
375                 BT_DBG("Address match \n");
376
377                 BT_DBG("Connection type = %x\n", connected_device->type);
378
379                 switch (type) {
380                 case BT_AUDIO_A2DP:
381                         if (connected_device->type & BT_AUDIO_A2DP)
382                                 connected_device->type &= ~(BT_AUDIO_A2DP);
383                         break;
384                 case BT_AUDIO_HSP:
385                         if (connected_device->type & BT_AUDIO_HSP)
386                                 connected_device->type &= ~(BT_AUDIO_HSP);
387                         break;
388                 case BT_AUDIO_ALL:
389                         if (connected_device->type & BT_AUDIO_ALL)
390                                 connected_device->type &= ~(BT_AUDIO_ALL);
391                         break;
392                 }
393
394                 BT_DBG("Connection type = %x\n", connected_device->type);
395
396                 if (connected_device->type == 0x00) {
397                         g_connected_list = g_list_remove(g_connected_list, connected_device);
398                         g_free(connected_device);
399                 }
400
401                 node = g_list_next(node);
402         }
403 }
404
405 int _bt_audio_connect(int request_id, int type,
406                 bluetooth_device_address_t *device_address,
407                 GArray **out_param1)
408 {
409         int result = BLUETOOTH_ERROR_NONE;
410         gchar *device_path = NULL;
411         char *uuid = NULL;
412         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
413         bt_function_data_t *func_data;
414         DBusGProxy *adapter_proxy;
415         DBusGProxy *profile_proxy;
416         DBusGConnection *g_conn;
417
418         BT_CHECK_PARAMETER(device_address, return);
419
420         _bt_convert_addr_type_to_string(address, device_address->addr);
421
422         switch (type) {
423         case BT_AUDIO_HSP:
424                 uuid = HFP_HS_UUID;
425                 break;
426         case BT_AUDIO_A2DP:
427                 uuid = A2DP_SINK_UUID;
428                 break;
429         case BT_AUDIO_ALL:
430                 uuid = GENERIC_AUDIO_UUID;
431                 break;
432         default:
433                 BT_ERR("Unknown role");
434                 result = BLUETOOTH_ERROR_INTERNAL;
435                 goto fail;
436         }
437
438         if (__bt_is_headset_connected(type, request_id, address, out_param1))
439                 return BLUETOOTH_ERROR_NONE;
440
441         adapter_proxy = _bt_get_adapter_proxy();
442         if (adapter_proxy == NULL) {
443                 result = BLUETOOTH_ERROR_INTERNAL;
444                 goto fail;
445         }
446
447         device_path = _bt_get_device_object_path(address);
448         if (device_path == NULL) {
449                 result = BLUETOOTH_ERROR_INTERNAL;
450                 goto fail;
451         }
452
453         g_conn = _bt_get_system_gconn();
454         if (g_conn == NULL) {
455                 result = BLUETOOTH_ERROR_INTERNAL;
456                 goto fail;
457         }
458
459         profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
460                                         device_path, BT_DEVICE_INTERFACE);
461
462         g_free(device_path);
463
464         if (profile_proxy == NULL) {
465                 result = BLUETOOTH_ERROR_INTERNAL;
466                 goto fail;
467         }
468
469         func_data = g_malloc0(sizeof(bt_function_data_t));
470         func_data->address = g_strdup(address);
471         func_data->req_id = request_id;
472
473         if (g_strcmp0(uuid, GENERIC_AUDIO_UUID) == 0){
474                 if (!dbus_g_proxy_begin_call(profile_proxy, "Connect",
475                                 (DBusGProxyCallNotify)__bt_audio_request_cb,
476                                 func_data, NULL,
477                                 G_TYPE_INVALID)) {
478                         BT_ERR("Audio connect Dbus Call Error");
479                         g_object_unref(profile_proxy);
480
481                         g_free(func_data->address);
482                         g_free(func_data);
483
484                         result = BLUETOOTH_ERROR_INTERNAL;
485                         goto fail;
486                 }
487         }else {
488                 if (!dbus_g_proxy_begin_call(profile_proxy, "ConnectProfile",
489                                 (DBusGProxyCallNotify)__bt_audio_request_cb,
490                                 func_data, NULL,
491                                 G_TYPE_STRING, uuid,
492                                 G_TYPE_INVALID)) {
493                         BT_ERR("Audio connect Dbus Call Error");
494                         g_object_unref(profile_proxy);
495
496                         g_free(func_data->address);
497                         g_free(func_data);
498
499                         result = BLUETOOTH_ERROR_INTERNAL;
500                         goto fail;
501                 }
502         }
503         /* Add data to the connected list */
504         _bt_add_headset_to_list(type, BT_STATE_CONNECTING, address);
505         __bt_free_wait_data();
506
507         return BLUETOOTH_ERROR_NONE;
508 fail:
509         g_array_append_vals(*out_param1, address,
510                                 BT_ADDRESS_STR_LEN);
511
512         return result;
513 }
514
515 int _bt_audio_disconnect(int request_id, int type,
516                 bluetooth_device_address_t *device_address,
517                 GArray **out_param1)
518 {
519         int result = BLUETOOTH_ERROR_NONE;
520         gchar *device_path = NULL;
521         char *uuid = NULL;
522         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
523         bt_function_data_t *func_data;
524         DBusGProxy *adapter_proxy;
525         DBusGProxy *profile_proxy;
526         DBusGConnection *g_conn;
527
528         BT_CHECK_PARAMETER(device_address, return);
529
530         _bt_convert_addr_type_to_string(address, device_address->addr);
531
532         switch (type) {
533         case BT_AUDIO_HSP:
534                 uuid = HFP_HS_UUID;
535                 break;
536         case BT_AUDIO_A2DP:
537                 uuid = A2DP_SINK_UUID;
538                 break;
539         case BT_AUDIO_ALL:
540                 uuid = GENERIC_AUDIO_UUID;
541                 break;
542         default:
543                 BT_ERR("Unknown role");
544                 return BLUETOOTH_ERROR_INTERNAL;
545         }
546
547         adapter_proxy = _bt_get_adapter_proxy();
548         if (adapter_proxy == NULL) {
549                 result = BLUETOOTH_ERROR_INTERNAL;
550                 goto fail;
551         }
552
553         device_path = _bt_get_device_object_path(address);
554         if (device_path == NULL) {
555                 result = BLUETOOTH_ERROR_INTERNAL;
556                 goto fail;
557         }
558
559         g_conn = _bt_get_system_gconn();
560         if (g_conn == NULL) {
561                 result = BLUETOOTH_ERROR_INTERNAL;
562                 goto fail;
563         }
564
565         profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
566                                         device_path, BT_DEVICE_INTERFACE);
567
568         g_free(device_path);
569
570         if (profile_proxy == NULL) {
571                 result = BLUETOOTH_ERROR_INTERNAL;
572                 goto fail;
573         }
574
575         if (g_wait_data != NULL) {
576                 if (g_strcmp0(uuid, GENERIC_AUDIO_UUID) == 0){
577                         if (!dbus_g_proxy_begin_call(profile_proxy,
578                                 "Disconnect",NULL, NULL, NULL,
579                                 G_TYPE_INVALID)) {
580                                 BT_ERR("Audio disconnect Dbus Call Error");
581                                 g_object_unref(profile_proxy);
582                                 return BLUETOOTH_ERROR_INTERNAL;
583                         }
584                 } else {
585                         if (!dbus_g_proxy_begin_call(profile_proxy,
586                                 "DisconnectProfile",NULL, NULL, NULL,
587                                 G_TYPE_STRING, uuid,
588                                 G_TYPE_INVALID)) {
589                                 BT_ERR("Audio disconnect Dbus Call Error");
590                                 g_object_unref(profile_proxy);
591                                 return BLUETOOTH_ERROR_INTERNAL;
592                         }
593                 }
594         } else {
595                 func_data = g_malloc0(sizeof(bt_function_data_t));
596                 func_data->address = g_strdup(address);
597                 func_data->req_id = request_id;
598                 if (g_strcmp0(uuid, GENERIC_AUDIO_UUID) == 0){
599                         if (!dbus_g_proxy_begin_call(profile_proxy,
600                                 "Disconnect",
601                                 (DBusGProxyCallNotify)__bt_audio_request_cb,
602                                 func_data, NULL,
603                                 G_TYPE_INVALID)) {
604                                 BT_ERR("Audio disconnect Dbus Call Error");
605                                 g_object_unref(profile_proxy);
606
607                                 g_free(func_data->address);
608                                 g_free(func_data);
609
610                                 result = BLUETOOTH_ERROR_INTERNAL;
611                                 goto fail;
612                         }
613                 } else {
614                         if (!dbus_g_proxy_begin_call(profile_proxy,
615                                 "DisconnectProfile",
616                                 (DBusGProxyCallNotify)__bt_audio_request_cb,
617                                 func_data, NULL,
618                                 G_TYPE_STRING, uuid,
619                                 G_TYPE_INVALID)) {
620                                 BT_ERR("Audio disconnect Dbus Call Error");
621                                 g_object_unref(profile_proxy);
622
623                                 g_free(func_data->address);
624                                 g_free(func_data);
625
626                                 result = BLUETOOTH_ERROR_INTERNAL;
627                                 goto fail;
628                         }
629                 }
630         }
631
632         return BLUETOOTH_ERROR_NONE;
633 fail:
634         g_array_append_vals(*out_param1, address,
635                                 BT_ADDRESS_STR_LEN);
636
637         return result;
638 }
639
640 int _bt_audio_get_speaker_gain(unsigned int *gain)
641 {
642         char *device_path = NULL;
643         DBusGProxy *adapter_proxy;
644         DBusGProxy *profile_proxy;
645         DBusGConnection *g_conn;
646         GHashTable *hash = NULL;
647         GValue *value;
648
649         adapter_proxy = _bt_get_adapter_proxy();
650         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
651
652         g_conn = _bt_get_system_gconn();
653         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
654
655         device_path = __bt_get_connected_audio_path();
656         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
657
658         profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
659                                       device_path, BT_HFP_AGENT_INTERFACE);
660
661         g_free(device_path);
662
663         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
664
665         dbus_g_proxy_call(profile_proxy, "GetProperties", NULL,
666                         G_TYPE_INVALID,
667                         dbus_g_type_get_map("GHashTable",
668                         G_TYPE_STRING, G_TYPE_VALUE),
669                         &hash, G_TYPE_INVALID);
670
671         g_object_unref(profile_proxy);
672
673         retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
674
675         value = g_hash_table_lookup(hash, "SpeakerGain");
676         *gain = value ? g_value_get_uint(value) : 0;
677         g_hash_table_destroy(hash);
678         return BLUETOOTH_ERROR_NONE;
679 }
680
681 int _bt_audio_set_speaker_gain(unsigned int gain)
682 {
683         char *device_path = NULL;
684         char *gain_str = "SpeakerGain";
685         char sig[2] = {DBUS_TYPE_UINT16, '\0'};
686         int ret = BLUETOOTH_ERROR_NONE;
687         DBusMessage *msg;
688         DBusMessageIter iter;
689         DBusMessageIter value;
690         DBusConnection *conn;
691
692         conn = _bt_get_system_conn();
693         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
694
695         device_path = __bt_get_connected_audio_path();
696         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
697
698         msg = dbus_message_new_method_call(BT_BLUEZ_NAME,
699                         device_path, BT_HFP_AGENT_INTERFACE,
700                         "SetProperty");
701
702         g_free(device_path);
703
704         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
705
706         dbus_message_iter_init_append(msg, &iter);
707         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
708                         &gain_str);
709         dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
710                         sig, &value);
711         dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT16,
712                         &gain);
713         dbus_message_iter_close_container(&iter, &value);
714
715         if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL)
716                 dbus_message_set_no_reply(msg, TRUE);
717
718         if (!dbus_connection_send(conn, msg, NULL)) {
719                 BT_ERR("Dbus sending failed\n");
720                 ret = BLUETOOTH_ERROR_INTERNAL;
721         }
722         dbus_message_unref(msg);
723
724         return ret;
725 }