Merge "Fix Memory leak issue" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-audio.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19
20 #include "bluetooth-api.h"
21 #include "bluetooth-audio-api.h"
22 #include "bt-internal-types.h"
23
24 #include "bt-common.h"
25 #include "bt-request-sender.h"
26 #include "bt-event-handler.h"
27
28 BT_EXPORT_API int bluetooth_audio_init(bt_audio_func_ptr cb, void *user_data)
29 {
30         int ret;
31
32         if (cb == NULL) {
33                 BT_ERR("callback is NULL");
34                 return BLUETOOTH_ERROR_INVALID_PARAM;
35         }
36         ret = _bt_init_event_handler();
37
38         if (ret != BLUETOOTH_ERROR_NONE &&
39              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
40                 BT_ERR("Fail to init the event handler");
41                 return ret;
42         }
43
44         _bt_set_user_data(BT_AUDIO, (void *)cb, user_data);
45
46         /* Register All events */
47         ret = _bt_register_event(BT_HEADSET_EVENT, (void *)cb, user_data);
48         if (ret != BLUETOOTH_ERROR_NONE &&
49             ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
50                 _bt_deinit_event_handler();
51                 return ret;
52         }
53
54         ret = _bt_register_event(BT_A2DP_SOURCE_EVENT, (void *)cb, user_data);
55         if (ret != BLUETOOTH_ERROR_NONE &&
56                         ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
57                 _bt_deinit_event_handler();
58                 return ret;
59         }
60
61         return BLUETOOTH_ERROR_NONE;
62 }
63
64 BT_EXPORT_API int bluetooth_audio_deinit(void)
65 {
66         _bt_unregister_event(BT_HEADSET_EVENT);
67         _bt_unregister_event(BT_A2DP_SOURCE_EVENT);
68         _bt_set_user_data(BT_AUDIO, NULL, NULL);
69
70         return BLUETOOTH_ERROR_NONE;
71 }
72
73 BT_EXPORT_API int bluetooth_audio_connect(bluetooth_device_address_t *remote_address)
74 {
75         int service_function = BT_AUDIO_CONNECT;
76         int result;
77         bt_user_info_t *user_info;
78
79         BT_CHECK_PARAMETER(remote_address, return);
80         BT_CHECK_ENABLED(return);
81
82         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AUDIO_CONNECT)
83              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
84                 BT_ERR("Don't have a privilege to use this API");
85                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
86         }
87
88         user_info = _bt_get_user_data(BT_AUDIO);
89         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
90
91         BT_INIT_PARAMS();
92         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
93
94         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
95
96         result = _bt_send_request_async(BT_BLUEZ_SERVICE, service_function,
97                 in_param1, in_param2, in_param3, in_param4,
98                 user_info->cb, user_info->user_data);
99
100         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
101
102         return result;
103 }
104
105 BT_EXPORT_API int bluetooth_audio_disconnect(bluetooth_device_address_t *remote_address)
106 {
107         int result;
108         bt_user_info_t *user_info;
109
110         BT_CHECK_PARAMETER(remote_address, return);
111         BT_CHECK_ENABLED(return);
112
113         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AUDIO_DISCONNECT)
114              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
115                 BT_ERR("Don't have a privilege to use this API");
116                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
117         }
118
119         user_info = _bt_get_user_data(BT_AUDIO);
120         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
121
122         BT_INIT_PARAMS();
123         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
124
125         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
126
127         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AUDIO_DISCONNECT,
128                 in_param1, in_param2, in_param3, in_param4,
129                 user_info->cb, user_info->user_data);
130
131         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
132
133         return result;
134 }
135
136 BT_EXPORT_API int bluetooth_ag_connect(bluetooth_device_address_t *remote_address)
137 {
138         int result;
139         bt_user_info_t *user_info;
140
141         BT_CHECK_PARAMETER(remote_address, return);
142         BT_CHECK_ENABLED(return);
143
144         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AG_CONNECT)
145              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
146                 BT_ERR("Don't have a privilege to use this API");
147                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
148         }
149
150         user_info = _bt_get_user_data(BT_AUDIO);
151         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
152
153         BT_INIT_PARAMS();
154         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
155
156         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
157
158         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_CONNECT,
159                 in_param1, in_param2, in_param3, in_param4,
160                 user_info->cb, user_info->user_data);
161
162         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
163
164         return result;
165 }
166
167 BT_EXPORT_API int bluetooth_ag_disconnect(bluetooth_device_address_t *remote_address)
168 {
169         int result;
170         bt_user_info_t *user_info;
171
172         BT_CHECK_PARAMETER(remote_address, return);
173         BT_CHECK_ENABLED(return);
174
175         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AG_DISCONNECT)
176              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
177                 BT_ERR("Don't have a privilege to use this API");
178                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
179         }
180
181         user_info = _bt_get_user_data(BT_AUDIO);
182         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
183
184         BT_INIT_PARAMS();
185         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
186
187         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
188
189         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_DISCONNECT,
190                 in_param1, in_param2, in_param3, in_param4,
191                 user_info->cb, user_info->user_data);
192
193         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
194
195         return result;
196 }
197
198 BT_EXPORT_API int bluetooth_av_connect(bluetooth_device_address_t *remote_address)
199 {
200         int result;
201         bt_user_info_t *user_info;
202
203         BT_CHECK_PARAMETER(remote_address, return);
204         BT_CHECK_ENABLED(return);
205
206         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_CONNECT)
207              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
208                 BT_ERR("Don't have a privilege to use this API");
209                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
210         }
211
212         user_info = _bt_get_user_data(BT_AUDIO);
213         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
214
215         BT_INIT_PARAMS();
216         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
217
218         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
219
220         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_CONNECT,
221                 in_param1, in_param2, in_param3, in_param4,
222                 user_info->cb, user_info->user_data);
223
224         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
225
226         return result;
227 }
228
229 BT_EXPORT_API int bluetooth_av_source_connect(bluetooth_device_address_t *remote_address)
230 {
231         int result;
232         bt_user_info_t *user_info;
233
234         BT_CHECK_PARAMETER(remote_address, return);
235         BT_CHECK_ENABLED(return);
236
237         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_SOURCE_CONNECT)
238                  == BLUETOOTH_ERROR_PERMISSION_DEINED) {
239                 BT_ERR("Don't have a privilege to use this API");
240                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
241         }
242
243         user_info = _bt_get_user_data(BT_AUDIO);
244         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
245
246         BT_INIT_PARAMS();
247         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
248
249         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
250
251         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_SOURCE_CONNECT,
252                 in_param1, in_param2, in_param3, in_param4,
253                 user_info->cb, user_info->user_data);
254
255         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
256
257         return result;
258 }
259
260 BT_EXPORT_API int bluetooth_av_disconnect(bluetooth_device_address_t *remote_address)
261 {
262         int result;
263         bt_user_info_t *user_info;
264
265         BT_CHECK_PARAMETER(remote_address, return);
266         BT_CHECK_ENABLED(return);
267
268         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_DISCONNECT)
269              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
270                 BT_ERR("Don't have a privilege to use this API");
271                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
272         }
273
274         user_info = _bt_get_user_data(BT_AUDIO);
275         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
276
277         BT_INIT_PARAMS();
278         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
279
280         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
281
282         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_DISCONNECT,
283                 in_param1, in_param2, in_param3, in_param4,
284                 user_info->cb, user_info->user_data);
285
286         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
287
288         return result;
289 }
290
291 BT_EXPORT_API int bluetooth_av_source_disconnect(bluetooth_device_address_t *remote_address)
292 {
293         int result;
294         bt_user_info_t *user_info;
295
296         BT_CHECK_PARAMETER(remote_address, return);
297         BT_CHECK_ENABLED(return);
298
299         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_SOURCE_DISCONNECT)
300              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
301                 BT_ERR("Don't have a privilege to use this API");
302                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
303         }
304
305         user_info = _bt_get_user_data(BT_AUDIO);
306         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
307
308         BT_INIT_PARAMS();
309         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
310
311         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
312
313         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_SOURCE_DISCONNECT,
314                 in_param1, in_param2, in_param3, in_param4,
315                 user_info->cb, user_info->user_data);
316
317         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
318
319         return result;
320 }
321
322 BT_EXPORT_API int bluetooth_ag_get_headset_volume(unsigned int *speaker_gain)
323 {
324         int result;
325
326         BT_CHECK_PARAMETER(speaker_gain, return);
327         BT_CHECK_ENABLED(return);
328
329         BT_INIT_PARAMS();
330         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
331
332         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GET_SPEAKER_GAIN,
333                 in_param1, in_param2, in_param3, in_param4, &out_param);
334
335         if (result == BLUETOOTH_ERROR_NONE) {
336                 *speaker_gain = g_array_index(out_param,
337                                 unsigned int, 0);
338         }
339
340         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
341
342         return result;
343 }
344
345 BT_EXPORT_API int bluetooth_ag_set_speaker_gain(unsigned int speaker_gain)
346 {
347         int result;
348
349         BT_CHECK_ENABLED(return);
350
351         BT_INIT_PARAMS();
352         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
353
354         g_array_append_vals(in_param1, &speaker_gain, sizeof(unsigned int));
355
356         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_SET_SPEAKER_GAIN,
357                 in_param1, in_param2, in_param3, in_param4, &out_param);
358
359         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
360
361         return result;
362 }
363
364 #define BT_HF_SERVICE_NAME "org.bluez.hf_agent"
365 #define BT_HF_OBJECT_PATH "/org/bluez/handsfree_agent"
366 #define BT_HF_INTERFACE "org.tizen.HfApp"
367
368
369 static GVariant* __bt_hf_agent_dbus_send(const char *path, const char *interface,
370                                 const char *method, GError **err, GVariant *parameters)
371 {
372         GVariant *reply = NULL;
373         GDBusProxy *proxy = NULL;
374         GDBusConnection *conn = NULL;
375
376         conn = _bt_gdbus_get_system_gconn();
377         retv_if(conn == NULL, NULL);
378
379         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
380                 NULL, BT_HF_SERVICE_NAME, path, interface, NULL, err);
381         if (proxy == NULL) {
382                 BT_ERR("Unable to allocate new proxy");
383                 return NULL;
384         }
385
386         reply = g_dbus_proxy_call_sync(proxy, method, parameters,
387                                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, err);
388
389         g_object_unref(proxy);
390         return reply;
391 }
392
393 static int __bt_hf_agent_read_call_list(GVariant *reply,
394                                 bt_hf_call_list_s **call_list) {
395
396         GVariantIter iter;
397         GVariant *var_temp = NULL;
398         int32_t call_count;
399         gchar *num = NULL;
400         int dir, status, mpart, idx;
401
402         BT_DBG("+");
403
404         g_variant_get(reply, "(i@a(siiii))", &call_count, &var_temp);
405
406         if(call_count <= 0) {
407                 *call_list = NULL;
408                 return BLUETOOTH_ERROR_NOT_FOUND;
409         }
410         BT_DBG("Call count = %d", call_count);
411
412         *call_list = g_malloc0(sizeof(bt_hf_call_list_s));
413         /* Fix : NULL_RETURNS */
414         retv_if(*call_list == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
415
416         (*call_list)->count = call_count;
417
418         g_variant_iter_init(&iter, var_temp);
419         while(g_variant_iter_loop(&iter, "(siiii)", &num, &dir, &status, &mpart, &idx)){
420                 bt_hf_call_status_info_t *call_info;
421
422                 call_info = g_malloc0(sizeof(bt_hf_call_status_info_t));
423                 /* Fix : NULL_RETURNS */
424                 retv_if(call_info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
425
426                 call_info->number = g_strdup(num);
427                 call_info->direction = dir;
428                 call_info->status = status;
429                 call_info->mpart= mpart;
430                 call_info->idx = idx;
431
432                 (*call_list)->list = g_list_append((*call_list)->list,
433                                                         (gpointer)call_info);
434         }
435         BT_DBG("-");
436         return BLUETOOTH_ERROR_NONE;
437 }
438
439 BT_EXPORT_API int bluetooth_hf_init(bt_hf_func_ptr cb, void *user_data)
440 {
441         int ret;
442
443         if (cb == NULL) {
444                 BT_ERR("callback is NULL");
445                 return BLUETOOTH_ERROR_INVALID_PARAM;
446         }
447
448         ret = _bt_init_event_handler();
449
450         if (ret != BLUETOOTH_ERROR_NONE &&
451              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
452                 BT_ERR("Fail to init the event handler");
453                 return ret;
454         }
455
456         _bt_set_user_data(BT_HF, (void *)cb, user_data);
457
458         /* Register All events */
459         ret = _bt_register_event(BT_HF_AGENT_EVENT, (void *)cb, user_data);
460         if (ret != BLUETOOTH_ERROR_NONE &&
461              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
462                 _bt_deinit_event_handler();
463                 return ret;
464         }
465
466         return BLUETOOTH_ERROR_NONE;
467 }
468
469 BT_EXPORT_API int bluetooth_hf_deinit(void)
470 {
471         int ret;
472
473         ret = _bt_unregister_event(BT_HF_AGENT_EVENT);
474         if (ret != BLUETOOTH_ERROR_NONE )
475                 BT_ERR("_bt_unregister_event failed");
476
477         _bt_set_user_data(BT_HF, NULL, NULL);
478
479         return BLUETOOTH_ERROR_NONE;
480 }
481
482 BT_EXPORT_API int bluetooth_hf_connect(bluetooth_device_address_t *remote_address)
483 {
484         int result;
485         bt_user_info_t *user_info;
486
487         BT_CHECK_ENABLED(return);
488         BT_CHECK_PARAMETER(remote_address, return);
489
490         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_CONNECT)
491              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
492                 BT_ERR("Don't have a privilege to use this API");
493                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
494         }
495
496         user_info = _bt_get_user_data(BT_HF);
497         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
498
499         BT_INIT_PARAMS();
500         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
501
502         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
503
504         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_CONNECT,
505                 in_param1, in_param2, in_param3, in_param4,
506                 user_info->cb, user_info->user_data);
507
508         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
509
510         return result;
511 }
512
513 BT_EXPORT_API int bluetooth_hf_disconnect(bluetooth_device_address_t *remote_address)
514 {
515         int result;
516         bt_user_info_t *user_info;
517
518         BT_CHECK_PARAMETER(remote_address, return);
519         BT_CHECK_ENABLED(return);
520
521         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_DISCONNECT)
522              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
523                 BT_ERR("Don't have a privilege to use this API");
524                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
525         }
526
527         user_info = _bt_get_user_data(BT_HF);
528         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
529
530         BT_INIT_PARAMS();
531         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
532
533         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
534
535         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_DISCONNECT,
536                 in_param1, in_param2, in_param3, in_param4,
537                 user_info->cb, user_info->user_data);
538
539         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
540
541         return result;
542 }
543
544 BT_EXPORT_API int bluetooth_hf_answer_call()
545 {
546         GVariant *reply = NULL;
547         GError *err = NULL;
548         int ret = BLUETOOTH_ERROR_INTERNAL;
549
550         BT_CHECK_ENABLED(return);
551
552         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
553                         "AnswerCall", &err, NULL);
554         if (!reply) {
555                 BT_ERR("Error returned in method call\n");
556                 if (err) {
557                         BT_ERR("Error = %s", err->message);
558                         g_dbus_error_strip_remote_error(err);
559                         if (strcmp(err->message, "Operation not supported") == 0)
560                                 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
561                         else if (strcmp(err->message, "Operation not allowed") == 0)
562                                 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
563                         else
564                                 ret = BLUETOOTH_ERROR_INTERNAL;
565                         g_clear_error(&err);
566                 }
567                 return ret;
568         }
569
570         g_variant_unref(reply);
571         return BLUETOOTH_ERROR_NONE;
572
573 }
574
575 BT_EXPORT_API int bluetooth_hf_terminate_call()
576 {
577         GVariant *reply = NULL;
578         GError *err = NULL;
579
580         BT_CHECK_ENABLED(return);
581
582         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
583                         "TerminateCall", &err, NULL);
584         if (!reply) {
585                 BT_ERR("Error returned in method call\n");
586                 if (err) {
587                         BT_ERR("Error = %s", err->message);
588                         g_clear_error(&err);
589                 }
590                 return BLUETOOTH_ERROR_INTERNAL;
591         }
592
593         g_variant_unref(reply);
594         return BLUETOOTH_ERROR_NONE;
595 }
596
597 BT_EXPORT_API int bluetooth_hf_initiate_call(char *number)
598 {
599         GVariant *reply = NULL;
600         GError *err = NULL;
601         GVariant *param = NULL;
602         int ret = BLUETOOTH_ERROR_INTERNAL;
603
604         BT_CHECK_ENABLED(return);
605
606         if (!number)
607                 number = "";
608
609         param = g_variant_new("(s)", number);
610         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
611                         "InitiateCall", &err, param);
612         if (!reply) {
613                 BT_ERR("Error returned in method call");
614                 if (err) {
615                         BT_ERR("Error = %s", err->message);
616                         g_dbus_error_strip_remote_error(err);
617                         if (strcmp(err->message, "NotConnected") == 0)
618                                 ret = BLUETOOTH_ERROR_NOT_CONNECTED;
619                         else if (strcmp(err->message, "Operation not allowed") == 0)
620                                 ret = BLUETOOTH_ERROR_IN_PROGRESS;
621                         else
622                                 ret = BLUETOOTH_ERROR_INTERNAL;
623                         g_clear_error(&err);
624                 }
625                 return ret;
626         }
627
628         g_variant_unref(reply);
629         return BLUETOOTH_ERROR_NONE;
630 }
631
632 BT_EXPORT_API int bluetooth_hf_voice_recognition(unsigned int status)
633 {
634         GVariant *reply = NULL;
635         GError *err = NULL;
636         GVariant *param = NULL;
637
638         BT_CHECK_ENABLED(return);
639
640         param = g_variant_new("(i)", status);
641         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
642                         "VoiceRecognition", &err, param);
643         if (!reply) {
644                 BT_ERR("Error returned in method call\n");
645                 if (err) {
646                         BT_ERR("Error = %s", err->message);
647                         g_clear_error(&err);
648                 }
649                 return BLUETOOTH_ERROR_INTERNAL;
650         }
651
652         g_variant_unref(reply);
653         return BLUETOOTH_ERROR_NONE;
654 }
655
656 BT_EXPORT_API int bluetooth_hf_audio_disconnect(void)
657 {
658         GVariant *reply = NULL;
659         GError *err = NULL;
660
661         BT_CHECK_ENABLED(return);
662
663         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
664                         "ScoDisconnect", &err, NULL);
665         if (!reply) {
666                 BT_ERR("Error returned in method call\n");
667                 if (err) {
668                         BT_ERR("Error = %s", err->message);
669                         g_clear_error(&err);
670                 }
671                 return BLUETOOTH_ERROR_INTERNAL;
672         }
673
674         g_variant_unref(reply);
675         return BLUETOOTH_ERROR_NONE;
676 }
677
678 BT_EXPORT_API int bluetooth_hf_set_speaker_gain(unsigned int speaker_gain)
679 {
680         GVariant *reply = NULL;
681         GError *err = NULL;
682         GVariant *param = NULL;
683
684         BT_CHECK_ENABLED(return);
685
686         param = g_variant_new("(u)", speaker_gain);
687         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
688                         "SpeakerGain", &err, param);
689         if (!reply) {
690                 BT_ERR("Error returned in method call\n");
691                 if (err) {
692                         BT_ERR("Error = %s", err->message);
693                         g_clear_error(&err);
694                 }
695                 return BLUETOOTH_ERROR_INTERNAL;
696         }
697
698         g_variant_unref(reply);
699         return BLUETOOTH_ERROR_NONE;
700 }
701
702 BT_EXPORT_API int bluetooth_hf_send_dtmf(char *dtmf)
703 {
704         GVariant *reply = NULL;
705         GError *err = NULL;
706         GVariant *param = NULL;
707
708         BT_CHECK_ENABLED(return);
709
710         param = g_variant_new("(s)", dtmf);
711         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
712                         "SendDtmf", &err, param);
713         if (!reply) {
714                 BT_ERR("Error returned in method call\n");
715                 if (err) {
716                         BT_ERR("Error = %s", err->message);
717                         g_clear_error(&err);
718                 }
719                 return BLUETOOTH_ERROR_INTERNAL;
720         }
721
722         g_variant_unref(reply);
723         return BLUETOOTH_ERROR_NONE;
724 }
725
726 BT_EXPORT_API int bluetooth_hf_send_xsat_cmd(int app_id, char *xsat_cmd)
727 {
728         GVariant *reply = NULL;
729         GError *err = NULL;
730         GVariant *param = NULL;
731         char buffer[200] = {0,};
732         char *ptr = buffer;
733
734         BT_CHECK_ENABLED(return);
735
736         strncpy(buffer, "AT+XSAT=", strlen("AT+XSAT="));
737         snprintf(buffer + strlen(buffer), sizeof(buffer), "%d,", app_id);
738         strncat(buffer, xsat_cmd, (sizeof(buffer) - 1) - strlen(buffer));
739         BT_DBG("Xsat cmd received = %s", buffer);
740
741         param = g_variant_new("(s)", ptr);
742
743         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
744                                         "SendAtCmd", &err, param);
745         if (!reply) {
746                 BT_ERR("Error returned in method call\n");
747                 if (err) {
748                         BT_ERR("Error = %s", err->message);
749                         g_clear_error(&err);
750                 }
751                 return BLUETOOTH_ERROR_INTERNAL;
752         }
753
754         g_variant_unref(reply);
755         return BLUETOOTH_ERROR_NONE;
756 }
757
758 BT_EXPORT_API int bluetooth_hf_release_and_accept(void)
759 {
760         GVariant *reply = NULL;
761         GError *err = NULL;
762
763         BT_CHECK_ENABLED(return);
764
765         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
766                         "ReleaseAndAccept", &err, NULL);
767         if (!reply) {
768                 BT_ERR("Error returned in method call\n");
769                 if (err) {
770                         BT_ERR("Error = %s", err->message);
771                         g_clear_error(&err);
772                 }
773                 return BLUETOOTH_ERROR_INTERNAL;
774         }
775
776         g_variant_unref(reply);
777         return BLUETOOTH_ERROR_NONE;
778 }
779
780 BT_EXPORT_API int bluetooth_hf_swap_call(void)
781 {
782         GVariant *reply = NULL;
783         GError *err = NULL;
784
785         BT_CHECK_ENABLED(return);
786
787         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
788                         "CallSwap", &err, NULL);
789         if (!reply) {
790                 BT_ERR("Error returned in method call\n");
791                 if (err) {
792                         BT_ERR("Error = %s", err->message);
793                         g_clear_error(&err);
794                 }
795                 return BLUETOOTH_ERROR_INTERNAL;
796         }
797
798         g_variant_unref(reply);
799         return BLUETOOTH_ERROR_NONE;
800 }
801
802 BT_EXPORT_API int bluetooth_hf_release_all_call(void)
803 {
804         GVariant *reply = NULL;
805         GError *err = NULL;
806
807         BT_CHECK_ENABLED(return);
808
809         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
810                         "ReleaseAllCall", &err, NULL);
811         if (!reply) {
812                 BT_ERR("Error returned in method call\n");
813                 if (err) {
814                         BT_ERR("Error = %s", err->message);
815                         g_clear_error(&err);
816                 }
817                 return BLUETOOTH_ERROR_INTERNAL;
818         }
819
820         g_variant_unref(reply);
821         return BLUETOOTH_ERROR_NONE;
822 }
823
824 BT_EXPORT_API int bluetooth_hf_join_call(void)
825 {
826         GVariant *reply = NULL;
827         GError *err = NULL;
828
829         BT_CHECK_ENABLED(return);
830
831         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
832                         "JoinCall", &err, NULL);
833         if (!reply) {
834                 BT_ERR("Error returned in method call\n");
835                 if (err) {
836                         BT_ERR("Error = %s", err->message);
837                         g_clear_error(&err);
838                 }
839                 return BLUETOOTH_ERROR_INTERNAL;
840         }
841
842         g_variant_unref(reply);
843         return BLUETOOTH_ERROR_NONE;
844 }
845
846 BT_EXPORT_API int bluetooth_hf_get_call_list(void *call_list,
847                                                                 bt_hf_call_status_info_t **call_status)
848 {
849         int i;
850         GList *list = call_list;
851         int call_count;
852         bt_hf_call_status_info_t * call_info;
853
854         BT_CHECK_ENABLED(return);
855         retv_if(list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
856         retv_if(call_status == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
857
858         call_count = g_list_length(list);
859
860         BT_DBG(" call_count = [%d]", call_count);
861
862         for (i = 0; i < call_count; i++) {
863                 call_info = g_list_nth_data(list, i);
864                 BT_DBG(" direction = [%d]", call_info->direction);
865                 BT_DBG(" status = [%d]", call_info->status);
866                 BT_DBG(" mpart = [%d]", call_info->mpart);
867                 BT_DBG(" number = [%s]", call_info->number);
868                 BT_DBG(" idx = [%d]", call_info->idx);
869                 call_status[i] = call_info;
870         }
871
872         return BLUETOOTH_ERROR_NONE;
873 }
874
875 BT_EXPORT_API int bluetooth_hf_free_call_list(bt_hf_call_list_s *call_list)
876 {
877         bt_hf_call_list_s *handle;
878         bt_hf_call_status_info_t *call_status;
879
880         retv_if(call_list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
881
882         handle = (bt_hf_call_list_s *)call_list;
883         do  {
884                 call_status = (bt_hf_call_status_info_t *)g_list_nth_data(
885                                                         handle->list, 0);
886                 if (call_status == NULL)
887                         break;
888                 handle->list = g_list_remove(handle->list, call_status);
889                 g_free(call_status->number);
890                 g_free(call_status);
891         } while (1);
892         g_free(handle);
893         return BLUETOOTH_ERROR_NONE;
894 }
895
896 BT_EXPORT_API int bluetooth_hf_request_call_list(
897                                         bt_hf_call_list_s **call_list)
898 {
899         GVariant *reply = NULL;
900         GError *err = NULL;
901
902         BT_CHECK_ENABLED(return);
903
904         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
905                         "RequestCallList", &err, NULL);
906         if (!reply) {
907                 BT_ERR("dbus Error or call list is null\n");
908                 if (err) {
909                         BT_ERR("Error = %s", err->message);
910                         g_clear_error(&err);
911                 }
912                 *call_list = NULL;
913                 return BLUETOOTH_ERROR_INTERNAL;
914         }
915         __bt_hf_agent_read_call_list(reply, call_list);
916
917         g_variant_unref(reply);
918         return BLUETOOTH_ERROR_NONE;
919 }
920
921 BT_EXPORT_API int bluetooth_hf_get_codec(unsigned int *codec_id)
922 {
923         GVariant *reply = NULL;
924         GError *err = NULL;
925         int32_t current_codec;
926
927         BT_CHECK_ENABLED(return);
928
929         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
930                         "GetCurrentCodec", &err, NULL);
931         if (!reply) {
932                 BT_ERR("Error returned in method call\n");
933                 if (err) {
934                         BT_ERR("Error = %s", err->message);
935                         g_clear_error(&err);
936                 }
937                 return BLUETOOTH_ERROR_INTERNAL;
938         }
939
940         g_variant_get(reply, "(i)", &current_codec);
941         *codec_id = current_codec;
942         BT_DBG(" Codec ID is : %d", *codec_id);
943
944         g_variant_unref(reply);
945         return BLUETOOTH_ERROR_NONE;
946 }
947
948 BT_EXPORT_API int bluetooth_hf_get_audio_connected(unsigned int *audio_connected)
949 {
950         GVariant *reply = NULL;
951         GError *err = NULL;
952         int32_t sco_audio_connected_from_bt_agent;
953
954         BT_CHECK_ENABLED(return);
955
956         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
957                         "GetAudioConnected", &err, NULL);
958         if (!reply) {
959                 BT_ERR("Error returned in method call\n");
960                 if (err) {
961                         BT_ERR("Error = %s", err->message);
962                         g_clear_error(&err);
963                 }
964                 return BLUETOOTH_ERROR_INTERNAL;
965         }
966
967         g_variant_get(reply, "(i)", &sco_audio_connected_from_bt_agent);
968         *audio_connected = sco_audio_connected_from_bt_agent;
969
970         if (*audio_connected == BLUETOOTH_HF_AUDIO_CONNECTED) {
971                 BT_DBG("SCO Audio is Connected");
972         } else {
973                 BT_DBG("SCO Audio is Disconnected");
974         }
975
976         g_variant_unref(reply);
977         return BLUETOOTH_ERROR_NONE;
978 }
979
980 BT_EXPORT_API int bluetooth_hf_is_connected(gboolean *hf_connected)
981 {
982         GVariant *reply = NULL;
983         GError *err = NULL;
984         gboolean hf_connected_from_bt_agent;
985
986         BT_CHECK_ENABLED(return);
987
988         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
989                         "IsHfConnected", &err, NULL);
990         if (!reply) {
991                 BT_ERR("Error returned in method call\n");
992                 if (err) {
993                         BT_ERR("Error = %s", err->message);
994                         g_clear_error(&err);
995                 }
996                 return BLUETOOTH_ERROR_INTERNAL;
997         }
998
999         g_variant_get(reply, "(b)", &hf_connected_from_bt_agent);
1000         *hf_connected = hf_connected_from_bt_agent;
1001
1002         BT_DBG("%s", *hf_connected ? "Connected":"Disconnected");
1003
1004         g_variant_unref(reply);
1005         return BLUETOOTH_ERROR_NONE;
1006 }
1007