summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAyush Garg <ayush.garg@samsung.com>2022-03-07 17:20:54 +0530
committerAyush Garg <ayush.garg@samsung.com>2022-03-08 15:02:24 +0530
commit3c56836f5db3c368b3c9dd2d82e5575893820090 (patch)
treefba2c9cb66db2efe0c556b71f46326b339e3dfea /src
parentacdf8729efd36375eaf421d0f96a1cee82299897 (diff)
downloadbluetooth-3c56836f5db3c368b3c9dd2d82e5575893820090.tar.gz
bluetooth-3c56836f5db3c368b3c9dd2d82e5575893820090.tar.bz2
bluetooth-3c56836f5db3c368b3c9dd2d82e5575893820090.zip
LE CoC: Implement CAPIs
This patch primarily handles following: - CAPIs to create and listen to L2CAP_LE socket - CAPIs to connect and disconnect to L2CAP_LE socket - CAPIs to get PSM of the listening L2CAP_LE socket - Event Handlers for connection, disconnection and authorization of L2CAP_LE socket Change-Id: I6ac0595799602db1402778da3f73109366a013c2 Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth-common.c79
-rw-r--r--src/bluetooth-socket.c233
2 files changed, 311 insertions, 1 deletions
diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c
index b3f328f..da623f9 100644
--- a/src/bluetooth-common.c
+++ b/src/bluetooth-common.c
@@ -301,6 +301,10 @@ static bt_event2index_table_t event2index[] = {
{ BLUETOOTH_EVENT_MESH_MODEL_VIRTUAL_SUBSCRIPTION_CONFGURED, BT_EVENT_MESH_NODE_MODEL_GROUP_VIR_SUB },
{ BLUETOOTH_EVENT_MESH_MODEL_PUBLICATION_STATUS, BT_EVENT_MESH_NODE_MODEL_PUBLICATION },
{ BLUETOOTH_EVENT_MESH_JOIN_COMPLETED, BT_EVENT_MESH_JOIN_NETWORK },
+ { BLUETOOTH_EVENT_L2CAP_LE_DATA_RECEIVED, BT_EVENT_DATA_RECEIVED},
+ { BLUETOOTH_EVENT_L2CAP_LE_CONNECTED, BT_EVENT_L2CAP_CHANNEL_CONNECTION_STATE_CHANGED},
+ { BLUETOOTH_EVENT_L2CAP_LE_DISCONNECTED, BT_EVENT_L2CAP_CHANNEL_CONNECTION_STATE_CHANGED},
+ { BLUETOOTH_EVENT_L2CAP_LE_AUTHORIZE, BT_EVENT_L2CAP_CHANNEL_CONNECTION_REQUESTED},
{ 0, -1 }
};
@@ -1554,6 +1558,10 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
bt_ipsp_connection_info_t *bt_ipsp_iface_info = NULL;
bt_pxp_property_changed_params_t *bt_pxp_property_info = NULL;
bluetooth_tds_activation_req_t *tds_act_req_info = NULL;
+ bluetooth_l2cap_le_connection_t *l2cap_le_connection_ind = NULL;
+ bluetooth_l2cap_le_disconnection_t *l2cap_le_disconnection_ind = NULL;
+ bluetooth_l2cap_le_connection_request_t *l2cap_le_request_ind = NULL;
+ bt_socket_l2cap_le_connection_s l2cap_le_connection;
#ifdef TIZEN_GATT_CLIENT
bt_gatt_char_property_t *char_prop = NULL;
@@ -4287,7 +4295,76 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
(_bt_get_error_code(param->result), (bt_mesh_node_h) info,
bt_event_slot_container[event_index].user_data);
break;
- }
+ } case BLUETOOTH_EVENT_L2CAP_LE_DATA_RECEIVED:
+ BT_INFO("L2CAP_LE: bt_socket_data_received_cb() will be * called");
+ ((bt_socket_data_received_cb)bt_event_slot_container[event_index].callback)
+ ((bt_socket_received_data_s *)(param->param_data), bt_event_slot_container[event_index].user_data);
+ break;
+ case BLUETOOTH_EVENT_L2CAP_LE_CONNECTED:
+ BT_INFO("L2CAP_LE: bt_socket_l2cap_channel_connection_state_changed_cb() will be called with BT_SOCKET_CONNECTED");
+ if (param->result == BLUETOOTH_ERROR_INVALID_PARAM)
+ error_code = BT_ERROR_OPERATION_FAILED;
+ else
+ error_code = _bt_get_error_code(param->result);
+
+ memset(&l2cap_le_connection, 0x00, sizeof(bt_socket_l2cap_le_connection_s));
+ l2cap_le_connection_ind = (bluetooth_l2cap_le_connection_t *)(param->param_data);
+
+ if (l2cap_le_connection_ind) {
+ l2cap_le_connection.socket_fd = l2cap_le_connection_ind->socket_fd;
+ l2cap_le_connection.local_role = l2cap_le_connection_ind->device_role;
+ l2cap_le_connection.server_fd = l2cap_le_connection_ind->server_id;
+ l2cap_le_connection.psm = l2cap_le_connection_ind->psm;
+
+ BT_INFO("L2CAP_LE PSM[%d] FD[%d] Role [%d] serverFD [%d]", l2cap_le_connection_ind->psm,
+ l2cap_le_connection_ind->socket_fd, (int)l2cap_le_connection_ind->device_role,
+ l2cap_le_connection_ind->server_id);
+
+ _bt_convert_address_to_string(&(l2cap_le_connection.remote_address),
+ &(l2cap_le_connection_ind->device_addr));
+ }
+
+ ((bt_socket_l2cap_channel_connection_state_changed_cb)bt_event_slot_container[event_index].callback)
+ (error_code, BT_SOCKET_CONNECTED, &l2cap_le_connection, bt_event_slot_container[event_index].user_data);
+
+ if (l2cap_le_connection.remote_address != NULL) {
+ free(l2cap_le_connection.remote_address);
+ l2cap_le_connection.remote_address = NULL;
+ }
+ break;
+ case BLUETOOTH_EVENT_L2CAP_LE_DISCONNECTED:
+ BT_INFO("L2CAP_LE: bt_socket_l2cap_channel_connection_state_changed_cb() will be called with BT_SOCKET_DISCONNECTED");
+
+ memset(&l2cap_le_connection, 0x00, sizeof(bt_socket_l2cap_le_connection_s));
+ l2cap_le_disconnection_ind = (bluetooth_l2cap_le_disconnection_t *)(param->param_data);
+
+ if (l2cap_le_disconnection_ind) {
+ l2cap_le_connection.socket_fd = l2cap_le_disconnection_ind->socket_fd;
+ l2cap_le_connection.local_role = l2cap_le_disconnection_ind->device_role;
+ l2cap_le_connection.psm = l2cap_le_disconnection_ind->psm;
+
+ _bt_convert_address_to_string(&(l2cap_le_connection.remote_address),
+ &(l2cap_le_disconnection_ind->device_addr));
+ }
+
+ ((bt_socket_l2cap_channel_connection_state_changed_cb)bt_event_slot_container[event_index].callback)
+ (_bt_get_error_code(param->result), BT_SOCKET_DISCONNECTED, &l2cap_le_connection, bt_event_slot_container[event_index].user_data);
+
+ if (l2cap_le_connection.remote_address != NULL) {
+ free(l2cap_le_connection.remote_address);
+ l2cap_le_connection.remote_address = NULL;
+ }
+ break;
+ case BLUETOOTH_EVENT_L2CAP_LE_AUTHORIZE:
+ BT_INFO("L2CAP_LE: Authorize bt_socket_connection_requested_cb() will be called");
+ l2cap_le_request_ind = (bluetooth_l2cap_le_connection_request_t *)(param->param_data);
+ _bt_convert_address_to_string(&device_addr, &(l2cap_le_request_ind->device_addr));
+ ((bt_socket_connection_requested_cb)bt_event_slot_container[event_index].callback)
+ (l2cap_le_request_ind->socket_fd, device_addr, bt_event_slot_container[event_index].user_data);
+
+ if (device_addr != NULL)
+ free(device_addr);
+ break;
default:
BT_INFO("Unknown function");
break;
diff --git a/src/bluetooth-socket.c b/src/bluetooth-socket.c
index 3973b7f..26bf4fd 100644
--- a/src/bluetooth-socket.c
+++ b/src/bluetooth-socket.c
@@ -312,3 +312,236 @@ int bt_socket_unset_connection_state_changed_cb(void)
return BT_ERROR_NONE;
}
+int bt_socket_create_l2cap_channel(int psm, int *socket_fd)
+{
+ int ret = 0;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(socket_fd);
+
+ ret = bluetooth_l2cap_le_create_socket(psm);
+ if (ret < 0) {
+ ret = _bt_get_error_code(ret); /* LCOV_EXCL_LINE */
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret); /* LCOV_EXCL_LINE */
+ return ret; /* LCOV_EXCL_LINE */
+ } else {
+ *socket_fd = ret;
+ return BT_ERROR_NONE;
+ }
+}
+
+int bt_socket_destroy_l2cap_channel(int socket_fd)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_remove_socket(socket_fd));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), /* LCOV_EXCL_LINE */
+ error_code);
+ }
+
+ return error_code;
+}
+
+/* LCOV_EXCL_START */
+int bt_socket_is_psm_used(int psm, bool *used)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(used);
+
+ *used = bluetooth_l2cap_le_is_server_psm_available(psm);
+
+ return BT_ERROR_NONE; /* LCOV_EXCL_STOP */
+}
+
+int bt_socket_listen_and_accept_l2cap_channel(int socket_fd,
+ int max_pending_connections)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_listen_and_accept(socket_fd, max_pending_connections));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), /* LCOV_EXCL_LINE */
+ error_code);
+ }
+
+ return error_code;
+}
+
+/* LCOV_EXCL_START */
+int bt_socket_listen_l2cap_channel(int socket_fd, int max_pending_connections)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_listen(socket_fd, max_pending_connections));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ }
+
+ return error_code;
+}
+
+int bt_socket_accept_l2cap_channel(int socket_fd)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_accept_connection(socket_fd));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ }
+
+ return error_code;
+}
+
+int bt_socket_reject_l2cap_channel(int socket_fd)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_reject_connection(socket_fd));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ }
+
+ return error_code;
+}
+/* LCOV_EXCL_STOP */
+
+int bt_socket_connect_l2cap_channel(const char *remote_address, int psm)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS(); /* LCOV_EXCL_START */
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_connect(&addr_hex, psm));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ }
+
+ return error_code; /* LCOV_EXCL_STOP */
+}
+
+int bt_socket_disconnect_l2cap_channel(int socket_fd)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS(); /* LCOV_EXCL_START */
+
+ error_code = _bt_get_error_code(bluetooth_l2cap_le_disconnect(socket_fd));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ }
+
+ return error_code; /* LCOV_EXCL_STOP */
+}
+
+int bt_socket_send_data_l2cap_channel(int socket_fd, const char *data,
+ int length)
+{
+ int ret = 0;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS(); /* LCOV_EXCL_START */
+ BT_CHECK_INPUT_PARAMETER(data);
+
+ ret = bluetooth_l2cap_le_write(socket_fd, data, length);
+ if (ret <= 0) {
+ if (ret == -1) {
+ /* write fail case */
+ if (errno == EACCES || errno == EPERM) {
+ set_last_result(BT_ERROR_PERMISSION_DENIED);
+ BT_ERR("PERMISSION_DENIED, errno = %d", errno);
+ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ set_last_result(BT_ERROR_AGAIN);
+ BT_ERR("BT_ERROR_AGAIN, errno = %d", errno);
+ } else {
+ set_last_result(BT_ERROR_OPERATION_FAILED);
+ BT_ERR("BT_ERROR_OPERATION_FAILED, errno = %d", errno);
+ }
+ } else {
+ ret = _bt_get_error_code(ret);
+ set_last_result(ret);
+ BT_ERR("Write failed, ret = %d", ret);
+ }
+ }
+
+ return ret; /* LCOV_EXCL_STOP */
+}
+
+int bt_socket_get_l2cap_psm(int socket_fd, int *psm)
+{
+ int ret = 0;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS(); /* LCOV_EXCL_START */
+
+ ret = bluetooth_l2cap_le_get_psm(socket_fd, psm);
+ if (ret < 0) {
+ ret = _bt_get_error_code(ret);
+ BT_ERR("Get PSM failed, ret = %d", ret);
+ }
+
+ return ret; /* LCOV_EXCL_STOP */
+}
+
+int bt_socket_set_l2cap_channel_connection_state_changed_cb(
+ bt_socket_l2cap_channel_connection_state_changed_cb callback, void *user_data)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_L2CAP_CHANNEL_CONNECTION_STATE_CHANGED, callback, user_data);
+ return BT_ERROR_NONE;
+}
+
+int bt_socket_unset_l2cap_channel_connection_state_changed_cb(void)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ _bt_unset_cb(BT_EVENT_L2CAP_CHANNEL_CONNECTION_STATE_CHANGED);
+ return BT_ERROR_NONE;
+}
+
+int bt_socket_set_l2cap_channel_connection_requested_cb(
+ bt_socket_connection_requested_cb callback, void *user_data)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_L2CAP_CHANNEL_CONNECTION_REQUESTED, callback, user_data);
+ return BT_ERROR_NONE;
+}
+
+int bt_socket_unset_l2cap_channel_connection_requested_cb(void)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ _bt_unset_cb(BT_EVENT_L2CAP_CHANNEL_CONNECTION_REQUESTED);
+ return BT_ERROR_NONE;
+}
+