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