Merge tizen_next codes into tizen branch
[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)
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         g_array_append_vals(in_param1, server_info->uuid, BLUETOOTH_UUID_STRING_MAX);
1065         result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
1066                         in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
1067
1068         BT_DBG("result: %x", result);
1069         if (result != BLUETOOTH_ERROR_NONE) {
1070                 BT_ERR("Fail to send request");
1071                 return result;
1072         } else if (NULL == out_fd_list) {
1073                 BT_ERR("out_fd_list is NULL");
1074                 return BLUETOOTH_ERROR_INTERNAL;
1075         } else {
1076                 int *fd_list_array;
1077                 int len = 0;
1078
1079                 if (!out_fd_list)
1080                         return BLUETOOTH_ERROR_INTERNAL;
1081
1082                 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
1083                 BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
1084                 server_info->server_fd = fd_list_array[0];
1085                 BT_INFO("Socket fd: %d", server_info->server_fd);
1086
1087                 g_free(fd_list_array);
1088                 g_object_unref(out_fd_list);
1089         }
1090
1091         server_io = g_io_channel_unix_new(server_info->server_fd);
1092         g_io_channel_set_encoding(server_io, NULL, NULL);
1093         g_io_channel_set_flags(server_io, G_IO_FLAG_NONBLOCK, NULL);
1094         server_info->watch_id = g_io_add_watch(server_io,
1095                         G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
1096                         __new_connection_request_cb, server_info);
1097         g_io_channel_unref(server_io);
1098
1099         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1100
1101         return BLUETOOTH_ERROR_NONE;
1102 }
1103 #endif
1104
1105 BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid)
1106 {
1107 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1108         rfcomm_info_t *info;
1109 #else
1110         rfcomm_server_info_t *server_info;
1111 #endif
1112
1113         BT_CHECK_ENABLED(return);
1114         BT_CHECK_PARAMETER(uuid, return);
1115         BT_INFO("UUID Provided %s", uuid);
1116
1117         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET)
1118                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1119                 BT_ERR("Don't have a privilege to use this API");
1120                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1121         }
1122
1123 #ifdef TIZEN_FEATURE_BT_DPM
1124         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1125                 BT_ERR("Not allow to use SPP profile");
1126                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1127         }
1128 #endif
1129
1130 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1131         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
1132         info = __register_method();
1133         if (info == NULL)
1134                 return -1;
1135
1136         info->uuid = g_strdup(uuid);
1137         info->disconnect_idle_id = 0;
1138         return info->id;
1139 #else
1140         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
1141
1142         server_info = __get_rfcomm_server_info_with_uuid(uuid);
1143         if (!server_info) {
1144                 server_info = g_malloc0(sizeof(rfcomm_server_info_t));
1145                 g_strlcpy(server_info->uuid, uuid, BLUETOOTH_UUID_STRING_MAX);
1146                 server_info->server_id = __rfcomm_assign_server_id();
1147                 server_info->server_fd = -1;
1148                 server_info->watch_id = -1;
1149                 server_info->auto_accept = FALSE;
1150                 rfcomm_servers = g_slist_append(rfcomm_servers, server_info);
1151         }
1152         return server_info->server_id;
1153 #endif
1154 }
1155
1156 BT_EXPORT_API int bluetooth_rfcomm_create_socket_ex(const char *uuid, const char *bus_name, const char *path)
1157 {
1158 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1159         rfcomm_info_t *info;
1160
1161         BT_CHECK_ENABLED(return);
1162         BT_CHECK_PARAMETER(path, return);
1163         BT_INFO("PATH Provided %s", path);
1164
1165         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET_EX)
1166                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1167                 BT_ERR("Don't have a privilege to use this API");
1168                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1169         }
1170
1171 #ifdef TIZEN_FEATURE_BT_DPM
1172         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1173                 BT_ERR("Not allow to use SPP profile");
1174                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1175         }
1176 #endif
1177
1178         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
1179         info = __register_method_2(path, bus_name);
1180         if (info == NULL)
1181                 return BLUETOOTH_ERROR_IN_PROGRESS;
1182         info->uuid = g_strdup(uuid);
1183         info->disconnect_idle_id = 0;
1184
1185         return BLUETOOTH_ERROR_NONE;
1186 #else
1187         return BLUETOOTH_ERROR_NOT_SUPPORT;
1188 #endif
1189 }
1190
1191
1192 BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int id)
1193 {
1194 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1195         rfcomm_info_t *info;
1196 #else
1197         rfcomm_server_info_t *server_info;
1198 #endif
1199
1200         BT_CHECK_ENABLED(return);
1201
1202         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET)
1203                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1204                 BT_ERR("Don't have a privilege to use this API");
1205                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1206         }
1207
1208         if (id < 0) {
1209                 BT_ERR("Invalid ID");
1210                 return BLUETOOTH_ERROR_INVALID_PARAM;
1211         }
1212
1213 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1214         BT_INFO("RFCOMM Remove socket request from app, ID [%d]", id);
1215
1216         info = __find_rfcomm_info_with_id(id);
1217         if (info == NULL)
1218                 return BLUETOOTH_ERROR_INVALID_PARAM;
1219
1220         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid);
1221         _bt_unregister_profile(info->path);
1222
1223         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
1224         free_rfcomm_info(info);
1225
1226         return BLUETOOTH_ERROR_NONE;
1227 #else
1228         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd);
1229
1230         server_info = __get_rfcomm_server_info_with_id(id);
1231         if (!server_info) {
1232                 BT_ERR("server_info not found for socket_fd: %d", id);
1233                 return BLUETOOTH_ERROR_INVALID_PARAM;
1234         }
1235
1236         __remove_rfcomm_server(server_info);
1237
1238         return BLUETOOTH_ERROR_NONE;
1239 #endif
1240 }
1241
1242 BT_EXPORT_API int bluetooth_rfcomm_remove_socket_ex(const char *uuid)
1243 {
1244 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1245         rfcomm_info_t *info;
1246
1247         BT_CHECK_ENABLED(return);
1248
1249         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET)
1250                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1251                 BT_ERR("Don't have a privilege to use this API");
1252                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1253         }
1254
1255         BT_INFO("RFCOMM Remove socket request from app, uuid=[%s]", uuid);
1256
1257         info = __find_rfcomm_info_with_uuid(uuid);
1258         if (info == NULL)
1259                 return BLUETOOTH_ERROR_INVALID_PARAM;
1260
1261         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid);
1262         _bt_unregister_profile(info->path);
1263
1264         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
1265         free_rfcomm_info(info);
1266
1267         return BLUETOOTH_ERROR_NONE;
1268 #else
1269         return BLUETOOTH_ERROR_NOT_SUPPORT;
1270 #endif
1271 }
1272
1273 BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd)
1274 {
1275 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1276         rfcomm_info_t *info;
1277         rfcomm_conn_t *conn;
1278
1279         char address[20];
1280
1281         BT_INFO("### Disconnect RFCOMM server");
1282         if (socket_fd < 0) {
1283                 BT_ERR("Invalid FD");
1284                 return BLUETOOTH_ERROR_INVALID_PARAM;
1285         }
1286
1287         info = __find_rfcomm_info_with_fd(socket_fd);
1288         if (info == NULL)
1289                 return BLUETOOTH_ERROR_INVALID_PARAM;
1290
1291         conn = __find_rfcomm_conn_with_fd(info, socket_fd);
1292         if (conn == NULL)
1293                 return BLUETOOTH_ERROR_INVALID_PARAM;
1294
1295         if (conn->watch_id == 0 || conn->disconnected)
1296                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1297
1298         close(conn->fd);
1299         conn->disconnected = TRUE;
1300
1301         _bt_convert_addr_type_to_string(address, conn->addr.addr);
1302
1303         BT_DBG("Address %s", address);
1304         _bt_disconnect_ext_profile(address, info->path);
1305
1306         if (info->disconnect_idle_id == 0)
1307                 info->disconnect_idle_id = g_idle_add(
1308                                 (GSourceFunc)__rfcomm_server_disconnect, info);
1309         BT_DBG("-");
1310
1311         return BLUETOOTH_ERROR_NONE;
1312 #else
1313         rfcomm_remote_client_info_t *client_info;
1314
1315         BT_CHECK_ENABLED(return);
1316
1317         BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>");
1318         if (socket_fd < 0) {
1319                 BT_ERR("Invalid FD");
1320                 return BLUETOOTH_ERROR_INVALID_PARAM;
1321         }
1322
1323         client_info = __get_rfcomm_rem_client_info_with_fd(socket_fd);
1324         if (!client_info) {
1325                 BT_ERR("client_info not found for socket_fd: %d", socket_fd);
1326                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1327         }
1328
1329         if (client_info->sock_fd) {
1330                 shutdown(client_info->sock_fd, SHUT_RDWR);
1331                 close(client_info->sock_fd);
1332                 client_info->sock_fd = -1;
1333         }
1334
1335         return BLUETOOTH_ERROR_NONE;
1336 #endif
1337 }
1338
1339 BT_EXPORT_API gboolean bluetooth_rfcomm_is_server_uuid_available(const char *uuid)
1340 {
1341         int result;
1342         gboolean available = TRUE;
1343         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
1344
1345         retv_if(uuid == NULL, FALSE);
1346         retv_if(bluetooth_check_adapter() ==
1347                                 BLUETOOTH_ADAPTER_DISABLED, FALSE);
1348
1349         BT_INIT_PARAMS();
1350         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1351
1352         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
1353         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
1354
1355         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_IS_UUID_AVAILABLE,
1356                 in_param1, in_param2, in_param3, in_param4, &out_param);
1357
1358         BT_DBG("result: %x", result);
1359
1360         if (result == BLUETOOTH_ERROR_NONE)
1361                 available = g_array_index(out_param, gboolean, 0);
1362
1363         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1364
1365         BT_DBG("available: %d", available);
1366
1367         return available;
1368 }
1369
1370 BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(const bluetooth_device_address_t *device_address, gboolean *connected)
1371 {
1372 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1373         GSList *l;
1374         GSList *ll;
1375         rfcomm_info_t *info;
1376         rfcomm_conn_t *conn;
1377 #else
1378         char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
1379         rfcomm_remote_client_info_t *info;
1380 #endif
1381
1382         BT_CHECK_PARAMETER(device_address, return);
1383         BT_CHECK_PARAMETER(connected, return);
1384
1385         *connected = FALSE;
1386
1387 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1388         for (l = rfcomm_nodes; l; l = l->next) {
1389                 info = l->data;
1390
1391                 if (info == NULL || info->rfcomm_conns == NULL)
1392                         continue;
1393
1394                 for (ll = info->rfcomm_conns; ll; ll = ll->next) {
1395                         conn = ll->data;
1396
1397                         if (memcmp(device_address, &conn->addr,
1398                                         sizeof(bluetooth_device_address_t)))
1399                                 continue;
1400
1401                         *connected = TRUE;
1402                         return BLUETOOTH_ERROR_NONE;
1403                 }
1404         }
1405
1406         return BLUETOOTH_ERROR_NONE;
1407 #else
1408         _bt_convert_addr_type_to_string(input_addr, (unsigned char *)device_address->addr);
1409         info = __get_rfcomm_rem_client_info_with_addr(input_addr);
1410         if (info)
1411                 *connected = TRUE;
1412
1413         return BLUETOOTH_ERROR_NONE;
1414 #endif
1415 }
1416
1417 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int id, int max_pending_connection)
1418 {
1419 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1420         rfcomm_info_t *info;
1421 #else
1422         rfcomm_server_info_t *server_info;
1423 #endif
1424
1425         BT_CHECK_ENABLED(return);
1426         if (id < 0) {
1427                 BT_ERR("Invalid ID");
1428                 return BLUETOOTH_ERROR_INVALID_PARAM;
1429         }
1430
1431 #ifdef TIZEN_FEATURE_BT_DPM
1432         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1433                 BT_ERR("Not allow to use SPP profile");
1434                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1435         }
1436 #endif
1437
1438 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1439         BT_INFO("RFCOMM Listen & accept from app");
1440
1441         info = __find_rfcomm_info_with_id(id);
1442         if (info == NULL)
1443                 return BLUETOOTH_ERROR_INVALID_PARAM;
1444
1445         bt_register_profile_info_t profile_info;
1446         int result;
1447
1448         profile_info.authentication = TRUE;
1449         profile_info.authorization = TRUE;
1450         profile_info.obj_path = info->path;
1451         profile_info.role = NULL;
1452         profile_info.service = info->uuid;
1453         profile_info.uuid = info->uuid;
1454
1455         BT_INFO("uuid %s", profile_info.uuid);
1456         result = _bt_register_profile(&profile_info, TRUE);
1457
1458         return result;
1459 #else
1460         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
1461
1462         server_info = __get_rfcomm_server_info_with_id(id);
1463         if (!server_info) {
1464                 BT_ERR("server_info not found for id: %d", id);
1465                 return BLUETOOTH_ERROR_INVALID_PARAM;
1466         }
1467
1468         if (server_info->server_fd >= 0) {
1469                 BT_ERR("server already listining");
1470                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1471         }
1472
1473         server_info->max_pending_conn = max_pending_connection;
1474         server_info->auto_accept = TRUE;
1475
1476         return __rfcomm_listen(server_info);
1477 #endif
1478 }
1479
1480 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept_ex(const char *uuid,
1481                                         int max_pending_connection,
1482                                         const char *bus_name, const char *path)
1483 {
1484 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1485         rfcomm_info_t *info;
1486
1487         BT_CHECK_ENABLED(return);
1488
1489 #ifdef TIZEN_FEATURE_BT_DPM
1490         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1491                 BT_ERR("Not allow to use SPP profile");
1492                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1493         }
1494 #endif
1495
1496         BT_INFO("RFCOMM Listen & accept from app");
1497
1498         info = __find_rfcomm_info_with_uuid(uuid);
1499         if (info == NULL)
1500                 return BLUETOOTH_ERROR_INVALID_PARAM;
1501
1502         bt_register_profile_info_t profile_info;
1503         int result;
1504
1505         profile_info.authentication = TRUE;
1506         profile_info.authorization = TRUE;
1507         profile_info.obj_path = info->path;
1508         profile_info.role = NULL;
1509         profile_info.service = info->uuid;
1510         profile_info.uuid = info->uuid;
1511
1512         BT_INFO("uuid %s", profile_info.uuid);
1513         result = _bt_register_profile_ex(&profile_info, TRUE, bus_name, path);
1514
1515         return result;
1516 #else
1517         return BLUETOOTH_ERROR_NOT_SUPPORT;
1518 #endif
1519 }
1520
1521 BT_EXPORT_API int bluetooth_rfcomm_listen(int id, int max_pending_connection)
1522 {
1523 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1524         rfcomm_info_t *info;
1525 #else
1526         rfcomm_server_info_t *server_info;
1527 #endif
1528
1529         BT_CHECK_ENABLED(return);
1530         if (id < 0) {
1531                 BT_ERR("Invalid ID");
1532                 return BLUETOOTH_ERROR_INVALID_PARAM;
1533         }
1534
1535 #ifdef TIZEN_FEATURE_BT_DPM
1536         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1537                 BT_ERR("Not allow to use SPP profile");
1538                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1539         }
1540 #endif
1541
1542 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1543         BT_INFO("RFCOMM Listen");
1544
1545         info = __find_rfcomm_info_with_id(id);
1546         if (info == NULL)
1547                 return BLUETOOTH_ERROR_INVALID_PARAM;
1548
1549         bt_register_profile_info_t profile_info;
1550         int result;
1551
1552         profile_info.authentication = TRUE;
1553         profile_info.authorization = TRUE;
1554         profile_info.obj_path = info->path;
1555         profile_info.role = NULL;
1556         profile_info.service = info->uuid;
1557         profile_info.uuid = info->uuid;
1558         BT_INFO("UUID %s", info->uuid);
1559         BT_INFO("PATH %s", info->path);
1560         result = _bt_register_profile_platform(&profile_info, TRUE);
1561         if (result != BLUETOOTH_ERROR_NONE)
1562                 return result;
1563
1564         return _bt_register_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid,
1565                                                 info->path, id);
1566
1567 #else
1568         BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>");
1569
1570         server_info = __get_rfcomm_server_info_with_id(id);
1571         if (!server_info) {
1572                 BT_ERR("server_info not found for id: %d", id);
1573                 return BLUETOOTH_ERROR_INVALID_PARAM;
1574         }
1575
1576         if (server_info->server_fd >= 0) {
1577                 BT_ERR("server already listining");
1578                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1579         }
1580
1581         server_info->max_pending_conn = max_pending_connection;
1582         server_info->auto_accept = FALSE;
1583         return __rfcomm_listen(server_info);
1584 #endif
1585 }
1586
1587 BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd)
1588 {
1589         int result;
1590 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1591 #else
1592         rfcomm_server_info_t *server_info;
1593 #endif
1594
1595         BT_CHECK_ENABLED(return);
1596
1597 #ifdef TIZEN_FEATURE_BT_DPM
1598         if (_bt_check_dpm(BT_DPM_SPP, NULL) == BT_DPM_RESTRICTED) {
1599                 BT_ERR("Not allow to use SPP profile");
1600                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
1601         }
1602 #endif
1603
1604         if (server_fd < 0) {
1605                 BT_ERR("Invalid FD");
1606                 return BLUETOOTH_ERROR_INVALID_PARAM;
1607         }
1608
1609         BT_INIT_PARAMS();
1610         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1611
1612 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1613         g_array_append_vals(in_param1, &server_fd, sizeof(int));
1614 #else
1615         server_info = __get_rfcomm_server_info_with_id(server_fd);
1616         if (!server_info) {
1617                 BT_ERR("No server with fd: %d", server_fd);
1618                 return BLUETOOTH_ERROR_INVALID_PARAM;
1619         }
1620
1621         g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
1622 #endif
1623
1624         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_ACCEPT_CONNECTION,
1625                 in_param1, in_param2, in_param3, in_param4, &out_param);
1626
1627         BT_DBG("result: %x", result);
1628
1629         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1630
1631         return result;
1632 }
1633
1634 BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd)
1635 {
1636         int result;
1637 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1638 #else
1639         rfcomm_server_info_t *server_info;
1640 #endif
1641
1642         BT_CHECK_ENABLED(return);
1643
1644         if (server_fd < 0) {
1645                 BT_ERR("Invalid FD");
1646                 return BLUETOOTH_ERROR_INVALID_PARAM;
1647         }
1648
1649         BT_INFO("+");
1650
1651         BT_INIT_PARAMS();
1652         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1653
1654 #ifdef TIZEN_FEATURE_BT_RFCOMM_DIRECT
1655         g_array_append_vals(in_param1, &server_fd, sizeof(int));
1656 #else
1657         server_info = __get_rfcomm_server_info_with_id(server_fd);
1658         if (!server_info) {
1659                 BT_ERR("No server with fd: %d", server_fd);
1660                 return BLUETOOTH_ERROR_INVALID_PARAM;
1661         }
1662
1663         g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
1664 #endif
1665         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REJECT_CONNECTION,
1666                 in_param1, in_param2, in_param3, in_param4, &out_param);
1667
1668         BT_DBG("result: %x", result);
1669
1670         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1671
1672         return result;
1673 }
1674