Merge branch 'master' into tizen_2.1
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-network.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-network.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-util.h"
31
32 static void __bt_network_connect_cb(DBusGProxy *proxy, DBusGProxyCall *call,
33                                     gpointer user_data)
34 {
35         GError *g_error = NULL;
36         char *device = NULL;
37         GArray *out_param1 = NULL;
38         GArray *out_param2 = NULL;
39         bluetooth_device_address_t device_addr = { {0} };
40         int result = BLUETOOTH_ERROR_NONE;
41         bt_function_data_t *func_data;
42         request_info_t *req_info;
43
44         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_STRING, &device, G_TYPE_INVALID);
45
46         g_object_unref(proxy);
47
48         func_data = user_data;
49
50         if (func_data == NULL) {
51                 /* Send reply */
52                 BT_ERR("func_data == NULL");
53                 goto done;
54         }
55
56         req_info = _bt_get_request_info(func_data->req_id);
57         if (req_info == NULL) {
58                 BT_ERR("req_info == NULL");
59                 goto done;
60         }
61
62         if (g_error != NULL) {
63                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
64                 result = BLUETOOTH_ERROR_INTERNAL;
65                 goto dbus_return;
66         }
67
68 dbus_return:
69         if (req_info->context == NULL)
70                 goto done;
71
72         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
73         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
74
75         _bt_convert_addr_string_to_type(device_addr.addr,
76                                         func_data->address);
77
78         g_array_append_vals(out_param1, &device_addr,
79                                 sizeof(bluetooth_device_address_t));
80         g_array_append_vals(out_param2, &result, sizeof(int));
81
82         dbus_g_method_return(req_info->context, out_param1, out_param2);
83
84         g_array_free(out_param1, TRUE);
85         g_array_free(out_param2, TRUE);
86
87         _bt_delete_request_list(req_info->req_id);
88 done:
89         if (g_error)
90                 g_error_free(g_error);
91
92         if (func_data) {
93                 g_free(func_data->address);
94                 g_free(func_data);
95         }
96 }
97
98 static void __bt_network_disconnect_cb(DBusGProxy *proxy, DBusGProxyCall *call,
99                                     gpointer user_data)
100 {
101         GError *g_error = NULL;
102         GArray *out_param1 = NULL;
103         GArray *out_param2 = NULL;
104         bluetooth_device_address_t device_addr = { {0} };
105         int result = BLUETOOTH_ERROR_NONE;
106         bt_function_data_t *func_data;
107         request_info_t *req_info;
108
109         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
110
111         g_object_unref(proxy);
112
113         func_data = user_data;
114
115         if (func_data == NULL) {
116                 /* Send reply */
117                 BT_ERR("func_data == NULL");
118                 goto done;
119         }
120
121         req_info = _bt_get_request_info(func_data->req_id);
122         if (req_info == NULL) {
123                 BT_ERR("req_info == NULL");
124                 goto done;
125         }
126
127         if (g_error != NULL) {
128                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
129                 result = BLUETOOTH_ERROR_INTERNAL;
130                 goto dbus_return;
131         }
132
133 dbus_return:
134         if (req_info->context == NULL)
135                 goto done;
136
137         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
138         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
139
140         _bt_convert_addr_string_to_type(device_addr.addr,
141                                         func_data->address);
142
143         g_array_append_vals(out_param1, &device_addr,
144                                 sizeof(bluetooth_device_address_t));
145         g_array_append_vals(out_param2, &result, sizeof(int));
146
147         dbus_g_method_return(req_info->context, out_param1, out_param2);
148
149         g_array_free(out_param1, TRUE);
150         g_array_free(out_param2, TRUE);
151
152         _bt_delete_request_list(req_info->req_id);
153 done:
154         if (g_error)
155                 g_error_free(g_error);
156
157         if (func_data) {
158                 g_free(func_data->address);
159                 g_free(func_data);
160         }
161 }
162
163 int _bt_network_activate(void)
164 {
165         int ret = BLUETOOTH_ERROR_NONE;
166         char *adapter_path;
167         GError *err = NULL;
168         DBusGConnection *conn;
169         DBusGProxy *server_proxy;
170
171         conn = _bt_get_system_gconn();
172         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
173
174         adapter_path = _bt_get_adapter_path();
175         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
176
177         server_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
178                              adapter_path, BT_NETWORK_SERVER_INTERFACE);
179
180         g_free(adapter_path);
181
182         if (server_proxy == NULL) {
183                 BT_ERR("Failed to get the network server proxy\n");
184                 return BLUETOOTH_ERROR_INTERNAL;
185         }
186
187         if (!dbus_g_proxy_call(server_proxy, "Register", &err,
188                         G_TYPE_STRING, NAP_UUID_NAME,
189                         G_TYPE_STRING, NET_BRIDGE_INTERFACE,
190                         G_TYPE_INVALID, G_TYPE_INVALID)) {
191                 if (err != NULL) {
192                         BT_ERR("Network server register Error: %s\n", err->message);
193                         if (g_strcmp0(err->message, "Already Exists") == 0) {
194                                 ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
195                         } else {
196                                 ret = BLUETOOTH_ERROR_INTERNAL;
197                         }
198                         g_error_free(err);
199                 }
200         }
201
202         g_object_unref(server_proxy);
203
204         return ret;
205 }
206
207 int _bt_network_deactivate(void)
208 {
209         char *adapter_path;
210         GError *err = NULL;
211         DBusGConnection *conn;
212         DBusGProxy *server_proxy;
213
214         conn = _bt_get_system_gconn();
215         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
216
217         adapter_path = _bt_get_adapter_path();
218         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
219
220         server_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
221                              adapter_path, BT_NETWORK_SERVER_INTERFACE);
222
223         g_free(adapter_path);
224
225         if (server_proxy == NULL) {
226                 BT_ERR("Failed to get the network server proxy\n");
227                 return BLUETOOTH_ERROR_INTERNAL;
228         }
229
230         if (!dbus_g_proxy_call(server_proxy, "Unregister", &err,
231                         G_TYPE_STRING, NAP_UUID_NAME,
232                         G_TYPE_INVALID, G_TYPE_INVALID)) {
233                 if (err != NULL) {
234                         BT_ERR("Network server unregister Error: %s\n", err->message);
235                         g_error_free(err);
236                 }
237                 g_object_unref(server_proxy);
238                 return BLUETOOTH_ERROR_INTERNAL;
239         }
240
241         g_object_unref(server_proxy);
242
243         return BLUETOOTH_ERROR_NONE;
244 }
245
246 int _bt_network_connect(int request_id, int role,
247                 bluetooth_device_address_t *device_address)
248 {
249         gchar *device_path = NULL;
250         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
251         char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
252         bt_function_data_t *func_data;
253         DBusGProxy *adapter_proxy;
254         DBusGProxy *profile_proxy;
255         DBusGConnection *conn;
256
257         BT_CHECK_PARAMETER(device_address, return);
258
259         switch (role) {
260         case BLUETOOTH_NETWORK_PANU_ROLE:
261                 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
262                 break;
263
264         case BLUETOOTH_NETWORK_NAP_ROLE:
265                 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
266                 break;
267
268         case BLUETOOTH_NETWORK_GN_ROLE:
269                 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
270                 break;
271         default:
272                 BT_ERR("Unknown role");
273                 return BLUETOOTH_ERROR_INTERNAL;
274         }
275
276         adapter_proxy = _bt_get_adapter_proxy();
277         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
278
279         conn = _bt_get_system_gconn();
280         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
281
282         _bt_convert_addr_type_to_string(address, device_address->addr);
283
284         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
285                           G_TYPE_STRING, address, G_TYPE_INVALID,
286                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
287
288         if (device_path == NULL) {
289                 BT_ERR("No paired device");
290                 return BLUETOOTH_ERROR_NOT_PAIRED;
291         }
292
293         profile_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
294                                       device_path, BT_NETWORK_CLIENT_INTERFACE);
295         g_free(device_path);
296         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
297         func_data = g_malloc0(sizeof(bt_function_data_t));
298
299         func_data->address = g_strdup(address);
300         func_data->req_id = request_id;
301
302         if (!dbus_g_proxy_begin_call(profile_proxy, "Connect",
303                         (DBusGProxyCallNotify)__bt_network_connect_cb,
304                         func_data, NULL,
305                         G_TYPE_STRING, remote_role,
306                         G_TYPE_INVALID)) {
307                 BT_ERR("network connect Dbus Call Error");
308                 g_object_unref(profile_proxy);
309                 return BLUETOOTH_ERROR_INTERNAL;
310         }
311
312         return BLUETOOTH_ERROR_NONE;
313 }
314
315 int _bt_network_disconnect(int request_id,
316                 bluetooth_device_address_t *device_address)
317 {
318         gchar *device_path = NULL;
319         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
320         bt_function_data_t *func_data;
321         DBusGProxy *adapter_proxy;
322         DBusGProxy *profile_proxy;
323         DBusGConnection *conn;
324
325         BT_CHECK_PARAMETER(device_address, return);
326
327         adapter_proxy = _bt_get_adapter_proxy();
328         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
329
330         conn = _bt_get_system_gconn();
331         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
332
333         _bt_convert_addr_type_to_string(address, device_address->addr);
334
335         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
336                           G_TYPE_STRING, address, G_TYPE_INVALID,
337                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
338
339         if (device_path == NULL) {
340                 BT_ERR("No paired device");
341                 return BLUETOOTH_ERROR_NOT_PAIRED;
342         }
343
344         profile_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
345                                       device_path, BT_NETWORK_CLIENT_INTERFACE);
346         g_free(device_path);
347         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
348         func_data = g_malloc0(sizeof(bt_function_data_t));
349
350         func_data->address = g_strdup(address);
351         func_data->req_id = request_id;
352
353         if (!dbus_g_proxy_begin_call(profile_proxy, "Disconnect",
354                         (DBusGProxyCallNotify)__bt_network_disconnect_cb,
355                         func_data, NULL, G_TYPE_INVALID)) {
356                 BT_ERR("network disconnect Dbus Call Error");
357                 g_object_unref(profile_proxy);
358                 return BLUETOOTH_ERROR_INTERNAL;
359         }
360
361         return BLUETOOTH_ERROR_NONE;
362 }