Tizen 2.1 base
[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);
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);
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         g_free(server_info->serial_path);
688         g_free(server_info->uuid);
689         g_free(server_info->sender);
690         g_free(server_info);
691
692         BT_DBG("-");
693
694         return BLUETOOTH_ERROR_NONE;
695 }
696
697 static int __bt_rfcomm_server_disconnect_cb(void *data)
698 {
699         bt_rfcomm_event_info_t *event_info = data;
700         int result = BLUETOOTH_ERROR_NONE;
701
702         retv_if(event_info == NULL, BLUETOOTH_ERROR_NONE);
703         retv_if(event_info->uuid == NULL, BLUETOOTH_ERROR_NONE);
704
705         if (event_info->remote_address == NULL)
706                 event_info->remote_address = g_strdup("");
707
708         _bt_send_event(BT_RFCOMM_SERVER_EVENT,
709                 BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
710                 DBUS_TYPE_INT32, &result,
711                 DBUS_TYPE_STRING, &event_info->remote_address,
712                 DBUS_TYPE_STRING, &event_info->uuid,
713                 DBUS_TYPE_INT16, &event_info->data_fd,
714                 DBUS_TYPE_INVALID);
715
716         g_free(event_info->uuid);
717         g_free(event_info->remote_address);
718         g_free(event_info);
719
720         return BLUETOOTH_ERROR_NONE;
721 }
722
723 int _bt_rfcomm_server_disconnect(int data_fd)
724 {
725         bt_rfcomm_server_info_t *server_info;
726         bt_rfcomm_event_info_t *event_info;
727
728         BT_DBG("+");
729
730         retv_if(data_fd <= 0, BLUETOOTH_ERROR_INVALID_PARAM);
731
732         server_info = __bt_rfcomm_get_server_info_using_data_fd(data_fd);
733         retv_if(server_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
734
735         if (server_info->data_id > 0)
736                 g_source_remove(server_info->data_id);
737
738         if (server_info->data_fd > 0)
739                 close(server_info->data_fd);
740
741         event_info = g_malloc0(sizeof(bt_rfcomm_event_info_t));
742         event_info->data_fd = server_info->data_fd;
743         event_info->remote_address = g_strdup(server_info->remote_address);
744         event_info->uuid = g_strdup(server_info->uuid);
745
746         /* Send the disconnected event after return the function */
747         g_idle_add((GSourceFunc)__bt_rfcomm_server_disconnect_cb, event_info);
748
749         g_free(server_info->remote_address);
750         server_info->remote_address = NULL;
751         server_info->data_fd = -1;
752         server_info->data_id = 0;
753         server_info->data_io = NULL;
754
755         BT_DBG("-");
756
757         return BLUETOOTH_ERROR_NONE;
758 }
759
760 /* To support the BOT  */
761 int _bt_rfcomm_is_uuid_available(char *uuid, gboolean *available)
762 {
763         GSList *l;
764         bt_rfcomm_server_info_t *server_info;
765
766         BT_CHECK_PARAMETER(uuid);
767         BT_CHECK_PARAMETER(available);
768
769         *available = FALSE;
770
771         for (l = server_list; l != NULL; l = l->next) {
772                 server_info = l->data;
773
774                 if (server_info == NULL)
775                         continue;
776
777                 if (g_ascii_strcasecmp(uuid, server_info->uuid) == 0) {
778                         *available = TRUE;
779                         return BLUETOOTH_ERROR_NONE;
780                 }
781         }
782
783         return BLUETOOTH_ERROR_NONE;
784 }
785
786 gboolean __bt_rfcomm_server_accept_timeout_cb(gpointer user_data)
787 {
788         bt_rfcomm_server_info_t *server_info;
789         request_info_t *req_info;
790         GArray *out_param1;
791         GArray *out_param2;
792         int result = BLUETOOTH_ERROR_TIMEOUT;
793
794         server_info = (bt_rfcomm_server_info_t *)user_data;
795
796         /* Already reply in __bt_rfcomm_server_connected_cb */
797         retv_if(server_info == NULL, FALSE);
798         retv_if(server_info->accept_id == 0, FALSE);
799
800         req_info = _bt_get_request_info(server_info->accept_id);
801         if (req_info == NULL || req_info->context == NULL) {
802                 BT_ERR("info is NULL");
803                 return FALSE;
804         }
805
806         server_info->accept_id = 0;
807
808         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
809         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
810
811         g_array_append_vals(out_param2, &result, sizeof(int));
812
813         dbus_g_method_return(req_info->context, out_param1, out_param2);
814
815         g_array_free(out_param1, TRUE);
816         g_array_free(out_param2, TRUE);
817
818         _bt_delete_request_list(req_info->req_id);
819
820         return FALSE;
821 }
822
823 /* To support the BOT  */
824 int _bt_rfcomm_accept_connection(int server_fd, int request_id)
825 {
826         bt_rfcomm_server_info_t *server_info;
827
828         server_info = __bt_rfcomm_get_server_info(server_fd);
829         retv_if(server_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
830         retv_if(server_info->server_type != BT_CUSTOM_SERVER,
831                                         BLUETOOTH_ERROR_INVALID_PARAM);
832
833         if (!_bt_agent_reply_authorize(TRUE))
834                 return BLUETOOTH_ERROR_INTERNAL;
835
836         server_info->accept_id = request_id;
837
838         g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
839                         (GSourceFunc)__bt_rfcomm_server_accept_timeout_cb,
840                         server_info);
841
842         return BLUETOOTH_ERROR_NONE;
843 }
844
845 /* To support the BOT  */
846 int _bt_rfcomm_reject_connection(int server_fd)
847 {
848         bt_rfcomm_server_info_t *server_info;
849
850         server_info = __bt_rfcomm_get_server_info(server_fd);
851         retv_if(server_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
852         retv_if(server_info->server_type != BT_CUSTOM_SERVER,
853                                         BLUETOOTH_ERROR_INVALID_PARAM);
854
855         if (!_bt_agent_reply_authorize(FALSE))
856                 return BLUETOOTH_ERROR_INTERNAL;
857
858         return BLUETOOTH_ERROR_NONE;
859 }
860
861 bt_rfcomm_server_info_t *_bt_rfcomm_get_server_info_using_uuid(char *uuid)
862 {
863         GSList *l;
864         bt_rfcomm_server_info_t *server_info;
865
866         retv_if(uuid == NULL, NULL);
867
868         for (l = server_list; l != NULL; l = l->next) {
869                 server_info = l->data;
870
871                 if (server_info == NULL)
872                         continue;
873
874                 if (g_strcmp0(server_info->uuid, uuid) == 0)
875                         return server_info;
876         }
877
878         return NULL;
879 }
880
881 int _bt_rfcomm_server_disconnect_all_connection(void)
882 {
883         GSList *l;
884         bt_rfcomm_server_info_t *server_info;
885
886         for (l = server_list; l != NULL; l = l->next) {
887                 server_info = l->data;
888
889                 if (server_info == NULL)
890                         continue;
891
892                 _bt_rfcomm_disconnect(server_info->data_fd);
893         }
894
895         return BLUETOOTH_ERROR_NONE;
896 }
897
898 int _bt_rfcomm_server_check_existence(gboolean *existence)
899 {
900         BT_CHECK_PARAMETER(existence);
901
902         if (server_list && g_slist_length(server_list) > 0) {
903                 *existence = TRUE;
904         } else {
905                 *existence = FALSE;
906         }
907
908         return BLUETOOTH_ERROR_NONE;
909 }
910
911 int _bt_rfcomm_server_check_termination(char *name)
912 {
913         GSList *l;
914         bt_rfcomm_server_info_t *server_info;
915
916         BT_CHECK_PARAMETER(name);
917
918         for (l = server_list; l != NULL; l = l->next) {
919                 server_info = l->data;
920
921                 if (server_info == NULL)
922                         continue;
923
924                 if (g_strcmp0(server_info->sender, name) == 0) {
925                         _bt_rfcomm_remove_socket(server_info->control_fd);
926                 }
927         }
928
929         return BLUETOOTH_ERROR_NONE;
930 }
931
932