hci.c (db3c1f8953db60524595003c01ae187087b26388) hci.c (88f925b1380e6f3279a1bb5853619c27cd034996)
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

--- 297 unchanged lines hidden (view full) ---

306#endif
307}
308
309/**
310 * create connection for given address
311 *
312 * @return connection OR NULL, if no memory left
313 */
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

--- 297 unchanged lines hidden (view full) ---

306#endif
307}
308
309/**
310 * create connection for given address
311 *
312 * @return connection OR NULL, if no memory left
313 */
314static hci_connection_t * create_connection_for_bd_addr_and_type(const bd_addr_t addr, bd_addr_type_t addr_type){
314static hci_connection_t *
315create_connection_for_bd_addr_and_type(const bd_addr_t addr, bd_addr_type_t addr_type, hci_role_t role) {
315 log_info("create_connection_for_addr %s, type %x", bd_addr_to_str(addr), addr_type);
316
317 hci_connection_t * conn = btstack_memory_hci_connection_get();
318 if (!conn) return NULL;
319 hci_connection_init(conn);
320
321 bd_addr_copy(conn->address, addr);
322 conn->address_type = addr_type;
323 conn->con_handle = HCI_CON_HANDLE_INVALID;
316 log_info("create_connection_for_addr %s, type %x", bd_addr_to_str(addr), addr_type);
317
318 hci_connection_t * conn = btstack_memory_hci_connection_get();
319 if (!conn) return NULL;
320 hci_connection_init(conn);
321
322 bd_addr_copy(conn->address, addr);
323 conn->address_type = addr_type;
324 conn->con_handle = HCI_CON_HANDLE_INVALID;
324 conn->role = HCI_ROLE_INVALID;
325 conn->role = role;
325#ifdef ENABLE_LE_PERIODIC_ADVERTISING
326 conn->le_past_sync_handle = HCI_CON_HANDLE_INVALID;
327#endif
328 btstack_linked_list_add(&hci_stack->connections, (btstack_linked_item_t *) conn);
329
330 return conn;
331}
332

--- 2792 unchanged lines hidden (view full) ---

3125#ifdef ENABLE_BLE
3126static void event_handle_le_connection_complete(const uint8_t * packet){
3127 bd_addr_t addr;
3128 bd_addr_type_t addr_type;
3129 hci_connection_t * conn;
3130
3131 // read fields
3132 uint8_t status = packet[3];
326#ifdef ENABLE_LE_PERIODIC_ADVERTISING
327 conn->le_past_sync_handle = HCI_CON_HANDLE_INVALID;
328#endif
329 btstack_linked_list_add(&hci_stack->connections, (btstack_linked_item_t *) conn);
330
331 return conn;
332}
333

--- 2792 unchanged lines hidden (view full) ---

3126#ifdef ENABLE_BLE
3127static void event_handle_le_connection_complete(const uint8_t * packet){
3128 bd_addr_t addr;
3129 bd_addr_type_t addr_type;
3130 hci_connection_t * conn;
3131
3132 // read fields
3133 uint8_t status = packet[3];
3133 uint8_t role = packet[6];
3134 uint16_t conn_interval;
3134 hci_role_t role = (hci_role_t) packet[6];
3135
3136 // support different connection complete events
3135
3136 // support different connection complete events
3137 uint16_t conn_interval;
3137 switch (packet[2]){
3138 case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
3139 conn_interval = hci_subevent_le_connection_complete_get_conn_interval(packet);
3140 break;
3141#ifdef ENABLE_LE_EXTENDED_ADVERTISING
3142 case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE_V1:
3143 conn_interval = hci_subevent_le_enhanced_connection_complete_v1_get_conn_interval(packet);
3144 break;

--- 52 unchanged lines hidden (view full) ---

3197#ifdef ENABLE_LE_PERIPHERAL
3198 // if we're slave, it was an incoming connection, advertisements have stopped
3199 hci_stack->le_advertisements_state &= ~LE_ADVERTISEMENT_STATE_ACTIVE;
3200#endif
3201 }
3202
3203 // LE connections are auto-accepted, so just create a connection if there isn't one already
3204 if (!conn){
3138 switch (packet[2]){
3139 case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
3140 conn_interval = hci_subevent_le_connection_complete_get_conn_interval(packet);
3141 break;
3142#ifdef ENABLE_LE_EXTENDED_ADVERTISING
3143 case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE_V1:
3144 conn_interval = hci_subevent_le_enhanced_connection_complete_v1_get_conn_interval(packet);
3145 break;

--- 52 unchanged lines hidden (view full) ---

3198#ifdef ENABLE_LE_PERIPHERAL
3199 // if we're slave, it was an incoming connection, advertisements have stopped
3200 hci_stack->le_advertisements_state &= ~LE_ADVERTISEMENT_STATE_ACTIVE;
3201#endif
3202 }
3203
3204 // LE connections are auto-accepted, so just create a connection if there isn't one already
3205 if (!conn){
3205 conn = create_connection_for_bd_addr_and_type(addr, addr_type);
3206 conn = create_connection_for_bd_addr_and_type(addr, addr_type, role);
3206 }
3207
3208 // no memory, sorry.
3209 if (!conn){
3210 return;
3211 }
3212
3213 conn->state = OPEN;
3207 }
3208
3209 // no memory, sorry.
3210 if (!conn){
3211 return;
3212 }
3213
3214 conn->state = OPEN;
3214 conn->role = role;
3215 conn->con_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
3216 conn->le_connection_interval = conn_interval;
3217
3218 // workaround: PAST doesn't work without LE Read Remote Features on PacketCraft Controller with LMP 568B
3219 conn->gap_connection_tasks = GAP_CONNECTION_TASK_LE_READ_REMOTE_FEATURES;
3220
3221#ifdef ENABLE_LE_PERIPHERAL
3222 if (role == HCI_ROLE_SLAVE){

--- 272 unchanged lines hidden (view full) ---

3495 }
3496 }
3497
3498 // TODO: eval COD 8-10
3499 log_info("Connection_incoming: %s, type %u", bd_addr_to_str(addr), (unsigned int) link_type);
3500 addr_type = (link_type == HCI_LINK_TYPE_ACL) ? BD_ADDR_TYPE_ACL : BD_ADDR_TYPE_SCO;
3501 conn = hci_connection_for_bd_addr_and_type(addr, addr_type);
3502 if (!conn) {
3215 conn->con_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
3216 conn->le_connection_interval = conn_interval;
3217
3218 // workaround: PAST doesn't work without LE Read Remote Features on PacketCraft Controller with LMP 568B
3219 conn->gap_connection_tasks = GAP_CONNECTION_TASK_LE_READ_REMOTE_FEATURES;
3220
3221#ifdef ENABLE_LE_PERIPHERAL
3222 if (role == HCI_ROLE_SLAVE){

--- 272 unchanged lines hidden (view full) ---

3495 }
3496 }
3497
3498 // TODO: eval COD 8-10
3499 log_info("Connection_incoming: %s, type %u", bd_addr_to_str(addr), (unsigned int) link_type);
3500 addr_type = (link_type == HCI_LINK_TYPE_ACL) ? BD_ADDR_TYPE_ACL : BD_ADDR_TYPE_SCO;
3501 conn = hci_connection_for_bd_addr_and_type(addr, addr_type);
3502 if (!conn) {
3503 conn = create_connection_for_bd_addr_and_type(addr, addr_type);
3503 conn = create_connection_for_bd_addr_and_type(addr, addr_type, HCI_ROLE_SLAVE);
3504 }
3505 if (!conn) {
3506 // CONNECTION REJECTED DUE TO LIMITED RESOURCES (0X0D)
3507 hci_stack->decline_reason = ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES;
3508 bd_addr_copy(hci_stack->decline_addr, addr);
3509 hci_run();
3510 // avoid event to higher layer
3511 return;
3512 }
3504 }
3505 if (!conn) {
3506 // CONNECTION REJECTED DUE TO LIMITED RESOURCES (0X0D)
3507 hci_stack->decline_reason = ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES;
3508 bd_addr_copy(hci_stack->decline_addr, addr);
3509 hci_run();
3510 // avoid event to higher layer
3511 return;
3512 }
3513 conn->role = HCI_ROLE_SLAVE;
3514 conn->state = RECEIVED_CONNECTION_REQUEST;
3515 // store info about eSCO
3516 if (link_type == HCI_LINK_TYPE_ESCO){
3517 conn->remote_supported_features[0] |= 1;
3518 }
3519 hci_run();
3520 break;
3521

--- 475 unchanged lines hidden (view full) ---

3997
3998#ifdef ENABLE_CLASSIC
3999 case HCI_EVENT_ROLE_CHANGE:
4000 if (packet[2]) break; // status != 0
4001 reverse_bd_addr(&packet[3], addr);
4002 addr_type = BD_ADDR_TYPE_ACL;
4003 conn = hci_connection_for_bd_addr_and_type(addr, addr_type);
4004 if (!conn) break;
3513 conn->state = RECEIVED_CONNECTION_REQUEST;
3514 // store info about eSCO
3515 if (link_type == HCI_LINK_TYPE_ESCO){
3516 conn->remote_supported_features[0] |= 1;
3517 }
3518 hci_run();
3519 break;
3520

--- 475 unchanged lines hidden (view full) ---

3996
3997#ifdef ENABLE_CLASSIC
3998 case HCI_EVENT_ROLE_CHANGE:
3999 if (packet[2]) break; // status != 0
4000 reverse_bd_addr(&packet[3], addr);
4001 addr_type = BD_ADDR_TYPE_ACL;
4002 conn = hci_connection_for_bd_addr_and_type(addr, addr_type);
4003 if (!conn) break;
4005 conn->role = packet[9];
4004 conn->role = (hci_role_t) packet[9];
4006 break;
4007#endif
4008
4009 case HCI_EVENT_TRANSPORT_PACKET_SENT:
4010 // release packet buffer only for asynchronous transport and if there are not further fragments
4011 if (hci_transport_synchronous()) {
4012 log_error("Synchronous HCI Transport shouldn't send HCI_EVENT_TRANSPORT_PACKET_SENT");
4013 return; // instead of break: to avoid re-entering hci_run()

--- 2815 unchanged lines hidden (view full) ---

6829#endif
6830#endif
6831 break;
6832 }
6833 return true;
6834
6835#ifdef ENABLE_CLASSIC
6836 case RECEIVED_CONNECTION_REQUEST:
4005 break;
4006#endif
4007
4008 case HCI_EVENT_TRANSPORT_PACKET_SENT:
4009 // release packet buffer only for asynchronous transport and if there are not further fragments
4010 if (hci_transport_synchronous()) {
4011 log_error("Synchronous HCI Transport shouldn't send HCI_EVENT_TRANSPORT_PACKET_SENT");
4012 return; // instead of break: to avoid re-entering hci_run()

--- 2815 unchanged lines hidden (view full) ---

6828#endif
6829#endif
6830 break;
6831 }
6832 return true;
6833
6834#ifdef ENABLE_CLASSIC
6835 case RECEIVED_CONNECTION_REQUEST:
6837 connection->role = HCI_ROLE_SLAVE;
6838 if (connection->address_type == BD_ADDR_TYPE_ACL){
6839 log_info("sending hci_accept_connection_request");
6840 connection->state = ACCEPTED_CONNECTION_REQUEST;
6841 hci_send_cmd(&hci_accept_connection_request, connection->address, hci_stack->master_slave_policy);
6842 return true;
6843 }
6844 break;
6845#endif

--- 408 unchanged lines hidden (view full) ---

7254 // CVE-2020-26555: reject outgoing connection to device with same BD ADDR
7255 if (memcmp(hci_stack->local_bd_addr, addr, 6) == 0) {
7256 hci_emit_connection_complete(addr, 0, ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR);
7257 return ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR;
7258 }
7259
7260 conn = hci_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL);
7261 if (!conn) {
6836 if (connection->address_type == BD_ADDR_TYPE_ACL){
6837 log_info("sending hci_accept_connection_request");
6838 connection->state = ACCEPTED_CONNECTION_REQUEST;
6839 hci_send_cmd(&hci_accept_connection_request, connection->address, hci_stack->master_slave_policy);
6840 return true;
6841 }
6842 break;
6843#endif

--- 408 unchanged lines hidden (view full) ---

7252 // CVE-2020-26555: reject outgoing connection to device with same BD ADDR
7253 if (memcmp(hci_stack->local_bd_addr, addr, 6) == 0) {
7254 hci_emit_connection_complete(addr, 0, ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR);
7255 return ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR;
7256 }
7257
7258 conn = hci_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL);
7259 if (!conn) {
7262 conn = create_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL);
7260 conn = create_connection_for_bd_addr_and_type(addr, BD_ADDR_TYPE_ACL, HCI_ROLE_MASTER);
7263 if (!conn) {
7264 // notify client that alloc failed
7265 hci_emit_connection_complete(addr, 0, BTSTACK_MEMORY_ALLOC_FAILED);
7266 return BTSTACK_MEMORY_ALLOC_FAILED; // packet not sent to controller
7267 }
7268 conn->state = SEND_CREATE_CONNECTION;
7261 if (!conn) {
7262 // notify client that alloc failed
7263 hci_emit_connection_complete(addr, 0, BTSTACK_MEMORY_ALLOC_FAILED);
7264 return BTSTACK_MEMORY_ALLOC_FAILED; // packet not sent to controller
7265 }
7266 conn->state = SEND_CREATE_CONNECTION;
7269 conn->role = HCI_ROLE_MASTER;
7270 }
7271
7272 log_info("conn state %u", conn->state);
7273 // TODO: L2CAP should not send create connection command, instead a (new) gap function should be used
7274 switch (conn->state) {
7275 // if connection active exists
7276 case OPEN:
7277 // and OPEN, emit connection complete command

--- 32 unchanged lines hidden (view full) ---

7310 } else {
7311 switch (conn->address_type){
7312 case BD_ADDR_TYPE_ACL:
7313 // assert SCO connection does not exit
7314 if (hci_connection_for_bd_addr_and_type(conn->address, BD_ADDR_TYPE_SCO) != NULL){
7315 return ERROR_CODE_COMMAND_DISALLOWED;
7316 }
7317 // allocate connection struct
7267 }
7268
7269 log_info("conn state %u", conn->state);
7270 // TODO: L2CAP should not send create connection command, instead a (new) gap function should be used
7271 switch (conn->state) {
7272 // if connection active exists
7273 case OPEN:
7274 // and OPEN, emit connection complete command

--- 32 unchanged lines hidden (view full) ---

7307 } else {
7308 switch (conn->address_type){
7309 case BD_ADDR_TYPE_ACL:
7310 // assert SCO connection does not exit
7311 if (hci_connection_for_bd_addr_and_type(conn->address, BD_ADDR_TYPE_SCO) != NULL){
7312 return ERROR_CODE_COMMAND_DISALLOWED;
7313 }
7314 // allocate connection struct
7318 conn = create_connection_for_bd_addr_and_type(conn->address, BD_ADDR_TYPE_SCO);
7315 conn = create_connection_for_bd_addr_and_type(conn->address, BD_ADDR_TYPE_SCO,
7316 HCI_ROLE_MASTER);
7319 if (!conn) {
7320 return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
7321 }
7317 if (!conn) {
7318 return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
7319 }
7322 conn->role = HCI_ROLE_MASTER;
7323 break;
7324 case BD_ADDR_TYPE_SCO:
7325 // update of existing SCO connection
7326 break;
7327 default:
7328 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
7329 }
7330 }

--- 616 unchanged lines hidden (view full) ---

7947 * @brief start dedicated bonding with device. disconnect after bonding
7948 * @param device
7949 * @param request MITM protection
7950 * @result GAP_DEDICATED_BONDING_COMPLETE
7951 */
7952int gap_dedicated_bonding(bd_addr_t device, int mitm_protection_required){
7953
7954 // create connection state machine
7320 break;
7321 case BD_ADDR_TYPE_SCO:
7322 // update of existing SCO connection
7323 break;
7324 default:
7325 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
7326 }
7327 }

--- 616 unchanged lines hidden (view full) ---

7944 * @brief start dedicated bonding with device. disconnect after bonding
7945 * @param device
7946 * @param request MITM protection
7947 * @result GAP_DEDICATED_BONDING_COMPLETE
7948 */
7949int gap_dedicated_bonding(bd_addr_t device, int mitm_protection_required){
7950
7951 // create connection state machine
7955 hci_connection_t * connection = create_connection_for_bd_addr_and_type(device, BD_ADDR_TYPE_ACL);
7952 hci_connection_t * connection = create_connection_for_bd_addr_and_type(device, BD_ADDR_TYPE_ACL, HCI_ROLE_MASTER);
7956
7957 if (!connection){
7958 return BTSTACK_MEMORY_ALLOC_FAILED;
7959 }
7960
7961 // delete linkn key
7962 gap_drop_link_key_for_bd_addr(device);
7963

--- 66 unchanged lines hidden (view full) ---

8030 if (!conn){
8031 // disallow if le connection is already outgoing
8032 if (hci_is_le_connection_type(addr_type) && hci_stack->le_connecting_request != LE_CONNECTING_IDLE){
8033 log_error("le connection already active");
8034 return ERROR_CODE_COMMAND_DISALLOWED;
8035 }
8036
8037 log_info("gap_connect: no connection exists yet, creating context");
7953
7954 if (!connection){
7955 return BTSTACK_MEMORY_ALLOC_FAILED;
7956 }
7957
7958 // delete linkn key
7959 gap_drop_link_key_for_bd_addr(device);
7960

--- 66 unchanged lines hidden (view full) ---

8027 if (!conn){
8028 // disallow if le connection is already outgoing
8029 if (hci_is_le_connection_type(addr_type) && hci_stack->le_connecting_request != LE_CONNECTING_IDLE){
8030 log_error("le connection already active");
8031 return ERROR_CODE_COMMAND_DISALLOWED;
8032 }
8033
8034 log_info("gap_connect: no connection exists yet, creating context");
8038 conn = create_connection_for_bd_addr_and_type(addr, addr_type);
8035 conn = create_connection_for_bd_addr_and_type(addr, addr_type, HCI_ROLE_MASTER);
8039 if (!conn){
8040 // notify client that alloc failed
8041 hci_emit_le_connection_complete(addr_type, addr, 0, BTSTACK_MEMORY_ALLOC_FAILED);
8042 log_info("gap_connect: failed to alloc hci_connection_t");
8043 return GATT_CLIENT_NOT_CONNECTED; // don't sent packet to controller
8044 }
8045
8046 // set le connecting state

--- 2170 unchanged lines hidden ---
8036 if (!conn){
8037 // notify client that alloc failed
8038 hci_emit_le_connection_complete(addr_type, addr, 0, BTSTACK_MEMORY_ALLOC_FAILED);
8039 log_info("gap_connect: failed to alloc hci_connection_t");
8040 return GATT_CLIENT_NOT_CONNECTED; // don't sent packet to controller
8041 }
8042
8043 // set le connecting state

--- 2170 unchanged lines hidden ---