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