l2cap.c (7bbeb3ad8cec0c1816689843bf9383cf4c644ef8) | l2cap.c (5cc4b885855e6b1e18d5071e6f8bea446642a73d) |
---|---|
1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 25 unchanged lines hidden (view full) --- 34 * [email protected] 35 * 36 */ 37 38#define BTSTACK_FILE__ "l2cap.c" 39 40/* 41 * l2cap.c | 1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 25 unchanged lines hidden (view full) --- 34 * [email protected] 35 * 36 */ 37 38#define BTSTACK_FILE__ "l2cap.c" 39 40/* 41 * 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) |
46 */ 47 48#include "l2cap.h" 49#include "hci.h" 50#include "hci_dump.h" 51#include "bluetooth_sdp.h" 52#include "bluetooth_psm.h" 53#include "btstack_bool.h" 54#include "btstack_debug.h" 55#include "btstack_event.h" 56#include "btstack_memory.h" 57 | 43 */ 44 45#include "l2cap.h" 46#include "hci.h" 47#include "hci_dump.h" 48#include "bluetooth_sdp.h" 49#include "bluetooth_psm.h" 50#include "btstack_bool.h" 51#include "btstack_debug.h" 52#include "btstack_event.h" 53#include "btstack_memory.h" 54 |
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 |
|
58#include <stdarg.h> 59#include <string.h> 60 61/* 62 * @brief L2CAP Supervisory function in S-Frames 63 */ 64typedef enum { 65 L2CAP_SUPERVISORY_FUNCTION_RR_RECEIVER_READY = 0, --- 3899 unchanged lines hidden (view full) --- 3965 3966 // set state decline connection 3967 channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_DECLINE; 3968 channel->reason = 0x04; // no resources available 3969 l2cap_run(); 3970 return ERROR_CODE_SUCCESS; 3971} 3972 | 60#include <stdarg.h> 61#include <string.h> 62 63/* 64 * @brief L2CAP Supervisory function in S-Frames 65 */ 66typedef enum { 67 L2CAP_SUPERVISORY_FUNCTION_RR_RECEIVER_READY = 0, --- 3899 unchanged lines hidden (view full) --- 3967 3968 // set state decline connection 3969 channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_DECLINE; 3970 channel->reason = 0x04; // no resources available 3971 l2cap_run(); 3972 return ERROR_CODE_SUCCESS; 3973} 3974 |
3973uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, hci_con_handle_t con_handle, | 3975static gap_security_level_t l2cap_le_security_level_for_connection(hci_con_handle_t con_handle){ 3976 uint8_t encryption_key_size = gap_encryption_key_size(con_handle); 3977 if (encryption_key_size == 0) return LEVEL_0; 3978 3979 uint8_t authenticated = gap_authenticated(con_handle); 3980 if (!authenticated) return LEVEL_2; 3981 3982 return encryption_key_size == 16 ? LEVEL_4 : LEVEL_3; 3983} 3984 3985// used to handle pairing complete after triggering to increase 3986static void l2cap_sm_packet_handler(uint8_t packet_type, uint16_t channel_nr, uint8_t *packet, uint16_t size) { 3987 UNUSED(channel_nr); 3988 UNUSED(size); 3989 btstack_assert(packet_type = HCI_EVENT_PACKET); 3990 if (hci_event_packet_get_type(packet) != SM_EVENT_PAIRING_COMPLETE) return; 3991 hci_con_handle_t con_handle = sm_event_pairing_complete_get_handle(packet); 3992 btstack_linked_list_iterator_t it; 3993 btstack_linked_list_iterator_init(&it, &l2cap_channels); 3994 while (btstack_linked_list_iterator_has_next(&it)) { 3995 l2cap_channel_t *channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it); 3996 if (!l2cap_is_dynamic_channel_type(channel->channel_type)) continue; 3997 if (channel->con_handle != con_handle) continue; 3998 if (channel->state != L2CAP_STATE_WAIT_OUTGOING_SECURITY_LEVEL_UPDATE) continue; 3999 4000 // found channel, check security level 4001 if (l2cap_le_security_level_for_connection(con_handle) < channel->required_security_level){ 4002 // pairing failed or wasn't good enough, inform user 4003 l2cap_emit_le_channel_opened(channel, ERROR_CODE_INSUFFICIENT_SECURITY); 4004 // discard channel 4005 btstack_linked_list_remove(&l2cap_channels, (btstack_linked_item_t *) channel); 4006 l2cap_free_channel_entry(channel); 4007 } else { 4008 // send conn request now 4009 channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST; 4010 l2cap_run(); 4011 } 4012 } 4013} 4014 4015uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, hci_con_handle_t con_handle, |
3974 uint16_t psm, uint8_t * receive_sdu_buffer, uint16_t mtu, uint16_t initial_credits, gap_security_level_t security_level, 3975 uint16_t * out_local_cid) { 3976 | 4016 uint16_t psm, uint8_t * receive_sdu_buffer, uint16_t mtu, uint16_t initial_credits, gap_security_level_t security_level, 4017 uint16_t * out_local_cid) { 4018 |
4019 static btstack_packet_callback_registration_t sm_event_callback_registration; 4020 static bool sm_callback_registered = false; 4021 |
|
3977 log_info("L2CAP_LE_CREATE_CHANNEL handle 0x%04x psm 0x%x mtu %u", con_handle, psm, mtu); 3978 | 4022 log_info("L2CAP_LE_CREATE_CHANNEL handle 0x%04x psm 0x%x mtu %u", con_handle, psm, mtu); 4023 |
3979 | |
3980 hci_connection_t * connection = hci_connection_for_handle(con_handle); 3981 if (!connection) { 3982 log_error("no hci_connection for handle 0x%04x", con_handle); 3983 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 3984 } 3985 3986 l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, L2CAP_CHANNEL_TYPE_LE_DATA_CHANNEL, connection->address, connection->address_type, psm, mtu, security_level); 3987 if (!channel) { 3988 return BTSTACK_MEMORY_ALLOC_FAILED; 3989 } 3990 log_info("l2cap_le_create_channel %p", channel); 3991 3992 // store local_cid 3993 if (out_local_cid){ 3994 *out_local_cid = channel->local_cid; 3995 } 3996 | 4024 hci_connection_t * connection = hci_connection_for_handle(con_handle); 4025 if (!connection) { 4026 log_error("no hci_connection for handle 0x%04x", con_handle); 4027 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 4028 } 4029 4030 l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, L2CAP_CHANNEL_TYPE_LE_DATA_CHANNEL, connection->address, connection->address_type, psm, mtu, security_level); 4031 if (!channel) { 4032 return BTSTACK_MEMORY_ALLOC_FAILED; 4033 } 4034 log_info("l2cap_le_create_channel %p", channel); 4035 4036 // store local_cid 4037 if (out_local_cid){ 4038 *out_local_cid = channel->local_cid; 4039 } 4040 |
3997 // provide buffer | 4041 // setup channel entry |
3998 channel->con_handle = con_handle; 3999 channel->receive_sdu_buffer = receive_sdu_buffer; | 4042 channel->con_handle = con_handle; 4043 channel->receive_sdu_buffer = receive_sdu_buffer; |
4000 channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST; | |
4001 channel->new_credits_incoming = initial_credits; 4002 channel->automatic_credits = initial_credits == L2CAP_LE_AUTOMATIC_CREDITS; 4003 4004 // add to connections list 4005 btstack_linked_list_add_tail(&l2cap_channels, (btstack_linked_item_t *) channel); 4006 | 4044 channel->new_credits_incoming = initial_credits; 4045 channel->automatic_credits = initial_credits == L2CAP_LE_AUTOMATIC_CREDITS; 4046 4047 // add to connections list 4048 btstack_linked_list_add_tail(&l2cap_channels, (btstack_linked_item_t *) channel); 4049 |
4007 // go 4008 l2cap_run(); | 4050 // check security level 4051 if (l2cap_le_security_level_for_connection(con_handle) < channel->required_security_level){ 4052 if (!sm_callback_registered){ 4053 sm_callback_registered = true; 4054 // lazy registration for SM events 4055 sm_event_callback_registration.callback = &l2cap_sm_packet_handler; 4056 sm_add_event_handler(&sm_event_callback_registration); 4057 } 4058 4059 // start pairing 4060 channel->state = L2CAP_STATE_WAIT_OUTGOING_SECURITY_LEVEL_UPDATE; 4061 sm_request_pairing(con_handle); 4062 } else { 4063 // send conn request right away 4064 channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST; 4065 l2cap_run(); 4066 } 4067 |
4009 return ERROR_CODE_SUCCESS; 4010} 4011 4012/** 4013 * @brief Provide credtis for LE Data Channel 4014 * @param local_cid L2CAP LE Data Channel Identifier 4015 * @param credits Number additional credits for peer 4016 */ --- 119 unchanged lines hidden --- | 4068 return ERROR_CODE_SUCCESS; 4069} 4070 4071/** 4072 * @brief Provide credtis for LE Data Channel 4073 * @param local_cid L2CAP LE Data Channel Identifier 4074 * @param credits Number additional credits for peer 4075 */ --- 119 unchanged lines hidden --- |