mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-03 20:54:18 +00:00
l2cap and rfcomm close connection functionality was moved to deamon
This commit is contained in:
parent
5d227f2503
commit
03ce1a58ea
163
src/daemon.c
163
src/daemon.c
@ -108,6 +108,8 @@ typedef struct {
|
||||
connection_t * connection;
|
||||
linked_list_t rfcomm_cids;
|
||||
linked_list_t rfcomm_services;
|
||||
linked_list_t l2cap_cids;
|
||||
linked_list_t l2cap_psms;
|
||||
|
||||
// power mode
|
||||
HCI_POWER_MODE power_mode;
|
||||
@ -117,6 +119,15 @@ typedef struct {
|
||||
|
||||
} client_state_t;
|
||||
|
||||
typedef struct linked_list_uint16 {
|
||||
linked_item_t item;
|
||||
uint16_t value;
|
||||
} linked_list_uint16_t;
|
||||
|
||||
typedef struct gatt_client_helper {
|
||||
uint16_t characteristic_length;
|
||||
} gatt_client_helper_t;
|
||||
|
||||
// MARK: prototypes
|
||||
static void handle_sdp_rfcomm_service_result(sdp_query_event_t * event, void * context);
|
||||
static void handle_sdp_client_query_result(sdp_query_event_t * event);
|
||||
@ -127,6 +138,8 @@ static int clients_require_discoverable(void);
|
||||
static void clients_clear_power_request(void);
|
||||
static void start_power_off_timer(void);
|
||||
static void stop_power_off_timer(void);
|
||||
static client_state_t * client_for_connection(connection_t *connection);
|
||||
|
||||
|
||||
// MARK: globals
|
||||
static hci_transport_t * transport;
|
||||
@ -172,28 +185,129 @@ static void daemon_no_connections_timeout(struct timer *ts){
|
||||
// ATT_MTU - 1
|
||||
#define ATT_MAX_ATTRIBUTE_SIZE 22
|
||||
|
||||
static void daemon_add_client_rfcomm_service(connection_t * conn, uint16_t service_channel){
|
||||
}
|
||||
static void daemon_remove_client_rfcomm_service(connection_t * conn, uint16_t service_channel){
|
||||
}
|
||||
static void daemon_add_client_rfcomm_channel(connection_t * conn, uint16_t cid){
|
||||
}
|
||||
static void daemon_remove_client_rfcomm_channel(connection_t * conn, uint16_t cid){
|
||||
static void add_uint16_to_list(linked_list_t *list, uint16_t value){
|
||||
linked_list_uint16_t * item = malloc(sizeof(linked_list_uint16_t));
|
||||
if (!item) return;
|
||||
item->value = value;
|
||||
linked_list_add(list, (linked_item_t *) item);
|
||||
}
|
||||
|
||||
static void daemon_add_client_l2cap_service(connection_t * conn, uint16_t psm){
|
||||
}
|
||||
static void daemon_remove_client_l2cap_service(connection_t * conn, uint16_t psm){
|
||||
}
|
||||
static void daemon_add_client_l2cap_channel(connection_t * conn, uint16_t cid){
|
||||
}
|
||||
static void daemon_remove_client_l2cap_channel(connection_t * conn, uint16_t cid){
|
||||
static void remove_and_free_uint16_from_list(linked_list_t *list, uint16_t value){
|
||||
linked_list_iterator_t it;
|
||||
linked_list_iterator_init(&it, list);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
linked_list_uint16_t * item = (linked_list_uint16_t*) linked_list_iterator_next(&it);
|
||||
if ( item->value != value) continue;
|
||||
linked_list_remove(list, (linked_item_t *) item);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void daemon_add_client_rfcomm_service(connection_t * connection, uint16_t service_channel){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
add_uint16_to_list(&client_state->rfcomm_services, service_channel);
|
||||
}
|
||||
|
||||
typedef struct gatt_client_helper {
|
||||
uint16_t characteristic_length;
|
||||
} gatt_client_helper_t;
|
||||
static void daemon_remove_client_rfcomm_service(connection_t * connection, uint16_t service_channel){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
remove_and_free_uint16_from_list(&client_state->rfcomm_services, service_channel);
|
||||
}
|
||||
|
||||
static void daemon_add_client_rfcomm_channel(connection_t * connection, uint16_t cid){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
add_uint16_to_list(&client_state->rfcomm_cids, cid);
|
||||
}
|
||||
|
||||
static void daemon_remove_client_rfcomm_channel(connection_t * connection, uint16_t cid){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
remove_and_free_uint16_from_list(&client_state->rfcomm_cids, cid);
|
||||
}
|
||||
|
||||
static void daemon_add_client_l2cap_service(connection_t * connection, uint16_t psm){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
add_uint16_to_list(&client_state->l2cap_psms, psm);
|
||||
}
|
||||
|
||||
static void daemon_remove_client_l2cap_service(connection_t * connection, uint16_t psm){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
remove_and_free_uint16_from_list(&client_state->l2cap_psms, psm);
|
||||
}
|
||||
|
||||
static void daemon_add_client_l2cap_channel(connection_t * connection, uint16_t cid){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
add_uint16_to_list(&client_state->l2cap_cids, cid);
|
||||
}
|
||||
|
||||
static void daemon_remove_client_l2cap_channel(connection_t * connection, uint16_t cid){
|
||||
client_state_t * client_state = client_for_connection(connection);
|
||||
if (!client_state) return;
|
||||
remove_and_free_uint16_from_list(&client_state->l2cap_cids, cid);
|
||||
}
|
||||
|
||||
static void daemon_rfcomm_close_connection(linked_list_t *rfcomm_services, linked_list_t *rfcomm_cids){
|
||||
linked_list_iterator_t it;
|
||||
|
||||
linked_list_iterator_init(&it, rfcomm_services);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
linked_list_uint16_t * item = (linked_list_uint16_t*) linked_list_iterator_next(&it);
|
||||
rfcomm_unregister_service_internal(item->value);
|
||||
linked_list_remove(rfcomm_services, (linked_item_t *) item);
|
||||
free(item);
|
||||
}
|
||||
|
||||
linked_list_iterator_init(&it, rfcomm_cids);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
linked_list_uint16_t * item = (linked_list_uint16_t*) linked_list_iterator_next(&it);
|
||||
rfcomm_disconnect_internal(item->value);
|
||||
linked_list_remove(rfcomm_cids, (linked_item_t *) item);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void daemon_l2cap_close_connection(linked_list_t *l2cap_psms, linked_list_t *l2cap_cids){
|
||||
linked_list_iterator_t it;
|
||||
|
||||
linked_list_iterator_init(&it, l2cap_psms);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
linked_list_uint16_t * item = (linked_list_uint16_t*) linked_list_iterator_next(&it);
|
||||
l2cap_unregister_service_internal(NULL, item->value);
|
||||
linked_list_remove(l2cap_psms, (linked_item_t *) item);
|
||||
free(item);
|
||||
}
|
||||
|
||||
linked_list_iterator_init(&it, l2cap_cids);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
linked_list_uint16_t * item = (linked_list_uint16_t*) linked_list_iterator_next(&it);
|
||||
l2cap_disconnect_internal(item->value, 0); // note: reason isn't used
|
||||
linked_list_remove(l2cap_cids, (linked_item_t *) item);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void daemon_disconnect_client(connection_t * connection){
|
||||
log_info("Daemon disconnect client %p\n",connection);
|
||||
|
||||
client_state_t * client = client_for_connection(connection);
|
||||
if (!client) return;
|
||||
|
||||
sdp_unregister_services_for_connection(connection);
|
||||
daemon_rfcomm_close_connection(&client->rfcomm_services, &client->rfcomm_cids);
|
||||
daemon_l2cap_close_connection(&client->l2cap_psms, &client->l2cap_cids);
|
||||
#ifdef HAVE_BLE
|
||||
// NOTE: experimental - disconnect all LE connections where GATT Client was used
|
||||
gatt_client_disconnect_connection(connection);
|
||||
#endif
|
||||
|
||||
linked_list_remove(&clients, (linked_item_t *) client);
|
||||
free(client);
|
||||
}
|
||||
|
||||
static gatt_client_t * daemon_provide_gatt_client_context_for_handle(uint16_t handle){
|
||||
gatt_client_t *context;
|
||||
@ -496,7 +610,7 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
break;
|
||||
case RFCOMM_UNREGISTER_SERVICE:
|
||||
service_channel = READ_BT_16(packet, 3);
|
||||
daemon_remove_client_rfcomm_service(service_channel);
|
||||
daemon_remove_client_rfcomm_service(connection, service_channel);
|
||||
rfcomm_unregister_service_internal(service_channel);
|
||||
break;
|
||||
case RFCOMM_ACCEPT_CONNECTION:
|
||||
@ -770,24 +884,13 @@ static int daemon_client_handler(connection_t *connection, uint16_t packet_type,
|
||||
break;
|
||||
case DAEMON_EVENT_CONNECTION_CLOSED:
|
||||
log_info("DAEMON_EVENT_CONNECTION_CLOSED %p\n",connection);
|
||||
sdp_unregister_services_for_connection(connection);
|
||||
rfcomm_close_connection(connection);
|
||||
l2cap_close_connection(connection);
|
||||
#ifdef HAVE_BLE
|
||||
// NOTE: experimental - disconnect all LE connections where GATT Client was used
|
||||
gatt_client_disconnect_connection(connection);
|
||||
#endif
|
||||
daemon_disconnect_client(connection);
|
||||
sdp_query_rfcomm_deregister_callback();
|
||||
// no clients -> no HCI connections
|
||||
if (!clients){
|
||||
hci_disconnect_all();
|
||||
}
|
||||
|
||||
client = client_for_connection(connection);
|
||||
if (!client) break;
|
||||
linked_list_remove(&clients, (linked_item_t *) client);
|
||||
free(client);
|
||||
|
||||
// update discoverable mode
|
||||
hci_discoverable_control(clients_require_discoverable());
|
||||
// start power off, if last active client
|
||||
|
26
src/l2cap.c
26
src/l2cap.c
@ -1486,32 +1486,6 @@ void l2cap_unregister_service_internal(void *connection, uint16_t psm){
|
||||
hci_connectable_control(0);
|
||||
}
|
||||
|
||||
//
|
||||
void l2cap_close_connection(void *connection){
|
||||
|
||||
linked_list_iterator_t it;
|
||||
|
||||
// close open channels
|
||||
linked_list_iterator_init(&it, &l2cap_channels);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
l2cap_channel_t * channel = (l2cap_channel_t *) linked_list_iterator_next(&it);
|
||||
if (channel->connection != connection) continue;
|
||||
channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||
channel->connection = NULL;
|
||||
}
|
||||
|
||||
// unregister services
|
||||
linked_list_iterator_init(&it, &l2cap_services);
|
||||
while (linked_list_iterator_has_next(&it)){
|
||||
l2cap_service_t * service = (l2cap_service_t *) linked_list_iterator_next(&it);
|
||||
if (service->connection != connection) continue;
|
||||
linked_list_iterator_remove(&it);
|
||||
btstack_memory_l2cap_service_free(service);
|
||||
}
|
||||
|
||||
// process
|
||||
l2cap_run();
|
||||
}
|
||||
|
||||
// Bluetooth 4.0 - allows to register handler for Attribute Protocol and Security Manager Protocol
|
||||
void l2cap_register_fixed_channel(btstack_packet_handler_t packet_handler, uint16_t channel_id) {
|
||||
|
@ -225,8 +225,6 @@ uint16_t l2cap_max_le_mtu(void);
|
||||
|
||||
int l2cap_send_connectionless(uint16_t handle, uint16_t cid, uint8_t *data, uint16_t len);
|
||||
|
||||
void l2cap_close_connection(void *connection);
|
||||
|
||||
int l2cap_send_echo_request(uint16_t handle, uint8_t *data, uint16_t len);
|
||||
|
||||
void l2cap_require_security_level_2_for_outgoing_sdp(); // testing
|
||||
|
28
src/rfcomm.c
28
src/rfcomm.c
@ -2257,34 +2257,6 @@ void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits){
|
||||
rfcomm_run();
|
||||
}
|
||||
|
||||
//
|
||||
void rfcomm_close_connection(void *connection){
|
||||
linked_item_t *it;
|
||||
|
||||
// close open channels
|
||||
for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
|
||||
rfcomm_channel_t * channel = (rfcomm_channel_t *)it;
|
||||
if (channel->connection != connection) continue;
|
||||
channel->state = RFCOMM_CHANNEL_SEND_DISC;
|
||||
channel->connection = NULL;
|
||||
}
|
||||
|
||||
// unregister services
|
||||
it = (linked_item_t *) &rfcomm_services;
|
||||
while (it->next) {
|
||||
rfcomm_service_t * service = (rfcomm_service_t *) it->next;
|
||||
if (service->connection == connection){
|
||||
it->next = it->next->next;
|
||||
btstack_memory_rfcomm_service_free(service);
|
||||
} else {
|
||||
it = it->next;
|
||||
}
|
||||
}
|
||||
|
||||
// process
|
||||
rfcomm_run();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -363,7 +363,6 @@ typedef struct {
|
||||
} rfcomm_channel_t;
|
||||
|
||||
void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
void rfcomm_close_connection(void *connection);
|
||||
|
||||
/** Embedded API **/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user