ee38cc0094f0cee55f14b26e6136e208fae1a3ef
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-rfcomm-server.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <string.h>
19 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
20 #include <gio/gio.h>
21 #include <gio/gunixfdlist.h>
22 #include <sys/socket.h>
23 #endif
24
25 #include "bluetooth-api.h"
26 #include "bt-internal-types.h"
27
28 #include "bt-common.h"
29 #include "bt-request-sender.h"
30 #include "bt-event-handler.h"
31 #include "bt-dpm.h"
32
33 #define BLUETOOTH_SOCK_CONNECT_INFO_LEN 16
34 #define BATTERY_MONITOR_RFCOMM_INTERVAL 5
35
36 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
37
38 static GSList *rfcomm_nodes;
39
40 typedef struct {
41         bluetooth_device_address_t addr;
42         int fd;
43         guint watch_id;
44         gboolean disconnected;
45 } rfcomm_conn_t;
46
47 typedef struct {
48         guint object_id;
49         gchar *path;
50         int id;
51         char *uuid;
52         GSList *rfcomm_conns;
53         guint disconnect_idle_id;
54 } rfcomm_info_t;
55
56 static unsigned int rx_data = 0;
57 static guint rx_tag = 0;
58
59 static bool __rfcomm_record_rx_data(void)
60 {
61         if (rx_data) {
62                 int ret = _bt_common_send_rfcomm_rx_details(rx_data);
63                 if (ret == BLUETOOTH_ERROR_NONE) {
64                         rx_data = 0;
65                         return TRUE;
66                 } else {
67                         BT_ERR("RFCOMM rx data could not be registered");
68                 }
69         }
70
71         rx_data = 0;
72         rx_tag = 0;
73
74         return FALSE;
75 }
76
77 static rfcomm_info_t *__find_rfcomm_info_with_id(int id)
78 {
79         GSList *l;
80
81         for (l = rfcomm_nodes; l != NULL; l = l->next) {
82                 rfcomm_info_t *info = l->data;
83
84                 if (info->id == id)
85                         return info;
86         }
87
88         return NULL;
89 }
90
91 static rfcomm_info_t *__find_rfcomm_info_with_fd(int fd)
92 {
93         GSList *l;
94         GSList *ll;
95
96         for (l = rfcomm_nodes; l != NULL; l = l->next) {
97                 rfcomm_info_t *info = l->data;
98
99                 for (ll = info->rfcomm_conns; ll; ll = ll->next) {
100                         rfcomm_conn_t *conn = ll->data;
101
102                         if (conn && conn->fd == fd)
103                                 return info;
104                 }
105         }
106
107         return NULL;
108 }
109
110 static rfcomm_info_t *__find_rfcomm_info_with_path(const gchar *path)
111 {
112         GSList *l;
113
114         for (l = rfcomm_nodes; l != NULL; l = l->next) {
115                 rfcomm_info_t *info = l->data;
116
117                 if (g_ascii_strcasecmp(info->path, path) == 0)
118                         return info;
119         }
120
121         return NULL;
122 }
123
124 static rfcomm_info_t *__find_rfcomm_info_with_uuid(const char *uuid)
125 {
126         GSList *l;
127
128         for (l = rfcomm_nodes; l != NULL; l = l->next) {
129                 rfcomm_info_t *info = l->data;
130
131                 if (g_ascii_strcasecmp(info->uuid, uuid) == 0)
132                         return info;
133         }
134
135         return NULL;
136 }
137
138 static rfcomm_conn_t *__find_rfcomm_conn_with_fd(rfcomm_info_t *info,
139                                                       int fd)
140 {
141         GSList *l;
142         rfcomm_conn_t *conn;
143
144         for (l = info->rfcomm_conns; l; l = l->next) {
145                 conn = l->data;
146
147                 if (conn && conn->fd == fd)
148                         return conn;
149         }
150
151         return NULL;
152 }
153
154 static void __rfcomm_remove_conn(rfcomm_info_t *info, int fd)
155 {
156         rfcomm_conn_t *conn;
157
158         conn = __find_rfcomm_conn_with_fd(info, fd);
159         if (conn == NULL)
160                 return;
161
162         info->rfcomm_conns = g_slist_remove(info->rfcomm_conns, conn);
163
164         if (conn->watch_id > 0)
165                 g_source_remove(conn->watch_id);
166         g_free(conn);
167 }
168
169 gboolean _check_uuid_path(char *path, char *uuid)
170 {
171         rfcomm_info_t *info = NULL;
172         info = __find_rfcomm_info_with_path(path);
173         if (!info)
174                 return FALSE;
175
176         if (g_ascii_strcasecmp(info->uuid, uuid) == 0)
177                 return TRUE;
178
179         return FALSE;
180 }
181
182 static void __connected_cb(rfcomm_info_t *info, rfcomm_conn_t *conn,
183                            bt_event_info_t *event_info)
184 {
185         bluetooth_rfcomm_connection_t conn_info;
186
187         memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
188
189         conn_info.device_role = RFCOMM_ROLE_SERVER;
190         g_strlcpy(conn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
191         conn_info.socket_fd = conn->fd;
192         conn_info.device_addr = conn->addr;
193         conn_info.server_id = info->id;
194
195         BT_INFO_C("### Connected [RFCOMM Server]");
196
197         if (_bt_common_send_rfcomm_conn_info(RFCOMM_ROLE_SERVER,
198                         TRUE, conn_info.socket_fd) != BLUETOOTH_ERROR_NONE)
199                 BT_ERR("Fail to send the connection info");
200
201         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_CONNECTED,
202                         BLUETOOTH_ERROR_NONE, &conn_info,
203                         event_info->cb, event_info->user_data);
204 }
205
206 static void __rfcomm_server_disconnect_conn(rfcomm_conn_t *conn,
207                                             rfcomm_info_t *info)
208 {
209         bluetooth_rfcomm_disconnection_t disconn_info;
210         bt_event_info_t *event_info;
211
212         if (conn == NULL)
213                 return;
214
215         if (conn->disconnected == FALSE)
216                 return;
217
218         if (conn->watch_id > 0) {
219                 g_source_remove(conn->watch_id);
220                 conn->watch_id = 0;
221         }
222
223         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
224         if (event_info == NULL) {
225                 BT_ERR("event_info is NULL");
226                 __rfcomm_remove_conn(info, conn->fd);
227                 return;
228         }
229
230         memset(&disconn_info, 0x00, sizeof(bluetooth_rfcomm_disconnection_t));
231         disconn_info.device_role = RFCOMM_ROLE_SERVER;
232         g_strlcpy(disconn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
233         disconn_info.device_addr = conn->addr;
234
235         BT_INFO("Disconnected FD [%d]", conn->fd);
236         disconn_info.socket_fd = conn->fd;
237
238         if (_bt_common_send_rfcomm_conn_info(RFCOMM_ROLE_SERVER,
239                         FALSE, disconn_info.socket_fd) != BLUETOOTH_ERROR_NONE)
240                 BT_ERR("Fail to send the connection info");
241
242         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
243                         BLUETOOTH_ERROR_NONE, &disconn_info,
244                         event_info->cb, event_info->user_data);
245
246         __rfcomm_remove_conn(info, conn->fd);
247 }
248
249 static gboolean __rfcomm_server_disconnect(rfcomm_info_t *info)
250 {
251         BT_INFO_C("### Disconnected [RFCOMM Server]");
252
253         if (g_slist_find(rfcomm_nodes, info) == NULL) {
254                 BT_INFO("rfcomm resource is already freed");
255                 return FALSE;
256         }
257
258         info->disconnect_idle_id = 0;
259
260         g_slist_foreach(info->rfcomm_conns,
261                         (GFunc)__rfcomm_server_disconnect_conn, info);
262
263         BT_DBG("-");
264         return FALSE;
265 }
266
267 static gboolean __is_error_by_disconnect(GError *err)
268 {
269         return !g_strcmp0(err->message, "Connection reset by peer") ||
270                         !g_strcmp0(err->message, "Connection timed out") ||
271                         !g_strcmp0(err->message, "Software caused connection abort");
272 }
273
274 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
275                                                                 gpointer data)
276 {
277         char *buffer = NULL;
278         gsize len = 0;
279         int result = BLUETOOTH_ERROR_NONE;
280         rfcomm_info_t *info = data;
281         rfcomm_conn_t *conn;
282         bt_event_info_t *event_info;
283         bluetooth_rfcomm_received_data_t data_r;
284         GIOStatus status = G_IO_STATUS_NORMAL;
285         GError *err = NULL;
286         int fd;
287
288         retv_if(info == NULL, FALSE);
289
290         fd = g_io_channel_unix_get_fd(chan);
291         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
292                 BT_ERR_C("RFComm Server disconnected: %d", fd);
293
294                 if (info->disconnect_idle_id > 0) {
295                         BT_INFO("Disconnect idle still not process remove source");
296                         g_source_remove(info->disconnect_idle_id);
297                         info->disconnect_idle_id = 0;
298                 }
299
300                 conn = __find_rfcomm_conn_with_fd(info, fd);
301                 if (conn == NULL) {
302                         BT_ERR("No Connection info found with FD [%d]", fd);
303                         return FALSE;
304                 }
305
306                 if (conn->disconnected == FALSE) {
307                         close(conn->fd);
308                         conn->disconnected = TRUE;
309                 }
310                 __rfcomm_server_disconnect(info);
311                 return FALSE;
312         }
313
314         buffer = g_malloc0(BT_RFCOMM_BUFFER_LEN + 1);
315
316         status =  g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_LEN,
317                                                 &len, &err);
318         if (status != G_IO_STATUS_NORMAL) {
319                 BT_ERR("IO Channel read is failed with %d", status);
320
321                 g_free(buffer);
322                 if (!err)
323                         return TRUE;
324
325                 BT_ERR("IO Channel read error [%s]", err->message);
326                 if (status == G_IO_STATUS_ERROR &&
327                     __is_error_by_disconnect(err)) {
328                         BT_ERR("cond : %d", cond);
329                         g_error_free(err);
330
331                         if (info->disconnect_idle_id > 0) {
332                                 BT_INFO("Disconnect idle still not process remove source");
333                                 g_source_remove(info->disconnect_idle_id);
334                                 info->disconnect_idle_id = 0;
335                         }
336
337                         conn = __find_rfcomm_conn_with_fd(info, fd);
338                         if (conn == NULL) {
339                                 BT_ERR("No Connection info found with FD [%d]", fd);
340                                 return FALSE;
341                         }
342
343                         if (conn->disconnected == FALSE) {
344                                 close(conn->fd);
345                                 conn->disconnected = TRUE;
346                         }
347                         __rfcomm_server_disconnect(info);
348                         return FALSE;
349                 }
350                 g_error_free(err);
351                 return TRUE;
352         }
353
354         if (len == 0)
355                 BT_ERR("Length is zero");
356
357         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
358         if (event_info == NULL) {
359                 BT_ERR("event_info is NULL. Unable to invoke the callback");
360                 g_free(buffer);
361                 return TRUE;
362         }
363
364         data_r.socket_fd = fd;
365         data_r.buffer_size = len;
366         data_r.buffer = buffer;
367
368         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED,
369                         result, &data_r,
370                         event_info->cb, event_info->user_data);
371
372         if (bluetooth_get_battery_monitor_state()) {
373                 if (rx_tag == 0) {
374                         BT_DBG("Adding rfcomm rx timeout function for battery monitor");
375                         rx_tag = g_timeout_add_seconds(BATTERY_MONITOR_RFCOMM_INTERVAL, (GSourceFunc)__rfcomm_record_rx_data, NULL);
376                 }
377                 rx_data += len;
378         }
379
380         g_free(buffer);
381
382         return TRUE;
383 }
384
385 int new_server_connection(const char *path, int fd, bluetooth_device_address_t *addr)
386 {
387         rfcomm_info_t *info;
388         rfcomm_conn_t *conn;
389         GIOChannel *data_io;
390         bt_event_info_t *event_info;
391
392         BT_INFO("%s %d", path, fd);
393
394         info = __find_rfcomm_info_with_path(path);
395         if (info == NULL) {
396                 BT_ERR("rfcomm info is NULL");
397                 return -1;
398         }
399
400         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
401                 char addr_str[20];
402
403                 BT_ERR("Not allow to use SPP profile");
404
405                 close(fd);
406                 _bt_convert_addr_type_to_string(addr_str, addr->addr);
407                 _bt_disconnect_ext_profile(addr_str, info->path);
408
409                 return -1;
410         }
411
412         conn = g_new0(rfcomm_conn_t, 1);
413         conn->fd = fd;
414         memcpy(&conn->addr, addr, sizeof(bluetooth_device_address_t));
415         info->rfcomm_conns = g_slist_append(info->rfcomm_conns, conn);
416
417         data_io = g_io_channel_unix_new(conn->fd);
418
419         g_io_channel_set_encoding(data_io, NULL, NULL);
420         g_io_channel_set_flags(data_io, G_IO_FLAG_NONBLOCK, NULL);
421
422         conn->watch_id = g_io_add_watch(data_io,
423                            G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
424                            __data_received_cb, info);
425
426         g_io_channel_unref(data_io);
427
428         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
429         if (event_info)
430                 __connected_cb(info, conn, event_info);
431
432         return 0;
433 }
434
435 static rfcomm_info_t *__register_method()
436 {
437         gchar *path;
438         rfcomm_info_t *info;
439         int object_id;
440         int id;
441
442         id = __rfcomm_assign_id();
443         if (id < 0)
444                 return NULL;
445
446         path = g_strdup_printf("/org/socket/server/%d/%d", getpid(), id);
447
448         object_id = _bt_register_new_conn(path, new_server_connection);
449         if (object_id < 0) {
450                 __rfcomm_delete_id(id);
451                 g_free(path);
452                 return NULL;
453         }
454         info = g_new0(rfcomm_info_t, 1);
455         info->object_id = (guint)object_id;
456         info->path = path;
457         info->id = id;
458
459         rfcomm_nodes = g_slist_append(rfcomm_nodes, info);
460
461         return info;
462 }
463
464 static rfcomm_info_t *__register_method_2(const char *path, const char *bus_name)
465 {
466         rfcomm_info_t *info;
467         int object_id;
468
469         object_id = _bt_register_new_conn_ex(path, bus_name, new_server_connection);
470         if (object_id < 0)
471                 return NULL;
472
473         info = g_new0(rfcomm_info_t, 1);
474         info->object_id = (guint)object_id;
475         info->path = g_strdup(path);
476         info->id = -1;
477
478         rfcomm_nodes = g_slist_append(rfcomm_nodes, info);
479
480         return info;
481 }
482
483 void free_rfcomm_conn(rfcomm_conn_t *conn, rfcomm_info_t *info)
484 {
485         if (conn->disconnected == FALSE) {
486                 close(conn->fd);
487                 conn->disconnected = TRUE;
488         }
489         __rfcomm_server_disconnect_conn(conn, info);
490 }
491
492 void free_rfcomm_info(rfcomm_info_t *info)
493 {
494         BT_DBG("");
495
496         if (info->disconnect_idle_id > 0) {
497                 BT_INFO("Disconnect idle still not process remove source");
498                 g_source_remove(info->disconnect_idle_id);
499                 info->disconnect_idle_id = 0;
500         }
501
502         __rfcomm_delete_id(info->id);
503         _bt_unregister_gdbus(info->object_id);
504
505         g_slist_foreach(info->rfcomm_conns, (GFunc)free_rfcomm_conn, info);
506
507         g_free(info->path);
508         g_free(info->uuid);
509         g_free(info);
510 }
511
512 void _bt_rfcomm_server_free_all(void)
513 {
514         BT_DBG("Free all the servers");
515
516         g_slist_free_full(rfcomm_nodes, (GDestroyNotify)free_rfcomm_info);
517         rfcomm_nodes = NULL;
518 }
519
520 void _bt_rfcomm_server_disconnect_all(void)
521 {
522         GSList *server;
523         GSList *conn;
524         char addr[20];
525
526         BT_INFO(" ### Disconnect all RFCOMM server connections");
527
528         for (server = rfcomm_nodes; server; ) {
529                 rfcomm_info_t *info = server->data;
530
531                 for (conn = info->rfcomm_conns; conn; conn = conn->next) {
532                         rfcomm_conn_t *conn_info = conn->data;
533
534                         if (conn_info == NULL)
535                                 continue;
536
537                         if (conn_info->watch_id == 0 || conn_info->disconnected)
538                                 continue;
539
540                         close(conn_info->fd);
541                         conn_info->disconnected = TRUE;
542
543                         _bt_convert_addr_type_to_string(addr,
544                                                         conn_info->addr.addr);
545                         _bt_disconnect_ext_profile(addr, info->path);
546                 }
547
548                 server = server->next;
549                 __rfcomm_server_disconnect(info);
550         }
551
552         return;
553 }
554
555 void _bt_rfcomm_server_reset_timer(void)
556 {
557         if (rx_tag > 0) {
558                 g_source_remove(rx_tag);
559                 rx_tag = 0;
560         }
561
562         rx_data = 0;
563 }
564 #else
565
566 #define BT_RFCOMM_SERVER_ID_MAX 254
567
568 typedef struct {
569         char addr[BT_ADDRESS_STRING_SIZE];
570         int sock_fd;
571         int watch_id;
572         int server_id;
573 } rfcomm_remote_client_info_t;
574
575 typedef struct {
576         char uuid[BLUETOOTH_UUID_STRING_MAX];
577         int server_id;
578         int server_fd;
579         int watch_id;
580         int max_pending_conn;
581         gboolean auto_accept;
582         char pending_addr[BT_ADDRESS_STRING_SIZE];
583         GSList *conn_list;
584 } rfcomm_server_info_t;
585
586 static GSList *rfcomm_servers;
587 static gboolean id_used[BT_RFCOMM_SERVER_ID_MAX];
588 int latest_id = 0;
589
590 int __rfcomm_assign_server_id(void)
591 {
592         int index;
593
594         BT_DBG("latest_id: %d", latest_id);
595
596         index = latest_id + 1;
597
598         if (index >= BT_RFCOMM_SERVER_ID_MAX)
599                 index = 0;
600
601         BT_DBG("index: %d", index);
602
603         while (id_used[index] == TRUE) {
604                 if (index == latest_id) {
605                         /* No available ID */
606                         BT_ERR("All request ID is used");
607                         return -1;
608                 }
609
610                 index++;
611
612                 if (index >= BT_RFCOMM_SERVER_ID_MAX)
613                         index = 0;
614         }
615
616         latest_id = index;
617         id_used[index] = TRUE;
618
619         BT_DBG("Assigned Id: %d", latest_id);
620
621         return latest_id;
622 }
623
624 void __rfcomm_delete_server_id(int id)
625 {
626         ret_if(id >= BT_RFCOMM_SERVER_ID_MAX);
627         ret_if(id < 0);
628
629         id_used[id] = FALSE;
630
631         /* Next server will use this ID */
632         latest_id = id - 1;
633 }
634
635 static rfcomm_server_info_t *__get_rfcomm_server_info_with_uuid(const char *uuid)
636 {
637         GSList *l;
638
639         if (!uuid)
640                 return NULL;
641
642         for (l = rfcomm_servers; l != NULL; l = l->next) {
643                 rfcomm_server_info_t *info = l->data;
644
645                 if (!strncasecmp(info->uuid, uuid, strlen(info->uuid)))
646                         return info;
647         }
648
649         return NULL;
650 }
651
652 int _get_rfcomm_server_id(char *uuid, gboolean *auto_accept)
653 {
654         rfcomm_server_info_t *server_info;
655
656         server_info = __get_rfcomm_server_info_with_uuid(uuid);
657         if (!server_info)
658                 return -1;
659
660         *auto_accept = server_info->auto_accept;
661         return server_info->server_id;
662 }
663
664 static rfcomm_server_info_t *__get_rfcomm_server_info_with_id(int server_id)
665 {
666         GSList *l;
667
668         for (l = rfcomm_servers; l != NULL; l = l->next) {
669                 rfcomm_server_info_t *info = l->data;
670                 if (!info)
671                         continue;
672
673                 BT_DBG("info->server_fd: %d, sock_fd:%d", info->server_id, server_id);
674                 if (info->server_id == server_id)
675                         return info;
676         }
677
678         return NULL;
679 }
680
681 void _bt_rfcomm_server_set_pending_conn(int server_id, char *address)
682 {
683         rfcomm_server_info_t *server_info;
684
685
686         if (!address)
687                 return;
688
689         server_info = __get_rfcomm_server_info_with_id(server_id);
690         if (!server_info)
691                 return;
692
693         g_strlcpy(server_info->pending_addr, address, BT_ADDRESS_STRING_SIZE);
694 }
695
696 static rfcomm_remote_client_info_t *__get_rfcomm_rem_client_info_with_fd(int sock_fd)
697 {
698         GSList *l;
699         GSList *l1;
700
701         for (l = rfcomm_servers; l != NULL; l = l->next) {
702                 rfcomm_server_info_t *info = l->data;
703
704                 if (!info)
705                         continue;
706
707                 for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) {
708                         rfcomm_remote_client_info_t *client_info = l1->data;
709                         if (!client_info)
710                                 continue;
711
712                         if (client_info->sock_fd == sock_fd)
713                                 return client_info;
714                 }
715         }
716
717         return NULL;
718 }
719
720 static rfcomm_remote_client_info_t *__get_rfcomm_rem_client_info_with_addr(char *addr)
721 {
722         GSList *l;
723         GSList *l1;
724
725         retv_if(NULL == addr, NULL);
726
727         for (l = rfcomm_servers; l != NULL; l = l->next) {
728                 rfcomm_server_info_t *info = l->data;
729
730                 if (!info)
731                         continue;
732
733                 for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) {
734                         rfcomm_remote_client_info_t *client_info = l1->data;
735                         if (!client_info)
736                                 continue;
737
738                         if (!strncasecmp(client_info->addr, addr, strlen(client_info->addr)))
739                                 return client_info;
740                 }
741         }
742
743         return NULL;
744 }
745
746 static void __remove_remote_client_info(rfcomm_remote_client_info_t *rem_client)
747 {
748         BT_DBG("+");
749
750         if (rem_client == NULL)
751                 return;
752
753         if (0 < rem_client->sock_fd) {
754                 shutdown(rem_client->sock_fd, SHUT_RDWR);
755                 close(rem_client->sock_fd);
756         }
757
758         if (rem_client->watch_id > 0)
759                 g_source_remove(rem_client->watch_id);
760
761         g_free(rem_client);
762
763         BT_DBG("-");
764 }
765
766 static void __handle_rfcomm_client_disconnected(rfcomm_server_info_t *server_info,
767                 rfcomm_remote_client_info_t *rem_client)
768 {
769         bluetooth_rfcomm_disconnection_t disconn_info;
770         bt_event_info_t *event_info;
771
772         BT_DBG("+");
773
774         if (rem_client == NULL || server_info == NULL)
775                 return;
776
777         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
778         if (event_info == NULL)
779                 return;
780
781         memset(&disconn_info, 0x00, sizeof(bluetooth_rfcomm_disconnection_t));
782         disconn_info.device_role = RFCOMM_ROLE_SERVER;
783         g_strlcpy(disconn_info.uuid, server_info->uuid, BLUETOOTH_UUID_STRING_MAX);
784         _bt_convert_addr_string_to_type(disconn_info.device_addr.addr, rem_client->addr);
785         BT_DBG("Disconnected FD [%d]", rem_client->sock_fd);
786         disconn_info.socket_fd = rem_client->sock_fd;
787
788         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
789                         BLUETOOTH_ERROR_NONE, &disconn_info,
790                         event_info->cb, event_info->user_data);
791 }
792
793 static void __remove_rfcomm_server(rfcomm_server_info_t *info)
794 {
795         rfcomm_remote_client_info_t *client_info;
796
797         BT_DBG("+");
798
799         if (!info)
800                 return;
801
802         rfcomm_servers = g_slist_remove(rfcomm_servers, info);
803         if (info->conn_list) {
804                 do {
805                         client_info = info->conn_list->data;
806                         if (!client_info)
807                                 break;
808
809                         info->conn_list = g_slist_remove(info->conn_list, client_info);
810                         __handle_rfcomm_client_disconnected(info, client_info);
811                         __remove_remote_client_info(client_info);
812                 } while (info->conn_list);
813         }
814
815         if (info->server_fd) {
816                 shutdown(info->server_fd, SHUT_RDWR);
817                 close(info->server_fd);
818         }
819
820         if (info->watch_id)
821                 g_source_remove(info->watch_id);
822
823         __rfcomm_delete_server_id(info->server_id);
824         g_free(info);
825
826         BT_DBG("-");
827 }
828
829 static void __connected_cb(rfcomm_remote_client_info_t *client_info, bt_event_info_t *event_info)
830 {
831         bluetooth_rfcomm_connection_t conn_info;
832         rfcomm_server_info_t *server_info;
833
834         server_info = __get_rfcomm_server_info_with_id(client_info->server_id);
835         ret_if(server_info == NULL);
836
837         memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
838         conn_info.device_role = RFCOMM_ROLE_SERVER;
839         g_strlcpy(conn_info.uuid, server_info->uuid, BLUETOOTH_UUID_STRING_MAX);
840         conn_info.socket_fd = client_info->sock_fd;
841         _bt_convert_addr_string_to_type(conn_info.device_addr.addr, client_info->addr);
842         conn_info.server_id = server_info->server_id;
843
844         BT_INFO_C("Connected [RFCOMM Server]");
845         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_CONNECTED,
846                         BLUETOOTH_ERROR_NONE, &conn_info,
847                         event_info->cb, event_info->user_data);
848 }
849
850 static int __process_cmsg(struct msghdr *msg)
851 {
852         int sock_fd = -1;
853         struct cmsghdr *cmsg_ptr = NULL;
854
855         for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL;
856                         cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) {
857
858                 if (cmsg_ptr->cmsg_level != SOL_SOCKET)
859                         continue;
860
861                 if (cmsg_ptr->cmsg_type == SCM_RIGHTS) {
862                         //int *desc = (int *)CMSG_DATA(cmsg_ptr);
863                         int count
864                                 = ((cmsg_ptr->cmsg_len - CMSG_LEN(0)) / sizeof(int));
865
866                         if (count < 0) {
867                                 BT_ERR("ERROR Invalid count of descriptors");
868                                 continue;
869                         }
870
871                         //sock_fd = desc[0];
872                         memcpy(&sock_fd, CMSG_DATA(cmsg_ptr), sizeof(sock_fd));
873                         BT_DBG("Remote client fd: %d", sock_fd);
874                 }
875         }
876
877         return sock_fd;
878 }
879
880 static int __read_incomming_client_connection(
881                 int server_fd, char *buf, unsigned int len, int *client_fd)
882 {
883         int ret;
884         struct msghdr msg;
885         struct iovec iv;
886         struct cmsghdr cmsgbuf[2 * sizeof(struct cmsghdr) + 4];
887         int retryCount = 0;
888
889         retv_if(0 > server_fd, -1);
890         retv_if(NULL == client_fd, -1);
891
892         BT_INFO("server_fd = %d", server_fd);
893
894         memset(&msg, 0, sizeof(msg));
895         memset(&iv, 0, sizeof(iv));
896
897         iv.iov_base = buf;
898         iv.iov_len = len;
899         msg.msg_iov = &iv;
900         msg.msg_iovlen = 1;
901         msg.msg_control = cmsgbuf;
902         msg.msg_controllen = sizeof(cmsgbuf);
903
904         for (retryCount = 0; retryCount < 5; retryCount++) {
905                 ret = recvmsg(server_fd, &msg, 0);
906                 BT_DBG("recvmsg ret = %d", ret);
907                 if (ret < 0 && errno == EINTR)
908                         continue;
909                 else
910                         break;
911         }
912
913         if (ret < 0 && errno == EPIPE) {
914                 /* End of stream, server listining stopped */
915                 BT_ERR("EOS errno: %d", errno);
916                 return 0;
917         }
918
919         if (ret < 0) {
920                 BT_ERR("Ret errno: %d", errno);
921                 return -1;
922         }
923
924         if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) {
925                 BT_ERR("MSG Flags errno: %d", errno);
926                 return -1;
927         }
928
929         BT_INFO("Connection received");
930         *client_fd = __process_cmsg(&msg);
931         if (*client_fd < 0)
932                 BT_ERR("Invalid client_fd received");
933
934         return ret;
935 }
936
937 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
938                                                                 gpointer data)
939 {
940         char *buffer = NULL;
941         gsize len = 0;
942         int result = BLUETOOTH_ERROR_NONE;
943         bt_event_info_t *event_info;
944         bluetooth_rfcomm_received_data_t data_r;
945         GIOStatus status = G_IO_STATUS_NORMAL;
946         GError *err = NULL;
947         rfcomm_remote_client_info_t *client_info = data;
948         rfcomm_server_info_t *server_info;
949
950         retv_if(client_info == NULL, FALSE);
951
952         server_info = __get_rfcomm_server_info_with_id(client_info->server_id);
953
954         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
955                 BT_ERR_C("RFComm Server  disconnected: %d", client_info->sock_fd);
956                 goto fail;
957         }
958
959         buffer = g_malloc0(BT_RFCOMM_BUFFER_LEN + 1);
960         status =  g_io_channel_read_chars(chan, buffer,
961                         BT_RFCOMM_BUFFER_LEN, &len, &err);
962         if (status != G_IO_STATUS_NORMAL) {
963                 BT_ERR("IO Channel read is failed with %d", status);
964                 g_free(buffer);
965                 if (err) {
966                         BT_ERR("IO Channel read error [%s]", err->message);
967                         if (status == G_IO_STATUS_ERROR &&
968                                         !g_strcmp0(err->message, "Connection reset by peer")) {
969                                 BT_ERR("cond : %d", cond);
970                                 g_error_free(err);
971                                 goto fail;
972                         }
973                         g_error_free(err);
974                 }
975                 return TRUE;
976         }
977
978         if (len == 0) {
979                 BT_ERR("Length is zero, remote end hang up");
980                 goto fail;
981         }
982
983         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
984         if (event_info == NULL) {
985                 g_free(buffer);
986                 return TRUE;
987         }
988
989         data_r.socket_fd = client_info->sock_fd;
990         data_r.buffer_size = len;
991         data_r.buffer = buffer;
992
993         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED,
994                         result, &data_r,
995                         event_info->cb, event_info->user_data);
996
997         g_free(buffer);
998
999         return TRUE;
1000
1001 fail:
1002         BT_ERR("Failure occured, remove client connection");
1003         server_info->conn_list = g_slist_remove(
1004                         server_info->conn_list, client_info);
1005         __handle_rfcomm_client_disconnected(server_info, client_info);
1006         __remove_remote_client_info(client_info);
1007         return FALSE;
1008 }
1009
1010 static gboolean __new_connection_request_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
1011 {
1012         int len;
1013         int size;
1014         int channel;
1015         int status;
1016         int client_fd;
1017         char buf[BLUETOOTH_SOCK_CONNECT_INFO_LEN];
1018         unsigned char addr[BT_ADDRESS_LENGTH_MAX];
1019
1020         bt_event_info_t *event_info;
1021         GIOChannel *io;
1022         rfcomm_remote_client_info_t *rem_client;
1023         rfcomm_server_info_t *server_info = data;
1024
1025         if (!server_info) {
1026                 BT_ERR("Server info is invalid");
1027                 return FALSE;
1028         }
1029
1030         if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
1031                 BT_INFO("RFCOMM Server with fd:%d is closed with cond:0x%X",
1032                                 server_info->server_fd, cond);
1033                 goto err;
1034         }
1035
1036         BT_INFO("Server fd: %d", server_info->server_fd);
1037         len = __read_incomming_client_connection(
1038                         server_info->server_fd, buf, BLUETOOTH_SOCK_CONNECT_INFO_LEN, &client_fd);
1039         BT_DBG("Socket Read len: %d", len);
1040         if (len == 0) {
1041                 BT_ERR("Listen stopped");
1042                 goto err;
1043         } else if (len != BLUETOOTH_SOCK_CONNECT_INFO_LEN) {
1044                 BT_ERR("Read length is not same as socket info length");
1045                 goto err;
1046         }
1047
1048         len = 0;
1049         /* Read size of data */
1050         size = buf[len] | (buf[len + 1] << 8);
1051         len += 2;
1052
1053         /* Read bluetooth address */
1054         memcpy(addr, buf + len, BT_ADDRESS_LENGTH_MAX);
1055         len += BT_ADDRESS_LENGTH_MAX;
1056
1057         /* Read channel */
1058         channel = buf[len] | (buf[len + 1] << 8) |
1059                 (buf[len + 2] << 16) | (buf[len + 3] << 24);
1060         len += 4;
1061
1062         /* Read status */
1063         status = buf[len] | (buf[len + 1] << 8) |
1064                 (buf[len + 2] << 16) | (buf[len + 3] << 24);
1065         len += 4;
1066
1067         BT_DBG("size: %d, channel: %d, status: %d", size, channel, status);
1068
1069         rem_client = g_malloc0(sizeof(rfcomm_remote_client_info_t));
1070         rem_client->sock_fd = client_fd;
1071         rem_client->server_id = server_info->server_id;
1072         _bt_convert_addr_type_to_string(rem_client->addr, addr);
1073
1074         BT_INFO("New client [%s] connection with socket_fd: %d, server_id: %d",
1075                         rem_client->addr, rem_client->sock_fd, rem_client->server_id);
1076
1077         io = g_io_channel_unix_new(rem_client->sock_fd);
1078         g_io_channel_set_encoding(io, NULL, NULL);
1079         g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
1080         rem_client->watch_id = g_io_add_watch(io,
1081                         G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
1082                         __data_received_cb, rem_client);
1083         g_io_channel_unref(io);
1084
1085         server_info->conn_list = g_slist_append(server_info->conn_list, rem_client);
1086         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
1087         if (event_info)
1088                 __connected_cb(rem_client, event_info);
1089
1090         return TRUE;
1091
1092 err:
1093         /* Error occurred, Remove RFCOMM server*/
1094         __remove_rfcomm_server(server_info);
1095         return FALSE;
1096 }
1097
1098 static int __rfcomm_listen(rfcomm_server_info_t *server_info, bool accept)
1099 {
1100         int result;
1101         GUnixFDList *out_fd_list = NULL;
1102         GIOChannel *server_io;
1103
1104         retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1105
1106         BT_INIT_PARAMS();
1107         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1108
1109         if (accept == false) {
1110                 g_array_append_vals(in_param1, server_info->uuid, BLUETOOTH_UUID_STRING_MAX);
1111                 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
1112                                 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
1113         } else {
1114                 g_array_append_vals(in_param1, server_info->uuid, BLUETOOTH_UUID_STRING_MAX);
1115                 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN_AND_ACCEPT,
1116                                 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
1117         }
1118
1119         BT_DBG("result: %x", result);
1120         if (result != BLUETOOTH_ERROR_NONE) {
1121                 BT_ERR("Fail to send request");
1122                 return result;
1123         } else if (NULL == out_fd_list) {
1124                 BT_ERR("out_fd_list is NULL");
1125                 return BLUETOOTH_ERROR_INTERNAL;
1126         } else {
1127                 int *fd_list_array;
1128                 int len = 0;
1129
1130                 if (!out_fd_list)
1131                         return BLUETOOTH_ERROR_INTERNAL;
1132
1133                 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
1134                 BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
1135                 server_info->server_fd = fd_list_array[0];
1136                 BT_INFO("Socket fd: %d", server_info->server_fd);
1137
1138                 g_free(fd_list_array);
1139                 g_object_unref(out_fd_list);
1140         }
1141
1142         server_io = g_io_channel_unix_new(server_info->server_fd);
1143         g_io_channel_set_encoding(server_io, NULL, NULL);
1144         g_io_channel_set_flags(server_io, G_IO_FLAG_NONBLOCK, NULL);
1145         server_info->watch_id = g_io_add_watch(server_io,
1146                         G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
1147                         __new_connection_request_cb, server_info);
1148         g_io_channel_unref(server_io);
1149
1150         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1151
1152         return BLUETOOTH_ERROR_NONE;
1153 }
1154 #endif
1155
1156 BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid)
1157 {
1158 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1159         rfcomm_info_t *info;
1160 #else
1161         rfcomm_server_info_t *server_info;
1162 #endif
1163
1164         BT_CHECK_ENABLED(return);
1165         BT_CHECK_PARAMETER(uuid, return);
1166         BT_INFO("UUID Provided %s", uuid);
1167
1168         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_CREATE_SOCKET)
1169                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1170                 BT_ERR("Don't have a privilege to use this API");
1171                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1172         }
1173
1174         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1175                 BT_ERR("Not allow to use SPP profile");
1176                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1177         }
1178
1179 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1180         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
1181         info = __register_method();
1182         if (info == NULL)
1183                 return -1;
1184
1185         info->uuid = g_strdup(uuid);
1186         info->disconnect_idle_id = 0;
1187         return info->id;
1188 #else
1189         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
1190
1191         server_info = __get_rfcomm_server_info_with_uuid(uuid);
1192         if (!server_info) {
1193                 server_info = g_malloc0(sizeof(rfcomm_server_info_t));
1194                 g_strlcpy(server_info->uuid, uuid, BLUETOOTH_UUID_STRING_MAX);
1195                 server_info->server_id = __rfcomm_assign_server_id();
1196                 server_info->server_fd = -1;
1197                 server_info->watch_id = -1;
1198                 server_info->auto_accept = FALSE;
1199                 rfcomm_servers = g_slist_append(rfcomm_servers, server_info);
1200         }
1201         return server_info->server_id;
1202 #endif
1203 }
1204
1205 BT_EXPORT_API int bluetooth_rfcomm_create_socket_ex(const char *uuid, const char *bus_name, const char *path)
1206 {
1207 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1208         rfcomm_info_t *info;
1209
1210         BT_CHECK_ENABLED(return);
1211         BT_CHECK_PARAMETER(path, return);
1212         BT_INFO("PATH Provided %s", path);
1213
1214         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_CREATE_SOCKET_EX)
1215                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1216                 BT_ERR("Don't have a privilege to use this API");
1217                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1218         }
1219
1220         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1221                 BT_ERR("Not allow to use SPP profile");
1222                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1223         }
1224
1225         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
1226         info = __register_method_2(path, bus_name);
1227         if (info == NULL)
1228                 return BLUETOOTH_ERROR_IN_PROGRESS;
1229         info->uuid = g_strdup(uuid);
1230         info->disconnect_idle_id = 0;
1231
1232         return BLUETOOTH_ERROR_NONE;
1233 #else
1234         return BLUETOOTH_ERROR_NOT_SUPPORT;
1235 #endif
1236 }
1237
1238
1239 BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int id)
1240 {
1241 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1242         rfcomm_info_t *info;
1243 #else
1244         rfcomm_server_info_t *server_info;
1245 #endif
1246
1247         BT_CHECK_ENABLED(return);
1248
1249         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_REMOVE_SOCKET)
1250                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1251                 BT_ERR("Don't have a privilege to use this API");
1252                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1253         }
1254
1255         if (id < 0) {
1256                 BT_ERR("Invalid ID");
1257                 return BLUETOOTH_ERROR_INVALID_PARAM;
1258         }
1259
1260 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1261         BT_INFO("RFCOMM Remove socket request from app, ID [%d]", id);
1262
1263         info = __find_rfcomm_info_with_id(id);
1264         if (info == NULL)
1265                 return BLUETOOTH_ERROR_INVALID_PARAM;
1266
1267         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid);
1268         _bt_unregister_profile(info->path);
1269
1270         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
1271         free_rfcomm_info(info);
1272
1273         return BLUETOOTH_ERROR_NONE;
1274 #else
1275         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd);
1276
1277         server_info = __get_rfcomm_server_info_with_id(id);
1278         if (!server_info) {
1279                 BT_ERR("server_info not found for socket_fd: %d", id);
1280                 return BLUETOOTH_ERROR_INVALID_PARAM;
1281         }
1282
1283         __remove_rfcomm_server(server_info);
1284
1285         return BLUETOOTH_ERROR_NONE;
1286 #endif
1287 }
1288
1289 BT_EXPORT_API int bluetooth_rfcomm_remove_socket_ex(const char *uuid)
1290 {
1291 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1292         rfcomm_info_t *info;
1293
1294         BT_CHECK_ENABLED(return);
1295
1296         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_RFCOMM_REMOVE_SOCKET)
1297                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1298                 BT_ERR("Don't have a privilege to use this API");
1299                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1300         }
1301
1302         BT_INFO("RFCOMM Remove socket request from app, uuid=[%s]", uuid);
1303
1304         info = __find_rfcomm_info_with_uuid(uuid);
1305         if (info == NULL)
1306                 return BLUETOOTH_ERROR_INVALID_PARAM;
1307
1308         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid);
1309         _bt_unregister_profile(info->path);
1310
1311         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
1312         free_rfcomm_info(info);
1313
1314         return BLUETOOTH_ERROR_NONE;
1315 #else
1316         return BLUETOOTH_ERROR_NOT_SUPPORT;
1317 #endif
1318 }
1319
1320 BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd)
1321 {
1322 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1323         rfcomm_info_t *info;
1324         rfcomm_conn_t *conn;
1325
1326         char address[20];
1327
1328         BT_INFO(" ### Disconnect RFCOMM server");
1329         if (socket_fd < 0) {
1330                 BT_ERR("Invalid FD");
1331                 return BLUETOOTH_ERROR_INVALID_PARAM;
1332         }
1333
1334         info = __find_rfcomm_info_with_fd(socket_fd);
1335         if (info == NULL)
1336                 return BLUETOOTH_ERROR_INVALID_PARAM;
1337
1338         conn = __find_rfcomm_conn_with_fd(info, socket_fd);
1339         if (conn == NULL)
1340                 return BLUETOOTH_ERROR_INVALID_PARAM;
1341
1342         if (conn->watch_id == 0 || conn->disconnected)
1343                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1344
1345         close(conn->fd);
1346         conn->disconnected = TRUE;
1347
1348         _bt_convert_addr_type_to_string(address, conn->addr.addr);
1349
1350         BT_DBG("Address %s", address);
1351         _bt_disconnect_ext_profile(address, info->path);
1352
1353         if (info->disconnect_idle_id == 0)
1354                 info->disconnect_idle_id = g_idle_add(
1355                                 (GSourceFunc)__rfcomm_server_disconnect, info);
1356         BT_DBG("-");
1357
1358         return BLUETOOTH_ERROR_NONE;
1359 #else
1360         rfcomm_remote_client_info_t *client_info;
1361
1362         BT_CHECK_ENABLED(return);
1363
1364         BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>");
1365         if (socket_fd < 0) {
1366                 BT_ERR("Invalid FD");
1367                 return BLUETOOTH_ERROR_INVALID_PARAM;
1368         }
1369
1370         client_info = __get_rfcomm_rem_client_info_with_fd(socket_fd);
1371         if (!client_info) {
1372                 BT_ERR("client_info not found for socket_fd: %d", socket_fd);
1373                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1374         }
1375
1376         if (client_info->sock_fd) {
1377                 shutdown(client_info->sock_fd, SHUT_RDWR);
1378                 close(client_info->sock_fd);
1379                 client_info->sock_fd = -1;
1380         }
1381
1382         return BLUETOOTH_ERROR_NONE;
1383 #endif
1384 }
1385
1386 BT_EXPORT_API gboolean bluetooth_rfcomm_is_server_uuid_available(const char *uuid)
1387 {
1388         int result;
1389         gboolean available = TRUE;
1390         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
1391
1392         retv_if(uuid == NULL, FALSE);
1393         retv_if(bluetooth_check_adapter() ==
1394                                 BLUETOOTH_ADAPTER_DISABLED, FALSE);
1395
1396         BT_INIT_PARAMS();
1397         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1398
1399         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
1400         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
1401
1402         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_IS_UUID_AVAILABLE,
1403                 in_param1, in_param2, in_param3, in_param4, &out_param);
1404
1405         BT_DBG("result: %x", result);
1406
1407         if (result == BLUETOOTH_ERROR_NONE)
1408                 available = g_array_index(out_param, gboolean, 0);
1409
1410         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1411
1412         BT_DBG("available: %d", available);
1413
1414         return available;
1415 }
1416
1417 BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(const bluetooth_device_address_t *device_address, gboolean *connected)
1418 {
1419 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1420         GSList *l;
1421         GSList *ll;
1422         rfcomm_info_t *info;
1423         rfcomm_conn_t *conn;
1424 #else
1425         char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
1426         rfcomm_remote_client_info_t *info;
1427 #endif
1428
1429         BT_CHECK_PARAMETER(device_address, return);
1430         BT_CHECK_PARAMETER(connected, return);
1431
1432         *connected = FALSE;
1433
1434 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1435         for (l = rfcomm_nodes; l; l = l->next) {
1436                 info = l->data;
1437
1438                 if (info == NULL || info->rfcomm_conns == NULL)
1439                         continue;
1440
1441                 for (ll = info->rfcomm_conns; ll; ll = ll->next) {
1442                         conn = ll->data;
1443
1444                         if (memcmp(device_address, &conn->addr,
1445                                         sizeof(bluetooth_device_address_t)))
1446                                 continue;
1447
1448                         *connected = TRUE;
1449                         return BLUETOOTH_ERROR_NONE;
1450                 }
1451         }
1452
1453         return BLUETOOTH_ERROR_NONE;
1454 #else
1455         _bt_convert_addr_type_to_string(input_addr, (unsigned char *)device_address->addr);
1456         info = __get_rfcomm_rem_client_info_with_addr(input_addr);
1457         if (info)
1458                 *connected = TRUE;
1459
1460         return BLUETOOTH_ERROR_NONE;
1461 #endif
1462 }
1463
1464 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int id, int max_pending_connection)
1465 {
1466 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1467         rfcomm_info_t *info;
1468 #else
1469         rfcomm_server_info_t *server_info;
1470 #endif
1471
1472         BT_CHECK_ENABLED(return);
1473         if (id < 0) {
1474                 BT_ERR("Invalid ID");
1475                 return BLUETOOTH_ERROR_INVALID_PARAM;
1476         }
1477
1478         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1479                 BT_ERR("Not allow to use SPP profile");
1480                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1481         }
1482
1483 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1484         BT_INFO("RFCOMM Listen & accept from app");
1485
1486         info = __find_rfcomm_info_with_id(id);
1487         if (info == NULL)
1488                 return BLUETOOTH_ERROR_INVALID_PARAM;
1489
1490         bt_register_profile_info_t profile_info;
1491         int result;
1492
1493         profile_info.authentication = TRUE;
1494         profile_info.authorization = TRUE;
1495         profile_info.obj_path = info->path;
1496         profile_info.role = NULL;
1497         profile_info.service = info->uuid;
1498         profile_info.uuid = info->uuid;
1499
1500         BT_INFO("uuid %s", profile_info.uuid);
1501         result = _bt_register_profile(&profile_info, TRUE);
1502
1503         return result;
1504 #else
1505         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
1506
1507         server_info = __get_rfcomm_server_info_with_id(id);
1508         if (!server_info) {
1509                 BT_ERR("server_info not found for id: %d", id);
1510                 return BLUETOOTH_ERROR_INVALID_PARAM;
1511         }
1512
1513         if (server_info->server_fd >= 0) {
1514                 BT_ERR("server already listining");
1515                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1516         }
1517
1518         server_info->max_pending_conn = max_pending_connection;
1519         server_info->auto_accept = TRUE;
1520
1521         return __rfcomm_listen(server_info, true);
1522 #endif
1523 }
1524
1525 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept_ex(const char *uuid,
1526                                         int max_pending_connection,
1527                                         const char *bus_name, const char *path)
1528 {
1529 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1530         rfcomm_info_t *info;
1531
1532         BT_CHECK_ENABLED(return);
1533
1534         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1535                 BT_ERR("Not allow to use SPP profile");
1536                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1537         }
1538
1539         BT_INFO("RFCOMM Listen & accept from app");
1540
1541         info = __find_rfcomm_info_with_uuid(uuid);
1542         if (info == NULL)
1543                 return BLUETOOTH_ERROR_INVALID_PARAM;
1544
1545         bt_register_profile_info_t profile_info;
1546         int result;
1547
1548         profile_info.authentication = TRUE;
1549         profile_info.authorization = TRUE;
1550         profile_info.obj_path = info->path;
1551         profile_info.role = NULL;
1552         profile_info.service = info->uuid;
1553         profile_info.uuid = info->uuid;
1554
1555         BT_INFO("uuid %s", profile_info.uuid);
1556         result = _bt_register_profile_ex(&profile_info, TRUE, bus_name, path);
1557
1558         return result;
1559 #else
1560         return BLUETOOTH_ERROR_NOT_SUPPORT;
1561 #endif
1562 }
1563
1564 BT_EXPORT_API int bluetooth_rfcomm_listen(int id, int max_pending_connection)
1565 {
1566 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1567         rfcomm_info_t *info;
1568 #else
1569         rfcomm_server_info_t *server_info;
1570 #endif
1571
1572         BT_CHECK_ENABLED(return);
1573         if (id < 0) {
1574                 BT_ERR("Invalid ID");
1575                 return BLUETOOTH_ERROR_INVALID_PARAM;
1576         }
1577
1578         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1579                 BT_ERR("Not allow to use SPP profile");
1580                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1581         }
1582
1583 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1584         BT_INFO("RFCOMM Listen");
1585
1586         info = __find_rfcomm_info_with_id(id);
1587         if (info == NULL)
1588                 return BLUETOOTH_ERROR_INVALID_PARAM;
1589
1590         bt_register_profile_info_t profile_info;
1591         int result;
1592
1593         profile_info.authentication = TRUE;
1594         profile_info.authorization = TRUE;
1595         profile_info.obj_path = info->path;
1596         profile_info.role = NULL;
1597         profile_info.service = info->uuid;
1598         profile_info.uuid = info->uuid;
1599         BT_INFO("UUID %s", info->uuid);
1600         BT_INFO("PATH %s", info->path);
1601         result = _bt_register_profile_platform(&profile_info, TRUE);
1602         if (result != BLUETOOTH_ERROR_NONE)
1603                 return result;
1604
1605         return _bt_register_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid,
1606                                                 info->path, id);
1607
1608 #else
1609         BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>");
1610
1611         server_info = __get_rfcomm_server_info_with_id(id);
1612         if (!server_info) {
1613                 BT_ERR("server_info not found for id: %d", id);
1614                 return BLUETOOTH_ERROR_INVALID_PARAM;
1615         }
1616
1617         if (server_info->server_fd >= 0) {
1618                 BT_ERR("server already listining");
1619                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1620         }
1621
1622         server_info->max_pending_conn = max_pending_connection;
1623         server_info->auto_accept = FALSE;
1624         return __rfcomm_listen(server_info, false);
1625 #endif
1626 }
1627
1628 BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd)
1629 {
1630         int result;
1631 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1632 #else
1633         rfcomm_server_info_t *server_info;
1634 #endif
1635
1636         BT_CHECK_ENABLED(return);
1637
1638         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1639                 BT_ERR("Not allow to use SPP profile");
1640                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1641         }
1642
1643         if (server_fd < 0) {
1644                 BT_ERR("Invalid FD");
1645                 return BLUETOOTH_ERROR_INVALID_PARAM;
1646         }
1647
1648         BT_INIT_PARAMS();
1649         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1650
1651 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1652         g_array_append_vals(in_param1, &server_fd, sizeof(int));
1653 #else
1654         server_info = __get_rfcomm_server_info_with_id(server_fd);
1655         if (!server_info) {
1656                 BT_ERR("No server with fd: %d", server_fd);
1657                 return BLUETOOTH_ERROR_INVALID_PARAM;
1658         }
1659
1660         g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
1661 #endif
1662
1663         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_ACCEPT_CONNECTION,
1664                 in_param1, in_param2, in_param3, in_param4, &out_param);
1665
1666         BT_DBG("result: %x", result);
1667
1668         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1669
1670         return result;
1671 }
1672
1673 BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd)
1674 {
1675         int result;
1676 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1677 #else
1678         rfcomm_server_info_t *server_info;
1679 #endif
1680
1681         BT_CHECK_ENABLED(return);
1682
1683         if (server_fd < 0) {
1684                 BT_ERR("Invalid FD");
1685                 return BLUETOOTH_ERROR_INVALID_PARAM;
1686         }
1687
1688         BT_INFO("+");
1689
1690         BT_INIT_PARAMS();
1691         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1692
1693 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1694         g_array_append_vals(in_param1, &server_fd, sizeof(int));
1695 #else
1696         server_info = __get_rfcomm_server_info_with_id(server_fd);
1697         if (!server_info) {
1698                 BT_ERR("No server with fd: %d", server_fd);
1699                 return BLUETOOTH_ERROR_INVALID_PARAM;
1700         }
1701
1702         g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
1703 #endif
1704         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REJECT_CONNECTION,
1705                 in_param1, in_param2, in_param3, in_param4, &out_param);
1706
1707         BT_DBG("result: %x", result);
1708
1709         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1710
1711         return result;
1712 }
1713