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