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 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));
438 if (status == G_IO_STATUS_AGAIN)
442 BT_ERR("IO Channel read error [%s]", err->message);
449 BT_ERR("Length is zero, remote end hang up");
454 BT_DBG("fd: %d, len: %zu, buffer: %s", client_info->sock_fd, len, buffer);
456 event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
457 if (event_info == NULL) {
462 data_r.socket_fd = client_info->sock_fd;
463 data_r.buffer_size = len;
464 data_r.buffer = buffer;
466 _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_DATA_RECEIVED,
467 result, &data_r, event_info->cb, event_info->user_data);
472 BT_ERR("Failure occured, remove client connection");
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);
482 static gboolean __new_connection_request_cb(GIOChannel *chan,
483 GIOCondition cond, gpointer data)
490 char buf[BLUETOOTH_SOCK_CONNECT_INFO_LEN];
491 unsigned char addr[BT_ADDRESS_LENGTH_MAX];
493 bt_event_info_t *event_info;
495 l2cap_le_remote_client_info_t *rem_client;
496 l2cap_le_server_info_t *server_info = data;
499 BT_ERR("Server info is invalid");
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);
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);
514 BT_ERR("Listen stopped");
516 } else if (len != BLUETOOTH_SOCK_CONNECT_INFO_LEN) {
517 BT_ERR("Read length is not same as socket info length");
522 /* Read size of data */
523 size = buf[len] | (buf[len + 1] << 8);
526 /* Read bluetooth address */
527 memcpy(addr, buf + len, BT_ADDRESS_LENGTH_MAX);
528 len += BT_ADDRESS_LENGTH_MAX;
531 channel = buf[len] | (buf[len + 1] << 8) |
532 (buf[len + 2] << 16) | (buf[len + 3] << 24);
536 status = buf[len] | (buf[len + 1] << 8) |
537 (buf[len + 2] << 16) | (buf[len + 3] << 24);
540 BT_DBG("size: %d, channel: %d, status: %d", size, channel, status);
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);
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);
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);
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);
561 __connected_cb(rem_client, event_info);
566 /* Error occurred, Remove l2cap_le server*/
567 BT_ERR("some error has occured, remove server");
568 __remove_l2cap_le_server(server_info);
572 static int __getInt(char *buf, int len)
576 if (len != SOCK_INT_LEN)
579 val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
583 static int __sock_wait_for_psm(int sock_fd)
586 char buf[SOCK_INT_LEN];
588 readlen = __sock_read(sock_fd, buf, SOCK_INT_LEN, NULL);
589 return __getInt(buf, readlen);
592 static int __l2cap_le_listen(l2cap_le_server_info_t *server_info, bool accept)
595 GUnixFDList *out_fd_list = NULL;
596 GIOChannel *server_io;
599 retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
602 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
604 psm = server_info->psm;
605 g_array_append_vals(in_param1, &psm, sizeof(int));
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);
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);
614 BT_INFO("result: %x", result);
615 if (result != BLUETOOTH_ERROR_NONE) {
616 BT_ERR("Fail to send request");
618 } else if (NULL == out_fd_list) {
619 BT_ERR("out_fd_list is NULL");
620 return BLUETOOTH_ERROR_INTERNAL;
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);
630 g_free(fd_list_array);
631 g_object_unref(out_fd_list);
634 psm = __sock_wait_for_psm(server_info->server_fd);
636 BT_ERR("Reading PSM failed, psm %d", psm);
637 return BLUETOOTH_ERROR_INTERNAL;
639 server_info->psm = psm;
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);
650 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
652 return BLUETOOTH_ERROR_NONE;
655 BT_EXPORT_API int bluetooth_l2cap_le_create_socket(int psm)
657 l2cap_le_server_info_t *server_info;
659 BT_CHECK_ENABLED_LE(return);
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;
667 BT_INFO("<<<<<<<<< L2CAP_LE Create socket from app, psm %d >>>>>>>>>", psm);
669 server_info = __get_l2cap_le_server_info_from_psm(psm);
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);
680 return server_info->server_id;
683 BT_EXPORT_API int bluetooth_l2cap_le_remove_socket(int id)
685 l2cap_le_server_info_t *server_info;
687 BT_CHECK_ENABLED_LE(return);
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;
696 BT_ERR("Invalid ID");
697 return BLUETOOTH_ERROR_INVALID_PARAM;
700 BT_INFO("<<<<<< L2CAP_LE Remove socket request from app, fd=[%d] >>>>>>", id);
702 server_info = __get_l2cap_le_server_info_with_id(id);
704 BT_ERR("server_info not found for socket_fd: %d", id);
705 return BLUETOOTH_ERROR_INVALID_PARAM;
708 __remove_l2cap_le_server(server_info);
710 return BLUETOOTH_ERROR_NONE;
713 BT_EXPORT_API int bluetooth_l2cap_le_server_disconnect(int socket_fd)
715 l2cap_le_remote_client_info_t *client_info;
717 BT_CHECK_ENABLED_LE(return);
719 BT_INFO("<<<<<< L2CAP_LE server disconnect request from APP >>>>>>");
721 BT_ERR("Invalid FD");
722 return BLUETOOTH_ERROR_INVALID_PARAM;
725 client_info = __get_l2cap_le_rem_client_info_with_fd(socket_fd);
727 BT_ERR("client_info not found for socket_fd: %d", socket_fd);
728 return BLUETOOTH_ERROR_NOT_CONNECTED;
731 if (0 < client_info->sock_fd) {
732 l2cap_le_server_info_t *server_info;
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;
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;
748 /* Remove remote client info from l2cap_le server context */
750 server_info->conn_list = g_slist_remove(
751 server_info->conn_list, client_info);
753 /* Release remote client info */
754 __remove_remote_client_info(client_info);
757 return BLUETOOTH_ERROR_NONE;
760 BT_EXPORT_API gboolean bluetooth_l2cap_le_is_server_psm_available(int psm)
763 gboolean available = TRUE;
766 retv_if(bluetooth_check_adapter_le() ==
767 BLUETOOTH_ADAPTER_DISABLED, FALSE);
770 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
773 g_array_append_vals(in_param1, &t_psm, sizeof(int));
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);
779 BT_DBG("result: %x", result);
781 if (result == BLUETOOTH_ERROR_NONE)
782 available = g_array_index(out_param, gboolean, 0);
784 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
786 BT_DBG("available: %d", available);
791 BT_EXPORT_API int bluetooth_l2cap_le_server_is_connected(
792 const bluetooth_device_address_t *device_address, gboolean *connected)
794 char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
795 l2cap_le_remote_client_info_t *info;
797 BT_CHECK_PARAMETER(device_address, return);
798 BT_CHECK_PARAMETER(connected, return);
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);
808 return BLUETOOTH_ERROR_NONE;
811 BT_EXPORT_API int bluetooth_l2cap_le_listen_and_accept(int id, int max_pending_connection)
813 l2cap_le_server_info_t *server_info;
815 BT_CHECK_ENABLED_LE(return);
817 BT_ERR("Invalid ID");
818 return BLUETOOTH_ERROR_INVALID_PARAM;
821 BT_INFO("<<<<<<<<< L2CAP_LE Listen & accept from app >>>>>>>>>>>");
823 server_info = __get_l2cap_le_server_info_with_id(id);
825 BT_ERR("server_info not found for id: %d", id);
826 return BLUETOOTH_ERROR_INVALID_PARAM;
829 if (server_info->server_fd >= 0) {
830 BT_ERR("server already listening");
831 return BLUETOOTH_ERROR_DEVICE_BUSY;
834 server_info->max_pending_conn = max_pending_connection;
835 server_info->auto_accept = TRUE;
837 return __l2cap_le_listen(server_info, true);
840 BT_EXPORT_API int bluetooth_l2cap_le_listen(int id, int max_pending_connection)
842 l2cap_le_server_info_t *server_info;
844 BT_CHECK_ENABLED_LE(return);
846 BT_ERR("Invalid ID");
847 return BLUETOOTH_ERROR_INVALID_PARAM;
850 BT_INFO("<<<<<<<<< L2CAP_LE Listen >>>>>>>>>>>");
852 server_info = __get_l2cap_le_server_info_with_id(id);
854 BT_ERR("server_info not found for id: %d", id);
855 return BLUETOOTH_ERROR_INVALID_PARAM;
858 if (server_info->server_fd >= 0) {
859 BT_ERR("server already listening");
860 return BLUETOOTH_ERROR_DEVICE_BUSY;
863 server_info->max_pending_conn = max_pending_connection;
864 server_info->auto_accept = FALSE;
866 return __l2cap_le_listen(server_info, false);
870 BT_EXPORT_API int bluetooth_l2cap_le_accept_connection(int server_fd)
873 l2cap_le_server_info_t *server_info;
875 BT_CHECK_ENABLED_LE(return);
878 BT_ERR("Invalid FD");
879 return BLUETOOTH_ERROR_INVALID_PARAM;
883 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
885 server_info = __get_l2cap_le_server_info_with_id(server_fd);
887 BT_ERR("No server with fd: %d", server_fd);
888 return BLUETOOTH_ERROR_INVALID_PARAM;
891 g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
893 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_ACCEPT_CONNECTION,
894 in_param1, in_param2, in_param3, in_param4, &out_param);
896 BT_DBG("result: %x", result);
897 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
902 BT_EXPORT_API int bluetooth_l2cap_le_reject_connection(int server_fd)
905 l2cap_le_server_info_t *server_info;
907 BT_CHECK_ENABLED_LE(return);
910 BT_ERR("Invalid FD");
911 return BLUETOOTH_ERROR_INVALID_PARAM;
915 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
917 server_info = __get_l2cap_le_server_info_with_id(server_fd);
919 BT_ERR("No server with fd: %d", server_fd);
920 return BLUETOOTH_ERROR_INVALID_PARAM;
923 g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
925 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_REJECT_CONNECTION,
926 in_param1, in_param2, in_param3, in_param4, &out_param);
928 BT_DBG("result: %x", result);
929 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
934 BT_EXPORT_API int bluetooth_l2cap_le_get_psm(int id, int *psm)
936 l2cap_le_server_info_t *server_info;
938 BT_CHECK_ENABLED_LE(return);
941 BT_ERR("Invalid ID");
942 return BLUETOOTH_ERROR_INVALID_PARAM;
945 server_info = __get_l2cap_le_server_info_with_id(id);
947 BT_ERR("server_info not found for sock_fd: %d", id);
948 return BLUETOOTH_ERROR_INVALID_PARAM;
951 *psm = server_info->psm;
953 return BLUETOOTH_ERROR_NONE;