Fix infinite callback issue in EOF status
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-l2cap-le-server.c
1 /*
2  * Copyright (c) 2022 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 #include <sys/socket.h>
20 #include <gio/gunixfdlist.h>
21 #include "bluetooth-api.h"
22 #include "bt-internal-types.h"
23 #include "bt-common.h"
24 #include "bt-request-sender.h"
25 #include "bt-event-handler.h"
26
27 #define SOCK_INT_LEN 4
28
29 #ifdef TIZEN_BLUEDROID_PORTING
30 #define BLUETOOTH_SOCK_CONNECT_INFO_LEN 20
31 #else
32 #define BLUETOOTH_SOCK_CONNECT_INFO_LEN 16
33 #endif
34
35 #define BT_L2CAP_LE_SERVER_ID_MAX 254
36
37 typedef struct {
38         char addr[BT_ADDRESS_STRING_SIZE];
39         int sock_fd;
40         int watch_id;
41         int server_id;
42 } l2cap_le_remote_client_info_t;
43
44 typedef struct {
45         int psm;
46         int server_id;
47         int server_fd;
48         int watch_id;
49         int max_pending_conn;
50         gboolean auto_accept;
51         char pending_addr[BT_ADDRESS_STRING_SIZE];
52         GSList *conn_list;
53 } l2cap_le_server_info_t;
54
55 static GSList *l2cap_le_servers;
56 static gboolean id_used[BT_L2CAP_LE_SERVER_ID_MAX];
57 static int latest_id = 0;
58
59 int __l2cap_le_assign_server_id(void)
60 {
61         int index;
62
63         BT_DBG("latest_id: %d", latest_id);
64
65         index = latest_id + 1;
66         if (index >= BT_L2CAP_LE_SERVER_ID_MAX)
67                 index = 0;
68
69         BT_DBG("index: %d", index);
70
71         while (id_used[index] == TRUE) {
72                 if (index == latest_id) {
73                         /* No available ID */
74                         BT_ERR("All request ID is used");
75                         return -1;
76                 }
77
78                 index++;
79                 if (index >= BT_L2CAP_LE_SERVER_ID_MAX)
80                         index = 0;
81         }
82
83         latest_id = index;
84         id_used[index] = TRUE;
85         BT_DBG("Assigned Id: %d", latest_id);
86
87         return latest_id;
88 }
89
90 void __l2cap_le_delete_server_id(int id)
91 {
92         ret_if(id >= BT_L2CAP_LE_SERVER_ID_MAX);
93         ret_if(id < 0);
94
95         id_used[id] = FALSE;
96
97         /* Next server will use this ID */
98         latest_id = id - 1;
99 }
100
101 static l2cap_le_server_info_t *__get_l2cap_le_server_info_from_psm(int psm)
102 {
103         GSList *l;
104
105         if (psm < 0)
106                 return NULL;
107
108         for (l = l2cap_le_servers; l != NULL; l = l->next) {
109                 l2cap_le_server_info_t *info = l->data;
110
111                 if (info->psm == psm) {
112                         BT_INFO("server found with psm %d fd %d", info->psm,
113                                         info->server_fd);
114                         return info;
115                 }
116         }
117
118         return NULL;
119 }
120
121 int _get_l2cap_le_server_id(int psm, gboolean *auto_accept)
122 {
123         l2cap_le_server_info_t *server_info;
124
125         server_info = __get_l2cap_le_server_info_from_psm(psm);
126         if (!server_info)
127                 return -1;
128
129         *auto_accept = server_info->auto_accept;
130         return server_info->server_id;
131 }
132
133 static l2cap_le_server_info_t *__get_l2cap_le_server_info_with_id(int server_id)
134 {
135         GSList *l;
136
137         for (l = l2cap_le_servers; l != NULL; l = l->next) {
138                 l2cap_le_server_info_t *info = l->data;
139                 if (!info)
140                         continue;
141
142                 BT_DBG("info->server_fd: %d, sock_fd:%d", info->server_id, server_id);
143                 if (info->server_id == server_id)
144                         return info;
145         }
146
147         return NULL;
148 }
149
150 void _bt_l2cap_le_server_set_pending_conn(int server_id, char *address)
151 {
152         l2cap_le_server_info_t *server_info;
153
154         if (!address)
155                 return;
156
157         server_info = __get_l2cap_le_server_info_with_id(server_id);
158         if (!server_info)
159                 return;
160
161         g_strlcpy(server_info->pending_addr, address, BT_ADDRESS_STRING_SIZE);
162 }
163
164 static l2cap_le_remote_client_info_t *__get_l2cap_le_rem_client_info_with_fd(
165                                                 int sock_fd)
166 {
167         GSList *l;
168         GSList *l1;
169
170         for (l = l2cap_le_servers; l != NULL; l = l->next) {
171                 l2cap_le_server_info_t *info = l->data;
172
173                 if (!info)
174                         continue;
175
176                 for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) {
177                         l2cap_le_remote_client_info_t *client_info = l1->data;
178                         if (!client_info)
179                                 continue;
180
181                         if (client_info->sock_fd == sock_fd)
182                                 return client_info;
183                 }
184         }
185
186         return NULL;
187 }
188
189 static l2cap_le_remote_client_info_t *__get_l2cap_le_rem_client_info_with_addr(
190                                                 char *addr)
191 {
192         GSList *l;
193         GSList *l1;
194
195         retv_if(NULL == addr, NULL);
196
197         for (l = l2cap_le_servers; l != NULL; l = l->next) {
198                 l2cap_le_server_info_t *info = l->data;
199
200                 if (!info)
201                         continue;
202
203                 for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) {
204                         l2cap_le_remote_client_info_t *client_info = l1->data;
205                         if (!client_info)
206                                 continue;
207
208                         if (!strncasecmp(client_info->addr, addr, strlen(client_info->addr)))
209                                 return client_info;
210                 }
211         }
212
213         return NULL;
214 }
215
216 static void __remove_remote_client_info(l2cap_le_remote_client_info_t *rem_client)
217 {
218         BT_DBG("+");
219
220         if (rem_client == NULL)
221                 return;
222
223         if (0 < rem_client->sock_fd) {
224                 shutdown(rem_client->sock_fd, SHUT_RDWR);
225                 close(rem_client->sock_fd);
226         }
227
228         if (rem_client->watch_id > 0)
229                 g_source_remove(rem_client->watch_id);
230
231         g_free(rem_client);
232
233         BT_DBG("-");
234 }
235
236 static void __handle_l2cap_le_client_disconnected(
237                 l2cap_le_server_info_t *server_info, l2cap_le_remote_client_info_t *rem_client)
238 {
239         bluetooth_l2cap_le_disconnection_t disconn_info;
240         bt_event_info_t *event_info;
241
242         BT_DBG("+");
243
244         if (rem_client == NULL || server_info == NULL)
245                 return;
246
247         event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
248         if (event_info == NULL)
249                 return;
250
251         memset(&disconn_info, 0x00, sizeof(bluetooth_l2cap_le_disconnection_t));
252         disconn_info.device_role = L2CAP_LE_ROLE_SERVER;
253         disconn_info.psm = server_info->psm;
254         _bt_convert_addr_string_to_type(disconn_info.device_addr.addr, rem_client->addr);
255         BT_DBG("Disconnected FD [%d] PSM [%d]", rem_client->sock_fd, server_info->psm);
256         disconn_info.socket_fd = rem_client->sock_fd;
257
258         _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_DISCONNECTED,
259                         BLUETOOTH_ERROR_NONE, &disconn_info,
260                         event_info->cb, event_info->user_data);
261         BT_DBG("-");
262 }
263
264 static void __remove_l2cap_le_server(l2cap_le_server_info_t *info)
265 {
266         l2cap_le_remote_client_info_t *client_info;
267
268         BT_DBG("+");
269
270         if (!info)
271                 return;
272
273         l2cap_le_servers = g_slist_remove(l2cap_le_servers, info);
274         if (info->conn_list) {
275                 do {
276                         client_info = info->conn_list->data;
277                         if (!client_info)
278                                 break;
279
280                         BT_INFO("Disconnect l2cap_le client fd %d", client_info->sock_fd);
281                         info->conn_list = g_slist_remove(info->conn_list, client_info);
282                         __handle_l2cap_le_client_disconnected(info, client_info);
283                         __remove_remote_client_info(client_info);
284                 } while (info->conn_list);
285         }
286
287         if (info->server_fd) {
288                 shutdown(info->server_fd, SHUT_RDWR);
289                 close(info->server_fd);
290         }
291
292         if (info->watch_id)
293                 g_source_remove(info->watch_id);
294
295         __l2cap_le_delete_server_id(info->server_id);
296         g_free(info);
297
298         BT_DBG("-");
299 }
300
301 static void __connected_cb(l2cap_le_remote_client_info_t *client_info,
302                                         bt_event_info_t *event_info)
303 {
304         bluetooth_l2cap_le_connection_t conn_info;
305         l2cap_le_server_info_t *server_info;
306
307         server_info = __get_l2cap_le_server_info_with_id(client_info->server_id);
308         ret_if(server_info == NULL);
309
310         memset(&conn_info, 0x00, sizeof(bluetooth_l2cap_le_connection_t));
311         conn_info.device_role = L2CAP_LE_ROLE_SERVER;
312         conn_info.socket_fd = client_info->sock_fd;
313         conn_info.psm = server_info->psm;
314         _bt_convert_addr_string_to_type(conn_info.device_addr.addr, client_info->addr);
315         conn_info.server_id = server_info->server_id;
316
317         BT_INFO_C("Connected [L2CAP_LE Server] psm %d", server_info->psm);
318         _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_CONNECTED,
319                         BLUETOOTH_ERROR_NONE, &conn_info,
320                         event_info->cb, event_info->user_data);
321 }
322
323 static int __process_cmsg(struct msghdr *msg)
324 {
325         int sock_fd = -1;
326         struct cmsghdr *cmsg_ptr = NULL;
327
328         for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL;
329                         cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) {
330
331                 if (cmsg_ptr->cmsg_level != SOL_SOCKET)
332                         continue;
333
334                 if (cmsg_ptr->cmsg_type == SCM_RIGHTS) {
335                         int count
336                                 = ((cmsg_ptr->cmsg_len - CMSG_LEN(0)) / sizeof(int));
337
338                         if (count < 0) {
339                                 BT_ERR("ERROR Invalid count of descriptors");
340                                 continue;
341                         }
342
343                         memcpy(&sock_fd, CMSG_DATA(cmsg_ptr), sizeof(sock_fd));
344                         BT_DBG("Remote client fd: %d", sock_fd);
345                 }
346         }
347         return sock_fd;
348 }
349
350 static int __sock_read(int server_fd, char *buf, unsigned int len,
351                                         int *client_fd)
352 {
353         int ret;
354         struct msghdr msg;
355         struct iovec iv;
356         struct cmsghdr cmsgbuf[2 * sizeof(struct cmsghdr) + 4];
357         int retryCount = 0;
358
359         retv_if(0 > server_fd, -1);
360
361         BT_INFO("server_fd = %d", server_fd);
362
363         memset(&msg, 0, sizeof(msg));
364         memset(&iv, 0, sizeof(iv));
365
366         iv.iov_base = buf;
367         iv.iov_len = len;
368         msg.msg_iov = &iv;
369         msg.msg_iovlen = 1;
370         msg.msg_control = cmsgbuf;
371         msg.msg_controllen = sizeof(cmsgbuf);
372
373         for (retryCount = 0; retryCount < 5; retryCount++) {
374                 ret = recvmsg(server_fd, &msg, 0);
375                 BT_DBG("recvmsg ret = %d", ret);
376                 if (ret < 0 && errno == EINTR)
377                         continue;
378                 else
379                         break;
380         }
381
382         if (ret < 0 && errno == EPIPE) {
383                 /* End of stream, server listining stopped */
384                 BT_ERR("EOS errno: %d", errno);
385                 return 0;
386         }
387
388         if (ret < 0) {
389                 BT_ERR("Ret errno: %d", errno);
390                 return -1;
391         }
392
393         if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) {
394                 BT_ERR("MSG Flags errno: %d", errno);
395                 return -1;
396         }
397
398         if (ret >= 0 && client_fd) {
399                 BT_INFO("Connection received");
400                 *client_fd = __process_cmsg(&msg);
401                 if (*client_fd < 0)
402                         BT_ERR("Invalid client_fd received");
403         }
404
405         return ret;
406 }
407
408 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
409                                                 gpointer data)
410 {
411         char *buffer = NULL;
412         gsize len = 0;
413         int result = BLUETOOTH_ERROR_NONE;
414         bt_event_info_t *event_info;
415         bluetooth_l2cap_le_received_data_t data_r;
416         GIOStatus status = G_IO_STATUS_NORMAL;
417         GError *err = NULL;
418         l2cap_le_remote_client_info_t *client_info = data;
419         l2cap_le_server_info_t *server_info;
420
421         retv_if(client_info == NULL, FALSE);
422
423         server_info = __get_l2cap_le_server_info_with_id(client_info->server_id);
424
425         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
426                 BT_ERR_C("l2cap_le Server disconnected: %d", client_info->sock_fd);
427                 goto fail;
428         }
429
430         buffer = g_malloc0(BT_L2CAP_LE_BUFFER_LEN + 1);
431         g_io_channel_set_buffer_size(chan, BT_L2CAP_LE_BUFFER_LEN);
432         status = g_io_channel_read_chars(chan, buffer,
433                         BT_L2CAP_LE_BUFFER_LEN, &len, &err);
434         if (status != G_IO_STATUS_NORMAL) {
435                 BT_ERR("IO Channel read is failed with %d(%s)", status, _bt_print_gio_status(status));
436                 g_free(buffer);
437
438                 if (status == G_IO_STATUS_AGAIN)
439                         return TRUE;
440
441                 if (err) {
442                         BT_ERR("IO Channel read error [%s]", err->message);
443                         g_error_free(err);
444                 }
445                 goto fail;
446         }
447
448         if (len == 0) {
449                 BT_ERR("Length is zero, remote end hang up");
450                 g_free(buffer);
451                 goto fail;
452         }
453
454         BT_DBG("fd: %d, len: %zu, buffer: %s", client_info->sock_fd, len, buffer);
455
456         event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
457         if (event_info == NULL) {
458                 g_free(buffer);
459                 return TRUE;
460         }
461
462         data_r.socket_fd = client_info->sock_fd;
463         data_r.buffer_size = len;
464         data_r.buffer = buffer;
465
466         _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_DATA_RECEIVED,
467                         result, &data_r, event_info->cb, event_info->user_data);
468
469         g_free(buffer);
470         return TRUE;
471 fail:
472         BT_ERR("Failure occured, remove client connection");
473         if (server_info)
474                 server_info->conn_list = g_slist_remove(
475                         server_info->conn_list, client_info);
476         __handle_l2cap_le_client_disconnected(server_info, client_info);
477         client_info->watch_id = -1;
478         __remove_remote_client_info(client_info);
479         return FALSE;
480 }
481
482 static gboolean __new_connection_request_cb(GIOChannel *chan,
483                                                 GIOCondition cond, gpointer data)
484 {
485         int len;
486         int size;
487         int channel;
488         int status;
489         int client_fd;
490         char buf[BLUETOOTH_SOCK_CONNECT_INFO_LEN];
491         unsigned char addr[BT_ADDRESS_LENGTH_MAX];
492
493         bt_event_info_t *event_info;
494         GIOChannel *io;
495         l2cap_le_remote_client_info_t *rem_client;
496         l2cap_le_server_info_t *server_info = data;
497
498         if (!server_info) {
499                 BT_ERR("Server info is invalid");
500                 return FALSE;
501         }
502
503         if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
504                 BT_INFO("l2cap_le Server with fd:%d is closed with cond:0x%X",
505                                 server_info->server_fd, cond);
506                 goto err;
507         }
508
509         BT_INFO("Server fd: %d", server_info->server_fd);
510         len = __sock_read( server_info->server_fd, buf,
511                                         BLUETOOTH_SOCK_CONNECT_INFO_LEN, &client_fd);
512         BT_DBG("Socket Read len: %d", len);
513         if (len == 0) {
514                 BT_ERR("Listen stopped");
515                 goto err;
516         } else if (len != BLUETOOTH_SOCK_CONNECT_INFO_LEN) {
517                 BT_ERR("Read length is not same as socket info length");
518                 goto err;
519         }
520
521         len = 0;
522         /* Read size of data */
523         size = buf[len] | (buf[len + 1] << 8);
524         len += 2;
525
526         /* Read bluetooth address */
527         memcpy(addr, buf + len, BT_ADDRESS_LENGTH_MAX);
528         len += BT_ADDRESS_LENGTH_MAX;
529
530         /* Read channel */
531         channel = buf[len] | (buf[len + 1] << 8) |
532                 (buf[len + 2] << 16) | (buf[len + 3] << 24);
533         len += 4;
534
535         /* Read status */
536         status = buf[len] | (buf[len + 1] << 8) |
537                 (buf[len + 2] << 16) | (buf[len + 3] << 24);
538         len += 4;
539
540         BT_DBG("size: %d, channel: %d, status: %d", size, channel, status);
541
542         rem_client = g_malloc0(sizeof(l2cap_le_remote_client_info_t));
543         rem_client->sock_fd = client_fd;
544         rem_client->server_id = server_info->server_id;
545         _bt_convert_addr_type_to_string(rem_client->addr, addr);
546
547         BT_INFO("New client [%s] connection with socket_fd: %d, server_id: %d",
548                         rem_client->addr, rem_client->sock_fd, rem_client->server_id);
549
550         io = g_io_channel_unix_new(rem_client->sock_fd);
551         g_io_channel_set_encoding(io, NULL, NULL);
552         g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
553         rem_client->watch_id = g_io_add_watch(io,
554                         G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
555                         __data_received_cb, rem_client);
556         g_io_channel_unref(io);
557
558         server_info->conn_list = g_slist_append(server_info->conn_list, rem_client);
559         event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
560         if (event_info)
561                 __connected_cb(rem_client, event_info);
562
563         return TRUE;
564
565 err:
566         /* Error occurred, Remove l2cap_le server*/
567         BT_ERR("some error has occured, remove server");
568         __remove_l2cap_le_server(server_info);
569         return FALSE;
570 }
571
572 static int __getInt(char *buf, int len)
573 {
574         int val = 0;
575
576         if (len != SOCK_INT_LEN)
577                 return -1;
578
579         val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
580         return val;
581 }
582
583 static int __sock_wait_for_psm(int sock_fd)
584 {
585         int readlen = -1;
586         char buf[SOCK_INT_LEN];
587
588         readlen = __sock_read(sock_fd, buf, SOCK_INT_LEN, NULL);
589         return __getInt(buf, readlen);
590 }
591
592 static int __l2cap_le_listen(l2cap_le_server_info_t *server_info, bool accept)
593 {
594         int result;
595         GUnixFDList *out_fd_list = NULL;
596         GIOChannel *server_io;
597         int psm;
598
599         retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
600
601         BT_INIT_PARAMS();
602         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
603
604         psm = server_info->psm;
605         g_array_append_vals(in_param1, &psm, sizeof(int));
606
607         if (accept == false)
608                 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_L2CAP_LE_LISTEN,
609                                 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
610         else
611                 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_L2CAP_LE_LISTEN_AND_ACCEPT,
612                                 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
613
614         BT_INFO("result: %x", result);
615         if (result != BLUETOOTH_ERROR_NONE) {
616                 BT_ERR("Fail to send request");
617                 return result;
618         } else if (NULL == out_fd_list) {
619                 BT_ERR("out_fd_list is NULL");
620                 return BLUETOOTH_ERROR_INTERNAL;
621         } else {
622                 int *fd_list_array;
623                 int len = 0;
624
625                 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
626                 BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
627                 server_info->server_fd = fd_list_array[0];
628                 BT_INFO("Socket fd: %d", server_info->server_fd);
629
630                 g_free(fd_list_array);
631                 g_object_unref(out_fd_list);
632         }
633
634         psm = __sock_wait_for_psm(server_info->server_fd);
635         if (psm < 0) {
636                 BT_ERR("Reading PSM failed, psm %d", psm);
637                 return BLUETOOTH_ERROR_INTERNAL;
638         }
639         server_info->psm = psm;
640
641         BT_INFO("socket fd: %d psm %d", server_info->server_fd, server_info->psm);
642         server_io = g_io_channel_unix_new(server_info->server_fd);
643         g_io_channel_set_encoding(server_io, NULL, NULL);
644         g_io_channel_set_flags(server_io, G_IO_FLAG_NONBLOCK, NULL);
645         server_info->watch_id = g_io_add_watch(server_io,
646                         G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
647                         __new_connection_request_cb, server_info);
648         g_io_channel_unref(server_io);
649
650         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
651
652         return BLUETOOTH_ERROR_NONE;
653 }
654
655 BT_EXPORT_API int bluetooth_l2cap_le_create_socket(int psm)
656 {
657         l2cap_le_server_info_t *server_info;
658
659         BT_CHECK_ENABLED_LE(return);
660
661         if (_bt_check_privilege_le(BT_CHECK_PRIVILEGE, BT_L2CAP_LE_CREATE_SOCKET)
662                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
663                 BT_ERR("Don't have a privilege to use this API");
664                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
665         }
666
667         BT_INFO("<<<<<<<<< L2CAP_LE Create socket from app, psm %d >>>>>>>>>", psm);
668
669         server_info = __get_l2cap_le_server_info_from_psm(psm);
670         if (!server_info) {
671                 server_info = g_malloc0(sizeof(l2cap_le_server_info_t));
672                 server_info->psm = psm;
673                 server_info->server_id = __l2cap_le_assign_server_id();
674                 server_info->server_fd = -1;
675                 server_info->watch_id = -1;
676                 server_info->auto_accept = FALSE;
677                 l2cap_le_servers = g_slist_append(l2cap_le_servers, server_info);
678         }
679
680         return server_info->server_id;
681 }
682
683 BT_EXPORT_API int bluetooth_l2cap_le_remove_socket(int id)
684 {
685         l2cap_le_server_info_t *server_info;
686
687         BT_CHECK_ENABLED_LE(return);
688
689         if (_bt_check_privilege_le(BT_CHECK_PRIVILEGE, BT_L2CAP_LE_REMOVE_SOCKET)
690                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
691                 BT_ERR("Don't have a privilege to use this API");
692                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
693         }
694
695         if (id < 0) {
696                 BT_ERR("Invalid ID");
697                 return BLUETOOTH_ERROR_INVALID_PARAM;
698         }
699
700         BT_INFO("<<<<<< L2CAP_LE Remove socket request from app, fd=[%d] >>>>>>", id);
701
702         server_info = __get_l2cap_le_server_info_with_id(id);
703         if (!server_info) {
704                 BT_ERR("server_info not found for socket_fd: %d", id);
705                 return BLUETOOTH_ERROR_INVALID_PARAM;
706         }
707
708         __remove_l2cap_le_server(server_info);
709
710         return BLUETOOTH_ERROR_NONE;
711 }
712
713 BT_EXPORT_API int bluetooth_l2cap_le_server_disconnect(int socket_fd)
714 {
715         l2cap_le_remote_client_info_t *client_info;
716
717         BT_CHECK_ENABLED_LE(return);
718
719         BT_INFO("<<<<<< L2CAP_LE server disconnect request from APP >>>>>>");
720         if (socket_fd < 0) {
721                 BT_ERR("Invalid FD");
722                 return BLUETOOTH_ERROR_INVALID_PARAM;
723         }
724
725         client_info = __get_l2cap_le_rem_client_info_with_fd(socket_fd);
726         if (!client_info) {
727                 BT_ERR("client_info not found for socket_fd: %d", socket_fd);
728                 return BLUETOOTH_ERROR_NOT_CONNECTED;
729         }
730
731         if (0 < client_info->sock_fd) {
732                 l2cap_le_server_info_t *server_info;
733
734                 /* Remove IO watch for client socket */
735                 if (0 < client_info->watch_id)
736                         g_source_remove(client_info->watch_id);
737                 client_info->watch_id = -1;
738
739                 /* close client socket and send L2CAP_LE disconneted event */
740                 shutdown(client_info->sock_fd, SHUT_RDWR);
741                 close(client_info->sock_fd);
742                 server_info = __get_l2cap_le_server_info_with_id(
743                                 client_info->server_id);
744                 __handle_l2cap_le_client_disconnected(
745                                 server_info, client_info);
746                 client_info->sock_fd = -1;
747
748                 /* Remove remote client info from l2cap_le server context */
749                 if (server_info)
750                         server_info->conn_list = g_slist_remove(
751                                 server_info->conn_list, client_info);
752
753                 /* Release remote client info */
754                 __remove_remote_client_info(client_info);
755         }
756
757         return BLUETOOTH_ERROR_NONE;
758 }
759
760 BT_EXPORT_API gboolean bluetooth_l2cap_le_is_server_psm_available(int psm)
761 {
762         int result;
763         gboolean available = TRUE;
764         int t_psm;
765
766         retv_if(bluetooth_check_adapter_le() ==
767                                 BLUETOOTH_ADAPTER_DISABLED, FALSE);
768
769         BT_INIT_PARAMS();
770         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
771
772         t_psm = psm;
773         g_array_append_vals(in_param1, &t_psm, sizeof(int));
774
775         /* TODO: Need to implement BT_L2CAP_LE_IS_PSM_AVAILABLE in BT-Service  */
776         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_IS_PSM_AVAILABLE,
777                 in_param1, in_param2, in_param3, in_param4, &out_param);
778
779         BT_DBG("result: %x", result);
780
781         if (result == BLUETOOTH_ERROR_NONE)
782                 available = g_array_index(out_param, gboolean, 0);
783
784         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
785
786         BT_DBG("available: %d", available);
787
788         return available;
789 }
790
791 BT_EXPORT_API int bluetooth_l2cap_le_server_is_connected(
792                                         const bluetooth_device_address_t *device_address, gboolean *connected)
793 {
794         char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
795         l2cap_le_remote_client_info_t *info;
796
797         BT_CHECK_PARAMETER(device_address, return);
798         BT_CHECK_PARAMETER(connected, return);
799
800         *connected = FALSE;
801
802         _bt_convert_addr_type_to_string(input_addr,
803                                         (unsigned char *)device_address->addr);
804         info = __get_l2cap_le_rem_client_info_with_addr(input_addr);
805         if (info)
806                 *connected = TRUE;
807
808         return BLUETOOTH_ERROR_NONE;
809 }
810
811 BT_EXPORT_API int bluetooth_l2cap_le_listen_and_accept(int id, int max_pending_connection)
812 {
813         l2cap_le_server_info_t *server_info;
814
815         BT_CHECK_ENABLED_LE(return);
816         if (id < 0) {
817                 BT_ERR("Invalid ID");
818                 return BLUETOOTH_ERROR_INVALID_PARAM;
819         }
820
821         BT_INFO("<<<<<<<<< L2CAP_LE Listen & accept from app >>>>>>>>>>>");
822
823         server_info = __get_l2cap_le_server_info_with_id(id);
824         if (!server_info) {
825                 BT_ERR("server_info not found for id: %d", id);
826                 return BLUETOOTH_ERROR_INVALID_PARAM;
827         }
828
829         if (server_info->server_fd >= 0) {
830                 BT_ERR("server already listening");
831                 return BLUETOOTH_ERROR_DEVICE_BUSY;
832         }
833
834         server_info->max_pending_conn = max_pending_connection;
835         server_info->auto_accept = TRUE;
836
837         return __l2cap_le_listen(server_info, true);
838 }
839
840 BT_EXPORT_API int bluetooth_l2cap_le_listen(int id, int max_pending_connection)
841 {
842         l2cap_le_server_info_t *server_info;
843
844         BT_CHECK_ENABLED_LE(return);
845         if (id < 0) {
846                 BT_ERR("Invalid ID");
847                 return BLUETOOTH_ERROR_INVALID_PARAM;
848         }
849
850         BT_INFO("<<<<<<<<< L2CAP_LE Listen >>>>>>>>>>>");
851
852         server_info = __get_l2cap_le_server_info_with_id(id);
853         if (!server_info) {
854                 BT_ERR("server_info not found for id: %d", id);
855                 return BLUETOOTH_ERROR_INVALID_PARAM;
856         }
857
858         if (server_info->server_fd >= 0) {
859                 BT_ERR("server already listening");
860                 return BLUETOOTH_ERROR_DEVICE_BUSY;
861         }
862
863         server_info->max_pending_conn = max_pending_connection;
864         server_info->auto_accept = FALSE;
865
866         return __l2cap_le_listen(server_info, false);
867 }
868
869
870 BT_EXPORT_API int bluetooth_l2cap_le_accept_connection(int server_fd)
871 {
872         int result;
873         l2cap_le_server_info_t *server_info;
874
875         BT_CHECK_ENABLED_LE(return);
876
877         if (server_fd < 0) {
878                 BT_ERR("Invalid FD");
879                 return BLUETOOTH_ERROR_INVALID_PARAM;
880         }
881
882         BT_INIT_PARAMS();
883         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
884
885         server_info = __get_l2cap_le_server_info_with_id(server_fd);
886         if (!server_info) {
887                 BT_ERR("No server with fd: %d", server_fd);
888                 return BLUETOOTH_ERROR_INVALID_PARAM;
889         }
890
891         g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
892
893         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_ACCEPT_CONNECTION,
894                 in_param1, in_param2, in_param3, in_param4, &out_param);
895
896         BT_DBG("result: %x", result);
897         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
898
899         return result;
900 }
901
902 BT_EXPORT_API int bluetooth_l2cap_le_reject_connection(int server_fd)
903 {
904         int result;
905         l2cap_le_server_info_t *server_info;
906
907         BT_CHECK_ENABLED_LE(return);
908
909         if (server_fd < 0) {
910                 BT_ERR("Invalid FD");
911                 return BLUETOOTH_ERROR_INVALID_PARAM;
912         }
913
914         BT_INIT_PARAMS();
915         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
916
917         server_info = __get_l2cap_le_server_info_with_id(server_fd);
918         if (!server_info) {
919                 BT_ERR("No server with fd: %d", server_fd);
920                 return BLUETOOTH_ERROR_INVALID_PARAM;
921         }
922
923         g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
924
925         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_REJECT_CONNECTION,
926                 in_param1, in_param2, in_param3, in_param4, &out_param);
927
928         BT_DBG("result: %x", result);
929         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
930
931         return result;
932 }
933
934 BT_EXPORT_API int bluetooth_l2cap_le_get_psm(int id, int *psm)
935 {
936         l2cap_le_server_info_t *server_info;
937
938         BT_CHECK_ENABLED_LE(return);
939
940         if (id < 0) {
941                 BT_ERR("Invalid ID");
942                 return BLUETOOTH_ERROR_INVALID_PARAM;
943         }
944
945         server_info = __get_l2cap_le_server_info_with_id(id);
946         if (!server_info) {
947                 BT_ERR("server_info not found for sock_fd: %d", id);
948                 return BLUETOOTH_ERROR_INVALID_PARAM;
949         }
950
951         *psm = server_info->psm;
952
953         return BLUETOOTH_ERROR_NONE;
954 }