separate .gatt profiles for peripheral and central tests, fix attribute lookup

This commit is contained in:
Matthias Ringwald 2015-11-01 10:02:01 +01:00
parent 141191bd8f
commit d6670ce8ef
6 changed files with 72 additions and 39 deletions

2
test/pts/.gitignore vendored
View File

@ -10,3 +10,5 @@ hsp_hs_test
l2cap_test
profile.h
ble_peripheral_test.h
ble_central_test.h

View File

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

View File

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

View File

@ -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){

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