Code Sync [Tizen3.0]: Merged the tizen_2.4 Spin code to tizen.org
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-rfcomm-server.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <dbus/dbus-glib.h>
25 #include <dbus/dbus.h>
26 #include <glib.h>
27 #include <dlog.h>
28 #include <string.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31
32 #include "bluetooth-api.h"
33 #include "bt-internal-types.h"
34
35 #include "bt-service-common.h"
36 #include "bt-service-event.h"
37 #include "bt-service-util.h"
38 #include "bt-service-rfcomm-client.h"
39 #include "bt-service-rfcomm-server.h"
40 #include "bt-service-agent.h"
41
42 /* Range of RFCOMM server ID : 0 ~ 244 */
43 #define BT_RFCOMM_SERVER_ID_MAX 245
44
45 #define BT_RFCOMM_PROXY_ADDRESS "x00/bluez/rfcomm"
46 #define BT_RFCOMM_SOCKET_ADDRESS "/bluez/rfcomm"
47
48 typedef struct {
49         int data_fd;
50         char *uuid;
51         char *remote_address;
52 } bt_rfcomm_event_info_t;
53
54 GSList *server_list;
55 static int latest_id = -1;
56 static gboolean server_id_used[BT_RFCOMM_SERVER_ID_MAX];
57
58 int __bt_rfcomm_assign_server_id(void)
59 {
60         int index;
61
62         BT_DBG("latest_id: %d", latest_id);
63
64         index = latest_id + 1;
65
66         if (index >= BT_RFCOMM_SERVER_ID_MAX)
67                 index = 0;
68
69         BT_DBG("index: %d", index);
70
71         while (server_id_used[index] == TRUE) {
72                 if (index == latest_id) {
73                         /* No available ID */
74                         BT_ERR("All request ID is used");
75                         return -1;
76                 }
77
78                 index++;
79
80                 if (index >= BT_RFCOMM_SERVER_ID_MAX)
81                         index = 0;
82         }
83
84         latest_id = index;
85         server_id_used[index] = TRUE;
86
87         BT_DBG("Assigned Id: %d", latest_id);
88
89         return latest_id;
90 }
91
92 void __bt_rfcomm_delete_server_id(int server_id)
93 {
94         ret_if(server_id >= BT_RFCOMM_SERVER_ID_MAX);
95         ret_if(server_id < 0);
96
97         server_id_used[server_id] = FALSE;
98
99         /* Next server will use this ID */
100         latest_id = server_id - 1;
101 }
102
103
104 static bt_rfcomm_server_info_t *__bt_rfcomm_get_server_info(int control_fd)
105 {
106         GSList *l;
107         bt_rfcomm_server_info_t *server_info;
108
109         retv_if(control_fd <= 0, NULL);
110
111         for (l = server_list; l != NULL; l = l->next) {
112                 server_info = l->data;
113
114                 if (server_info == NULL)
115                         continue;
116
117                 if (control_fd == server_info->control_fd)
118                         return server_info;
119         }
120
121         return NULL;
122 }
123
124 static bt_rfcomm_server_info_t *__bt_rfcomm_get_server_info_using_data_fd(int data_fd)
125 {
126         GSList *l;
127         bt_rfcomm_server_info_t *server_info;
128
129         retv_if(data_fd <= 0, NULL);
130
131         for (l = server_list; l != NULL; l = l->next) {
132                 server_info = l->data;
133
134                 if (server_info == NULL)
135                         continue;
136
137                 if (data_fd == server_info->data_fd)
138                         return server_info;
139         }
140
141         return NULL;
142 }
143
144 static DBusGProxy *__bt_rfcomm_get_serial_manager_proxy(void)
145 {
146         DBusGProxy *proxy;
147         DBusGConnection *g_conn;
148         char *adapter_path;
149
150         BT_DBG("+");
151
152         g_conn = _bt_get_system_gconn();
153         retv_if(g_conn == NULL, NULL);
154
155         adapter_path = _bt_get_adapter_path();
156         retv_if(adapter_path == NULL, NULL);
157
158         proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
159                         adapter_path, BT_SERIAL_MANAGER_INTERFACE);
160
161         g_free(adapter_path);
162
163         BT_DBG("-");
164
165         return proxy;
166 }
167
168 static DBusGProxy *__bt_get_serial_proxy(char *serial_path)
169 {
170         DBusGProxy *proxy;
171         DBusGConnection *g_conn;
172
173         g_conn = _bt_get_system_gconn();
174         retv_if(g_conn == NULL, NULL);
175
176         proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
177                         serial_path, BT_SERIAL_PROXY_INTERFACE);
178
179         return proxy;
180 }
181
182 static char *__bt_rfcomm_get_proxy_address(int server_id)
183 {
184         BT_DBG("+");
185
186         return g_strdup_printf("%s%d",
187                                 BT_RFCOMM_PROXY_ADDRESS,
188                                 server_id);
189 }
190
191 int __bt_rfcomm_get_socket(int server_id)
192 {
193         int result;
194         int socket_fd;
195         char *socket_address = NULL;
196         struct sockaddr_un server_addr;
197
198         retv_if(server_id < 0, -1);
199
200         socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
201         retv_if(socket_fd < 0, -1);
202
203         memset(&server_addr, 0, sizeof(server_addr));
204         server_addr.sun_family = PF_UNIX;
205
206         socket_address = g_strdup_printf("%s%d",
207                                 BT_RFCOMM_SOCKET_ADDRESS,
208                                 server_id);
209
210         BT_DBG("socket_address: %s", socket_address);
211
212         g_strlcpy(server_addr.sun_path + 1, socket_address,
213                                         sizeof(server_addr.sun_path));
214
215         if (bind(socket_fd, (struct sockaddr *)&server_addr,
216                                         sizeof(server_addr)) < 0) {
217                 BT_ERR("Can't Bind Sock");
218                 goto fail;
219         }
220
221         BT_DBG("socket_fd = %d", socket_fd);
222
223         result = _bt_set_socket_non_blocking(socket_fd);
224
225         if (result != BLUETOOTH_ERROR_NONE) {
226                 BT_ERR("Cannot set the tty");
227                 goto fail;
228         }
229
230         g_free(socket_address);
231         return socket_fd;
232 fail:
233         g_free(socket_address);
234         close(socket_fd);
235         return -1;
236 }
237
238 int _bt_rfcomm_create_socket(char *sender, char *uuid)
239 {
240         DBusGProxy *serial_manager = NULL;
241         DBusGProxy *serial_proxy = NULL;
242         GError *error = NULL;
243         char *proxy_address = NULL;
244         char *serial_path = NULL;
245         int server_id;
246         int socket_fd;
247         bt_rfcomm_server_info_t *server_info;
248
249         BT_CHECK_PARAMETER(uuid, return);
250
251         server_id = __bt_rfcomm_assign_server_id();
252         retv_if(server_id < 0, BLUETOOTH_ERROR_INTERNAL);
253
254         serial_manager = __bt_rfcomm_get_serial_manager_proxy();
255         if (serial_manager == NULL)
256                 goto fail;
257
258         proxy_address = __bt_rfcomm_get_proxy_address(server_id);
259         if (proxy_address == NULL)
260                 goto fail;
261
262         dbus_g_proxy_call(serial_manager, "CreateProxy", NULL,
263                         G_TYPE_STRING, uuid,
264                         G_TYPE_STRING, proxy_address,
265                         G_TYPE_INVALID,
266                         G_TYPE_STRING, &serial_path,
267                         G_TYPE_INVALID);
268
269         if (serial_path == NULL)
270                 goto fail;
271
272         BT_DBG("serial_path: %s", serial_path);
273
274         serial_proxy = __bt_get_serial_proxy(serial_path);
275         if (serial_proxy == NULL)
276                 goto fail;
277
278         if (!dbus_g_proxy_call(serial_proxy, "Enable", &error,
279                         G_TYPE_INVALID, G_TYPE_INVALID)) {
280                 if (error != NULL) {
281                         BT_ERR("Enable Error: %s\n", error->message);
282                         g_error_free(error);
283                 }
284                 goto fail;
285         }
286
287         socket_fd = __bt_rfcomm_get_socket(server_id);
288         if (socket_fd < 0) {
289                 BT_ERR("Can't get socket");
290                 goto fail;
291         }
292
293         server_info = g_malloc0(sizeof(bt_rfcomm_server_info_t));
294         server_info->server_id = server_id;
295         server_info->serial_proxy = serial_proxy;
296         server_info->manager_proxy = serial_manager;
297         server_info->serial_path = g_strdup(serial_path);
298         server_info->uuid = g_strdup(uuid);
299         server_info->sender = g_strdup(sender);
300         server_info->control_fd = socket_fd;
301
302         server_list = g_slist_append(server_list, server_info);
303
304         g_free(proxy_address);
305
306         return socket_fd;
307 fail:
308         __bt_rfcomm_delete_server_id(server_id);
309         g_free(proxy_address);
310
311         if (serial_manager) {
312                 if (serial_path) {
313                         dbus_g_proxy_call(serial_manager, "RemoveProxy", NULL,
314                                         G_TYPE_STRING, serial_path,
315                                         G_TYPE_INVALID,
316                                         G_TYPE_INVALID);
317                 }
318                 g_object_unref(serial_manager);
319         }
320
321         if (serial_proxy)
322                 g_object_unref(serial_proxy);
323
324         return BLUETOOTH_ERROR_INTERNAL;
325 }
326
327 static gboolean __bt_rfcomm_server_data_received_cb(GIOChannel *chan,
328                                                 GIOCondition cond,
329                                                 gpointer data)
330 {
331         char *buffer = NULL;
332         gsize len;
333         int result = BLUETOOTH_ERROR_NONE;
334         bt_rfcomm_server_info_t *server_info = data;
335
336         retv_if(server_info == NULL, FALSE);
337
338         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
339                 BT_ERR("Unix server  disconnected: %d", server_info->data_fd);
340                 _bt_rfcomm_server_disconnect(server_info->data_fd);
341                 return FALSE;
342         }
343
344         buffer = g_malloc0(BT_RFCOMM_BUFFER_MAX + 1);
345
346         if (g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_MAX, &len, NULL) ==
347                                                         G_IO_STATUS_ERROR) {
348                 BT_ERR("IO Channel read error server");
349                 g_free(buffer);
350                 _bt_rfcomm_server_disconnect(server_info->data_fd);
351                 return FALSE;
352         }
353
354         if (len == 0) {
355                 BT_ERR("Read failed len=%d, fd=%d\n",
356                                 len, server_info->data_fd);
357                 g_free(buffer);
358                 _bt_rfcomm_server_disconnect(server_info->data_fd);
359                 return FALSE;
360         }
361
362         _bt_send_event(BT_RFCOMM_SERVER_EVENT,
363                 BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED,
364                 DBUS_TYPE_INT32, &result,
365                 DBUS_TYPE_INT16, &server_info->data_fd,
366                 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
367                 &buffer, len,
368                 DBUS_TYPE_INVALID);
369
370         g_free(buffer);
371
372         return TRUE;
373 }
374
375 int __bt_rfcomm_server_get_address(bt_rfcomm_server_info_t *server_info)
376 {
377         DBusMessage *msg;
378         DBusMessage *reply;
379         DBusError error;
380         DBusMessageIter reply_iter;
381         DBusMessageIter reply_iter_entry;
382         DBusConnection *conn;
383         const char *property;
384
385         BT_CHECK_PARAMETER(server_info, return);
386
387         /* GetInfo Proxy Part */
388         msg = dbus_message_new_method_call(BT_BLUEZ_NAME,
389                                         server_info->serial_path,
390                                         BT_SERIAL_PROXY_INTERFACE,
391                                         "GetInfo");
392
393         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
394
395         dbus_error_init(&error);
396
397         conn = _bt_get_system_conn();
398
399         reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error);
400         dbus_message_unref(msg);
401
402         if (reply == NULL) {
403                 BT_ERR("Can't Call GetInfo Proxy");
404                 if (dbus_error_is_set(&error)) {
405                         BT_ERR("%s", error.message);
406                         dbus_error_free(&error);
407                 }
408                 return BLUETOOTH_ERROR_INTERNAL;
409         }
410
411         dbus_message_iter_init(reply, &reply_iter);
412
413         if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
414                 BT_ERR("Can't get reply arguments - DBUS_TYPE_ARRAY");
415                 goto fail;
416         }
417
418         dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
419
420         /*Parse the dict */
421         while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
422                                                 DBUS_TYPE_DICT_ENTRY) {
423                 DBusMessageIter dict_entry;
424                 DBusMessageIter dict_entry_val;
425
426                 dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
427
428                 dbus_message_iter_get_basic(&dict_entry, &property);
429
430                 if (g_strcmp0("connected", property) == 0) {
431                         dbus_bool_t value;
432
433                         dbus_message_iter_next(&dict_entry);
434                         dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
435                         dbus_message_iter_get_basic(&dict_entry_val, &value);
436
437                         if (value == FALSE)
438                                 goto fail;
439
440                         /*Parsing the address */
441                         dbus_message_iter_next(&reply_iter_entry);
442                         dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
443                         dbus_message_iter_get_basic(&dict_entry, &property);
444                         BT_DBG("String received...... = %s", property);
445
446                         if (g_strcmp0("address", property) == 0) {
447                                 if (!dbus_message_iter_next(&dict_entry)) {
448                                         BT_ERR("Failed getting next dict entry\n");
449                                         goto fail;
450                                 }
451
452                                 if (dbus_message_iter_get_arg_type(&dict_entry) !=
453                                                                 DBUS_TYPE_VARIANT) {
454                                         BT_ERR("Failed get arg type varient\n");
455                                         goto fail;
456                                 }
457
458                                 /*Getting the value of the varient*/
459                                 dbus_message_iter_recurse(&dict_entry,
460                                                           &dict_entry_val);
461
462                                 if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
463                                                                         DBUS_TYPE_STRING) {
464                                         BT_ERR("Failed get arg type string\n");
465                                         goto fail;
466                                 }
467
468                                 /*get  value string address*/
469                                 dbus_message_iter_get_basic(&dict_entry_val, &property);
470
471                                 BT_DBG("Address = %s\n", property);
472
473                                 g_free(server_info->remote_address);
474                                 server_info->remote_address = g_strdup(property);
475                         }
476
477                 }
478
479                 dbus_message_iter_next(&reply_iter_entry);
480         }
481
482         dbus_message_unref(reply);
483
484         return BLUETOOTH_ERROR_NONE;
485
486 fail:
487         dbus_message_unref(reply);
488         return BLUETOOTH_ERROR_INTERNAL;
489 }
490
491 static gboolean __bt_rfcomm_server_connected_cb(GIOChannel *chan,
492                                                         GIOCondition cond,
493                                                         gpointer data)
494 {
495         bt_rfcomm_server_info_t *server_info;
496         request_info_t *req_info;
497         int client_sock;
498         int addr_len;
499         struct sockaddr_un sock_addr;
500         int result = BLUETOOTH_ERROR_NONE;
501
502         BT_DBG("rfcomm_server.server_io_channel has %d", cond);
503
504         server_info = data;
505         retv_if(server_info == NULL, FALSE);
506
507         if (cond & G_IO_NVAL)
508                 return FALSE;
509
510         if (cond & (G_IO_HUP | G_IO_ERR)) {
511                 _bt_rfcomm_remove_socket(server_info->control_fd);
512                 return FALSE;
513         }
514
515         memset(&sock_addr, 0, sizeof(struct sockaddr_un));
516         addr_len = sizeof(struct sockaddr_un);
517
518         client_sock = accept(server_info->control_fd,
519                              (struct sockaddr *)&sock_addr,
520                              (socklen_t *)&addr_len);
521
522         if (client_sock < 0) {
523                 BT_ERR("Server Accept Error");
524                 return TRUE;
525
526         } else {
527                 BT_DBG("Accept Client Sock.(%d)\n", client_sock);
528
529         }
530
531         if (_bt_set_non_blocking_tty(client_sock) < 0) {
532                 /* Even if setting the tty fails we will continue */
533                 BT_ERR("Setting the tty properties failed(%d)\n", client_sock);
534         }
535
536         server_info->data_fd = client_sock;
537         server_info->data_io = g_io_channel_unix_new(client_sock);
538
539         g_io_channel_set_encoding(server_info->data_io, NULL, NULL);
540         g_io_channel_set_flags(server_info->data_io, G_IO_FLAG_NONBLOCK, NULL);
541         g_io_channel_set_close_on_unref(server_info->data_io, TRUE);
542
543         server_info->data_id =
544             g_io_add_watch(server_info->data_io,
545                            G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
546                            __bt_rfcomm_server_data_received_cb, server_info);
547
548         g_io_channel_unref(server_info->data_io);
549
550         __bt_rfcomm_server_get_address(server_info);
551
552         if (server_info->remote_address == NULL)
553                 server_info->remote_address = g_strdup("");
554
555         if (server_info->server_type == BT_CUSTOM_SERVER) {
556                 int result;
557                 GArray *out_param1;
558                 GArray *out_param2;
559
560                 req_info = _bt_get_request_info(server_info->accept_id);
561                 if (req_info == NULL || req_info->context == NULL) {
562                         BT_ERR("info is NULL");
563                         goto done;
564                 }
565
566                 server_info->accept_id = 0;
567                 result = BLUETOOTH_ERROR_NONE;
568
569                 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
570                 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
571
572                 g_array_append_vals(out_param1, &server_info->data_fd,
573                                         sizeof(int));
574                 g_array_append_vals(out_param2, &result, sizeof(int));
575
576                 dbus_g_method_return(req_info->context, out_param1, out_param2);
577
578                 g_array_free(out_param1, TRUE);
579                 g_array_free(out_param2, TRUE);
580
581                 _bt_delete_request_list(req_info->req_id);
582         }
583
584 done:
585         _bt_send_event(BT_RFCOMM_SERVER_EVENT,
586                 BLUETOOTH_EVENT_RFCOMM_CONNECTED,
587                 DBUS_TYPE_INT32, &result,
588                 DBUS_TYPE_STRING, &server_info->remote_address,
589                 DBUS_TYPE_STRING, &server_info->uuid,
590                 DBUS_TYPE_INT16, &server_info->data_fd,
591                 DBUS_TYPE_INVALID);
592
593         BT_DBG("-");
594         return TRUE;
595 }
596
597
598 int _bt_rfcomm_listen(int socket_fd, int max_pending, gboolean is_native)
599 {
600         int io_id;
601         bt_rfcomm_server_info_t *server_info;
602         GIOChannel *io_channel;
603
604         server_info = __bt_rfcomm_get_server_info(socket_fd);
605         retv_if(server_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
606         retv_if(server_info->control_io != NULL, BLUETOOTH_ERROR_DEVICE_BUSY);
607
608         if (listen(socket_fd, max_pending) != 0) {
609                 BT_ERR("Fail to listen");
610                 return BLUETOOTH_ERROR_INTERNAL;
611         }
612
613         io_channel = g_io_channel_unix_new(socket_fd);
614         server_info->control_io = io_channel;
615
616         g_io_channel_set_close_on_unref(io_channel, TRUE);
617         g_io_channel_set_encoding(io_channel, NULL, NULL);
618         g_io_channel_set_flags(io_channel, G_IO_FLAG_NONBLOCK, NULL);
619
620         io_id = g_io_add_watch(io_channel,
621                            G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
622                            __bt_rfcomm_server_connected_cb,
623                            server_info);
624
625         server_info->control_id = io_id;
626         g_io_channel_unref(io_channel);
627
628         /* BT_CUSTOM_SERVER / BT_NATIVE_SERVER*/
629         if (is_native) {
630                 server_info->server_type = BT_NATIVE_SERVER;
631         } else {
632                 server_info->server_type = BT_CUSTOM_SERVER;
633                 _bt_register_osp_server_in_agent(BT_RFCOMM_SERVER,
634                                                 server_info->uuid, NULL, -1);
635         }
636
637         return BLUETOOTH_ERROR_NONE;
638 }
639
640 int _bt_rfcomm_remove_socket(int socket_fd)
641 {
642         bt_rfcomm_server_info_t *server_info;
643         int result = BLUETOOTH_ERROR_NONE;
644
645         BT_DBG("+");
646
647         server_info = __bt_rfcomm_get_server_info(socket_fd);
648         retv_if(server_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
649
650         if (server_info->serial_proxy) {
651                 if (!dbus_g_proxy_call(server_info->serial_proxy, "Disable",
652                                         NULL,
653                                         G_TYPE_INVALID,
654                                         G_TYPE_INVALID)) {
655                         BT_ERR("Fail to disable");
656                 }
657         }
658
659         if (server_info->manager_proxy && server_info->serial_path) {
660                 if (!dbus_g_proxy_call(server_info->manager_proxy,
661                                 "RemoveProxy", NULL,
662                                 G_TYPE_STRING, server_info->serial_path,
663                                 G_TYPE_INVALID,
664                                 G_TYPE_INVALID)) {
665                         BT_ERR("Fail to remove proxy");
666                 }
667         }
668
669         if (server_info->server_type == BT_CUSTOM_SERVER) {
670                 _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER,
671                                                 server_info->uuid);
672         }
673
674         _bt_send_event(BT_RFCOMM_SERVER_EVENT,
675                 BLUETOOTH_EVENT_RFCOMM_SERVER_REMOVED,
676                 DBUS_TYPE_INT32, &result,
677                 DBUS_TYPE_INT16, &server_info->data_fd,
678                 DBUS_TYPE_INVALID);
679
680         _bt_rfcomm_server_disconnect(server_info->data_fd);
681
682         if (server_info->control_id > 0)
683                 g_source_remove(server_info->control_id);
684
685         if (server_info->control_fd > 0)
686                 close(server_info->control_fd);
687
688         server_list = g_slist_remove(server_list, server_info);
689
690         __bt_rfcomm_delete_server_id(server_info->server_id);
691
692         g_free(server_info->serial_path);
693         g_free(server_info->uuid);
694         g_free(server_info->sender);
695         g_free(server_info);
696
697         BT_DBG("-");
698
699         return BLUETOOTH_ERROR_NONE;
700 }
701
702 static int __bt_rfcomm_server_disconnect_cb(void *data)
703 {
704         bt_rfcomm_event_info_t *event_info = data;
705         int result = BLUETOOTH_ERROR_NONE;
706
707         retv_if(event_info == NULL, BLUETOOTH_ERROR_NONE);
708         retv_if(event_info->uuid == NULL, BLUETOOTH_ERROR_NONE);
709
710         if (event_info->remote_address == NULL)
711                 event_info->remote_address = g_strdup("");
712
713         _bt_send_event(BT_RFCOMM_SERVER_EVENT,
714                 BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
715                 DBUS_TYPE_INT32, &result,
716                 DBUS_TYPE_STRING, &event_info->remote_address,
717                 DBUS_TYPE_STRING, &event_info->uuid,
718                 DBUS_TYPE_INT16, &event_info->data_fd,
719                 DBUS_TYPE_INVALID);
720
721         g_free(event_info->uuid);
722         g_free(event_info->remote_address);
723         g_free(event_info);
724
725         return BLUETOOTH_ERROR_NONE;
726 }
727
728 int _bt_rfcomm_server_disconnect(int data_fd)
729 {
730         bt_rfcomm_server_info_t *server_info;
731         bt_rfcomm_event_info_t *event_info;
732
733         BT_DBG("+");
734
735         retv_if(data_fd <= 0, BLUETOOTH_ERROR_INVALID_PARAM);
736
737         server_info = __bt_rfcomm_get_server_info_using_data_fd(data_fd);
738         retv_if(server_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
739
740         if (server_info->data_id > 0)
741                 g_source_remove(server_info->data_id);
742
743         if (server_info->data_fd > 0)
744                 close(server_info->data_fd);
745
746         event_info = g_malloc0(sizeof(bt_rfcomm_event_info_t));
747         event_info->data_fd = server_info->data_fd;
748         event_info->remote_address = g_strdup(server_info->remote_address);
749         event_info->uuid = g_strdup(server_info->uuid);
750
751         /* Send the disconnected event after return the function */
752         g_idle_add((GSourceFunc)__bt_rfcomm_server_disconnect_cb, event_info);
753
754         g_free(server_info->remote_address);
755         server_info->remote_address = NULL;
756         server_info->data_fd = -1;
757         server_info->data_id = 0;
758         server_info->data_io = NULL;
759
760         BT_DBG("-");
761
762         return BLUETOOTH_ERROR_NONE;
763 }
764
765 /* To support the BOT  */
766 int _bt_rfcomm_is_uuid_available(char *uuid, gboolean *available)
767 {
768         GSList *l;
769         bt_rfcomm_server_info_t *server_info;
770
771         BT_CHECK_PARAMETER(uuid, return);
772         BT_CHECK_PARAMETER(available, return);
773
774         *available = FALSE;
775
776         for (l = server_list; l != NULL; l = l->next) {
777                 server_info = l->data;
778
779                 if (server_info == NULL)
780                         continue;
781
782                 if (g_ascii_strcasecmp(uuid, server_info->uuid) == 0) {
783                         *available = TRUE;
784                         return BLUETOOTH_ERROR_NONE;
785                 }
786         }
787
788         return BLUETOOTH_ERROR_NONE;
789 }
790
791 /* To support the BOT  */
792 int _bt_rfcomm_accept_connection(void)
793 {
794         BT_DBG("+");
795         if (!_bt_agent_reply_authorize(TRUE))
796                 return BLUETOOTH_ERROR_INTERNAL;
797
798         BT_DBG("-");
799         return BLUETOOTH_ERROR_NONE;
800 }
801
802 /* To support the BOT  */
803 int _bt_rfcomm_reject_connection(void)
804 {
805         BT_DBG("+");
806         if (!_bt_agent_reply_authorize(FALSE))
807                 return BLUETOOTH_ERROR_INTERNAL;
808
809         BT_DBG("-");
810         return BLUETOOTH_ERROR_NONE;
811 }
812
813 bt_rfcomm_server_info_t *_bt_rfcomm_get_server_info_using_uuid(char *uuid)
814 {
815         GSList *l;
816         bt_rfcomm_server_info_t *server_info;
817
818         retv_if(uuid == NULL, NULL);
819
820         for (l = server_list; l != NULL; l = l->next) {
821                 server_info = l->data;
822
823                 if (server_info == NULL)
824                         continue;
825
826                 if (g_strcmp0(server_info->uuid, uuid) == 0)
827                         return server_info;
828         }
829
830         return NULL;
831 }
832
833 int _bt_rfcomm_server_disconnect_all_connection(void)
834 {
835         GSList *l;
836         bt_rfcomm_server_info_t *server_info;
837
838         for (l = server_list; l != NULL; l = l->next) {
839                 server_info = l->data;
840
841                 if (server_info == NULL)
842                         continue;
843
844                 _bt_rfcomm_disconnect(server_info->data_fd);
845         }
846
847         return BLUETOOTH_ERROR_NONE;
848 }
849
850 int _bt_rfcomm_server_check_existence(gboolean *existence)
851 {
852         BT_CHECK_PARAMETER(existence, return);
853
854         if (server_list && g_slist_length(server_list) > 0) {
855                 *existence = TRUE;
856         } else {
857                 *existence = FALSE;
858         }
859
860         return BLUETOOTH_ERROR_NONE;
861 }
862
863 int _bt_rfcomm_server_check_termination(char *name)
864 {
865         GSList *l;
866         bt_rfcomm_server_info_t *server_info;
867
868         BT_CHECK_PARAMETER(name, return);
869
870         for (l = server_list; l != NULL; l = l->next) {
871                 server_info = l->data;
872
873                 if (server_info == NULL)
874                         continue;
875
876                 if (g_strcmp0(server_info->sender, name) == 0) {
877                         _bt_rfcomm_remove_socket(server_info->control_fd);
878                 }
879         }
880
881         return BLUETOOTH_ERROR_NONE;
882 }
883
884