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