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