3939
4040/*
4141 * l2cap.c
42- *
43- * Logical Link Control and Adaption Protocl (L2CAP)
44- *
45- * Created by Matthias Ringwald on 5/16/09.
42+ * Logical Link Control and Adaption Protocol (L2CAP)
4643 */
4744
4845#include "l2cap.h"
5552#include "btstack_event.h"
5653#include "btstack_memory.h"
5754
55+ #ifdef ENABLE_LE_DATA_CHANNELS
56+ // TODO avoid dependency on higher layer: used to trigger pairing for outgoing connections
57+ #include "ble/sm.h"
58+ #endif
59+
5860#include <stdarg.h>
5961#include <string.h>
6062
@@ -3970,12 +3972,44 @@ uint8_t l2cap_le_decline_connection(uint16_t local_cid){
39703972 return ERROR_CODE_SUCCESS ;
39713973}
39723974
3973- uint8_t l2cap_le_create_channel (btstack_packet_handler_t packet_handler , hci_con_handle_t con_handle ,
3975+ // used to handle pairing complete after triggering to increase
3976+ static void l2cap_sm_packet_handler (uint8_t packet_type , uint16_t channel_nr , uint8_t * packet , uint16_t size ) {
3977+ UNUSED (channel_nr );
3978+ UNUSED (size );
3979+ btstack_assert (packet_type = HCI_EVENT_PACKET );
3980+ if (hci_event_packet_get_type (packet ) != SM_EVENT_PAIRING_COMPLETE ) return ;
3981+ hci_con_handle_t con_handle = sm_event_pairing_complete_get_handle (packet );
3982+ btstack_linked_list_iterator_t it ;
3983+ btstack_linked_list_iterator_init (& it , & l2cap_channels );
3984+ while (btstack_linked_list_iterator_has_next (& it )) {
3985+ l2cap_channel_t * channel = (l2cap_channel_t * ) btstack_linked_list_iterator_next (& it );
3986+ if (!l2cap_is_dynamic_channel_type (channel -> channel_type )) continue ;
3987+ if (channel -> con_handle != con_handle ) continue ;
3988+ if (channel -> state != L2CAP_STATE_WAIT_OUTGOING_SECURITY_LEVEL_UPDATE ) continue ;
3989+
3990+ // found channel, check security level
3991+ if (gap_security_level (con_handle ) < channel -> required_security_level ){
3992+ // pairing failed or wasn't good enough, inform user
3993+ l2cap_emit_le_channel_opened (channel , ERROR_CODE_INSUFFICIENT_SECURITY );
3994+ // discard channel
3995+ btstack_linked_list_remove (& l2cap_channels , (btstack_linked_item_t * ) channel );
3996+ l2cap_free_channel_entry (channel );
3997+ } else {
3998+ // send conn request now
3999+ channel -> state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST ;
4000+ l2cap_run ();
4001+ }
4002+ }
4003+ }
4004+
4005+ uint8_t l2cap_le_create_channel (btstack_packet_handler_t packet_handler , hci_con_handle_t con_handle ,
39744006 uint16_t psm , uint8_t * receive_sdu_buffer , uint16_t mtu , uint16_t initial_credits , gap_security_level_t security_level ,
39754007 uint16_t * out_local_cid ) {
39764008
3977- log_info ("L2CAP_LE_CREATE_CHANNEL handle 0x%04x psm 0x%x mtu %u" , con_handle , psm , mtu );
4009+ static btstack_packet_callback_registration_t sm_event_callback_registration ;
4010+ static bool sm_callback_registered = false;
39784011
4012+ log_info ("L2CAP_LE_CREATE_CHANNEL handle 0x%04x psm 0x%x mtu %u" , con_handle , psm , mtu );
39794013
39804014 hci_connection_t * connection = hci_connection_for_handle (con_handle );
39814015 if (!connection ) {
@@ -3994,18 +4028,33 @@ uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, hci_con
39944028 * out_local_cid = channel -> local_cid ;
39954029 }
39964030
3997- // provide buffer
4031+ // setup channel entry
39984032 channel -> con_handle = con_handle ;
39994033 channel -> receive_sdu_buffer = receive_sdu_buffer ;
4000- channel -> state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST ;
40014034 channel -> new_credits_incoming = initial_credits ;
40024035 channel -> automatic_credits = initial_credits == L2CAP_LE_AUTOMATIC_CREDITS ;
40034036
40044037 // add to connections list
40054038 btstack_linked_list_add_tail (& l2cap_channels , (btstack_linked_item_t * ) channel );
40064039
4007- // go
4008- l2cap_run ();
4040+ // check security level
4041+ if (gap_security_level (con_handle ) < channel -> required_security_level ){
4042+ if (!sm_callback_registered ){
4043+ sm_callback_registered = true;
4044+ // lazy registration for SM events
4045+ sm_event_callback_registration .callback = & l2cap_sm_packet_handler ;
4046+ sm_add_event_handler (& sm_event_callback_registration );
4047+ }
4048+
4049+ // start pairing
4050+ channel -> state = L2CAP_STATE_WAIT_OUTGOING_SECURITY_LEVEL_UPDATE ;
4051+ sm_request_pairing (con_handle );
4052+ } else {
4053+ // send conn request right away
4054+ channel -> state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST ;
4055+ l2cap_run ();
4056+ }
4057+
40094058 return ERROR_CODE_SUCCESS ;
40104059}
40114060
0 commit comments