mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-10 06:44:32 +00:00
gatt_services/BMS: update error handling code
This commit is contained in:
parent
a644f869d1
commit
82fa854186
@ -3,5 +3,5 @@
|
||||
|
||||
// Bond Management Service 181E
|
||||
PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_BOND_MANAGEMENT
|
||||
CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BOND_MANAGEMENT_CONTROL_POINT, DYNAMIC | WRITE | RELIABLEWRITE,
|
||||
CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BOND_MANAGEMENT_CONTROL_POINT, DYNAMIC | WRITE | RELIABLE_WRITE,
|
||||
CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BOND_MANAGEMENT_FEATURE, DYNAMIC | READ,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2014 BlueKitchen GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,9 +69,11 @@ static void bond_management_delete_bonding_information_classic(hci_connection_t
|
||||
link_key_type_t type;
|
||||
btstack_link_key_iterator_t it;
|
||||
|
||||
log_info("BMS Classic: delete bonding %s - own %d, other %d", bd_addr_to_str(connection->address), delete_own_bonding?1:0, delete_all_bonding_but_active?1:0);
|
||||
|
||||
int ok = gap_link_key_iterator_init(&it);
|
||||
if (!ok) {
|
||||
log_error("could not initialize iterator");
|
||||
log_error("BMS: could not initialize iterator");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -95,11 +97,14 @@ static void bond_management_delete_bonding_information_le(hci_connection_t * con
|
||||
bd_addr_t entry_address;
|
||||
bd_addr_type_t device_address_type = connection->address_type;
|
||||
|
||||
log_info("BMS LE: delete bonding %s - own %d, other %d", bd_addr_to_str(connection->address), delete_own_bonding?1:0, delete_all_bonding_but_active?1:0);
|
||||
|
||||
uint16_t i;
|
||||
for (i=0; i < le_device_db_max_count(); i++){
|
||||
int entry_address_type = (int) BD_ADDR_TYPE_UNKNOWN;
|
||||
le_device_db_info(i, &entry_address_type, entry_address, NULL);
|
||||
// skip unused entries
|
||||
|
||||
if (entry_address_type == (int) BD_ADDR_TYPE_UNKNOWN) continue;
|
||||
|
||||
if ((entry_address_type == (int) device_address_type) && (memcmp(entry_address, connection->address, 6) == 0)){
|
||||
@ -121,6 +126,10 @@ static uint16_t bond_management_service_read_callback(hci_con_handle_t con_handl
|
||||
UNUSED(buffer_size);
|
||||
|
||||
if (attribute_handle == bm_supported_features_value_handle){
|
||||
|
||||
#if 0
|
||||
|
||||
// According to BMS Spec, 3.2.1 Bond Management Feature Characteristic Behavior, only relevant bits should be sent
|
||||
uint16_t relevant_octets = 0;
|
||||
|
||||
// The server shall only include the number of octets needed for returning the highest set feature bit
|
||||
@ -131,23 +140,33 @@ static uint16_t bond_management_service_read_callback(hci_con_handle_t con_handl
|
||||
} else if (bm_supported_features > 0x00){
|
||||
relevant_octets = 1;
|
||||
}
|
||||
#else
|
||||
// however PTS 8.0.3 expects 3 bytes
|
||||
uint16_t relevant_octets = 3;
|
||||
#endif
|
||||
|
||||
uint8_t feature_buffer[3];
|
||||
if (buffer != NULL){
|
||||
little_endian_store_24(feature_buffer, 0, bm_supported_features);
|
||||
(void) memcpy(buffer, feature_buffer, relevant_octets);
|
||||
}
|
||||
}
|
||||
return relevant_octets;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int bond_management_service_write_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
|
||||
UNUSED(transaction_mode);
|
||||
UNUSED(offset);
|
||||
UNUSED(buffer_size);
|
||||
|
||||
if (transaction_mode != ATT_TRANSACTION_MODE_NONE){
|
||||
return 0;
|
||||
}
|
||||
|
||||
hci_connection_t * connection = hci_connection_for_handle(con_handle);
|
||||
btstack_assert(connection != NULL);
|
||||
|
||||
@ -156,9 +175,9 @@ static int bond_management_service_write_callback(hci_con_handle_t con_handle, u
|
||||
return BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
uint8_t cmd = buffer[0];
|
||||
uint8_t remote_cmd = buffer[0];
|
||||
// check if command/auth is supported
|
||||
if (cmd > BOND_MANAGEMENT_CMD_DELETE_ALL_BUT_ACTIVE_BOND_LE) {
|
||||
if (remote_cmd > BOND_MANAGEMENT_CMD_DELETE_ALL_BUT_ACTIVE_BOND_LE) {
|
||||
return BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
uint16_t authorisation_code_size = buffer_size - 1;
|
||||
@ -166,27 +185,39 @@ static int bond_management_service_write_callback(hci_con_handle_t con_handle, u
|
||||
return BOND_MANAGEMENT_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
uint8_t auth_provided = authorisation_code_size > 0 ? 1 : 0;
|
||||
uint32_t requested_feature_mask = 1UL << (2*(cmd-1) + auth_provided);
|
||||
uint32_t requested_feature_mask_without_auth = 1UL << (2*(remote_cmd-1));
|
||||
uint32_t requested_feature_mask_with_auth = 1UL << (2*(remote_cmd-1) + 1);
|
||||
bool locally_supported_with_auth = (bm_supported_features & requested_feature_mask_with_auth) != 0;
|
||||
bool locally_supported_without_auth = (bm_supported_features & requested_feature_mask_without_auth) != 0;
|
||||
|
||||
if ((bm_supported_features & requested_feature_mask) == 0){
|
||||
// abort, feature not allowed
|
||||
return BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (auth_provided == 1){
|
||||
if (!bm_authorization_string){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
}
|
||||
if (strlen(bm_authorization_string) != authorisation_code_size){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
}
|
||||
if (memcmp(bm_authorization_string, (const char *)&buffer[1], authorisation_code_size) != 0){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
bool remote_auth_provided = authorisation_code_size > 0;
|
||||
|
||||
// log_info("cmd 0x%02X, features 0x%03X, auth_provided %d, LA %d, LW %d", remote_cmd, bm_supported_features, remote_auth_provided?1:0, locally_supported_with_auth?1:0, locally_supported_without_auth?1:0);
|
||||
if (remote_auth_provided){
|
||||
if (locally_supported_with_auth){
|
||||
if (!bm_authorization_string){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
}
|
||||
if (strlen(bm_authorization_string) != authorisation_code_size){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
}
|
||||
if (memcmp(bm_authorization_string, (const char *)&buffer[1], authorisation_code_size) != 0){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
}
|
||||
} else {
|
||||
return BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
if (!locally_supported_without_auth){
|
||||
if (locally_supported_with_auth){
|
||||
return ATT_ERROR_INSUFFICIENT_AUTHORIZATION;
|
||||
} else {
|
||||
return BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd){
|
||||
switch (remote_cmd){
|
||||
#ifdef ENABLE_CLASSIC
|
||||
case BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE:
|
||||
bond_management_delete_bonding_information_classic(connection, true, false);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "gatt_profiles.h"
|
||||
#include "btstack.h"
|
||||
@ -72,7 +73,10 @@
|
||||
/* LISTING_START(MainConfiguration): Init L2CAP SM ATT Server and start heartbeat timer */
|
||||
static int le_notification_enabled;
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
static btstack_packet_callback_registration_t sm_event_callback_registration;
|
||||
|
||||
static uint8_t battery = 100;
|
||||
static bool accept_next_pairing = true;
|
||||
|
||||
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
|
||||
@ -100,8 +104,26 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
||||
case ATT_EVENT_CAN_SEND_NOW:
|
||||
// att_server_notify(con_handle, ATT_CHARACTERISTIC_0000FF11_0000_1000_8000_00805F9B34FB_01_VALUE_HANDLE, (uint8_t*) counter_string, counter_string_len);
|
||||
break;
|
||||
case SM_EVENT_JUST_WORKS_REQUEST:
|
||||
if (accept_next_pairing){
|
||||
accept_next_pairing = false;
|
||||
printf("Accept Just Works\n");
|
||||
sm_just_works_confirm(sm_event_just_works_request_get_handle(packet));
|
||||
} else {
|
||||
printf("Reject Just Works\n");
|
||||
sm_bonding_decline(sm_event_just_works_request_get_handle(packet));
|
||||
}
|
||||
break;
|
||||
case SM_EVENT_NUMERIC_COMPARISON_REQUEST:
|
||||
printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet));
|
||||
sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +174,12 @@ static void show_usage(void){
|
||||
printf("a - send 50%% Battery level\n");
|
||||
printf("## TPS\n");
|
||||
printf("t - send 10 TX Power level\n");
|
||||
printf("## BMS\n");
|
||||
printf("b - enable classic and LE flags\n");
|
||||
printf("c - enable classic flag, no auth\n");
|
||||
printf("C - enable classic flag, with auth\n");
|
||||
printf("l - enable LE flag, no auth\n");
|
||||
printf("L - enable LE flag, with auth\n");
|
||||
}
|
||||
|
||||
static void stdin_process(char c){
|
||||
@ -164,6 +192,28 @@ static void stdin_process(char c){
|
||||
printf("TPS: Sending 10 TX Power level\n");
|
||||
tx_power_service_server_set_level(10);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf("BMS: enable only classic flag, no auth\n");
|
||||
bond_management_service_server_init(1);
|
||||
break;
|
||||
case 'C':
|
||||
printf("BMS: enable only classic flag, with auth\n");
|
||||
bond_management_service_server_init(2);
|
||||
break;
|
||||
case 'l':
|
||||
printf("BMS: enable only LE flag, no auth\n");
|
||||
bond_management_service_server_init(0x03);
|
||||
break;
|
||||
case 'L':
|
||||
printf("BMS: enable only LE flag, with auth\n");
|
||||
bond_management_service_server_init(0x04);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf("BMS: enable classic and LE flags\n");
|
||||
bond_management_service_server_init(0xFFFF);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
break;
|
||||
@ -184,6 +234,9 @@ int btstack_main(void)
|
||||
|
||||
// setup SM: Display only
|
||||
sm_init();
|
||||
// register for SM events
|
||||
sm_event_callback_registration.callback = &packet_handler;
|
||||
sm_add_event_handler(&sm_event_callback_registration);
|
||||
|
||||
// setup ATT server
|
||||
att_server_init(profile_data, att_read_callback, att_write_callback);
|
||||
@ -199,6 +252,7 @@ int btstack_main(void)
|
||||
tx_power_service_server_init(20);
|
||||
|
||||
bond_management_service_server_init(0xFFFF);
|
||||
bond_management_service_server_set_authorisation_string("000000000000");
|
||||
|
||||
microphone_control_service_server_init(GATT_MICROPHONE_CONTROL_MUTE_OFF);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user