diff --git a/src/ble/att_db.c b/src/ble/att_db.c index 59d4f0035..98d63b915 100644 --- a/src/ble/att_db.c +++ b/src/ble/att_db.c @@ -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 diff --git a/src/ble/att_db_util.c b/src/ble/att_db_util.c index bbe9f5fdb..9e5e1f14d 100644 --- a/src/ble/att_db_util.c +++ b/src/ble/att_db_util.c @@ -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; } diff --git a/src/btstack_defines.h b/src/btstack_defines.h index cbaf0f60c..513031802 100644 --- a/src/btstack_defines.h +++ b/src/btstack_defines.h @@ -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 diff --git a/tool/compile_gatt.py b/tool/compile_gatt.py index 34e3d28ef..c4bf467c7 100755 --- a/tool/compile_gatt.py +++ b/tool/compile_gatt.py @@ -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)