4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <dbus/dbus-glib.h>
25 #include "bluetooth-api.h"
26 #include "bluetooth-hid-api.h"
27 #include "bluetooth-audio-api.h"
28 #include "bt-internal-types.h"
30 #include "bt-common.h"
31 #include "bt-request-sender.h"
32 #include "bt-event-handler.h"
34 /* auto generated header by bt-request-service.xml*/
35 #include "bt-request-service.h"
37 static GSList *sending_requests;
39 DBusGConnection *service_conn;
40 DBusGConnection *system_conn;
41 DBusGProxy *service_proxy;
43 static void __bt_remove_all_sending_requests(void)
48 for (l = sending_requests; l != NULL; l = g_slist_next(l)) {
51 if (info && info->proxy && info->proxy_call)
52 dbus_g_proxy_cancel_call(info->proxy, info->proxy_call);
55 g_slist_free(sending_requests);
56 sending_requests = NULL;
59 DBusGProxy *_bt_init_service_proxy(void)
65 if (service_conn == NULL) {
66 service_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
67 retv_if(service_conn == NULL, NULL);
70 proxy = dbus_g_proxy_new_for_name(service_conn, BT_DBUS_NAME, BT_SERVICE_PATH,
74 dbus_g_connection_unref(service_conn);
79 service_proxy = proxy;
84 void _bt_deinit_proxys(void)
86 __bt_remove_all_sending_requests();
89 g_object_unref(service_proxy);
94 dbus_g_connection_unref(service_conn);
99 dbus_g_connection_unref(system_conn);
104 static DBusGProxy *__bt_get_service_proxy(void)
106 return (service_proxy) ? service_proxy : _bt_init_service_proxy();
109 static void __bt_get_event_info(int service_function, GArray *output,
110 int *event, int *event_type, void **param_data)
112 ret_if(event == NULL);
114 switch (service_function) {
116 *event_type = BT_ADAPTER_EVENT;
117 *event = BLUETOOTH_EVENT_BONDING_FINISHED;
118 ret_if(output == NULL);
119 *param_data = &g_array_index(output,
120 bluetooth_device_info_t, 0);
122 case BT_UNBOND_DEVICE:
123 *event_type = BT_ADAPTER_EVENT;
124 *event = BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED;
125 ret_if(output == NULL);
126 *param_data = &g_array_index(output,
127 bluetooth_device_info_t, 0);
129 case BT_SEARCH_SERVICE:
130 *event_type = BT_ADAPTER_EVENT;
131 *event = BLUETOOTH_EVENT_SERVICE_SEARCHED;
132 ret_if(output == NULL);
133 *param_data = &g_array_index(output,
134 bluetooth_device_info_t, 0);
137 *event_type = BT_HID_EVENT;
138 *event = BLUETOOTH_HID_CONNECTED;
139 ret_if(output == NULL);
140 *param_data = &g_array_index(output,
141 bluetooth_device_address_t, 0);
143 case BT_HID_DISCONNECT:
144 *event_type = BT_HID_EVENT;
145 *event = BLUETOOTH_HID_DISCONNECTED;
146 ret_if(output == NULL);
147 *param_data = &g_array_index(output,
148 bluetooth_device_address_t, 0);
150 case BT_AUDIO_CONNECT:
152 *event_type = BT_HEADSET_EVENT;
153 *event = BLUETOOTH_EVENT_AG_CONNECTED;
154 ret_if(output == NULL);
155 *param_data = &g_array_index(output, char, 0);
157 case BT_AUDIO_DISCONNECT:
158 case BT_AG_DISCONNECT:
159 *event_type = BT_HEADSET_EVENT;
160 *event = BLUETOOTH_EVENT_AG_DISCONNECTED;
161 ret_if(output == NULL);
162 *param_data = &g_array_index(output, char, 0);
165 *event_type = BT_HEADSET_EVENT;
166 *event = BLUETOOTH_EVENT_AV_CONNECTED;
167 ret_if(output == NULL);
168 *param_data = &g_array_index(output, char, 0);
170 case BT_AV_DISCONNECT:
171 *event_type = BT_HEADSET_EVENT;
172 *event = BLUETOOTH_EVENT_AV_DISCONNECTED;
173 ret_if(output == NULL);
174 *param_data = &g_array_index(output, char, 0);
176 case BT_NETWORK_CONNECT:
177 *event_type = BT_ADAPTER_EVENT;
178 *event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
179 ret_if(output == NULL);
180 *param_data = &g_array_index(output,
181 bluetooth_device_address_t, 0);
183 case BT_NETWORK_DISCONNECT:
184 *event_type = BT_ADAPTER_EVENT;
185 *event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
186 ret_if(output == NULL);
187 *param_data = &g_array_index(output,
188 bluetooth_device_address_t, 0);
190 case BT_RFCOMM_CLIENT_CONNECT:
191 *event_type = BT_RFCOMM_CLIENT_EVENT;
192 *event = BLUETOOTH_EVENT_RFCOMM_CONNECTED;
193 ret_if(output == NULL);
194 *param_data = &g_array_index(output,
195 bluetooth_rfcomm_connection_t, 0);
199 BT_ERR("Unknown function");
205 out param1: API result
206 out param2: return paramter
209 void __send_request_cb(DBusGProxy *proxy, GArray *out_param1,
210 GArray *out_param2, GError *error,
213 bluetooth_event_param_t bt_event;
214 bt_req_info_t *cb_data = userdata;
215 int result = BLUETOOTH_ERROR_NONE;
216 int event_type = BT_ADAPTER_EVENT;
219 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
222 /* dBUS gives error cause */
223 BT_ERR("D-Bus API failure: message[%s]", error->message);
225 result = BLUETOOTH_ERROR_TIMEOUT;
227 ret_if(cb_data == NULL);
229 __bt_get_event_info(cb_data->service_function, NULL,
230 &bt_event.event, &event_type,
231 &bt_event.param_data);
233 ret_if(out_param2 == NULL);
235 result = g_array_index(out_param2, int, 0);
237 ret_if(cb_data == NULL);
239 __bt_get_event_info(cb_data->service_function, out_param1,
240 &bt_event.event, &event_type,
241 &bt_event.param_data);
243 if (result == BLUETOOTH_ERROR_NONE) {
244 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
245 request_id = g_array_index(out_param1, int, 0);
246 _bt_add_push_request_id(request_id);
250 g_array_free(out_param1, FALSE);
253 g_array_free(out_param2, FALSE);
259 g_array_free(out_param1, FALSE);
262 g_array_free(out_param2, FALSE);
265 if (cb_data->cb == NULL)
268 /* Only if fail case, call the callback function*/
269 bt_event.result = result;
271 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
272 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
275 } else if (event_type == BT_HID_EVENT) {
276 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
277 (hid_event_param_t *)&bt_event,
279 } else if (event_type == BT_HEADSET_EVENT) {
280 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
281 (bt_audio_event_param_t *)&bt_event,
285 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
290 int _bt_send_request(int service_type, int service_function,
291 GArray *in_param1, GArray *in_param2,
292 GArray *in_param3, GArray *in_param4,
295 int result = BLUETOOTH_ERROR_NONE;
297 GError *error = NULL;
298 GArray *in_param5 = NULL;
299 GArray *out_param2 = NULL;
302 switch (service_type) {
303 case BT_BLUEZ_SERVICE:
304 case BT_OBEX_SERVICE:
305 proxy = __bt_get_service_proxy();
306 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
308 in_param5 = g_array_new(FALSE, FALSE, sizeof(gchar));
310 ret = org_projectx_bt_service_request(proxy,
311 service_type, service_function,
312 BT_SYNC_REQ, in_param1, in_param2,
313 in_param3, in_param4, in_param5,
314 out_param1, &out_param2, &error);
316 g_array_free(in_param5, TRUE);
319 BT_ERR("Unknown service type");
320 return BLUETOOTH_ERROR_INTERNAL;
324 result = g_array_index(out_param2, int, 0);
325 g_array_free(out_param2, TRUE);
327 result = BLUETOOTH_ERROR_INTERNAL;
331 /* dBUS-RPC is failed */
332 BT_ERR("dBUS-RPC is failed");
335 /* dBUS gives error cause */
336 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
337 error->code, error->message);
342 /* dBUS does not give error cause dBUS-RPC is failed */
343 BT_ERR("error returned was NULL");
349 BT_DBG("dBUS RPC is successfully done. type=%d, function=0x%x",
350 service_type, service_function);
355 int _bt_send_request_async(int service_type, int service_function,
356 GArray *in_param1, GArray *in_param2,
357 GArray *in_param3, GArray *in_param4,
358 void *callback, void *user_data)
360 GArray* in_param5 = NULL;
361 bt_req_info_t *cb_data;
363 DBusGProxyCall *proxy_call;
365 cb_data = g_new0(bt_req_info_t, 1);
367 cb_data->service_function = service_function;
368 cb_data->cb = callback;
369 cb_data->user_data = user_data;
371 switch (service_type) {
372 case BT_BLUEZ_SERVICE:
373 case BT_OBEX_SERVICE:
374 proxy = __bt_get_service_proxy();
375 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
377 dbus_g_proxy_set_default_timeout(proxy, BT_DBUS_TIMEOUT_MAX);
379 in_param5 = g_array_new(FALSE, FALSE, sizeof(gchar));
381 proxy_call = org_projectx_bt_service_request_async(proxy, service_type,
382 service_function, BT_ASYNC_REQ, in_param1, in_param2,
383 in_param3, in_param4, in_param5,
384 (org_projectx_bt_service_request_reply)__send_request_cb,
387 if (proxy_call == NULL) {
389 BT_ERR("dBUS-RPC is failed");
390 g_array_free(in_param5, TRUE);
392 return BLUETOOTH_ERROR_INTERNAL;
395 sending_requests = g_slist_append(sending_requests, cb_data);
397 g_array_free(in_param5, TRUE);
401 BT_DBG("dBUS RPC is successfully done. type=%d, function=0x%x",
402 service_type, service_function);
404 return BLUETOOTH_ERROR_NONE;