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