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 ---