Added NULL pointer guard check before g_ascii_strcasecmp.
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-network.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <glib.h>
19 #include <gio/gio.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <syspopup_caller.h>
24 #include <net_connection.h>
25
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 #include "bt-internal-types.h"
32
33 void _bt_util_addr_type_to_addr_net_string(char *address,
34                                         unsigned char *addr)
35 {
36         ret_if(address == NULL);
37         ret_if(addr == NULL);
38
39         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
40                         addr[1], addr[2], addr[3], addr[4], addr[5]);
41 }
42
43 static connection_profile_h __bt_get_net_profile(void *connection,
44                                                 connection_iterator_type_e type,
45                                                 unsigned char *address)
46 {
47         int result;
48         gchar **split_string;
49         char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
50         char *profile_name = NULL;
51         connection_profile_iterator_h profile_iter;
52         connection_profile_h profile_h;
53         connection_profile_type_e profile_type;
54
55         retv_if(connection == NULL, NULL);
56         retv_if(address == NULL, NULL);
57
58         BT_DBG("net_conn: %x", connection);
59
60         _bt_util_addr_type_to_addr_net_string(net_address, address);
61
62         result = connection_get_profile_iterator(connection,
63                                                         type,
64                                                         &profile_iter);
65         if (result != CONNECTION_ERROR_NONE) {
66                 BT_ERR("Fail to get profile iterator [%d]", result);
67                 return NULL;
68         }
69
70         while (connection_profile_iterator_has_next(profile_iter)) {
71                         profile_name = NULL;
72                         profile_h = NULL;
73                         split_string = NULL;
74
75                         if (connection_profile_iterator_next(profile_iter,
76                                                 &profile_h) != CONNECTION_ERROR_NONE) {
77                                 BT_ERR("Fail to get profile handle");
78                                 return NULL;
79                         }
80
81                         if (connection_profile_get_type(profile_h,
82                                                 &profile_type) != CONNECTION_ERROR_NONE) {
83                                 BT_ERR("Fail to get profile type");
84                                 continue;
85                         }
86
87                         if (profile_type != CONNECTION_PROFILE_TYPE_BT)
88                                 continue;
89
90                         if (connection_profile_get_name(profile_h,
91                                                 &profile_name) != CONNECTION_ERROR_NONE) {
92                                 BT_ERR("Fail to get profile name");
93                                 return NULL;
94                         }
95
96                         split_string = g_strsplit(profile_name, "_", 3);
97
98                         g_free(profile_name);
99
100                         if (g_strv_length(split_string) < 3)
101                                 continue;
102
103                         if (split_string[2] == NULL) {
104                                 BT_ERR("__bt_get_net_profile Error Parameter are NULL..\n");
105                                 continue;
106                         } else if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
107                                 BT_DBG("matched profile");
108                                 g_strfreev(split_string);
109                                 return profile_h;
110                         }
111
112                         g_strfreev(split_string);
113         }
114
115         return NULL;
116 }
117
118 int _bt_is_network_connected(void *connection, unsigned char *address,
119                                         gboolean *is_connected)
120 {
121         void *handle = NULL;
122         handle = __bt_get_net_profile(connection,
123                                 CONNECTION_ITERATOR_TYPE_CONNECTED,
124                                 address);
125         if (handle)
126                 *is_connected = TRUE;
127         else
128                 *is_connected = FALSE;
129
130         return BLUETOOTH_ERROR_NONE;
131 }
132
133 static void __bt_network_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
134                                         gpointer user_data)
135 {
136         GError *g_error = NULL;
137         GVariant *out_param1 = NULL;
138         GVariant *reply = NULL;
139         bluetooth_device_address_t device_addr = { {0} };
140         int result = BLUETOOTH_ERROR_NONE;
141         bt_function_data_t *func_data;
142         request_info_t *req_info;
143
144         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
145         g_object_unref(proxy);
146
147         if (reply == NULL) {
148                 BT_ERR("Network Connect Dbus Call Error");
149                 if (g_error) {
150                         BT_ERR("Error: %s\n", g_error->message);
151                         g_clear_error(&g_error);
152                 }
153                 result = BLUETOOTH_ERROR_INTERNAL;
154         } else {
155                 g_variant_unref(reply);
156         }
157
158         func_data = user_data;
159         if (func_data == NULL) {
160                 /* Send reply */
161                 BT_ERR("func_data == NULL");
162                 goto done;
163         }
164
165         BT_ERR("func_data->req_id: %d", func_data->req_id);
166         req_info = _bt_get_request_info(func_data->req_id);
167         if (req_info == NULL) {
168                 BT_ERR("req_info == NULL");
169                 goto done;
170         }
171
172         if (req_info->context == NULL)
173                 goto done;
174
175         _bt_convert_addr_string_to_type(device_addr.addr,
176                                         func_data->address);
177
178         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
179                                                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
180
181         g_dbus_method_invocation_return_value(req_info->context,
182                         g_variant_new("iv", result, out_param1));
183
184         _bt_delete_request_list(req_info->req_id);
185
186 done:
187         if (func_data) {
188                 g_free(func_data->address);
189                 g_free(func_data);
190         }
191 }
192
193 static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
194                                         gpointer user_data)
195 {
196         GError *g_error = NULL;
197         GVariant *out_param1 = NULL;
198         GVariant *reply = NULL;
199         bluetooth_device_address_t device_addr = { {0} };
200         int result = BLUETOOTH_ERROR_NONE;
201         bt_function_data_t *func_data;
202         request_info_t *req_info;
203
204         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
205         g_object_unref(proxy);
206
207         if (reply == NULL) {
208                 BT_ERR("Network Disconnect Dbus Call Error");
209                 if (g_error) {
210                         BT_ERR("Error: %s\n", g_error->message);
211                         g_clear_error(&g_error);
212                 }
213                 result = BLUETOOTH_ERROR_INTERNAL;
214         } else {
215                 g_variant_unref(reply);
216         }
217
218         func_data = user_data;
219         if (func_data == NULL) {
220                 /* Send reply */
221                 BT_ERR("func_data == NULL");
222                 goto done;
223         }
224         BT_ERR("func_data->req_id: %d", func_data->req_id);
225         req_info = _bt_get_request_info(func_data->req_id);
226         if (req_info == NULL) {
227                 BT_ERR("req_info == NULL");
228                 goto done;
229         }
230
231         if (g_error != NULL) {
232                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
233                 result = BLUETOOTH_ERROR_INTERNAL;
234         }
235
236         if (req_info->context == NULL)
237                 goto done;
238
239         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
240                                                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
241
242         g_dbus_method_invocation_return_value(req_info->context,
243                         g_variant_new("iv", result, out_param1));
244
245         _bt_delete_request_list(req_info->req_id);
246
247 done:
248         if (func_data) {
249                 g_free(func_data->address);
250                 g_free(func_data);
251         }
252 }
253
254 int _bt_network_activate(void)
255 {
256         int ret = BLUETOOTH_ERROR_NONE;
257         char *adapter_path;
258         GVariant *result = NULL;
259         GError *err = NULL;
260         GDBusConnection *conn;
261         GDBusProxy *server_proxy;
262
263         conn = _bt_gdbus_get_system_gconn();
264         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
265
266         adapter_path = _bt_get_adapter_path();
267         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
268
269         server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
270                         NULL, BT_BLUEZ_NAME,
271                         adapter_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
272         g_free(adapter_path);
273
274         if (server_proxy == NULL) {
275                 BT_ERR("Failed to get the network server proxy\n");
276                 return BLUETOOTH_ERROR_INTERNAL;
277         }
278
279         result = g_dbus_proxy_call_sync(server_proxy, "Register",
280                                  g_variant_new("(ss)", NAP_UUID_NAME, NET_BRIDGE_INTERFACE),
281                                  G_DBUS_CALL_FLAGS_NONE,
282                                  -1,
283                                  NULL,
284                                  &err);
285         if (result == NULL) {
286                 if (err != NULL) {
287                         g_dbus_error_strip_remote_error(err);
288                         BT_ERR("Network server register Error: %s\n", err->message);
289                         if (g_strcmp0(err->message, "Already Exists") == 0)
290                                 ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
291                         else
292                                 ret = BLUETOOTH_ERROR_INTERNAL;
293
294                         g_error_free(err);
295                 }
296         } else {
297                 g_variant_unref(result);
298         }
299
300         g_object_unref(server_proxy);
301
302         return ret;
303 }
304
305 int _bt_network_deactivate(void)
306 {
307         char *adapter_path;
308         GVariant *result = NULL;
309         GError *err = NULL;
310         GDBusConnection *conn;
311         GDBusProxy *server_proxy;
312         int ret = BLUETOOTH_ERROR_NONE;
313
314         conn = _bt_gdbus_get_system_gconn();
315         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
316
317         adapter_path = _bt_get_adapter_path();
318         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
319
320         server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
321                                                                 NULL, BT_BLUEZ_NAME,
322                                                                 adapter_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
323         g_free(adapter_path);
324
325         if (server_proxy == NULL) {
326                 BT_ERR("Failed to get the network server proxy\n");
327                 return BLUETOOTH_ERROR_INTERNAL;
328         }
329
330         result = g_dbus_proxy_call_sync(server_proxy, "Unregister",
331                                  g_variant_new("(s)", NAP_UUID_NAME),
332                                  G_DBUS_CALL_FLAGS_NONE,
333                                  -1,
334                                  NULL,
335                                  &err);
336         if (result == NULL) {
337                 if (err != NULL) {
338                         g_dbus_error_strip_remote_error(err);
339                         BT_ERR("Network server unregister Error: %s\n", err->message);
340                         if (g_strcmp0(err->message,
341                                         "Operation currently not available") == 0) {
342                                 ret = BLUETOOTH_ERROR_ALREADY_DEACTIVATED;
343                         } else {
344                                 ret = BLUETOOTH_ERROR_INTERNAL;
345                         }
346                         g_error_free(err);
347                 }
348         } else {
349                 g_variant_unref(result);
350         }
351
352         g_object_unref(server_proxy);
353
354         return ret;
355 }
356
357 int _bt_network_connect(int request_id, int role,
358                 bluetooth_device_address_t *device_address)
359 {
360         gchar *device_path = NULL;
361         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
362         char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
363         bt_function_data_t *func_data;
364         GDBusProxy *adapter_proxy;
365         GDBusProxy *profile_proxy;
366         GDBusConnection *conn;
367
368         BT_CHECK_PARAMETER(device_address, return);
369
370         switch (role) {
371         case BLUETOOTH_NETWORK_PANU_ROLE:
372                 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
373                 break;
374
375         case BLUETOOTH_NETWORK_NAP_ROLE:
376                 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
377                 break;
378
379         case BLUETOOTH_NETWORK_GN_ROLE:
380                 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
381                 break;
382         default:
383                 BT_ERR("Unknown role");
384                 return BLUETOOTH_ERROR_INTERNAL;
385         }
386
387         adapter_proxy = _bt_get_adapter_proxy();
388         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
389
390         conn = _bt_gdbus_get_system_gconn();
391         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
392
393         _bt_convert_addr_type_to_string(address, device_address->addr);
394
395         device_path = _bt_get_device_object_path(address);
396         if (device_path == NULL) {
397                 BT_ERR("No paired device");
398                 return BLUETOOTH_ERROR_NOT_PAIRED;
399         }
400
401         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
402                         NULL, BT_BLUEZ_NAME,
403                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
404
405         g_free(device_path);
406         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
407         func_data = g_malloc0(sizeof(bt_function_data_t));
408         func_data->address = g_strdup(address);
409         func_data->req_id = request_id;
410
411         g_dbus_proxy_call(profile_proxy, "Connect",
412                                 g_variant_new("(s)", remote_role),
413                                 G_DBUS_CALL_FLAGS_NONE,
414                                 BT_MAX_DBUS_TIMEOUT,
415                                 NULL,
416                                 (GAsyncReadyCallback)__bt_network_connect_cb,
417                                 func_data);
418
419         return BLUETOOTH_ERROR_NONE;
420 }
421
422 int _bt_network_disconnect(int request_id,
423                 bluetooth_device_address_t *device_address)
424 {
425         gchar *device_path = NULL;
426         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
427         bt_function_data_t *func_data;
428         GDBusProxy *adapter_proxy;
429         GDBusProxy *profile_proxy;
430         GDBusConnection *conn;
431
432         BT_CHECK_PARAMETER(device_address, return);
433
434         adapter_proxy = _bt_get_adapter_proxy();
435         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
436
437         conn = _bt_gdbus_get_system_gconn();
438         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
439
440         _bt_convert_addr_type_to_string(address, device_address->addr);
441
442         device_path = _bt_get_device_object_path(address);
443         if (device_path == NULL) {
444                 BT_ERR("No paired device");
445                 return BLUETOOTH_ERROR_NOT_PAIRED;
446         }
447
448         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
449                         NULL, BT_BLUEZ_NAME,
450                         device_path, BT_NETWORK_CLIENT_INTERFACE,  NULL, NULL);
451
452         g_free(device_path);
453         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
454         func_data = g_malloc0(sizeof(bt_function_data_t));
455         func_data->address = g_strdup(address);
456         func_data->req_id = request_id;
457
458         g_dbus_proxy_call(profile_proxy, "Disconnect",
459                         NULL,
460                         G_DBUS_CALL_FLAGS_NONE,
461                         BT_MAX_DBUS_TIMEOUT,
462                         NULL,
463                         (GAsyncReadyCallback)__bt_network_disconnect_cb,
464                         func_data);
465
466         return BLUETOOTH_ERROR_NONE;
467 }
468
469 int _bt_network_server_disconnect(int request_id,
470                 bluetooth_device_address_t *device_address)
471 {
472         gchar *adapter_path = NULL;
473         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
474         bt_function_data_t *func_data;
475         GDBusProxy *profile_proxy;
476         GDBusConnection *conn;
477
478         BT_CHECK_PARAMETER(device_address, return);
479
480         conn = _bt_gdbus_get_system_gconn();
481         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
482
483         adapter_path = _bt_get_adapter_path();
484         if (adapter_path == NULL) {
485                 BT_ERR("No adapter found");
486                 return BLUETOOTH_ERROR_INTERNAL;
487         }
488
489         _bt_convert_addr_type_to_string(address, device_address->addr);
490
491         profile_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
492                         NULL, BT_BLUEZ_NAME,
493                         adapter_path, BT_NETWORK_SERVER_INTERFACE, NULL, NULL);
494         g_free(adapter_path);
495         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
496         func_data = g_malloc0(sizeof(bt_function_data_t));
497
498         func_data->address = g_strdup(address);
499         func_data->req_id = request_id;
500
501         g_dbus_proxy_call(profile_proxy, "Disconnect",
502                                  g_variant_new("(s)", address),
503                                 G_DBUS_CALL_FLAGS_NONE,
504                                 BT_MAX_DBUS_TIMEOUT,
505                                 NULL,
506                                 (GAsyncReadyCallback)__bt_network_disconnect_cb,
507                                 func_data);
508
509         return BLUETOOTH_ERROR_NONE;
510 }