Merge branch 'master' into tizen_2.1
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-hid.c
1 /*
2  * bluetooth-frwk
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #include <syspopup_caller.h>
26 #include "bluetooth-api.h"
27 #include "bt-service-common.h"
28 #include "bt-service-hid.h"
29 #include "bt-service-event.h"
30 #include "bt-service-util.h"
31
32 static void __bt_hid_connect_cb(DBusGProxy *proxy, DBusGProxyCall *call,
33                                     gpointer user_data)
34 {
35         GError *g_error = NULL;
36         GArray *out_param1 = NULL;
37         GArray *out_param2 = NULL;
38         bluetooth_device_address_t device_addr = { {0} };
39         int result = BLUETOOTH_ERROR_NONE;
40         bt_function_data_t *func_data;
41         request_info_t *req_info;
42
43         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
44
45         g_object_unref(proxy);
46
47         func_data = user_data;
48
49         if (func_data == NULL) {
50                 /* Send reply */
51                 BT_ERR("func_data == NULL");
52                 goto done;
53         }
54
55         req_info = _bt_get_request_info(func_data->req_id);
56         if (req_info == NULL) {
57                 BT_ERR("req_info == NULL");
58                 goto done;
59         }
60
61         if (g_error != NULL) {
62                 BT_ERR("Hidh Connect Dbus Call Error: %s\n", g_error->message);
63                 result = BLUETOOTH_ERROR_INTERNAL;
64                 goto dbus_return;
65         }
66
67 dbus_return:
68         if (req_info->context == NULL)
69                 goto done;
70
71         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
72         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
73
74         _bt_convert_addr_string_to_type(device_addr.addr,
75                                         func_data->address);
76
77         g_array_append_vals(out_param1, &device_addr,
78                                 sizeof(bluetooth_device_address_t));
79         g_array_append_vals(out_param2, &result, sizeof(int));
80
81         dbus_g_method_return(req_info->context, out_param1, out_param2);
82
83         g_array_free(out_param1, TRUE);
84         g_array_free(out_param2, TRUE);
85
86         _bt_delete_request_list(req_info->req_id);
87 done:
88         if (g_error)
89                 g_error_free(g_error);
90
91         if (func_data) {
92                 g_free(func_data->address);
93                 g_free(func_data);
94         }
95 }
96
97 static void __bt_hid_disconnect_cb(DBusGProxy *proxy, DBusGProxyCall *call,
98                                     gpointer user_data)
99 {
100         GError *g_error = NULL;
101         GArray *out_param1 = NULL;
102         GArray *out_param2 = NULL;
103         bluetooth_device_address_t device_addr = { {0} };
104         int result = BLUETOOTH_ERROR_NONE;
105         bt_function_data_t *func_data;
106         request_info_t *req_info;
107
108         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
109
110         g_object_unref(proxy);
111
112         func_data = user_data;
113
114         if (func_data == NULL) {
115                 /* Send reply */
116                 BT_ERR("func_data == NULL");
117                 goto done;
118         }
119
120         req_info = _bt_get_request_info(func_data->req_id);
121         if (req_info == NULL) {
122                 BT_ERR("req_info == NULL");
123                 goto done;
124         }
125
126         if (g_error != NULL) {
127                 BT_ERR("Hidh Connect Dbus Call Error: %s\n", g_error->message);
128                 result = BLUETOOTH_ERROR_INTERNAL;
129                 goto dbus_return;
130         }
131
132 dbus_return:
133         if (req_info->context == NULL)
134                 goto done;
135
136         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
137         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
138
139         _bt_convert_addr_string_to_type(device_addr.addr,
140                                         func_data->address);
141
142         g_array_append_vals(out_param1, &device_addr,
143                                 sizeof(bluetooth_device_address_t));
144         g_array_append_vals(out_param2, &result, sizeof(int));
145
146         dbus_g_method_return(req_info->context, out_param1, out_param2);
147
148         g_array_free(out_param1, TRUE);
149         g_array_free(out_param2, TRUE);
150
151         _bt_delete_request_list(req_info->req_id);
152 done:
153         if (g_error)
154                 g_error_free(g_error);
155
156         if (func_data) {
157                 g_free(func_data->address);
158                 g_free(func_data);
159         }
160 }
161
162
163 /**********************************************************************
164 *                               HID APIs                              *
165 ***********************************************************************/
166
167 int _bt_hid_connect(int request_id,
168                 bluetooth_device_address_t *device_address)
169 {
170         gchar *device_path = NULL;
171         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
172         bt_function_data_t *func_data;
173         DBusGProxy *adapter_proxy;
174         DBusGProxy *hid_proxy;
175         DBusGConnection *conn;
176
177         BT_CHECK_PARAMETER(device_address, return);
178
179         adapter_proxy = _bt_get_adapter_proxy();
180         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
181
182         conn = _bt_get_system_gconn();
183         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
184
185         _bt_convert_addr_type_to_string(address, device_address->addr);
186
187         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
188                           G_TYPE_STRING, address, G_TYPE_INVALID,
189                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
190
191         if (device_path == NULL) {
192                 BT_ERR("No paired device");
193                 return BLUETOOTH_ERROR_NOT_PAIRED;
194         }
195
196         hid_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
197                                       device_path, BT_INPUT_INTERFACE);
198         g_free(device_path);
199         retv_if(hid_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
200         func_data = g_malloc0(sizeof(bt_function_data_t));
201
202         func_data->address = g_strdup(address);
203         func_data->req_id = request_id;
204
205         if (!dbus_g_proxy_begin_call(hid_proxy, "Connect",
206                         (DBusGProxyCallNotify)__bt_hid_connect_cb,
207                         func_data, NULL, G_TYPE_INVALID)) {
208                 BT_ERR("Hidh connect Dbus Call Error");
209                 g_object_unref(hid_proxy);
210                 return BLUETOOTH_ERROR_INTERNAL;
211         }
212
213         return BLUETOOTH_ERROR_NONE;
214 }
215
216 int _bt_hid_disconnect(int request_id,
217                 bluetooth_device_address_t *device_address)
218 {
219         gchar *device_path = NULL;
220         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
221         bt_function_data_t *func_data;
222         DBusGProxy *adapter_proxy;
223         DBusGProxy *hid_proxy;
224         DBusGConnection *conn;
225
226         BT_CHECK_PARAMETER(device_address, return);
227
228         adapter_proxy = _bt_get_adapter_proxy();
229         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
230
231         conn = _bt_get_system_gconn();
232         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
233
234         _bt_convert_addr_type_to_string(address, device_address->addr);
235
236         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
237                           G_TYPE_STRING, address, G_TYPE_INVALID,
238                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
239
240         if (device_path == NULL) {
241                 BT_ERR("No paired device");
242                 return BLUETOOTH_ERROR_NOT_PAIRED;
243         }
244
245         hid_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
246                                       device_path, BT_INPUT_INTERFACE);
247         g_free(device_path);
248         retv_if(hid_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
249         func_data = g_malloc0(sizeof(bt_function_data_t));
250
251         func_data->address = g_strdup(address);
252         func_data->req_id = request_id;
253
254         if (!dbus_g_proxy_begin_call(hid_proxy, "Disconnect",
255                         (DBusGProxyCallNotify)__bt_hid_disconnect_cb,
256                         func_data, NULL, G_TYPE_INVALID)) {
257                 BT_ERR("Hidh disconnect Dbus Call Error");
258                 g_object_unref(hid_proxy);
259                 return BLUETOOTH_ERROR_INTERNAL;
260         }
261
262         return BLUETOOTH_ERROR_NONE;
263 }