Modify bt-oal initialize code readably
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-hfp.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
5  *
6  * Contact: Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <sys/un.h>
24 #include <sys/socket.h>
25 #include <sys/errno.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <dlog.h>
29
30 #include <bluetooth.h>
31 #include <bt_hf.h>
32
33 #include "oal-common.h"
34 #include "oal-internal.h"
35 #include "oal-hfp.h"
36 #include "oal-utils.h"
37
38 #define CHECK_OAL_HF_ENABLED() \
39         do { \
40                 if (blued_hfp_interface == NULL) { \
41                         BT_ERR("OAL, HFP Not Enabled"); \
42                         return OAL_STATUS_NOT_READY; \
43                 } \
44         } while (0)
45
46 static void cb_hfp_connection_state(bthf_connection_state_t state, bt_bdaddr_t *bd_addr);
47 static void cb_hfp_audio_connection_state(bthf_audio_state_t state, bt_bdaddr_t *bd_addr);
48
49 const bt_interface_t * _bt_get_stack_interface(void);
50 static const bthf_interface_t *blued_hfp_interface = NULL;
51
52 static bthf_callbacks_t blued_hf_cb = {
53         .size = sizeof(blued_hf_cb),
54         .connection_state_cb = cb_hfp_connection_state,
55         .audio_state_cb = cb_hfp_audio_connection_state,
56         .vr_cmd_cb = NULL,
57         .answer_call_cmd_cb = NULL,
58         .hangup_call_cmd_cb = NULL,
59         .volume_cmd_cb = NULL,
60         .dial_call_cmd_cb = NULL,
61         .dtmf_cmd_cb = NULL,
62         .nrec_cmd_cb = NULL,
63         .wbs_cb = NULL,
64         .chld_cmd_cb = NULL,
65         .cnum_cmd_cb = NULL,
66         .cind_cmd_cb = NULL,
67         .cops_cmd_cb = NULL,
68         .clcc_cmd_cb = NULL,
69         .unknown_at_cmd_cb = NULL,
70         .key_pressed_cmd_cb = NULL
71 };
72
73 oal_status_t hfp_enable(int max_hf_clients_supported)
74 {
75         const bt_interface_t* blued_inf;
76         int ret;
77
78         API_TRACE("HF Enable");
79
80         if (max_hf_clients_supported > 1)
81                 return OAL_STATUS_NOT_SUPPORT;
82
83         if ((blued_inf = adapter_get_stack_interface()) == NULL) {
84                 BT_ERR("Bluetooth module is not loaded");
85                 return OAL_STATUS_NOT_READY;
86         }
87
88         if (blued_hfp_interface != NULL) {
89                 BT_WARN("HF Interface is already initialized...");
90                 return OAL_STATUS_ALREADY_DONE;
91         }
92
93         if ((blued_hfp_interface = (const bthf_interface_t *)blued_inf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) {
94                 BT_ERR("OAL, Failed to get Bluetooth HF Interface");
95                 return OAL_STATUS_INTERNAL_ERROR;
96         }
97
98         BT_DBG("Got profile interface");
99         if ((ret = blued_hfp_interface->init(&blued_hf_cb, 1)) != BT_STATUS_SUCCESS) {
100                 BT_ERR("Failed to initialize Bluetooth HF, status: %s", status2string(ret));
101                 blued_hfp_interface = NULL;
102                 return convert_to_oal_status(ret);
103         }
104         BT_DBG("OAL, Bluetooth HF interface initialised");
105
106         return OAL_STATUS_SUCCESS;
107 }
108
109 /* HF deinit: Resets all the HF information
110  * Note: Adapter should be disabled before calling deinit
111  * */
112 oal_status_t hfp_disable(void)
113 {
114         API_TRACE("HF disable");
115         CHECK_OAL_HF_ENABLED();
116
117         blued_hfp_interface->cleanup();
118         blued_hfp_interface = NULL;
119
120         return OAL_STATUS_SUCCESS;
121 }
122
123 void hfp_cleanup(void)
124 {
125         API_TRACE("HF Cleanup");
126         blued_hfp_interface = NULL;
127 }
128
129 oal_status_t hfp_connect(bt_address_t *device_address)
130 {
131         int result = OAL_STATUS_SUCCESS;
132         bt_status_t status;
133         bdstr_t bdstr;
134         API_TRACE("HF Connect");
135
136         CHECK_OAL_HF_ENABLED();
137         OAL_CHECK_PARAMETER(device_address, return);
138
139         BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr));
140         /* Call connect function of Bluedroid*/
141         status = blued_hfp_interface->connect((bt_bdaddr_t *)device_address);
142         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
143                 BT_ERR("Connection could not be established, err: %s", status2string(status));;
144                 result =  convert_to_oal_status(status);
145         }
146         return result;
147 }
148
149 oal_status_t hfp_disconnect(bt_address_t *device_address)
150 {
151         int result = OAL_STATUS_SUCCESS;
152         bdstr_t bdstr;
153         bt_status_t status;
154         API_TRACE("HF Disconnect");
155
156         CHECK_OAL_HF_ENABLED();
157         OAL_CHECK_PARAMETER(device_address, return);
158
159         BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr));
160         /* call Disconnect function of Bluedroid */
161         status = blued_hfp_interface->disconnect((bt_bdaddr_t *)device_address);
162         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
163                 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
164                 result =  convert_to_oal_status(status);
165         }
166         return result;
167 }
168
169 oal_status_t hfp_connect_audio(bt_address_t *device_address)
170 {
171         bt_status_t status;
172         int result = OAL_STATUS_SUCCESS;
173         bdstr_t bdstr;
174         API_TRACE("Connect HF Audio");
175
176         CHECK_OAL_HF_ENABLED();
177         OAL_CHECK_PARAMETER(device_address, return);
178
179         BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr));
180         status = blued_hfp_interface->connect_audio((bt_bdaddr_t *)device_address);
181
182         if (status != BT_STATUS_SUCCESS) {
183                 BT_ERR("Start stream failed err: %s", status2string(status));
184                 result = convert_to_oal_status(status);
185         }
186         return result;
187 }
188
189 oal_status_t hfp_disconnect_audio(bt_address_t *device_address)
190 {
191         bt_status_t status;
192         int result = OAL_STATUS_SUCCESS;
193         bdstr_t bdstr;
194         API_TRACE("DisConnect HF Audio");
195
196         CHECK_OAL_HF_ENABLED();
197
198         OAL_CHECK_PARAMETER(device_address, return);
199
200         BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr));
201         status = blued_hfp_interface->disconnect_audio((bt_bdaddr_t *)device_address);
202
203         if (status != BT_STATUS_SUCCESS) {
204                 BT_ERR("Start stream failed err: %s", status2string(status));
205                 result = convert_to_oal_status(status);
206         }
207         return result;
208 }
209
210 static void cb_hfp_connection_state(bthf_connection_state_t state, bt_bdaddr_t *bd_addr)
211 {
212         int event_type;
213         bdstr_t bdstr;
214         bt_address_t * event_data = NULL;
215         event_data = g_new0(bt_address_t, 1);
216         memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
217
218         if (bd_addr == NULL) {
219                 BT_ERR("Address is NULL");
220                 if (event_data)
221                         g_free(event_data);
222                 return;
223         }
224
225         BT_INFO("HFP Profile state = [%d],  BT Address = [%s]", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
226         switch (state) {
227         case BTHF_CONNECTION_STATE_DISCONNECTED: {
228                  event_type = OAL_EVENT_HFP_DISCONNECTED;
229                  break;
230         }
231         case BTHF_CONNECTION_STATE_CONNECTING: {
232                 event_type = OAL_EVENT_HFP_CONNECTING;
233                 break;
234         }
235         case BTHF_CONNECTION_STATE_CONNECTED: {
236                 event_type = OAL_EVENT_HFP_CONNECTED;
237                 break;
238         }
239         case BTHF_CONNECTION_STATE_DISCONNECTING: {
240                 event_type = OAL_EVENT_HFP_DISCONNECTING;
241                 break;
242         }
243         default: {
244                 BT_INFO("Invalid state");
245                 if (event_data)
246                         g_free(event_data);
247                 return;
248         }
249         }
250         send_event_bda_trace(event_type, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
251 }
252
253 static void cb_hfp_audio_connection_state(bthf_audio_state_t state, bt_bdaddr_t *bd_addr)
254 {
255         int event_type;
256         bdstr_t bdstr;
257         bt_address_t * event_data = NULL;
258         event_data = g_new0(bt_address_t, 1);
259         memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
260
261         if (bd_addr == NULL) {
262                 BT_ERR("Address is NULL");
263                 if (event_data)
264                         g_free(event_data);
265                 return;
266         }
267         BT_INFO("HFP Audio state = [%d],  BT Address = [%s]", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
268
269         switch (state) {
270         case BTHF_AUDIO_STATE_DISCONNECTED: {
271                 BT_INFO("HFP Audio(SCO) DisConnected");
272                 event_type = OAL_EVENT_HFP_AUDIO_DISCONNECTED;
273                 break;
274         }
275         case BTHF_AUDIO_STATE_CONNECTED: {
276                 BT_INFO("HFP Audio(SCO) Connected");
277                 event_type = OAL_EVENT_HFP_AUDIO_CONNECTED;
278                 break;
279         }
280         case BTHF_AUDIO_STATE_CONNECTING: {
281                 BT_INFO("HFP Audio(SCO) Connecting");
282                 event_type = OAL_EVENT_HFP_AUDIO_CONNECTING;
283                 break;
284         }
285         case BTHF_AUDIO_STATE_DISCONNECTING: {
286                 BT_INFO("HFP Audio(SCO) DisConnecting");
287                 event_type = OAL_EVENT_HFP_AUDIO_DISCONNECTING;
288                 break;
289         }
290         default: {
291                 BT_INFO("Invalid state");
292                 if (event_data)
293                         g_free(event_data);
294                 return;
295         }
296         }
297         send_event_bda_trace(event_type, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
298 }