diff --git a/CHANGELOG.md b/CHANGELOG.md index 381e105ec..abf406501 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - GAP: local name, EIR data, class of device and default link policy can be updated at any time - L2CAP: provide status instead of undocumented int error code and bool for API functions - L2CAP: remote features not required for SDP connections +- L2CAP: replaced l2cap_register_packet_handler with l2cap_add_event_handler to register multiple handlers - RFCOMM: `RFCOMM_EVENT_PORT_CONFIGURATION` contains rfcomm_cid and remote flag, emitted for query config - RFCOMM: provide status instead of undocumented int error code and bool for API functions - RFCOMM: remote port configuration, line status, and modem status are sent by channel state machine diff --git a/src/ble/gatt-service/cycling_power_service_server.c b/src/ble/gatt-service/cycling_power_service_server.c index 48fd8cff5..e6af9d9a2 100644 --- a/src/ble/gatt-service/cycling_power_service_server.c +++ b/src/ble/gatt-service/cycling_power_service_server.c @@ -218,6 +218,7 @@ typedef struct { static att_service_handler_t cycling_power_service; static cycling_power_t cycling_power; static btstack_packet_callback_registration_t hci_event_callback_registration; +static btstack_packet_callback_registration_t l2cap_event_callback_registration; static uint16_t cycling_power_service_read_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ UNUSED(con_handle); @@ -997,9 +998,12 @@ void cycling_power_service_server_init(uint32_t feature_flags, instance->con_interval_max = 6; instance->con_interval_status = CP_CONNECTION_INTERVAL_STATUS_NONE; instance->w4_indication_complete = 0; + hci_event_callback_registration.callback = &packet_handler; hci_add_event_handler(&hci_event_callback_registration); - l2cap_register_packet_handler(&packet_handler); + + l2cap_event_callback_registration.callback = &packet_handler; + l2cap_add_event_handler(&l2cap_event_callback_registration); instance->sensor_location = current_sensor_location; instance->num_supported_sensor_locations = 0; diff --git a/src/l2cap.c b/src/l2cap.c index 4170f6bfe..194c53766 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -214,10 +214,12 @@ static btstack_packet_callback_registration_t l2cap_hci_event_callback_registrat #ifdef ENABLE_BLE // only used for connection parameter update events -static btstack_packet_handler_t l2cap_event_packet_handler; static uint16_t l2cap_le_custom_max_mtu; #endif +/* callbacks for events */ +static btstack_linked_list_t l2cap_event_handlers; + #ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE // enable for testing @@ -931,7 +933,6 @@ void l2cap_deinit(void){ (void)memset(l2cap_outgoing_classic_addr, 0, 6); #endif #ifdef ENABLE_BLE - l2cap_event_packet_handler = NULL; l2cap_le_custom_max_mtu = 0; (void)memset(&l2cap_fixed_channel_att, 0, sizeof(l2cap_fixed_channel_att)); (void)memset(&l2cap_fixed_channel_sm, 0, sizeof(l2cap_fixed_channel_sm)); @@ -939,15 +940,26 @@ void l2cap_deinit(void){ #ifdef ENABLE_LE_DATA_CHANNELS l2cap_le_services = NULL; #endif - l2cap_signaling_responses_pending = 0; + l2cap_event_handlers = NULL; } -void l2cap_register_packet_handler(void (*handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){ -#ifdef ENABLE_BLE - l2cap_event_packet_handler = handler; -#else - UNUSED(handler); // ok: no code -#endif +void l2cap_add_event_handler(btstack_packet_callback_registration_t * callback_handler){ + btstack_linked_list_add_tail(&l2cap_event_handlers, (btstack_linked_item_t*) callback_handler); +} + +void l2cap_remove_event_handler(btstack_packet_callback_registration_t * callback_handler){ + btstack_linked_list_remove(&l2cap_event_handlers, (btstack_linked_item_t*) callback_handler); +} + +static void l2cap_emit_event(uint8_t *event, uint16_t size) { + hci_dump_packet( HCI_EVENT_PACKET, 0, event, size); + // dispatch to all event handlers + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, &l2cap_event_handlers); + while (btstack_linked_list_iterator_has_next(&it)){ + btstack_packet_callback_registration_t * entry = (btstack_packet_callback_registration_t*) btstack_linked_list_iterator_next(&it); + entry->callback(HCI_EVENT_PACKET, 0, event, size); + } } void l2cap_request_can_send_fix_channel_now_event(hci_con_handle_t con_handle, uint16_t channel_id){ @@ -3201,9 +3213,7 @@ static void l2cap_emit_connection_parameter_update_response(hci_con_handle_t con event[1] = 4; little_endian_store_16(event, 2, con_handle); little_endian_store_16(event, 4, result); - hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event)); - if (!l2cap_event_packet_handler) return; - (*l2cap_event_packet_handler)(HCI_EVENT_PACKET, 0, event, sizeof(event)); + l2cap_emit_event(event, sizeof(event)); } // @return valid @@ -3258,14 +3268,11 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t connection->le_con_param_update_identifier = sig_id; } - if (!l2cap_event_packet_handler) break; - event[0] = L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_REQUEST; event[1] = 8; little_endian_store_16(event, 2, handle); (void)memcpy(&event[4], &command[4], 8); - hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event)); - (*l2cap_event_packet_handler)( HCI_EVENT_PACKET, 0, event, sizeof(event)); + l2cap_emit_event(event, sizeof(event)); break; case CONNECTION_PARAMETER_UPDATE_RESPONSE: diff --git a/src/l2cap.h b/src/l2cap.h index 471eb2a83..3f83a15d2 100644 --- a/src/l2cap.h +++ b/src/l2cap.h @@ -447,10 +447,15 @@ bool l2cap_can_send_prepared_packet_now(uint16_t local_cid); */ void l2cap_init(void); -/** - * @brief Registers packet handler for LE Connection Parameter Update events +/** + * @brief Add event packet handler for LE Connection Parameter Update events */ -void l2cap_register_packet_handler(void (*handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)); +void l2cap_add_event_handler(btstack_packet_callback_registration_t * callback_handler); + +/** + * @brief Remove event packet handler. + */ +void l2cap_remove_event_handler(btstack_packet_callback_registration_t * callback_handler); /** * @brief Get max MTU for Classic connections based on btstack configuration