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