mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-31 19:20:26 +00:00
separate .gatt profiles for peripheral and central tests, fix attribute lookup
This commit is contained in:
parent
141191bd8f
commit
d6670ce8ef
2
test/pts/.gitignore
vendored
2
test/pts/.gitignore
vendored
@ -10,3 +10,5 @@ hsp_hs_test
|
||||
l2cap_test
|
||||
profile.h
|
||||
|
||||
ble_peripheral_test.h
|
||||
ble_central_test.h
|
||||
|
@ -28,11 +28,17 @@ EXAMPLES = hfp_hf_test hfp_ag_test ble_peripheral_test ble_central_test l2cap_te
|
||||
|
||||
all: ${BTSTACK_ROOT}/src/version.h ${EXAMPLES}
|
||||
|
||||
ble_peripheral_test: profile.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_REAL_OBJ} ble_peripheral_test.o
|
||||
${CC} $(filter-out profile.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
# compile .gatt descriptions
|
||||
ble_peripheral_test.h: ble_peripheral_test.gatt
|
||||
python ${BTSTACK_ROOT}/ble/compile-gatt.py $< $@
|
||||
ble_central_test.h: ble_central_test.gatt
|
||||
python ${BTSTACK_ROOT}/ble/compile-gatt.py $< $@
|
||||
|
||||
ble_peripheral_test: ble_peripheral_test.h ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${SM_REAL_OBJ} ble_peripheral_test.o
|
||||
${CC} $(filter-out ble_peripheral_test.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
ble_central_test: ${CORE_OBJ} ${COMMON_OBJ} ${SM_REAL_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${GATT_CLIENT_OBJ} ad_parser.o ble_central_test.c
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
ble_central_test: ble_central_test.h ${CORE_OBJ} ${COMMON_OBJ} ${SM_REAL_OBJ} ${ATT_OBJ} ${GATT_SERVER_OBJ} ${GATT_CLIENT_OBJ} ad_parser.o ble_central_test.c
|
||||
${CC} $(filter-out ble_central_test.h,$^) ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
hsp_ag_test: ${CORE_OBJ} ${COMMON_OBJ} ${SDP_CLIENT} hsp_ag.o hsp_ag_test.c
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
@ -66,7 +66,7 @@
|
||||
#include "ad_parser.h"
|
||||
|
||||
// test profile
|
||||
#include "profile.h"
|
||||
#include "ble_central_test.h"
|
||||
|
||||
// Non standard IXIT
|
||||
#define PTS_USES_RECONNECTION_ADDRESS_FOR_ITSELF
|
||||
|
@ -67,7 +67,7 @@
|
||||
#define HEARTBEAT_PERIOD_MS 1000
|
||||
|
||||
// test profile
|
||||
#include "profile.h"
|
||||
#include "ble_peripheral_test.h"
|
||||
|
||||
enum {
|
||||
DISABLE_ADVERTISEMENTS = 1 << 0,
|
||||
@ -302,44 +302,50 @@ static void app_run(void){
|
||||
// @param offset defines start of attribute value
|
||||
static uint16_t att_read_callback(uint16_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
|
||||
|
||||
printf("READ Callback, handle %04x, offset %u, buffer size %u\n", handle, offset, buffer_size);
|
||||
printf("READ Callback, handle %04x, offset %u, buffer size %u\n", attribute_handle, offset, buffer_size);
|
||||
uint16_t att_value_len;
|
||||
|
||||
uint16_t uuid16 = att_uuid_for_handle(handle);
|
||||
switch (uuid16){
|
||||
case 0x2902:
|
||||
if (buffer) {
|
||||
buffer[0] = client_configuration;
|
||||
}
|
||||
return 1;
|
||||
case 0x2a00:
|
||||
switch (attribute_handle){
|
||||
case ATT_CHARACTERISTIC_GAP_DEVICE_NAME_01_VALUE_HANDLE:
|
||||
att_value_len = strlen(gap_device_name);
|
||||
if (buffer) {
|
||||
memcpy(buffer, gap_device_name, att_value_len);
|
||||
}
|
||||
return att_value_len;
|
||||
case 0x2a01:
|
||||
return att_value_len;
|
||||
case ATT_CHARACTERISTIC_GAP_APPEARANCE_01_VALUE_HANDLE:
|
||||
if (buffer){
|
||||
bt_store_16(buffer, 0, gap_appearance);
|
||||
}
|
||||
return 2;
|
||||
case 0x2a02:
|
||||
case ATT_CHARACTERISTIC_GAP_PERIPHERAL_PRIVACY_FLAG_01_VALUE_HANDLE:
|
||||
if (buffer){
|
||||
buffer[0] = gap_privacy;
|
||||
}
|
||||
return 1;
|
||||
case 0x2A03:
|
||||
case ATT_CHARACTERISTIC_GAP_RECONNECTION_ADDRESS_01_VALUE_HANDLE:
|
||||
if (buffer) {
|
||||
bt_flip_addr(buffer, gap_reconnection_address);
|
||||
}
|
||||
return 6;
|
||||
|
||||
// handle device name
|
||||
// handle appearance
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t uuid16 = att_uuid_for_handle(handle);
|
||||
if (uuid16){
|
||||
printf("Resolved to UUID %04x\n", uuid16);
|
||||
switch (uuid16){
|
||||
case 0x2902:
|
||||
if (buffer) {
|
||||
buffer[0] = client_configuration;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// find attribute
|
||||
int index = att_attribute_for_handle(handle);
|
||||
uint8_t * att_value;
|
||||
@ -374,36 +380,43 @@ static uint16_t att_read_callback(uint16_t con_handle, uint16_t attribute_handle
|
||||
|
||||
// write requests
|
||||
static int att_write_callback(uint16_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
|
||||
printf("WRITE Callback, handle %04x, mode %u, offset %u, data: ", handle, transaction_mode, offset);
|
||||
printf("WRITE Callback, handle %04x, mode %u, offset %u, data: ", attribute_handle, transaction_mode, offset);
|
||||
printf_hexdump(buffer, buffer_size);
|
||||
|
||||
uint16_t uuid16 = att_uuid_for_handle(handle);
|
||||
switch (uuid16){
|
||||
case 0x2902:
|
||||
client_configuration = buffer[0];
|
||||
client_configuration_handle = handle;
|
||||
printf("Client Configuration set to %u for handle %04x\n", client_configuration, handle);
|
||||
return 0; // ok
|
||||
case 0x2a00:
|
||||
switch (attribute_handle){
|
||||
case ATT_CHARACTERISTIC_GAP_DEVICE_NAME_01_VALUE_HANDLE:
|
||||
memcpy(gap_device_name, buffer, buffer_size);
|
||||
gap_device_name[buffer_size]=0;
|
||||
printf("Setting device name to '%s'\n", gap_device_name);
|
||||
return 0;
|
||||
case 0x2a01:
|
||||
case ATT_CHARACTERISTIC_GAP_APPEARANCE_01_VALUE_HANDLE:
|
||||
gap_appearance = READ_BT_16(buffer, 0);
|
||||
printf("Setting appearance to 0x%04x'\n", gap_appearance);
|
||||
return 0;
|
||||
case 0x2a02:
|
||||
case ATT_CHARACTERISTIC_GAP_PERIPHERAL_PRIVACY_FLAG_01_VALUE_HANDLE:
|
||||
gap_privacy = buffer[0];
|
||||
printf("Setting privacy to 0x%04x'\n", gap_privacy);
|
||||
update_advertisements();
|
||||
return 0;
|
||||
case 0x2A03:
|
||||
case ATT_CHARACTERISTIC_GAP_RECONNECTION_ADDRESS_01_VALUE_HANDLE:
|
||||
bt_flip_addr(gap_reconnection_address, buffer);
|
||||
printf("Setting Reconnection Address to %s\n", bd_addr_to_str(gap_reconnection_address));
|
||||
return 0;
|
||||
// handle device name
|
||||
// handle appearance
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint16_t uuid16 = att_uuid_for_handle(attribute_handle);
|
||||
if (uuid16){
|
||||
printf("Resolved to UUID %04x\n", uuid16);
|
||||
switch (uuid16){
|
||||
case GATT_CLIENT_CHARACTERISTICS_CONFIGURATION:
|
||||
client_configuration = buffer[0];
|
||||
client_configuration_handle = attribute_handle;
|
||||
printf("Client Configuration set to %u for handle %04x\n", client_configuration, client_configuration_handle);
|
||||
return 0; // ok
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check transaction mode
|
||||
@ -411,11 +424,11 @@ static int att_write_callback(uint16_t con_handle, uint16_t attribute_handle, ui
|
||||
int writes_index;
|
||||
switch (transaction_mode){
|
||||
case ATT_TRANSACTION_MODE_NONE:
|
||||
attributes_index = att_attribute_for_handle(handle);
|
||||
attributes_index = att_attribute_for_handle(attribute_handle);
|
||||
if (attributes_index < 0){
|
||||
attributes_index = att_attribute_for_handle(0);
|
||||
if (attributes_index < 0) return 0; // ok, but we couldn't store it (our fault)
|
||||
att_attributes[attributes_index].handle = handle;
|
||||
att_attributes[attributes_index].handle = attribute_handle;
|
||||
// not written before
|
||||
uint8_t * att_value;
|
||||
uint16_t att_value_len;
|
||||
@ -433,7 +446,7 @@ static int att_write_callback(uint16_t con_handle, uint16_t attribute_handle, ui
|
||||
memcpy(att_attributes[attributes_index].value, buffer, buffer_size);
|
||||
break;
|
||||
case ATT_TRANSACTION_MODE_ACTIVE:
|
||||
writes_index = att_write_queue_for_handle(handle);
|
||||
writes_index = att_write_queue_for_handle(attribute_handle);
|
||||
if (writes_index < 0) return ATT_ERROR_PREPARE_QUEUE_FULL;
|
||||
if (offset > att_write_queues[writes_index].len) return ATT_ERROR_INVALID_OFFSET;
|
||||
if (buffer_size + offset > ATT_VALUE_MAX_LEN) return ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH;
|
||||
@ -442,7 +455,7 @@ static int att_write_callback(uint16_t con_handle, uint16_t attribute_handle, ui
|
||||
break;
|
||||
case ATT_TRANSACTION_MODE_EXECUTE:
|
||||
for (writes_index=0 ; writes_index<ATT_NUM_WRITE_QUEUES ; writes_index++){
|
||||
handle = att_write_queues[writes_index].handle;
|
||||
uint16_t handle = att_write_queues[writes_index].handle;
|
||||
if (handle == 0) continue;
|
||||
attributes_index = att_attribute_for_handle(handle);
|
||||
if (attributes_index < 0){
|
||||
|
12
test/pts/ble_peripheral_test.gatt
Normal file
12
test/pts/ble_peripheral_test.gatt
Normal file
@ -0,0 +1,12 @@
|
||||
PRIMARY_SERVICE, GAP_SERVICE
|
||||
CHARACTERISTIC, GAP_DEVICE_NAME, READ | WRITE | DYNAMIC
|
||||
CHARACTERISTIC, GAP_PERIPHERAL_PRIVACY_FLAG, READ | WRITE | DYNAMIC
|
||||
CHARACTERISTIC, GAP_PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS, READ, FF FF FF 00 03 FF FF
|
||||
CHARACTERISTIC, GAP_APPEARANCE, READ | WRITE | DYNAMIC
|
||||
CHARACTERISTIC, GAP_RECONNECTION_ADDRESS, READ | WRITE | DYNAMIC
|
||||
|
||||
PRIMARY_SERVICE, GATT_SERVICE
|
||||
CHARACTERISTIC, GATT_SERVICE_CHANGED, READ
|
||||
|
||||
PRIMARY_SERVICE, FFF0
|
||||
CHARACTERISTIC, FFF1, READ | WRITE | AUTHENTICATED_SIGNED_WRITE | AUTHENTICATION_REQUIRED, "A"
|
Loading…
x
Reference in New Issue
Block a user