2 * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
27 #define SOCK_INT_LEN 4
29 #ifdef TIZEN_BLUEDROID_PORTING
30 #define BLUETOOTH_SOCK_CONNECT_INFO_LEN 20
32 #define BLUETOOTH_SOCK_CONNECT_INFO_LEN 16
35 #define BT_L2CAP_LE_SERVER_ID_MAX 254
38 char addr[BT_ADDRESS_STRING_SIZE];
42 } l2cap_le_remote_client_info_t;
51 char pending_addr[BT_ADDRESS_STRING_SIZE];
53 } l2cap_le_server_info_t;
55 static GSList *l2cap_le_servers;
56 static gboolean id_used[BT_L2CAP_LE_SERVER_ID_MAX];
57 static int latest_id = 0;
59 int __l2cap_le_assign_server_id(void)
63 BT_DBG("latest_id: %d", latest_id);
65 index = latest_id + 1;
66 if (index >= BT_L2CAP_LE_SERVER_ID_MAX)
69 BT_DBG("index: %d", index);
71 while (id_used[index] == TRUE) {
72 if (index == latest_id) {
74 BT_ERR("All request ID is used");
79 if (index >= BT_L2CAP_LE_SERVER_ID_MAX)
84 id_used[index] = TRUE;
85 BT_DBG("Assigned Id: %d", latest_id);
90 void __l2cap_le_delete_server_id(int id)
92 ret_if(id >= BT_L2CAP_LE_SERVER_ID_MAX);
97 /* Next server will use this ID */
101 static l2cap_le_server_info_t *__get_l2cap_le_server_info_from_psm(int psm)
108 for (l = l2cap_le_servers; l != NULL; l = l->next) {
109 l2cap_le_server_info_t *info = l->data;
111 if (info->psm == psm) {
112 BT_INFO("server found with psm %d fd %d", info->psm,
121 int _get_l2cap_le_server_id(int psm, gboolean *auto_accept)
123 l2cap_le_server_info_t *server_info;
125 server_info = __get_l2cap_le_server_info_from_psm(psm);
129 *auto_accept = server_info->auto_accept;
130 return server_info->server_id;
133 static l2cap_le_server_info_t *__get_l2cap_le_server_info_with_id(int server_id)
137 for (l = l2cap_le_servers; l != NULL; l = l->next) {
138 l2cap_le_server_info_t *info = l->data;
142 BT_DBG("info->server_fd: %d, sock_fd:%d", info->server_id, server_id);
143 if (info->server_id == server_id)
150 void _bt_l2cap_le_server_set_pending_conn(int server_id, char *address)
152 l2cap_le_server_info_t *server_info;
157 server_info = __get_l2cap_le_server_info_with_id(server_id);
161 g_strlcpy(server_info->pending_addr, address, BT_ADDRESS_STRING_SIZE);
164 static l2cap_le_remote_client_info_t *__get_l2cap_le_rem_client_info_with_fd(
170 for (l = l2cap_le_servers; l != NULL; l = l->next) {
171 l2cap_le_server_info_t *info = l->data;
176 for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) {
177 l2cap_le_remote_client_info_t *client_info = l1->data;
181 if (client_info->sock_fd == sock_fd)
189 static l2cap_le_remote_client_info_t *__get_l2cap_le_rem_client_info_with_addr(
195 retv_if(NULL == addr, NULL);
197 for (l = l2cap_le_servers; l != NULL; l = l->next) {
198 l2cap_le_server_info_t *info = l->data;
203 for (l1 = info->conn_list; l1 != NULL; l1 = l1->next) {
204 l2cap_le_remote_client_info_t *client_info = l1->data;
208 if (!strncasecmp(client_info->addr, addr, strlen(client_info->addr)))
216 static void __remove_remote_client_info(l2cap_le_remote_client_info_t *rem_client)
220 if (rem_client == NULL)
223 if (0 < rem_client->sock_fd) {
224 shutdown(rem_client->sock_fd, SHUT_RDWR);
225 close(rem_client->sock_fd);
228 if (rem_client->watch_id > 0)
229 g_source_remove(rem_client->watch_id);
236 static void __handle_l2cap_le_client_disconnected(
237 l2cap_le_server_info_t *server_info, l2cap_le_remote_client_info_t *rem_client)
239 bluetooth_l2cap_le_disconnection_t disconn_info;
240 bt_event_info_t *event_info;
244 if (rem_client == NULL || server_info == NULL)
247 event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
248 if (event_info == NULL)
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;
258 _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_DISCONNECTED,
259 BLUETOOTH_ERROR_NONE, &disconn_info,
260 event_info->cb, event_info->user_data);
264 static void __remove_l2cap_le_server(l2cap_le_server_info_t *info)
266 l2cap_le_remote_client_info_t *client_info;
273 l2cap_le_servers = g_slist_remove(l2cap_le_servers, info);
274 if (info->conn_list) {
276 client_info = info->conn_list->data;
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);
287 if (info->server_fd) {
288 shutdown(info->server_fd, SHUT_RDWR);
289 close(info->server_fd);
293 g_source_remove(info->watch_id);
295 __l2cap_le_delete_server_id(info->server_id);
301 static void __connected_cb(l2cap_le_remote_client_info_t *client_info,
302 bt_event_info_t *event_info)
304 bluetooth_l2cap_le_connection_t conn_info;
305 l2cap_le_server_info_t *server_info;
307 server_info = __get_l2cap_le_server_info_with_id(client_info->server_id);
308 ret_if(server_info == NULL);
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;
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);
323 static int __process_cmsg(struct msghdr *msg)
326 struct cmsghdr *cmsg_ptr = NULL;
328 for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL;
329 cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) {
331 if (cmsg_ptr->cmsg_level != SOL_SOCKET)
334 if (cmsg_ptr->cmsg_type == SCM_RIGHTS) {
336 = ((cmsg_ptr->cmsg_len - CMSG_LEN(0)) / sizeof(int));
339 BT_ERR("ERROR Invalid count of descriptors");
343 memcpy(&sock_fd, CMSG_DATA(cmsg_ptr), sizeof(sock_fd));
344 BT_DBG("Remote client fd: %d", sock_fd);
350 static int __sock_read(int server_fd, char *buf, unsigned int len,
356 struct cmsghdr cmsgbuf[2 * sizeof(struct cmsghdr) + 4];
359 retv_if(0 > server_fd, -1);
361 BT_INFO("server_fd = %d", server_fd);
363 memset(&msg, 0, sizeof(msg));
364 memset(&iv, 0, sizeof(iv));
370 msg.msg_control = cmsgbuf;
371 msg.msg_controllen = sizeof(cmsgbuf);
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)
382 if (ret < 0 && errno == EPIPE) {
383 /* End of stream, server listining stopped */
384 BT_ERR("EOS errno: %d", errno);
389 BT_ERR("Ret errno: %d", errno);
393 if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) {
394 BT_ERR("MSG Flags errno: %d", errno);
398 if (ret >= 0 && client_fd) {
399 BT_INFO("Connection received");
400 *client_fd = __process_cmsg(&msg);
402 BT_ERR("Invalid client_fd received");
408 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
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;
418 l2cap_le_remote_client_info_t *client_info = data;
419 l2cap_le_server_info_t *server_info;
421 retv_if(client_info == NULL, FALSE);
423 server_info = __get_l2cap_le_server_info_with_id(client_info->server_id);
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);
430 buffer = g_malloc0(BT_L2CAP_LE_BUFFER_LEN + 1);
431 status = g_io_channel_read_chars(chan, buffer,
432 BT_L2CAP_LE_BUFFER_LEN, &len, &err);
433 if (status != G_IO_STATUS_NORMAL) {
434 BT_ERR("IO Channel read is failed with %d(%s)", status, _bt_print_gio_status(status));
437 if (status == G_IO_STATUS_AGAIN)
441 BT_ERR("IO Channel read error [%s]", err->message);
448 BT_ERR("Length is zero, remote end hang up");
453 event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
454 if (event_info == NULL) {
459 data_r.socket_fd = client_info->sock_fd;
460 data_r.buffer_size = len;
461 data_r.buffer = buffer;
463 _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_DATA_RECEIVED,
464 result, &data_r, event_info->cb, event_info->user_data);
469 BT_ERR("Failure occured, remove client connection");
471 server_info->conn_list = g_slist_remove(
472 server_info->conn_list, client_info);
473 __handle_l2cap_le_client_disconnected(server_info, client_info);
474 client_info->watch_id = -1;
475 __remove_remote_client_info(client_info);
479 static gboolean __new_connection_request_cb(GIOChannel *chan,
480 GIOCondition cond, gpointer data)
487 char buf[BLUETOOTH_SOCK_CONNECT_INFO_LEN];
488 unsigned char addr[BT_ADDRESS_LENGTH_MAX];
490 bt_event_info_t *event_info;
492 l2cap_le_remote_client_info_t *rem_client;
493 l2cap_le_server_info_t *server_info = data;
496 BT_ERR("Server info is invalid");
500 if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
501 BT_INFO("l2cap_le Server with fd:%d is closed with cond:0x%X",
502 server_info->server_fd, cond);
506 BT_INFO("Server fd: %d", server_info->server_fd);
507 len = __sock_read( server_info->server_fd, buf,
508 BLUETOOTH_SOCK_CONNECT_INFO_LEN, &client_fd);
509 BT_DBG("Socket Read len: %d", len);
511 BT_ERR("Listen stopped");
513 } else if (len != BLUETOOTH_SOCK_CONNECT_INFO_LEN) {
514 BT_ERR("Read length is not same as socket info length");
519 /* Read size of data */
520 size = buf[len] | (buf[len + 1] << 8);
523 /* Read bluetooth address */
524 memcpy(addr, buf + len, BT_ADDRESS_LENGTH_MAX);
525 len += BT_ADDRESS_LENGTH_MAX;
528 channel = buf[len] | (buf[len + 1] << 8) |
529 (buf[len + 2] << 16) | (buf[len + 3] << 24);
533 status = buf[len] | (buf[len + 1] << 8) |
534 (buf[len + 2] << 16) | (buf[len + 3] << 24);
537 BT_DBG("size: %d, channel: %d, status: %d", size, channel, status);
539 rem_client = g_malloc0(sizeof(l2cap_le_remote_client_info_t));
540 rem_client->sock_fd = client_fd;
541 rem_client->server_id = server_info->server_id;
542 _bt_convert_addr_type_to_string(rem_client->addr, addr);
544 BT_INFO("New client [%s] connection with socket_fd: %d, server_id: %d",
545 rem_client->addr, rem_client->sock_fd, rem_client->server_id);
547 io = g_io_channel_unix_new(rem_client->sock_fd);
548 g_io_channel_set_encoding(io, NULL, NULL);
549 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
550 rem_client->watch_id = g_io_add_watch(io,
551 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
552 __data_received_cb, rem_client);
553 g_io_channel_unref(io);
555 server_info->conn_list = g_slist_append(server_info->conn_list, rem_client);
556 event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
558 __connected_cb(rem_client, event_info);
563 /* Error occurred, Remove l2cap_le server*/
564 BT_ERR("some error has occured, remove server");
565 __remove_l2cap_le_server(server_info);
569 static int __getInt(char *buf, int len)
573 if (len != SOCK_INT_LEN)
576 val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
580 static int __sock_wait_for_psm(int sock_fd)
583 char buf[SOCK_INT_LEN];
585 readlen = __sock_read(sock_fd, buf, SOCK_INT_LEN, NULL);
586 return __getInt(buf, readlen);
589 static int __l2cap_le_listen(l2cap_le_server_info_t *server_info, bool accept)
592 GUnixFDList *out_fd_list = NULL;
593 GIOChannel *server_io;
596 retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
599 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
601 psm = server_info->psm;
602 g_array_append_vals(in_param1, &psm, sizeof(int));
605 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_L2CAP_LE_LISTEN,
606 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
608 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_L2CAP_LE_LISTEN_AND_ACCEPT,
609 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
611 BT_INFO("result: %x", result);
612 if (result != BLUETOOTH_ERROR_NONE) {
613 BT_ERR("Fail to send request");
615 } else if (NULL == out_fd_list) {
616 BT_ERR("out_fd_list is NULL");
617 return BLUETOOTH_ERROR_INTERNAL;
622 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
623 BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
624 server_info->server_fd = fd_list_array[0];
625 BT_INFO("Socket fd: %d", server_info->server_fd);
627 g_free(fd_list_array);
628 g_object_unref(out_fd_list);
631 psm = __sock_wait_for_psm(server_info->server_fd);
633 BT_ERR("Reading PSM failed, psm %d", psm);
634 return BLUETOOTH_ERROR_INTERNAL;
636 server_info->psm = psm;
638 BT_INFO("socket fd: %d psm %d", server_info->server_fd, server_info->psm);
639 server_io = g_io_channel_unix_new(server_info->server_fd);
640 g_io_channel_set_encoding(server_io, NULL, NULL);
641 g_io_channel_set_flags(server_io, G_IO_FLAG_NONBLOCK, NULL);
642 server_info->watch_id = g_io_add_watch(server_io,
643 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
644 __new_connection_request_cb, server_info);
645 g_io_channel_unref(server_io);
647 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
649 return BLUETOOTH_ERROR_NONE;
652 BT_EXPORT_API int bluetooth_l2cap_le_create_socket(int psm)
654 l2cap_le_server_info_t *server_info;
656 BT_CHECK_ENABLED_LE(return);
658 if (_bt_check_privilege_le(BT_CHECK_PRIVILEGE, BT_L2CAP_LE_CREATE_SOCKET)
659 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
660 BT_ERR("Don't have a privilege to use this API");
661 return BLUETOOTH_ERROR_PERMISSION_DEINED;
664 BT_INFO("<<<<<<<<< L2CAP_LE Create socket from app, psm %d >>>>>>>>>", psm);
666 server_info = __get_l2cap_le_server_info_from_psm(psm);
668 server_info = g_malloc0(sizeof(l2cap_le_server_info_t));
669 server_info->psm = psm;
670 server_info->server_id = __l2cap_le_assign_server_id();
671 server_info->server_fd = -1;
672 server_info->watch_id = -1;
673 server_info->auto_accept = FALSE;
674 l2cap_le_servers = g_slist_append(l2cap_le_servers, server_info);
677 return server_info->server_id;
680 BT_EXPORT_API int bluetooth_l2cap_le_remove_socket(int id)
682 l2cap_le_server_info_t *server_info;
684 BT_CHECK_ENABLED_LE(return);
686 if (_bt_check_privilege_le(BT_CHECK_PRIVILEGE, BT_L2CAP_LE_REMOVE_SOCKET)
687 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
688 BT_ERR("Don't have a privilege to use this API");
689 return BLUETOOTH_ERROR_PERMISSION_DEINED;
693 BT_ERR("Invalid ID");
694 return BLUETOOTH_ERROR_INVALID_PARAM;
697 BT_INFO("<<<<<< L2CAP_LE Remove socket request from app, fd=[%d] >>>>>>", id);
699 server_info = __get_l2cap_le_server_info_with_id(id);
701 BT_ERR("server_info not found for socket_fd: %d", id);
702 return BLUETOOTH_ERROR_INVALID_PARAM;
705 __remove_l2cap_le_server(server_info);
707 return BLUETOOTH_ERROR_NONE;
710 BT_EXPORT_API int bluetooth_l2cap_le_server_disconnect(int socket_fd)
712 l2cap_le_remote_client_info_t *client_info;
714 BT_CHECK_ENABLED_LE(return);
716 BT_INFO("<<<<<< L2CAP_LE server disconnect request from APP >>>>>>");
718 BT_ERR("Invalid FD");
719 return BLUETOOTH_ERROR_INVALID_PARAM;
722 client_info = __get_l2cap_le_rem_client_info_with_fd(socket_fd);
724 BT_ERR("client_info not found for socket_fd: %d", socket_fd);
725 return BLUETOOTH_ERROR_NOT_CONNECTED;
728 if (0 < client_info->sock_fd) {
729 l2cap_le_server_info_t *server_info;
731 /* Remove IO watch for client socket */
732 if (0 < client_info->watch_id)
733 g_source_remove(client_info->watch_id);
734 client_info->watch_id = -1;
736 /* close client socket and send L2CAP_LE disconneted event */
737 shutdown(client_info->sock_fd, SHUT_RDWR);
738 close(client_info->sock_fd);
739 server_info = __get_l2cap_le_server_info_with_id(
740 client_info->server_id);
741 __handle_l2cap_le_client_disconnected(
742 server_info, client_info);
743 client_info->sock_fd = -1;
745 /* Remove remote client info from l2cap_le server context */
747 server_info->conn_list = g_slist_remove(
748 server_info->conn_list, client_info);
750 /* Release remote client info */
751 __remove_remote_client_info(client_info);
754 return BLUETOOTH_ERROR_NONE;
757 BT_EXPORT_API gboolean bluetooth_l2cap_le_is_server_psm_available(int psm)
760 gboolean available = TRUE;
763 retv_if(bluetooth_check_adapter_le() ==
764 BLUETOOTH_ADAPTER_DISABLED, FALSE);
767 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
770 g_array_append_vals(in_param1, &t_psm, sizeof(int));
772 /* TODO: Need to implement BT_L2CAP_LE_IS_PSM_AVAILABLE in BT-Service */
773 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_IS_PSM_AVAILABLE,
774 in_param1, in_param2, in_param3, in_param4, &out_param);
776 BT_DBG("result: %x", result);
778 if (result == BLUETOOTH_ERROR_NONE)
779 available = g_array_index(out_param, gboolean, 0);
781 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
783 BT_DBG("available: %d", available);
788 BT_EXPORT_API int bluetooth_l2cap_le_server_is_connected(
789 const bluetooth_device_address_t *device_address, gboolean *connected)
791 char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
792 l2cap_le_remote_client_info_t *info;
794 BT_CHECK_PARAMETER(device_address, return);
795 BT_CHECK_PARAMETER(connected, return);
799 _bt_convert_addr_type_to_string(input_addr,
800 (unsigned char *)device_address->addr);
801 info = __get_l2cap_le_rem_client_info_with_addr(input_addr);
805 return BLUETOOTH_ERROR_NONE;
808 BT_EXPORT_API int bluetooth_l2cap_le_listen_and_accept(int id, int max_pending_connection)
810 l2cap_le_server_info_t *server_info;
812 BT_CHECK_ENABLED_LE(return);
814 BT_ERR("Invalid ID");
815 return BLUETOOTH_ERROR_INVALID_PARAM;
818 BT_INFO("<<<<<<<<< L2CAP_LE Listen & accept from app >>>>>>>>>>>");
820 server_info = __get_l2cap_le_server_info_with_id(id);
822 BT_ERR("server_info not found for id: %d", id);
823 return BLUETOOTH_ERROR_INVALID_PARAM;
826 if (server_info->server_fd >= 0) {
827 BT_ERR("server already listening");
828 return BLUETOOTH_ERROR_DEVICE_BUSY;
831 server_info->max_pending_conn = max_pending_connection;
832 server_info->auto_accept = TRUE;
834 return __l2cap_le_listen(server_info, true);
837 BT_EXPORT_API int bluetooth_l2cap_le_listen(int id, int max_pending_connection)
839 l2cap_le_server_info_t *server_info;
841 BT_CHECK_ENABLED_LE(return);
843 BT_ERR("Invalid ID");
844 return BLUETOOTH_ERROR_INVALID_PARAM;
847 BT_INFO("<<<<<<<<< L2CAP_LE Listen >>>>>>>>>>>");
849 server_info = __get_l2cap_le_server_info_with_id(id);
851 BT_ERR("server_info not found for id: %d", id);
852 return BLUETOOTH_ERROR_INVALID_PARAM;
855 if (server_info->server_fd >= 0) {
856 BT_ERR("server already listening");
857 return BLUETOOTH_ERROR_DEVICE_BUSY;
860 server_info->max_pending_conn = max_pending_connection;
861 server_info->auto_accept = FALSE;
863 return __l2cap_le_listen(server_info, false);
867 BT_EXPORT_API int bluetooth_l2cap_le_accept_connection(int server_fd)
870 l2cap_le_server_info_t *server_info;
872 BT_CHECK_ENABLED_LE(return);
875 BT_ERR("Invalid FD");
876 return BLUETOOTH_ERROR_INVALID_PARAM;
880 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
882 server_info = __get_l2cap_le_server_info_with_id(server_fd);
884 BT_ERR("No server with fd: %d", server_fd);
885 return BLUETOOTH_ERROR_INVALID_PARAM;
888 g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
890 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_ACCEPT_CONNECTION,
891 in_param1, in_param2, in_param3, in_param4, &out_param);
893 BT_DBG("result: %x", result);
894 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
899 BT_EXPORT_API int bluetooth_l2cap_le_reject_connection(int server_fd)
902 l2cap_le_server_info_t *server_info;
904 BT_CHECK_ENABLED_LE(return);
907 BT_ERR("Invalid FD");
908 return BLUETOOTH_ERROR_INVALID_PARAM;
912 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
914 server_info = __get_l2cap_le_server_info_with_id(server_fd);
916 BT_ERR("No server with fd: %d", server_fd);
917 return BLUETOOTH_ERROR_INVALID_PARAM;
920 g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
922 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_REJECT_CONNECTION,
923 in_param1, in_param2, in_param3, in_param4, &out_param);
925 BT_DBG("result: %x", result);
926 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
931 BT_EXPORT_API int bluetooth_l2cap_le_get_psm(int id, int *psm)
933 l2cap_le_server_info_t *server_info;
935 BT_CHECK_ENABLED_LE(return);
938 BT_ERR("Invalid ID");
939 return BLUETOOTH_ERROR_INVALID_PARAM;
942 server_info = __get_l2cap_le_server_info_with_id(id);
944 BT_ERR("server_info not found for sock_fd: %d", id);
945 return BLUETOOTH_ERROR_INVALID_PARAM;
948 *psm = server_info->psm;
950 return BLUETOOTH_ERROR_NONE;