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,
411 #ifdef TIZEN_BLUEDROID_PORTING
412 char len_buf[2] = {0, 0};
416 int result = BLUETOOTH_ERROR_NONE;
417 bt_event_info_t *event_info;
418 bluetooth_l2cap_le_received_data_t data_r;
419 GIOStatus status = G_IO_STATUS_NORMAL;
421 l2cap_le_remote_client_info_t *client_info = data;
422 l2cap_le_server_info_t *server_info;
424 retv_if(client_info == NULL, FALSE);
426 server_info = __get_l2cap_le_server_info_with_id(client_info->server_id);
428 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
429 BT_ERR_C("l2cap_le Server disconnected: %d", client_info->sock_fd);
433 #ifdef TIZEN_BLUEDROID_PORTING
434 /* Read buffer length from socket */
435 status = g_io_channel_read_chars(chan, len_buf, sizeof(len_buf), &len, &err);
436 if (status != G_IO_STATUS_NORMAL) {
437 BT_ERR("IO Channel read is failed with %d", status);
439 BT_ERR("IO Channel read error [%s]", err->message);
440 if (status == G_IO_STATUS_ERROR &&
441 !g_strcmp0(err->message,
442 "Connection reset by peer"))
443 BT_ERR("cond : %d", cond);
451 BT_ERR("Length is zero, remote end hang up");
455 len = (unsigned char)len_buf[0] + ((unsigned char)len_buf[1] << 8);
456 BT_INFO("Recieved buffer len: %d", len);
458 /* Read len bytes in buffer from socket */
459 buffer = g_malloc0(len + 1);
460 status = g_io_channel_read_chars(chan, buffer, len, &len, &err);
462 buffer = g_malloc0(BT_L2CAP_LE_BUFFER_LEN + 1);
463 status = g_io_channel_read_chars(chan, buffer,
464 BT_L2CAP_LE_BUFFER_LEN, &len, &err);
467 if (status != G_IO_STATUS_NORMAL) {
468 BT_ERR("IO Channel read is failed with %d", status);
471 BT_ERR("IO Channel read error [%s]", err->message);
472 if (status == G_IO_STATUS_ERROR &&
473 !g_strcmp0(err->message, "Connection reset by peer")) {
474 BT_ERR("cond : %d", cond);
485 BT_ERR("Length is zero, remote end hang up");
490 event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
491 if (event_info == NULL) {
496 data_r.socket_fd = client_info->sock_fd;
497 data_r.buffer_size = len;
498 data_r.buffer = buffer;
500 _bt_common_event_cb(BLUETOOTH_EVENT_L2CAP_LE_DATA_RECEIVED,
501 result, &data_r, event_info->cb, event_info->user_data);
506 BT_ERR("Failure occured, remove client connection");
507 server_info->conn_list = g_slist_remove(
508 server_info->conn_list, client_info);
509 __handle_l2cap_le_client_disconnected(server_info, client_info);
510 client_info->watch_id = -1;
511 __remove_remote_client_info(client_info);
515 static gboolean __new_connection_request_cb(GIOChannel *chan,
516 GIOCondition cond, gpointer data)
523 char buf[BLUETOOTH_SOCK_CONNECT_INFO_LEN];
524 unsigned char addr[BT_ADDRESS_LENGTH_MAX];
526 bt_event_info_t *event_info;
528 l2cap_le_remote_client_info_t *rem_client;
529 l2cap_le_server_info_t *server_info = data;
532 BT_ERR("Server info is invalid");
536 if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
537 BT_INFO("l2cap_le Server with fd:%d is closed with cond:0x%X",
538 server_info->server_fd, cond);
542 BT_INFO("Server fd: %d", server_info->server_fd);
543 len = __sock_read( server_info->server_fd, buf,
544 BLUETOOTH_SOCK_CONNECT_INFO_LEN, &client_fd);
545 BT_DBG("Socket Read len: %d", len);
547 BT_ERR("Listen stopped");
549 } else if (len != BLUETOOTH_SOCK_CONNECT_INFO_LEN) {
550 BT_ERR("Read length is not same as socket info length");
555 /* Read size of data */
556 size = buf[len] | (buf[len + 1] << 8);
559 /* Read bluetooth address */
560 memcpy(addr, buf + len, BT_ADDRESS_LENGTH_MAX);
561 len += BT_ADDRESS_LENGTH_MAX;
564 channel = buf[len] | (buf[len + 1] << 8) |
565 (buf[len + 2] << 16) | (buf[len + 3] << 24);
569 status = buf[len] | (buf[len + 1] << 8) |
570 (buf[len + 2] << 16) | (buf[len + 3] << 24);
573 BT_DBG("size: %d, channel: %d, status: %d", size, channel, status);
575 rem_client = g_malloc0(sizeof(l2cap_le_remote_client_info_t));
576 rem_client->sock_fd = client_fd;
577 rem_client->server_id = server_info->server_id;
578 _bt_convert_addr_type_to_string(rem_client->addr, addr);
580 BT_INFO("New client [%s] connection with socket_fd: %d, server_id: %d",
581 rem_client->addr, rem_client->sock_fd, rem_client->server_id);
583 io = g_io_channel_unix_new(rem_client->sock_fd);
584 g_io_channel_set_encoding(io, NULL, NULL);
585 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
586 rem_client->watch_id = g_io_add_watch(io,
587 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
588 __data_received_cb, rem_client);
589 g_io_channel_unref(io);
591 server_info->conn_list = g_slist_append(server_info->conn_list, rem_client);
592 event_info = _bt_event_get_cb_data(BT_L2CAP_LE_SERVER_EVENT);
594 __connected_cb(rem_client, event_info);
599 /* Error occurred, Remove l2cap_le server*/
600 BT_ERR("some error has occured, remove server");
601 __remove_l2cap_le_server(server_info);
605 static int __getInt(char *buf, int len)
609 if (len != SOCK_INT_LEN)
612 val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
616 static int __sock_wait_for_psm(int sock_fd)
619 char buf[SOCK_INT_LEN];
621 readlen = __sock_read(sock_fd, buf, SOCK_INT_LEN, NULL);
622 return __getInt(buf, readlen);
625 static int __l2cap_le_listen(l2cap_le_server_info_t *server_info, bool accept)
628 GUnixFDList *out_fd_list = NULL;
629 GIOChannel *server_io;
632 retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
635 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
637 psm = server_info->psm;
638 g_array_append_vals(in_param1, &psm, sizeof(int));
641 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_L2CAP_LE_LISTEN,
642 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
644 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_L2CAP_LE_LISTEN_AND_ACCEPT,
645 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
647 BT_INFO("result: %x", result);
648 if (result != BLUETOOTH_ERROR_NONE) {
649 BT_ERR("Fail to send request");
651 } else if (NULL == out_fd_list) {
652 BT_ERR("out_fd_list is NULL");
653 return BLUETOOTH_ERROR_INTERNAL;
659 return BLUETOOTH_ERROR_INTERNAL;
661 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
662 BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
663 server_info->server_fd = fd_list_array[0];
664 BT_INFO("Socket fd: %d", server_info->server_fd);
666 g_free(fd_list_array);
667 g_object_unref(out_fd_list);
670 psm = __sock_wait_for_psm(server_info->server_fd);
672 BT_ERR("Reading PSM failed, psm %d", psm);
673 return BLUETOOTH_ERROR_INTERNAL;
675 server_info->psm = psm;
677 BT_INFO("socket fd: %d psm %d", server_info->server_fd, server_info->psm);
678 server_io = g_io_channel_unix_new(server_info->server_fd);
679 g_io_channel_set_encoding(server_io, NULL, NULL);
680 g_io_channel_set_flags(server_io, G_IO_FLAG_NONBLOCK, NULL);
681 server_info->watch_id = g_io_add_watch(server_io,
682 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
683 __new_connection_request_cb, server_info);
684 g_io_channel_unref(server_io);
686 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
688 return BLUETOOTH_ERROR_NONE;
691 BT_EXPORT_API int bluetooth_l2cap_le_create_socket(int psm)
693 l2cap_le_server_info_t *server_info;
695 BT_CHECK_ENABLED_LE(return);
697 if (_bt_check_privilege_le(BT_CHECK_PRIVILEGE, BT_L2CAP_LE_CREATE_SOCKET)
698 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
699 BT_ERR("Don't have a privilege to use this API");
700 return BLUETOOTH_ERROR_PERMISSION_DEINED;
703 BT_INFO("<<<<<<<<< L2CAP_LE Create socket from app, psm %d >>>>>>>>>", psm);
705 server_info = __get_l2cap_le_server_info_from_psm(psm);
707 server_info = g_malloc0(sizeof(l2cap_le_server_info_t));
708 server_info->psm = psm;
709 server_info->server_id = __l2cap_le_assign_server_id();
710 server_info->server_fd = -1;
711 server_info->watch_id = -1;
712 server_info->auto_accept = FALSE;
713 l2cap_le_servers = g_slist_append(l2cap_le_servers, server_info);
716 return server_info->server_id;
719 BT_EXPORT_API int bluetooth_l2cap_le_remove_socket(int id)
721 l2cap_le_server_info_t *server_info;
723 BT_CHECK_ENABLED_LE(return);
725 if (_bt_check_privilege_le(BT_CHECK_PRIVILEGE, BT_L2CAP_LE_REMOVE_SOCKET)
726 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
727 BT_ERR("Don't have a privilege to use this API");
728 return BLUETOOTH_ERROR_PERMISSION_DEINED;
732 BT_ERR("Invalid ID");
733 return BLUETOOTH_ERROR_INVALID_PARAM;
736 BT_INFO("<<<<<< L2CAP_LE Remove socket request from app, fd=[%d] >>>>>>", id);
738 server_info = __get_l2cap_le_server_info_with_id(id);
740 BT_ERR("server_info not found for socket_fd: %d", id);
741 return BLUETOOTH_ERROR_INVALID_PARAM;
744 __remove_l2cap_le_server(server_info);
746 return BLUETOOTH_ERROR_NONE;
749 BT_EXPORT_API int bluetooth_l2cap_le_server_disconnect(int socket_fd)
751 l2cap_le_remote_client_info_t *client_info;
753 BT_CHECK_ENABLED_LE(return);
755 BT_INFO("<<<<<< L2CAP_LE server disconnect request from APP >>>>>>");
757 BT_ERR("Invalid FD");
758 return BLUETOOTH_ERROR_INVALID_PARAM;
761 client_info = __get_l2cap_le_rem_client_info_with_fd(socket_fd);
763 BT_ERR("client_info not found for socket_fd: %d", socket_fd);
764 return BLUETOOTH_ERROR_NOT_CONNECTED;
767 if (0 < client_info->sock_fd) {
768 l2cap_le_server_info_t *server_info;
770 /* Remove IO watch for client socket */
771 if (0 < client_info->watch_id)
772 g_source_remove(client_info->watch_id);
773 client_info->watch_id = -1;
775 /* close client socket and send L2CAP_LE disconneted event */
776 shutdown(client_info->sock_fd, SHUT_RDWR);
777 close(client_info->sock_fd);
778 server_info = __get_l2cap_le_server_info_with_id(
779 client_info->server_id);
780 __handle_l2cap_le_client_disconnected(
781 server_info, client_info);
782 client_info->sock_fd = -1;
784 /* Remove remote client info from l2cap_le server context */
785 server_info->conn_list = g_slist_remove(
786 server_info->conn_list, client_info);
788 /* Release remote client info */
789 __remove_remote_client_info(client_info);
792 return BLUETOOTH_ERROR_NONE;
795 BT_EXPORT_API gboolean bluetooth_l2cap_le_is_server_psm_available(int psm)
798 gboolean available = TRUE;
801 retv_if(bluetooth_check_adapter_le() ==
802 BLUETOOTH_ADAPTER_DISABLED, FALSE);
805 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
808 g_array_append_vals(in_param1, &t_psm, sizeof(int));
810 /* TODO: Need to implement BT_L2CAP_LE_IS_PSM_AVAILABLE in BT-Service */
811 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_IS_PSM_AVAILABLE,
812 in_param1, in_param2, in_param3, in_param4, &out_param);
814 BT_DBG("result: %x", result);
816 if (result == BLUETOOTH_ERROR_NONE)
817 available = g_array_index(out_param, gboolean, 0);
819 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
821 BT_DBG("available: %d", available);
826 BT_EXPORT_API int bluetooth_l2cap_le_server_is_connected(
827 const bluetooth_device_address_t *device_address, gboolean *connected)
829 char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
830 l2cap_le_remote_client_info_t *info;
832 BT_CHECK_PARAMETER(device_address, return);
833 BT_CHECK_PARAMETER(connected, return);
837 _bt_convert_addr_type_to_string(input_addr,
838 (unsigned char *)device_address->addr);
839 info = __get_l2cap_le_rem_client_info_with_addr(input_addr);
843 return BLUETOOTH_ERROR_NONE;
846 BT_EXPORT_API int bluetooth_l2cap_le_listen_and_accept(int id, int max_pending_connection)
848 l2cap_le_server_info_t *server_info;
850 BT_CHECK_ENABLED_LE(return);
852 BT_ERR("Invalid ID");
853 return BLUETOOTH_ERROR_INVALID_PARAM;
856 BT_INFO("<<<<<<<<< L2CAP_LE Listen & accept from app >>>>>>>>>>>");
858 server_info = __get_l2cap_le_server_info_with_id(id);
860 BT_ERR("server_info not found for id: %d", id);
861 return BLUETOOTH_ERROR_INVALID_PARAM;
864 if (server_info->server_fd >= 0) {
865 BT_ERR("server already listening");
866 return BLUETOOTH_ERROR_DEVICE_BUSY;
869 server_info->max_pending_conn = max_pending_connection;
870 server_info->auto_accept = TRUE;
872 return __l2cap_le_listen(server_info, true);
875 BT_EXPORT_API int bluetooth_l2cap_le_listen(int id, int max_pending_connection)
877 l2cap_le_server_info_t *server_info;
879 BT_CHECK_ENABLED_LE(return);
881 BT_ERR("Invalid ID");
882 return BLUETOOTH_ERROR_INVALID_PARAM;
885 BT_INFO("<<<<<<<<< L2CAP_LE Listen >>>>>>>>>>>");
887 server_info = __get_l2cap_le_server_info_with_id(id);
889 BT_ERR("server_info not found for id: %d", id);
890 return BLUETOOTH_ERROR_INVALID_PARAM;
893 if (server_info->server_fd >= 0) {
894 BT_ERR("server already listening");
895 return BLUETOOTH_ERROR_DEVICE_BUSY;
898 server_info->max_pending_conn = max_pending_connection;
899 server_info->auto_accept = FALSE;
901 return __l2cap_le_listen(server_info, false);
905 BT_EXPORT_API int bluetooth_l2cap_le_accept_connection(int server_fd)
908 l2cap_le_server_info_t *server_info;
910 BT_CHECK_ENABLED_LE(return);
913 BT_ERR("Invalid FD");
914 return BLUETOOTH_ERROR_INVALID_PARAM;
918 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
920 server_info = __get_l2cap_le_server_info_with_id(server_fd);
922 BT_ERR("No server with fd: %d", server_fd);
923 return BLUETOOTH_ERROR_INVALID_PARAM;
926 g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
928 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_ACCEPT_CONNECTION,
929 in_param1, in_param2, in_param3, in_param4, &out_param);
931 BT_DBG("result: %x", result);
932 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
937 BT_EXPORT_API int bluetooth_l2cap_le_reject_connection(int server_fd)
940 l2cap_le_server_info_t *server_info;
942 BT_CHECK_ENABLED_LE(return);
945 BT_ERR("Invalid FD");
946 return BLUETOOTH_ERROR_INVALID_PARAM;
950 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
952 server_info = __get_l2cap_le_server_info_with_id(server_fd);
954 BT_ERR("No server with fd: %d", server_fd);
955 return BLUETOOTH_ERROR_INVALID_PARAM;
958 g_array_append_vals(in_param1, server_info->pending_addr, BT_ADDRESS_STRING_SIZE);
960 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_L2CAP_LE_REJECT_CONNECTION,
961 in_param1, in_param2, in_param3, in_param4, &out_param);
963 BT_DBG("result: %x", result);
964 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
969 BT_EXPORT_API int bluetooth_l2cap_le_get_psm(int id, int *psm)
971 l2cap_le_server_info_t *server_info;
973 BT_CHECK_ENABLED_LE(return);
976 BT_ERR("Invalid ID");
977 return BLUETOOTH_ERROR_INVALID_PARAM;
980 server_info = __get_l2cap_le_server_info_with_id(id);
982 BT_ERR("server_info not found for sock_fd: %d", id);
983 return BLUETOOTH_ERROR_INVALID_PARAM;
986 *psm = server_info->psm;
988 return BLUETOOTH_ERROR_NONE;