compile_gatt+att_db+att_db_util: make Client Characteristic Configuration readable without authentication but require permissions for write

This commit is contained in:
Matthias Ringwald 2017-09-22 14:20:26 +02:00
parent 3721458b9d
commit eb6072adf6
4 changed files with 68 additions and 35 deletions

View File

@ -536,8 +536,10 @@ static uint16_t handle_read_by_type_request2(att_connection_t * att_connection,
}
// check security requirements
error_code = att_validate_security(att_connection, &it);
if (error_code) break;
if ((it.flags & ATT_DB_FLAGS_READ_WITHOUT_AUTHENTICATION) == 0){
error_code = att_validate_security(att_connection, &it);
if (error_code) break;
}
att_update_value_len(&it, att_connection->con_handle);
@ -621,9 +623,11 @@ static uint16_t handle_read_request2(att_connection_t * att_connection, uint8_t
}
// check security requirements
uint8_t error_code = att_validate_security(att_connection, &it);
if (error_code) {
return setup_error(response_buffer, request_type, handle, error_code);
if ((it.flags & ATT_DB_FLAGS_READ_WITHOUT_AUTHENTICATION) == 0){
uint8_t error_code = att_validate_security(att_connection, &it);
if (error_code) {
return setup_error(response_buffer, request_type, handle, error_code);
}
}
att_update_value_len(&it, att_connection->con_handle);
@ -667,9 +671,11 @@ static uint16_t handle_read_blob_request2(att_connection_t * att_connection, uin
}
// check security requirements
uint8_t error_code = att_validate_security(att_connection, &it);
if (error_code) {
return setup_error(response_buffer, request_type, handle, error_code);
if ((it.flags & ATT_DB_FLAGS_READ_WITHOUT_AUTHENTICATION) == 0){
uint8_t error_code = att_validate_security(att_connection, &it);
if (error_code) {
return setup_error(response_buffer, request_type, handle, error_code);
}
}
att_update_value_len(&it, att_connection->con_handle);
@ -736,9 +742,10 @@ static uint16_t handle_read_multiple_request2(att_connection_t * att_connection,
}
// check security requirements
error_code = att_validate_security(att_connection, &it);
if (error_code) break;
if ((it.flags & ATT_DB_FLAGS_READ_WITHOUT_AUTHENTICATION) == 0){
error_code = att_validate_security(att_connection, &it);
if (error_code) break;
}
att_update_value_len(&it, att_connection->con_handle);
// limit data

View File

@ -154,18 +154,26 @@ void att_db_util_add_service_uuid128(uint8_t * uuid128){
att_db_util_add_attribute_uuid16(GATT_PRIMARY_SERVICE_UUID, ATT_PROPERTY_READ, buffer, 16);
}
static void att_db_util_add_client_characteristic_configuration(uint16_t properties){
uint8_t buffer[2];
// keep authentication flags
uint16_t flags = (properties & 0x1ff00) | ATT_DB_FLAGS_READ_WITHOUT_AUTHENTICATION | ATT_PROPERTY_READ | ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC;
little_endian_store_16(buffer, 0, 0);
att_db_util_add_attribute_uuid16(GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, flags, buffer, 2);
}
uint16_t att_db_util_add_characteristic_uuid16(uint16_t uuid16, uint16_t properties, uint8_t * data, uint16_t data_len){
uint8_t buffer[5];
buffer[0] = properties;
little_endian_store_16(buffer, 1, att_db_next_handle + 1);
little_endian_store_16(buffer, 3, uuid16);
att_db_util_add_attribute_uuid16(GATT_CHARACTERISTICS_UUID, ATT_PROPERTY_READ, buffer, sizeof(buffer));
// drop Broadcast, Notify, Indicate - not used for flags
uint16_t value_flags = properties & 0x1ffce;
uint16_t value_handle = att_db_next_handle;
att_db_util_add_attribute_uuid16(uuid16, properties, data, data_len);
att_db_util_add_attribute_uuid16(uuid16, value_flags, data, data_len);
if (properties & (ATT_PROPERTY_NOTIFY | ATT_PROPERTY_INDICATE)){
uint16_t flags = ATT_PROPERTY_READ | ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC;
little_endian_store_16(buffer, 0, 0);
att_db_util_add_attribute_uuid16(GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, flags, buffer, 2);
att_db_util_add_client_characteristic_configuration(properties);
}
return value_handle;
}
@ -176,12 +184,12 @@ uint16_t att_db_util_add_characteristic_uuid128(uint8_t * uuid128, uint16_t prop
little_endian_store_16(buffer, 1, att_db_next_handle + 1);
reverse_128(uuid128, &buffer[3]);
att_db_util_add_attribute_uuid16(GATT_CHARACTERISTICS_UUID, ATT_PROPERTY_READ, buffer, sizeof(buffer));
// drop Broadcast, Notify, Indicate - not used for flags
uint16_t value_flags = properties & 0x1ffce;
uint16_t value_handle = att_db_next_handle;
att_db_util_add_attribute_uuid128(uuid128, properties, data, data_len);
att_db_util_add_attribute_uuid128(uuid128, value_flags, data, data_len);
if (properties & (ATT_PROPERTY_NOTIFY | ATT_PROPERTY_INDICATE)){
uint16_t flags = ATT_PROPERTY_READ | ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC;
little_endian_store_16(buffer, 0, 0);
att_db_util_add_attribute_uuid16(GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, flags, buffer, 2);
att_db_util_add_client_characteristic_configuration(properties);
}
return value_handle;
}

View File

@ -293,6 +293,12 @@ typedef uint8_t sm_key_t[16];
#define GATT_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION 0X81
#define GATT_GET_MTU 0x82
// ATT
// ..
// Internal properties reuse some GATT Characteristic Properties fields
#define ATT_DB_FLAGS_READ_WITHOUT_AUTHENTICATION 0x0001
// EVENTS

View File

@ -48,6 +48,7 @@ assigned_uuids = {
}
property_flags = {
# GATT Characteristic Properties
'BROADCAST' : 0x01,
'READ' : 0x02,
'WRITE_WITHOUT_RESPONSE' : 0x04,
@ -57,23 +58,30 @@ property_flags = {
'AUTHENTICATED_SIGNED_WRITE' : 0x40,
'EXTENDED_PROPERTIES' : 0x80,
# custom BTstack extension
'DYNAMIC': 0x100,
'LONG_UUID': 0x200,
'AUTHENTICATION_REQUIRED': 0x400,
'AUTHORIZATION_REQUIRED': 0x800,
'ENCRYPTION_KEY_SIZE_7': 0x6000,
'ENCRYPTION_KEY_SIZE_8': 0x7000,
'ENCRYPTION_KEY_SIZE_9': 0x8000,
'ENCRYPTION_KEY_SIZE_10': 0x9000,
'ENCRYPTION_KEY_SIZE_11': 0xa000,
'ENCRYPTION_KEY_SIZE_12': 0xb000,
'ENCRYPTION_KEY_SIZE_13': 0xc000,
'ENCRYPTION_KEY_SIZE_14': 0xd000,
'ENCRYPTION_KEY_SIZE_15': 0xe000,
'ENCRYPTION_KEY_SIZE_16': 0xf000,
'DYNAMIC': 0x100,
'LONG_UUID': 0x200,
'AUTHENTICATION_REQUIRED': 0x400,
'AUTHORIZATION_REQUIRED': 0x800,
'ENCRYPTION_KEY_SIZE_7': 0x6000,
'ENCRYPTION_KEY_SIZE_8': 0x7000,
'ENCRYPTION_KEY_SIZE_9': 0x8000,
'ENCRYPTION_KEY_SIZE_10': 0x9000,
'ENCRYPTION_KEY_SIZE_11': 0xa000,
'ENCRYPTION_KEY_SIZE_12': 0xb000,
'ENCRYPTION_KEY_SIZE_13': 0xc000,
'ENCRYPTION_KEY_SIZE_14': 0xd000,
'ENCRYPTION_KEY_SIZE_15': 0xe000,
'ENCRYPTION_KEY_SIZE_16': 0xf000,
# only used by gatt compiler >= 0xffff
# Extended Properties
'RELIABLE_WRITE': 0x10000,
# Broadcast, Notify, Indicate, Extended Properties are only used to describe a GATT Characteristic, but are free to use with att_db
'READ_WITHOUT_AUTHENTICATION': 0x0001,
# 0x10
# 0x20
# 0x80
}
btstack_root = ''
@ -314,9 +322,11 @@ def parseCharacteristic(fout, parts):
write_indent(fout)
fout.write('// 0x%04x VALUE-%s-'"'%s'"'\n' % (handle, '-'.join(parts[1:3]),value))
# drop Broadcast, Notify, Indicate - not used for flags
value_properties = properties & 0x1ffce
write_indent(fout)
write_16(fout, size)
write_16(fout, properties)
write_16(fout, value_properties)
write_16(fout, handle)
write_uuid(uuid)
if is_string(value):
@ -329,12 +339,14 @@ def parseCharacteristic(fout, parts):
handle = handle + 1
if add_client_characteristic_configuration(properties):
# replace GATT Characterstic Properties with READ|WRITE|READ_WITHOUT_AUTHENTICATION|DYNAMIC
ccc_properties = (properties & 0x1ff00) | property_flags['READ_WITHOUT_AUTHENTICATION'] | property_flags['READ'] | property_flags['WRITE'] | property_flags['DYNAMIC'];
size = 2 + 2 + 2 + 2 + 2
write_indent(fout)
fout.write('// 0x%04x CLIENT_CHARACTERISTIC_CONFIGURATION\n' % (handle))
write_indent(fout)
write_16(fout, size)
write_16(fout, property_flags['READ'] | property_flags['WRITE'] | property_flags['DYNAMIC'])
write_16(fout, ccc_properties)
write_16(fout, handle)
write_16(fout, 0x2902)
write_16(fout, 0)