This patchset reworks the way that GATT test databases are defined,
defines a "large database" as defined by the test spec, adds a set
of new tests from the test spec.
It also includes some minor cleanup.
Michael Janssen (14):
shared/gatt-db: Add gatt_db_find_by_type_value
shared/gatt-server: support Discover by UUID
unit/gatt: Bugfix small database construction
unit/gatt: Add add_desc_with_value function
unit/gatt: Rework service db definitions
unit/gatt: Add Test Spec Large Database 1
unit/gatt: Comment cleanup
unit/gatt: Add /TP/GAD/SR/BV-02-C test
unit/gatt: Add /TP/GAD/SR/BV-03-C test
unit/gatt: Add /TP/GAD/SR/BV-04-C test
unit/gatt: Add clarifying note about dup tests.
unit/gatt: Add /TP/GAD/SR/BV-06-C test
unit/gatt: Add /TP/GAR/SR/BV-01-C test
unit/gatt: Add /TP/GAR/SR/BI-02-C test
src/shared/gatt-db.c | 27 ++
src/shared/gatt-db.h | 7 +
src/shared/gatt-server.c | 107 +++++++
unit/test-gatt.c | 808 +++++++++++++++++++++++++++++++++++++++--------
4 files changed, 812 insertions(+), 137 deletions(-)
--
2.2.0.rc0.207.ga3a616c
Adds a large GATT database definition and initial service discovery test
which satisfies a number of the requirements from the GATT Test Spec
Document.
---
unit/test-gatt.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 322 insertions(+), 1 deletion(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 169fbd3..647dd4e 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -152,6 +152,31 @@ struct context {
raw_pdu(0x11, 0x06, 0x10, 0xF0, 0x17, 0xF0, 0x00, 0x18, \
0xFF, 0xFF, 0xFF, 0xFF, 0x0a, 0x18)
+#define PRIMARY_DISC_LARGE_DB_1 \
+ raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x06, 0x10, 0x00, 0x13, 0x00, 0x01, 0x18, \
+ 0x20, 0x00, 0x29, 0x00, 0x0A, 0xA0, \
+ 0x30, 0x00, 0x32, 0x00, 0x0B, 0xA0), \
+ raw_pdu(0x10, 0x33, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x06, 0x40, 0x00, 0x46, 0x00, 0x00, 0x18, \
+ 0x50, 0x00, 0x52, 0x00, 0x0B, 0xA0, \
+ 0x60, 0x00, 0x6B, 0x00, 0x0B, 0xA0), \
+ raw_pdu(0x10, 0x6C, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x06, 0x70, 0x00, 0x76, 0x00, 0x0B, 0xA0, \
+ 0x80, 0x00, 0x85, 0x00, 0x0B, 0xA0), \
+ raw_pdu(0x10, 0x86, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x14, 0x90, 0x00, 0x96, 0x00, \
+ 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, \
+ 0x00, 0x00, 0x00, 0x00, 0x0C, 0xA0, 0x00, 0x00),\
+ raw_pdu(0x10, 0x97, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x06, 0xa0, 0x00, 0xb1, 0x00, 0x0f, 0xa0),\
+ raw_pdu(0x10, 0xb2, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x14, 0xC0, 0x00, 0xDD, 0x00, \
+ 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, \
+ 0x00, 0x00, 0x00, 0x00, 0x0C, 0xA0, 0x00, 0x00),\
+ raw_pdu(0x10, 0xde, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x01, 0x10, 0xde, 0x00, 0x0a)
+
#define SECONDARY_DISC_SMALL_DB \
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28), \
raw_pdu(0x11, 0x06, 0x01, 0x00, 0x0F, 0x00, 0x0a, 0x18),\
@@ -883,6 +908,296 @@ static struct gatt_db *make_test_spec_small_db(void)
return make_db(specs);
}
+/*
+ * Defined Test database 2:
+ * Large Database with 128-bit services at the end
+ * Satisfies requirements:
+ * 4. at least one primary service without any include or characteristic
+ * at the max handle.
+ * 6. at least one secondary service
+ * 7. at least one each of 16-bit and 128-bit UUID with multiple instances
+ * 8. some simple services, some some with included services
+ * 9. one instance where an included service comes before the including
+ * 10. one or more services with both 16-bit and 128-bit service UUIDs
+ * 11. simple and complex characteristics
+ * 12. complex chars with 16-bit and 128-bit uuids
+ */
+
+static struct gatt_db *make_test_spec_large_db_1(void)
+{
+ const struct att_handle_spec specs[] = {
+ PRIMARY_SERVICE(0x0080, "a00b", 6),
+ CHARACTERISTIC(0xb008, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ 0x08),
+ DESCRIPTOR(0xb015, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE, 0x01),
+ DESCRIPTOR(0xb016, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE, 0x02),
+ DESCRIPTOR(0xb017, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE |
+ BT_ATT_PERM_ENCRYPT, 0x03),
+
+ SECONDARY_SERVICE(0x0001, "a00d", 6),
+ INCLUDE(0x0080),
+ CHARACTERISTIC(0xb00c, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+ 0x0C),
+ CHARACTERISTIC(0000b00b-0000-0000-0123-456789abcdef,
+ BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ, 0x0B),
+
+ PRIMARY_SERVICE(0x0010, GATT_UUID, 4),
+ CHARACTERISTIC(GATT_CHARAC_SERVICE_CHANGED, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_INDICATE,
+ 0x01, 0x00, 0xFF, 0xFF),
+ DESCRIPTOR(GATT_CLIENT_CHARAC_CFG_UUID,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x00, 0x00),
+
+ PRIMARY_SERVICE(0x0020, "a00a", 10),
+ INCLUDE(0x0001),
+ CHARACTERISTIC(0xb001, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+ 0x01),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "11111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233"),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_WRITE,
+ "11111222223333344444555556666677777888889999900000"),
+ CHARACTERISTIC(0xb003, BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_WRITE, 0x03),
+
+ PRIMARY_SERVICE(0x0030, "a00b", 3),
+ CHARACTERISTIC(0xb007, BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_WRITE, 0x07),
+
+ PRIMARY_SERVICE(0x0040, GAP_UUID, 7),
+ CHARACTERISTIC_STR(GATT_CHARAC_DEVICE_NAME, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ "Test Database"),
+ CHARACTERISTIC(GATT_CHARAC_APPEARANCE, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, 17),
+ CHARACTERISTIC(GATT_CHARAC_PERIPHERAL_PREF_CONN,
+ BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+ 0x64, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x07, 0xD0),
+
+ PRIMARY_SERVICE(0x0050, "a00b", 3),
+ CHARACTERISTIC(0xb006, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE |
+ BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP |
+ BT_GATT_CHRC_PROP_NOTIFY |
+ BT_GATT_CHRC_PROP_INDICATE, 0x06),
+
+ PRIMARY_SERVICE(0x0060, "a00b", 12),
+ CHARACTERISTIC(0xb004, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE, 0x04),
+ CHARACTERISTIC(0xb004, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE, 0x04),
+ DESCRIPTOR(GATT_SERVER_CHARAC_CFG_UUID,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x00, 0x00),
+ CHARACTERISTIC(0xb004, 0, 0, 0x04),
+ DESCRIPTOR(0xb012, 0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33,
+ 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11,
+ 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+ 0x00, 0x11, 0x22, 0x33),
+ CHARACTERISTIC(0xb004, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+ 0x04),
+ DESCRIPTOR(0xb012, BT_ATT_PERM_READ, 0x11, 0x22, 0x33, 0x44,
+ 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
+ 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33),
+
+ PRIMARY_SERVICE(0x0070, "a00b", 7),
+ CHARACTERISTIC(0xb005, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE |
+ BT_GATT_CHRC_PROP_EXT_PROP,
+ 0x05),
+ DESCRIPTOR(GATT_CHARAC_EXT_PROPER_UUID, BT_ATT_PERM_READ, 0x03,
+ 0x00),
+ DESCRIPTOR_STR(GATT_CHARAC_USER_DESC_UUID,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ DESCRIPTOR(GATT_CHARAC_FMT_UUID, 0x04, 0x00, 0x01, 0x30, 0x01,
+ 0x11, 0x31),
+ DESCRIPTOR(0000d5d4-0000-0000-0123-456789abcdef,
+ BT_ATT_PERM_READ, 0x44),
+
+ /* 0x0080 service defined earlier, included in 0x0001 */
+
+ PRIMARY_SERVICE(0x0090, "0000a00c-0000-0000-0123-456789abcdef",
+ 7),
+ INCLUDE(0x0001),
+ CHARACTERISTIC(0000b009-0000-0000-0123-456789abcdef,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE |
+ BT_GATT_CHRC_PROP_EXT_PROP, 0x09),
+ DESCRIPTOR(GATT_CHARAC_EXT_PROPER_UUID, BT_ATT_PERM_READ, 0x01,
+ 0x00),
+ DESCRIPTOR(0000d9d2-0000-0000-0123-456789abcdef,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE, 0x22),
+ DESCRIPTOR(0000d9d3-0000-0000-0123-456789abcdef,
+ BT_ATT_PERM_WRITE, 0x33),
+
+ PRIMARY_SERVICE(0x00a0, "a00f", 18),
+ CHARACTERISTIC_STR(0xb00e, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, "Length is "),
+ DESCRIPTOR(GATT_CHARAC_FMT_UUID, BT_ATT_PERM_READ, 0x19, 0x00,
+ 0x00, 0x30, 0x01, 0x00, 0x00),
+ CHARACTERISTIC(0xb00f, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE, 0x65),
+ DESCRIPTOR(GATT_CHARAC_FMT_UUID, BT_ATT_PERM_READ, 0x04, 0x00,
+ 0x01, 0x27, 0x01, 0x01, 0x00),
+ CHARACTERISTIC(0xb006, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ 0x34, 0x12),
+ DESCRIPTOR(GATT_CHARAC_FMT_UUID, BT_ATT_PERM_READ, 0x06, 0x00,
+ 0x10, 0x27, 0x01, 0x02, 0x00),
+ CHARACTERISTIC(0xb007, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ 0x04, 0x03, 0x02, 0x01),
+ DESCRIPTOR(GATT_CHARAC_FMT_UUID, BT_ATT_PERM_READ, 0x08, 0x00,
+ 0x17, 0x27, 0x01, 0x03, 0x00),
+ CHARACTERISTIC(0xb010, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+ 0x65, 0x34, 0x12, 0x04, 0x03, 0x02,
+ 0x01),
+ DESCRIPTOR(GATT_CHARAC_AGREG_FMT_UUID, BT_ATT_PERM_READ, 0xA6,
+ 0x00, 0xa9, 0x00, 0xac, 0x00),
+ CHARACTERISTIC(0xb011, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_AUTH, 0x012),
+
+ PRIMARY_SERVICE(0x00C0, "0000a00c-0000-0000-0123-456789abcdef",
+ 30),
+ CHARACTERISTIC(0xb00a, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
+ 0x0A),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "111112222233333444445"),
+ DESCRIPTOR(0xb012, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "2222233333444445555566"),
+ DESCRIPTOR(0xb013, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11,
+ 0x22),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "33333444445555566666777"),
+ DESCRIPTOR(0xb014, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11,
+ 0x22, 0x33),
+ CHARACTERISTIC(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33),
+ DESCRIPTOR(0xb012, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
+ 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
+ 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33),
+ CHARACTERISTIC(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44),
+ DESCRIPTOR(0xb013, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
+ 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
+ 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44),
+ CHARACTERISTIC(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55),
+ DESCRIPTOR(0xb014, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
+ 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
+ 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "1111122222333334444455555666667777788888999"),
+ DESCRIPTOR(0xb012, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
+ 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
+ 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "22222333334444455555666667777788888999990000"),
+ DESCRIPTOR(0xb013, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
+ 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
+ 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44),
+ CHARACTERISTIC_STR(0xb002, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE,
+ "333334444455555666667777788888999990000011111"),
+ DESCRIPTOR(0xb014, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
+ 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
+ 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x11, 0x22,
+ 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00,
+ 0x11, 0x22, 0x33, 0x44, 0x55),
+ { }
+ };
+
+ return make_db(specs);
+}
+
static void test_client(gconstpointer data)
{
struct context *context = create_context(512, data);
@@ -1104,12 +1419,13 @@ static void test_read_by_type(gconstpointer data)
int main(int argc, char *argv[])
{
- struct gatt_db *service_db_1, *ts_small_db;
+ struct gatt_db *service_db_1, *ts_small_db, *ts_large_db_1;
g_test_init(&argc, &argv, NULL);
service_db_1 = make_service_data_1_db();
ts_small_db = make_test_spec_small_db();
+ ts_large_db_1 = make_test_spec_large_db_1();
/*
* Server Configuration
@@ -1165,6 +1481,11 @@ int main(int argc, char *argv[])
raw_pdu(0x03, 0x00, 0x02),
PRIMARY_DISC_SMALL_DB);
+ define_test_server("/TP/GAD/SR/BV-01-C-large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ PRIMARY_DISC_LARGE_DB_1);
+
define_test_att("/TP/GAD/CL/BV-02-C-1", test_search_primary, &uuid_16,
NULL,
MTU_EXCHANGE_CLIENT_PDUS,
--
2.2.0.rc0.207.ga3a616c
Introduces a set of macros providing a simple syntax for definining a
test GATT database.
The two defined databases are reconstructed using the new format.
Some old helper methods are not used anymore and are removed.
---
unit/test-gatt.c | 277 +++++++++++++++++++++++++++++++------------------------
1 file changed, 159 insertions(+), 118 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 4f5857f..169fbd3 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -676,99 +676,168 @@ add_desc_with_value(struct gatt_db_attribute *att, bt_uuid_t *uuid,
return desc_att;
}
-static struct gatt_db_attribute *add_ccc(struct gatt_db_attribute *chrc_att,
- bool writable)
-{
- bt_uuid_t uuid;
- uint16_t tmp;
-
- bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
- tmp = 0x0000;
+enum gatt_type {
+ PRIMARY,
+ SECONDARY,
+ INCLUDE,
+ CHARACTERISTIC,
+ DESCRIPTOR
+};
- return add_desc_with_value(chrc_att, &uuid,
- BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
- (uint8_t *)&tmp, sizeof(tmp));
-}
+struct att_handle_spec {
+ uint16_t handle;
+ const char *uuid;
+ enum gatt_type type;
+ uint8_t char_properties;
+ uint32_t att_permissions;
+ const uint8_t *value;
+ size_t len;
+ bool valid;
+};
-static struct gatt_db_attribute *
-add_user_description(struct gatt_db_attribute *chrc_att, const char *desc,
- bool writable)
-{
- bt_uuid_t uuid;
+#define PRIMARY_SERVICE(start_handle, srv_uuid, num_handles) \
+ { \
+ .valid = true, \
+ .handle = start_handle, \
+ .type = PRIMARY, \
+ .uuid = srv_uuid, \
+ .len = num_handles, \
+ }
- bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
+#define SECONDARY_SERVICE(start_handle, srv_uuid, num_handles) \
+ { \
+ .valid = true, \
+ .handle = start_handle, \
+ .type = SECONDARY, \
+ .uuid = srv_uuid, \
+ .len = num_handles, \
+ }
- return add_desc_with_value(chrc_att, &uuid, 0x03, (uint8_t *)desc,
- strlen(desc));
-}
+#define INCLUDE(include_handle) \
+ { \
+ .valid = true, \
+ .type = INCLUDE, \
+ .handle = include_handle, \
+ }
+#define STR(x) #x
+
+#define CHARACTERISTIC(chr_uuid, permissions, properties, bytes...) \
+ { \
+ .valid = true, \
+ .type = CHARACTERISTIC, \
+ .uuid = STR(chr_uuid), \
+ .att_permissions = permissions, \
+ .char_properties = properties, \
+ .value = data(bytes), \
+ .len = sizeof(data(bytes)), \
+ }
-typedef struct gatt_db_attribute (*add_service_func) (struct gatt_db *db,
- uint16_t handle,
- bool primary,
- uint16_t extra_handles);
+#define CHARACTERISTIC_STR(chr_uuid, permissions, properties, string) \
+ { \
+ .valid = true, \
+ .type = CHARACTERISTIC, \
+ .uuid = STR(chr_uuid), \
+ .att_permissions = permissions, \
+ .char_properties = properties, \
+ .value = (uint8_t *)string, \
+ .len = strlen(string), \
+ }
-static struct gatt_db_attribute *
-add_device_information_service(struct gatt_db *db, uint16_t handle,
- bool primary, uint16_t extra_handles)
-{
- bt_uuid_t uuid;
- struct gatt_db_attribute *serv_att;
+#define DESCRIPTOR(desc_uuid, permissions, bytes...) \
+ { \
+ .valid = true, \
+ .type = DESCRIPTOR, \
+ .uuid = STR(desc_uuid), \
+ .att_permissions = permissions, \
+ .value = data(bytes), \
+ .len = sizeof(data(bytes)), \
+ }
- bt_string_to_uuid(&uuid, DEVICE_INFORMATION_UUID);
- serv_att = gatt_db_insert_service(db, handle, &uuid, primary,
- 1 + extra_handles);
+#define DESCRIPTOR_STR(desc_uuid, permissions, string) \
+ { \
+ .valid = true, \
+ .type = DESCRIPTOR, \
+ .uuid = STR(desc_uuid), \
+ .att_permissions = permissions, \
+ .value = (uint8_t *)string, \
+ .len = strlen(string), \
+ }
- return serv_att;
-}
-static struct gatt_db_attribute *add_gap(struct gatt_db *db, uint16_t handle,
- bool primary,
- uint16_t extra_handles)
+static struct gatt_db *make_db(const struct att_handle_spec *spec)
{
+ struct gatt_db *db = gatt_db_new();
+ struct gatt_db_attribute *att, *include_att;
bt_uuid_t uuid;
- struct gatt_db_attribute *serv_att;
- bt_string_to_uuid(&uuid, GAP_UUID);
- serv_att = gatt_db_insert_service(db, handle, &uuid, primary,
- 1 + extra_handles);
+ att = include_att = NULL;
- return serv_att;
-}
+ for (; spec->valid; spec++) {
+ switch (spec->type) {
+ case PRIMARY:
+ case SECONDARY:
+ bt_string_to_uuid(&uuid, spec->uuid);
-static struct gatt_db *make_service_data_1_db(void)
-{
- struct gatt_db *db = gatt_db_new();
- struct gatt_db_attribute *serv_att, *chrc_att;
- bt_uuid_t uuid;
+ if (att)
+ gatt_db_service_set_active(att, true);
- bt_uuid16_create(&uuid, 0x1801);
- serv_att = gatt_db_insert_service(db, 0x0001, &uuid, true, 4);
+ att = gatt_db_insert_service(db, spec->handle, &uuid,
+ spec->type == PRIMARY, spec->len);
+ break;
- bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
- chrc_att = add_char_with_value(db, serv_att, &uuid, BT_ATT_PERM_READ,
- BT_GATT_CHRC_PROP_READ, "BlueZ", 5);
+ case INCLUDE:
+ include_att = gatt_db_get_attribute(db, spec->handle);
- add_user_description(chrc_att, "Device Name", false);
+ gatt_db_service_add_included(att, include_att);
+ break;
- gatt_db_service_set_active(serv_att, true);
+ case CHARACTERISTIC:
+ bt_string_to_uuid(&uuid, spec->uuid);
- bt_uuid16_create(&uuid, 0x180d);
- serv_att = gatt_db_insert_service(db, 0x0005, &uuid, true, 4);
+ add_char_with_value(db, att, &uuid,
+ spec->att_permissions,
+ spec->char_properties,
+ spec->value, spec->len);
- bt_uuid16_create(&uuid, GATT_CHARAC_MANUFACTURER_NAME_STRING);
- chrc_att = gatt_db_service_add_characteristic(serv_att, &uuid,
- BT_ATT_PERM_READ,
- BT_GATT_CHRC_PROP_READ,
- NULL, NULL, NULL);
+ break;
- add_user_description(chrc_att, "Manufacturer Name", false);
+ case DESCRIPTOR:
+ bt_string_to_uuid(&uuid, spec->uuid);
- gatt_db_service_set_active(serv_att, true);
+ add_desc_with_value(att, &uuid, spec->att_permissions,
+ spec->value, spec->len);
+
+ break;
+ };
+ }
+
+ if (att)
+ gatt_db_service_set_active(att, true);
return db;
}
+static struct gatt_db *make_service_data_1_db(void)
+{
+ const struct att_handle_spec specs[] = {
+ PRIMARY_SERVICE(0x0001, GATT_UUID, 4),
+ CHARACTERISTIC_STR(GATT_CHARAC_DEVICE_NAME, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, "BlueZ"),
+ DESCRIPTOR_STR(GATT_CHARAC_USER_DESC_UUID, BT_ATT_PERM_READ,
+ "Device Name"),
+ PRIMARY_SERVICE(0x0005, HEART_RATE_UUID, 4),
+ CHARACTERISTIC_STR(GATT_CHARAC_MANUFACTURER_NAME_STRING,
+ BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, ""),
+ DESCRIPTOR_STR(GATT_CHARAC_USER_DESC_UUID, BT_ATT_PERM_READ,
+ "Manufacturer Name"),
+ { }
+ };
+
+ return make_db(specs);
+}
+
/*
* Defined Test database 1:
* Tiny database fits into a single minimum sized-pdu.
@@ -787,59 +856,31 @@ static struct gatt_db *make_service_data_1_db(void)
static struct gatt_db *make_test_spec_small_db(void)
{
- struct gatt_db *db;
- struct gatt_db_attribute *serv_att, *dis_att;
- bt_uuid_t uuid;
- const char *manuf_device_string = "BlueZ";
- const char *device_name_string = "BlueZ Unit Tester";
- const char *user_desc_manuf_name = "Manufacturer Name";
- uint16_t u16_value;
- uint8_t u8_value;
-
- db = gatt_db_new();
-
- dis_att = add_device_information_service(db, 0x0001, false, 15);
-
- bt_uuid16_create(&uuid, GATT_CHARAC_MANUFACTURER_NAME_STRING);
- add_char_with_value(db, dis_att, &uuid, BT_ATT_PERM_READ,
+ const struct att_handle_spec specs[] = {
+ SECONDARY_SERVICE(0x0001, DEVICE_INFORMATION_UUID, 16),
+ CHARACTERISTIC_STR(GATT_CHARAC_MANUFACTURER_NAME_STRING,
+ BT_ATT_PERM_READ,
BT_GATT_CHRC_PROP_READ,
- manuf_device_string,
- strlen(manuf_device_string));
- add_ccc(dis_att, false);
- add_user_description(dis_att, user_desc_manuf_name, false);
-
- gatt_db_service_set_active(dis_att, true);
-
- serv_att = add_gap(db, 0xF010, true, 7);
-
- gatt_db_service_add_included(serv_att, dis_att);
-
- bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
- add_char_with_value(db, serv_att, &uuid, BT_ATT_PERM_READ,
- BT_GATT_CHRC_PROP_READ,
- device_name_string,
- strlen(device_name_string));
-
- bt_string_to_uuid(&uuid, "0000B009-0000-0000-0123-456789abcdef");
- u8_value = 0x09;
- add_char_with_value(db, serv_att, &uuid, BT_ATT_PERM_READ,
- BT_GATT_CHRC_PROP_READ,
- &u8_value, sizeof(uint8_t));
-
- gatt_db_service_set_active(serv_att, true);
-
- u16_value = 0x0000; /* "Unknown" Appearance */
- bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
- add_char_with_value(db, serv_att, &uuid, BT_ATT_PERM_READ,
- BT_GATT_CHRC_PROP_READ, &u16_value,
- sizeof(uint16_t));
-
-
- serv_att = add_device_information_service(db, 0xFFFF, true, 0);
-
- gatt_db_service_set_active(serv_att, true);
-
- return db;
+ "BlueZ"),
+ DESCRIPTOR(GATT_CLIENT_CHARAC_CFG_UUID, BT_ATT_PERM_READ, 0x00,
+ 0x00),
+ DESCRIPTOR_STR(GATT_CHARAC_USER_DESC_UUID, BT_ATT_PERM_READ,
+ "Manufacturer Name"),
+ PRIMARY_SERVICE(0xF010, GAP_UUID, 8),
+ INCLUDE(0x0001),
+ CHARACTERISTIC_STR(GATT_CHARAC_DEVICE_NAME, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ "BlueZ Unit Tester"),
+ CHARACTERISTIC(0000B009-0000-0000-0123-456789abcdef,
+ BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, 0x09),
+ CHARACTERISTIC(GATT_CHARAC_APPEARANCE, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, 0x00, 0x00),
+ PRIMARY_SERVICE(0xFFFF, DEVICE_INFORMATION_UUID, 1),
+ { }
+ };
+
+ return make_db(specs);
}
static void test_client(gconstpointer data)
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can detect and reject a
Read Characteristic Value Request with an unsupported Characteristic
Value handle and issue an Invalid Handle Response.
---
unit/test-gatt.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 25a382b..8bdd2fd 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1739,6 +1739,18 @@ int main(int argc, char *argv[])
'4', '4', '5', '5', '5', '5', '5', '6', '6',
'6', '6', '6', '7', '7'));
+ define_test_server("/TP/GAR/SR/BI-02-C/small", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x0a, 0x00, 0x00),
+ raw_pdu(0x01, 0x0a, 0x00, 0x00, 0x01));
+
+ define_test_server("/TP/GAR/SR/BI-02-C/large", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x0a, 0x0f, 0xf0),
+ raw_pdu(0x01, 0x0a, 0x0f, 0xf0, 0x01));
+
define_test_att("/TP/GAR/CL/BV-03-C-1", test_read_by_type,
&uuid_char_16, &test_read_by_type_1,
raw_pdu(0x02, 0x00, 0x02),
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can support a search for
all descriptors of a specified characteristic.
---
unit/test-gatt.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 9981afe..5740322 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1678,6 +1678,25 @@ int main(int argc, char *argv[])
raw_pdu(0x05, 0x01, 0x15, 0x00, 0x04, 0x29, 0x16, 0x00,
0x05, 0x29));
+ define_test_server("/TP/GAD/SR/BV-06-C/small", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x04, 0x04, 0x00, 0x05, 0x00),
+ raw_pdu(0x05, 0x01, 0x04, 0x00, 0x02, 0x29, 0x05, 0x00,
+ 0x01, 0x29));
+
+ define_test_server("/TP/GAD/SR/BV-06-C/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x04, 0x73, 0x00, 0x76, 0x00),
+ raw_pdu(0x05, 0x01, 0x73, 0x00, 0x00, 0x29, 0x74, 0x00,
+ 0x01, 0x29, 0x75, 0x00, 0x04, 0x29),
+ raw_pdu(0x04, 0x76, 0x00, 0x76, 0x00),
+ raw_pdu(0x05, 0x02, 0x76, 0x00, 0xef, 0xcd, 0xab, 0x89,
+ 0x67, 0x45, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0xd4, 0xd5, 0x00, 0x00));
+
+
define_test_client("/TP/GAR/CL/BV-01-C", test_client, service_db_1,
&test_read_1,
SERVICE_DATA_1_PDUS,
--
2.2.0.rc0.207.ga3a616c
BV-05-C tests are identical to the BV-04-C tests, so add a note
explaining as such.
---
unit/test-gatt.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 24f5695..9981afe 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1664,6 +1664,11 @@ int main(int argc, char *argv[])
raw_pdu(0x08, 0x29, 0x00, 0x29, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x29, 0x00, 0x0a));
+ /*
+ * Note: /TP/GAD/CL/BV-05-C and /TP/GAD/SV/BV-05-C are identical to
+ * /TP/GAD/CL/BV-04-C and /TP/GAD/SV/BV-04-C for BlueZ
+ */
+
define_test_att("/TP/GAD/CL/BV-06-C", test_search_descs, NULL, NULL,
MTU_EXCHANGE_CLIENT_PDUS,
raw_pdu(0x04, 0x13, 0x00, 0x16, 0x00),
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can support reading a
Characteristic Value selected by handle.
---
unit/test-gatt.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 5740322..25a382b 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1721,6 +1721,24 @@ int main(int argc, char *argv[])
raw_pdu(0x0a, 0x03, 0x00),
raw_pdu(0x01, 0x0a, 0x03, 0x00, 0x08));
+ define_test_server("/TP/GAR/SR/BV-01-C/small", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x0a, 0x03, 0x00),
+ raw_pdu(0x0b, 0x42, 0x6c, 0x75, 0x65, 0x5a));
+
+ define_test_server("/TP/GAR/SR/BV-01-C/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x0a, 0xc4, 0x00),
+ raw_pdu(0x0b, '1', '1', '1', '1', '1', '2', '2', '2',
+ '2', '2', '3', '3', '3', '3', '3', '4', '4',
+ '4', '4', '4', '5'),
+ raw_pdu(0x0a, 0xca, 0x00),
+ raw_pdu(0x0b, '3', '3', '3', '3', '3', '4', '4', '4',
+ '4', '4', '5', '5', '5', '5', '5', '6', '6',
+ '6', '6', '6', '7', '7'));
+
define_test_att("/TP/GAR/CL/BV-03-C-1", test_read_by_type,
&uuid_char_16, &test_read_by_type_1,
raw_pdu(0x02, 0x00, 0x02),
--
2.2.0.rc0.207.ga3a616c
Implements Find By Type Value parsing and response, supporting the
"Discovery Primary Service by UUID" of GATT.
---
src/shared/gatt-server.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 00f36fd..985cca1 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -87,6 +87,7 @@ struct bt_gatt_server {
unsigned int read_by_grp_type_id;
unsigned int read_by_type_id;
unsigned int find_info_id;
+ unsigned int find_by_type_value_id;
unsigned int write_id;
unsigned int write_cmd_id;
unsigned int read_id;
@@ -114,6 +115,7 @@ static void bt_gatt_server_free(struct bt_gatt_server *server)
bt_att_unregister(server->att, server->read_by_grp_type_id);
bt_att_unregister(server->att, server->read_by_type_id);
bt_att_unregister(server->att, server->find_info_id);
+ bt_att_unregister(server->att, server->find_by_type_value_id);
bt_att_unregister(server->att, server->write_id);
bt_att_unregister(server->att, server->write_cmd_id);
bt_att_unregister(server->att, server->read_id);
@@ -639,6 +641,102 @@ error:
}
+static bool encode_find_by_type_value_rsp(struct queue *q, uint16_t mtu,
+ uint8_t *pdu, uint16_t *len)
+{
+ struct gatt_db_attribute *attr;
+ uint16_t handle, end_handle;
+ uint16_t iter = 0;
+
+ *len = 0;
+ while (queue_peek_head(q)) {
+ /*
+ * This OP is only valid for Primary Service per the spec
+ * page 562, so this should work.
+ */
+ attr = queue_pop_head(q);
+ gatt_db_attribute_get_service_data(attr, &handle, &end_handle,
+ NULL, NULL);
+ if (!handle || !end_handle)
+ return false;
+
+ if (iter + 4 > mtu - 1)
+ break;
+
+ put_le16(handle, pdu + iter);
+ put_le16(end_handle, pdu + iter + 2);
+
+ iter += 4;
+ }
+
+ *len = iter;
+
+ return true;
+}
+
+static void find_by_type_val_cb(uint8_t opcode, const void *pdu,
+ uint16_t length, void *user_data)
+{
+ struct bt_gatt_server *server = user_data;
+ uint16_t start, end, uuid16;
+ uint16_t mtu = bt_att_get_mtu(server->att);
+ uint8_t rsp_pdu[mtu];
+ uint16_t rsp_len;
+ uint8_t ecode = 0;
+ uint16_t ehandle = 0;
+ bt_uuid_t uuid;
+ struct queue *q = NULL;
+
+ if (length < 6) {
+ ecode = BT_ATT_ERROR_INVALID_PDU;
+ goto error;
+ }
+
+ q = queue_new();
+ if (!q) {
+ ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
+
+ start = get_le16(pdu);
+ end = get_le16(pdu + 2);
+ uuid16 = get_le16(pdu + 4);
+
+ util_debug(server->debug_callback, server->debug_data,
+ "Find By Type Value - start: 0x%04x end: 0x%04x uuid: 0x%04x",
+ start, end, uuid16);
+ ehandle = start;
+ if (start > end) {
+ ecode = BT_ATT_ERROR_INVALID_HANDLE;
+ goto error;
+ }
+
+ bt_uuid16_create(&uuid, uuid16);
+ gatt_db_find_by_type_value(server->db, start, end, &uuid, pdu + 6,
+ length - 6, q);
+
+ if (queue_isempty(q)) {
+ ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
+ goto error;
+ }
+
+ if (!encode_find_by_type_value_rsp(q, mtu, rsp_pdu, &rsp_len)) {
+ ecode = BT_ATT_ERROR_UNLIKELY;
+ goto error;
+ }
+
+ bt_att_send(server->att, BT_ATT_OP_FIND_BY_TYPE_VAL_RSP, rsp_pdu,
+ rsp_len, NULL, NULL, NULL);
+
+ queue_destroy(q, NULL);
+
+ return;
+
+error:
+ bt_att_send_error_rsp(server->att, opcode, ehandle, ecode);
+ queue_destroy(q, NULL);
+}
+
static void async_write_op_destroy(struct async_write_op *op)
{
if (op->server)
@@ -1128,6 +1226,15 @@ static bool gatt_server_register_att_handlers(struct bt_gatt_server *server)
if (!server->find_info_id)
return false;
+ /* Find By Type Value */
+ server->find_by_type_value_id = bt_att_register(server->att,
+ BT_ATT_OP_FIND_BY_TYPE_VAL_REQ,
+ find_by_type_val_cb,
+ server, NULL);
+
+ if (!server->find_by_type_value_id)
+ return false;
+
/* Write Request */
server->write_id = bt_att_register(server->att, BT_ATT_OP_WRITE_REQ,
write_cb,
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can support a search for
all Included Services in a specified handle range.
---
unit/test-gatt.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index fbccb18..4412219 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1589,6 +1589,28 @@ int main(int argc, char *argv[])
raw_pdu(0x08, 0x06, 0x00, 0xff, 0xff, 0x02, 0x28),
raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a));
+ define_test_server("/TP/GAD/SR/BV-03-C/small", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x08, 0x01, 0x00, 0xff, 0xff, 0x02, 0x28),
+ raw_pdu(0x09, 0x08, 0x11, 0xf0, 0x01, 0x00, 0x10, 0x00,
+ 0x0a, 0x18),
+ raw_pdu(0x08, 0x12, 0xf0, 0xff, 0xff, 0x02, 0x28),
+ raw_pdu(0x01, 0x08, 0x12, 0xf0, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-03-C/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x08, 0x01, 0x00, 0xff, 0xff, 0x02, 0x28),
+ raw_pdu(0x09, 0x08, 0x02, 0x00, 0x80, 0x00, 0x85, 0x00,
+ 0x0b, 0xa0, 0x21, 0x00, 0x01, 0x00, 0x06, 0x00,
+ 0x0d, 0xa0),
+ raw_pdu(0x08, 0x22, 0x00, 0xff, 0xff, 0x02, 0x28),
+ raw_pdu(0x09, 0x08, 0x91, 0x00, 0x01, 0x00, 0x06, 0x00,
+ 0x0d, 0xa0),
+ raw_pdu(0x08, 0x92, 0x00, 0xff, 0xff, 0x02, 0x28),
+ raw_pdu(0x01, 0x08, 0x92, 0x00, 0x0a));
+
define_test_att("/TP/GAD/CL/BV-04-C", test_search_chars, NULL,
NULL,
MTU_EXCHANGE_CLIENT_PDUS,
--
2.2.0.rc0.207.ga3a616c
---
unit/test-gatt.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 647dd4e..6e075f6 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -866,17 +866,16 @@ static struct gatt_db *make_service_data_1_db(void)
/*
* Defined Test database 1:
* Tiny database fits into a single minimum sized-pdu.
- * Satisfies:
- * 3. At least one primary seervice at the MAX handle
- * For each / all databases:
- * X 7. at least one service uuid with multiple instances
- * X 8. Some simple services, some with included services
- * X 9. an instance where handle of included service comes before the including
+ * Satisfies requirements:
+ * 3. At least one primary service at the MAX handle
+ * 7. at least one service uuid with multiple instances
+ * 8. Some simple services, some with included services
+ * 9. an instance where handle of included service comes before the including
* service
- * X 11. Simple characteristics (no desc) and complex characteristics
- * (multiple descriptors)
- * X 12. Instances of complex chars with 16-bit and 128-bit uuids
- * (although not in scrambled order)
+ * 11. Simple characteristics (no desc) and complex characteristics
+ * (multiple descriptors)
+ * 12. Instances of complex chars with 16-bit and 128-bit uuids
+ * (although not in scrambled order)
*/
static struct gatt_db *make_test_spec_small_db(void)
--
2.2.0.rc0.207.ga3a616c
This function mirrors add_char_with_value and deduplicates some repeated
code from convenience functions.
---
unit/test-gatt.c | 43 +++++++++++++++++++++----------------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index bee8f37..4f5857f 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -660,47 +660,46 @@ static struct gatt_db_attribute *add_char_with_value(struct gatt_db *db,
return attrib;
}
+static struct gatt_db_attribute *
+add_desc_with_value(struct gatt_db_attribute *att, bt_uuid_t *uuid,
+ uint32_t att_perms, const uint8_t *value,
+ size_t len)
+{
+ struct gatt_db_attribute *desc_att;
+
+ desc_att = gatt_db_service_add_descriptor(att, uuid, att_perms, NULL,
+ NULL, NULL);
+
+ gatt_db_attribute_write(desc_att, 0, value, len, 0x00, NULL,
+ att_write_cb, NULL);
+
+ return desc_att;
+}
+
static struct gatt_db_attribute *add_ccc(struct gatt_db_attribute *chrc_att,
bool writable)
{
- struct gatt_db_attribute *desc_att;
bt_uuid_t uuid;
- uint32_t permissions = BT_ATT_PERM_READ;
uint16_t tmp;
- if (writable)
- permissions |= BT_ATT_PERM_WRITE;
-
bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
- desc_att = gatt_db_service_add_descriptor(chrc_att, &uuid, permissions,
- NULL, NULL, NULL);
-
tmp = 0x0000;
- gatt_db_attribute_write(desc_att, 0, (uint8_t *)&tmp, sizeof(uint16_t),
- 0x00, NULL, att_write_cb, NULL);
- return desc_att;
+ return add_desc_with_value(chrc_att, &uuid,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ (uint8_t *)&tmp, sizeof(tmp));
}
static struct gatt_db_attribute *
add_user_description(struct gatt_db_attribute *chrc_att, const char *desc,
bool writable)
{
- struct gatt_db_attribute *desc_att;
bt_uuid_t uuid;
- uint32_t permissions = BT_ATT_PERM_READ;
-
- if (writable)
- permissions |= BT_ATT_PERM_WRITE;
bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
- desc_att = gatt_db_service_add_descriptor(chrc_att, &uuid, permissions,
- NULL, NULL, NULL);
- gatt_db_attribute_write(desc_att, 0, (uint8_t *)desc, strlen(desc),
- 0x00, NULL, att_write_cb, NULL);
-
- return desc_att;
+ return add_desc_with_value(chrc_att, &uuid, 0x03, (uint8_t *)desc,
+ strlen(desc));
}
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can support a search for
all characteristics of a specified Service, and report all of those
characteristics.
---
unit/test-gatt.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 4412219..24f5695 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1625,6 +1625,45 @@ int main(int argc, char *argv[])
raw_pdu(0x08, 0x14, 0x00, 0x20, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x12, 0x00, 0x0a));
+ define_test_server("/TP/GAD/SR/BV-04-C/small/1", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x08, 0x10, 0xf0, 0x17, 0xf0, 0x03, 0x28),
+ raw_pdu(0x09, 0x07, 0x12, 0xf0, 0x02, 0x13, 0xf0, 0x00,
+ 0x2a),
+ raw_pdu(0x08, 0x13, 0xf0, 0x17, 0xf0, 0x03, 0x28),
+ raw_pdu(0x09, 0x15, 0x14, 0xf0, 0x02, 0x15, 0xf0, 0xef,
+ 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0xb0, 0x00, 0x00),
+ raw_pdu(0x08, 0x15, 0xf0, 0x17, 0xf0, 0x03, 0x28),
+ raw_pdu(0x09, 0x07, 0x16, 0xf0, 0x02, 0x17, 0xf0, 0x01,
+ 0x2a),
+ raw_pdu(0x08, 0x17, 0xf0, 0x17, 0xf0, 0x03, 0x28),
+ raw_pdu(0x01, 0x08, 0x17, 0xf0, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-04-C/small/2", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x08, 0x01, 0x00, 0x0f, 0x00, 0x03, 0x28),
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x02, 0x03, 0x00, 0x29,
+ 0x2a),
+ raw_pdu(0x08, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x28),
+ raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-04-C/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x08, 0x20, 0x00, 0x29, 0x00, 0x03, 0x28),
+ raw_pdu(0x09, 0x07, 0x22, 0x00, 0x02, 0x23, 0x00, 0x01,
+ 0xb0, 0x24, 0x00, 0x0a, 0x25, 0x00, 0x02, 0xb0,
+ 0x26, 0x00, 0x08, 0x27, 0x00, 0x02, 0xb0),
+ raw_pdu(0x08, 0x27, 0x00, 0x29, 0x00, 0x03, 0x28),
+ raw_pdu(0x09, 0x07, 0x28, 0x00, 0x08, 0x29, 0x00, 0x03,
+ 0xb0),
+ raw_pdu(0x08, 0x29, 0x00, 0x29, 0x00, 0x03, 0x28),
+ raw_pdu(0x01, 0x08, 0x29, 0x00, 0x0a));
+
define_test_att("/TP/GAD/CL/BV-06-C", test_search_descs, NULL, NULL,
MTU_EXCHANGE_CLIENT_PDUS,
raw_pdu(0x04, 0x13, 0x00, 0x16, 0x00),
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can support discovery of
all particular Primary Services selected by service UUID, using 16-bit
UUIDs, and using 128-bit UUIDs where supported.
128-bit tests will be added once the larger databases with 128-bit UUIDs
are added.
---
unit/test-gatt.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 6e075f6..fbccb18 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1509,6 +1509,63 @@ int main(int argc, char *argv[])
0x18, 0x00, 0x00),
raw_pdu(0x01, 0x06, 0x18, 0x00, 0x0a));
+ define_test_server("/TP/GAD/SR/BV-02-C/exists-16/small", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0x00,
+ 0x18),
+ raw_pdu(0x07, 0x10, 0xf0, 0x17, 0xf0),
+ raw_pdu(0x06, 0x18, 0xf0, 0xff, 0xff, 0x00, 0x28, 0x00,
+ 0x18),
+ raw_pdu(0x01, 0x06, 0x18, 0xf0, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-02-C/exists-16/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0x0b,
+ 0xa0),
+ raw_pdu(0x07, 0x30, 0x00, 0x32, 0x00, 0x50, 0x00, 0x52,
+ 0x00, 0x60, 0x00, 0x6b, 0x00, 0x70, 0x00, 0x76,
+ 0x00, 0x80, 0x00, 0x85, 0x00),
+ raw_pdu(0x06, 0x86, 0x00, 0xff, 0xff, 0x00, 0x28, 0x0b,
+ 0xa0),
+ raw_pdu(0x01, 0x06, 0x86, 0x00, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-02-C/missing-16/small", test_server,
+ ts_small_db, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0x01,
+ 0x18),
+ raw_pdu(0x01, 0x06, 0x01, 0x00, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-02-C/missing-16/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0x0f,
+ 0xf0),
+ raw_pdu(0x01, 0x06, 0x01, 0x00, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-02-C/exists-128/large-1", test_server,
+ ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0xef,
+ 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00),
+ raw_pdu(0x07, 0x90, 0x00, 0x96, 0x00, 0xc0, 0x00, 0xdd,
+ 0x00),
+ raw_pdu(0x06, 0xde, 0x00, 0xff, 0xff, 0x00, 0x28, 0xef,
+ 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00),
+ raw_pdu(0x01, 0x06, 0xde, 0x00, 0x0a));
+
+ define_test_server("/TP/GAD/SR/BV-02-C/missing-128/large-1",
+ test_server, ts_large_db_1, NULL,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff,
+ 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00),
+ raw_pdu(0x01, 0x06, 0x01, 0x00, 0x0a));
+
define_test_att("/TP/GAD/CL/BV-03-C", test_search_included, NULL,
NULL,
MTU_EXCHANGE_CLIENT_PDUS,
--
2.2.0.rc0.207.ga3a616c
Added to support the GATT discovery of services by UUID.
Currently only works for values which are stored within the attribute
structure (not callback-based).
---
src/shared/gatt-db.c | 27 +++++++++++++++++++++++++++
src/shared/gatt-db.h | 7 +++++++
2 files changed, 34 insertions(+)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index d2cdacc..bef1308 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -830,6 +830,8 @@ struct find_by_type_value_data {
bt_uuid_t uuid;
uint16_t start_handle;
uint16_t end_handle;
+ const void *value;
+ size_t value_len;
};
static void find_by_type(void *data, void *user_data)
@@ -855,6 +857,12 @@ static void find_by_type(void *data, void *user_data)
if (bt_uuid_cmp(&search_data->uuid, &attribute->uuid))
continue;
+ /* TODO: fix for read-callback based attributes */
+ if (search_data->value && memcmp(attribute->value,
+ search_data->value,
+ search_data->value_len))
+ continue;
+
queue_push_tail(search_data->queue, attribute);
}
}
@@ -874,6 +882,25 @@ void gatt_db_find_by_type(struct gatt_db *db, uint16_t start_handle,
queue_foreach(db->services, find_by_type, &data);
}
+void gatt_db_find_by_type_value(struct gatt_db *db, uint16_t start_handle,
+ uint16_t end_handle,
+ const bt_uuid_t *type,
+ const void *value,
+ size_t value_len,
+ struct queue *queue)
+{
+ struct find_by_type_value_data data;
+
+ data.uuid = *type;
+ data.start_handle = start_handle;
+ data.end_handle = end_handle;
+ data.queue = queue;
+ data.value = value;
+ data.value_len = value_len;
+
+ queue_foreach(db->services, find_by_type, &data);
+}
+
struct read_by_type_data {
struct queue *queue;
bt_uuid_t uuid;
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index f188944..9281671 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -93,6 +93,13 @@ void gatt_db_find_by_type(struct gatt_db *db, uint16_t start_handle,
const bt_uuid_t *type,
struct queue *queue);
+void gatt_db_find_by_type_value(struct gatt_db *db, uint16_t start_handle,
+ uint16_t end_handle,
+ const bt_uuid_t *type,
+ const void *value,
+ size_t value_len,
+ struct queue *queue);
+
void gatt_db_read_by_type(struct gatt_db *db, uint16_t start_handle,
uint16_t end_handle,
const bt_uuid_t type,
--
2.2.0.rc0.207.ga3a616c
Small DB was constructed without noticing that the last characteristic is
not added, and needs two more handles in the service to hold it.
This patch will also cause unit/gatt to assert if characteristics are
not added when expected.
---
unit/test-gatt.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 5f5ad1b..bee8f37 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -149,7 +149,7 @@ struct context {
#define PRIMARY_DISC_SMALL_DB \
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \
- raw_pdu(0x11, 0x06, 0x10, 0xF0, 0x15, 0xF0, 0x00, 0x18, \
+ raw_pdu(0x11, 0x06, 0x10, 0xF0, 0x17, 0xF0, 0x00, 0x18, \
0xFF, 0xFF, 0xFF, 0xFF, 0x0a, 0x18)
#define SECONDARY_DISC_SMALL_DB \
@@ -652,6 +652,8 @@ static struct gatt_db_attribute *add_char_with_value(struct gatt_db *db,
NULL, NULL,
NULL);
+ g_assert(attrib != NULL);
+
gatt_db_attribute_write(attrib, 0, value, len, 0x00, NULL, att_write_cb,
NULL);
@@ -809,7 +811,7 @@ static struct gatt_db *make_test_spec_small_db(void)
gatt_db_service_set_active(dis_att, true);
- serv_att = add_gap(db, 0xF010, true, 5);
+ serv_att = add_gap(db, 0xF010, true, 7);
gatt_db_service_add_included(serv_att, dis_att);
@@ -1145,7 +1147,7 @@ int main(int argc, char *argv[])
0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00,
0x80, 0x00, 0x10, 0x00, 0x00, 0x0d,
0x18, 0x00, 0x00),
- raw_pdu(0x01, 0x06, 0x08, 0x00, 0x0a));
+ raw_pdu(0x01, 0x06, 0x18, 0x00, 0x0a));
define_test_att("/TP/GAD/CL/BV-03-C", test_search_included, NULL,
NULL,
--
2.2.0.rc0.207.ga3a616c
Hi Luiz,
>> This patchset reworks the way that GATT test databases are defined,
>> defines a "large database" as defined by the test spec, adds a set
>> of new tests from the test spec.
>>
>> It also includes some minor cleanup.
>>
>> Michael Janssen (14):
>> shared/gatt-db: Add gatt_db_find_by_type_value
>> shared/gatt-server: support Discover by UUID
>> unit/gatt: Bugfix small database construction
>> unit/gatt: Add add_desc_with_value function
>> unit/gatt: Rework service db definitions
>> unit/gatt: Add Test Spec Large Database 1
>> unit/gatt: Comment cleanup
>> unit/gatt: Add /TP/GAD/SR/BV-02-C test
>> unit/gatt: Add /TP/GAD/SR/BV-03-C test
>> unit/gatt: Add /TP/GAD/SR/BV-04-C test
>> unit/gatt: Add clarifying note about dup tests.
>> unit/gatt: Add /TP/GAD/SR/BV-06-C test
>> unit/gatt: Add /TP/GAR/SR/BV-01-C test
>> unit/gatt: Add /TP/GAR/SR/BI-02-C test
>>
>> src/shared/gatt-db.c | 27 ++
>> src/shared/gatt-db.h | 7 +
>> src/shared/gatt-server.c | 107 +++++++
>> unit/test-gatt.c | 808 +++++++++++++++++++++++++++++++++++++++--------
>> 4 files changed, 812 insertions(+), 137 deletions(-)
>>
>> --
>> 2.2.0.rc0.207.ga3a616c
>
> I went ahead and applied patches 3-5, patch 6/14 does not apply:
>
> Applying: unit/gatt: Add Test Spec Large Database 1
> WARNING:LONG_LINE: line over 80 characters
> #91: FILE: unit/test-gatt.c:961:
> + "11111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233"),
>
> WARNING:LONG_LINE: line over 80 characters
> #295: FILE: unit/test-gatt.c:1165:
> + "1111122222333334444455555666667777788888999"),
>
> WARNING:LONG_LINE: line over 80 characters
> #306: FILE: unit/test-gatt.c:1176:
> + "22222333334444455555666667777788888999990000"),
>
> WARNING:LONG_LINE: line over 80 characters
> #317: FILE: unit/test-gatt.c:1187:
> + "333334444455555666667777788888999990000011111"),
maybe it makes sense to split these over multiple lines. If it doesn't, then just force git am to ignore the warning and apply them anyway.
Regards
Marcel
Hi Michael,
On Tue, Dec 30, 2014 at 10:32 PM, Michael Janssen <[email protected]> wrote:
> This patchset reworks the way that GATT test databases are defined,
> defines a "large database" as defined by the test spec, adds a set
> of new tests from the test spec.
>
> It also includes some minor cleanup.
>
> Michael Janssen (14):
> shared/gatt-db: Add gatt_db_find_by_type_value
> shared/gatt-server: support Discover by UUID
> unit/gatt: Bugfix small database construction
> unit/gatt: Add add_desc_with_value function
> unit/gatt: Rework service db definitions
> unit/gatt: Add Test Spec Large Database 1
> unit/gatt: Comment cleanup
> unit/gatt: Add /TP/GAD/SR/BV-02-C test
> unit/gatt: Add /TP/GAD/SR/BV-03-C test
> unit/gatt: Add /TP/GAD/SR/BV-04-C test
> unit/gatt: Add clarifying note about dup tests.
> unit/gatt: Add /TP/GAD/SR/BV-06-C test
> unit/gatt: Add /TP/GAR/SR/BV-01-C test
> unit/gatt: Add /TP/GAR/SR/BI-02-C test
>
> src/shared/gatt-db.c | 27 ++
> src/shared/gatt-db.h | 7 +
> src/shared/gatt-server.c | 107 +++++++
> unit/test-gatt.c | 808 +++++++++++++++++++++++++++++++++++++++--------
> 4 files changed, 812 insertions(+), 137 deletions(-)
>
> --
> 2.2.0.rc0.207.ga3a616c
I went ahead and applied patches 3-5, patch 6/14 does not apply:
Applying: unit/gatt: Add Test Spec Large Database 1
WARNING:LONG_LINE: line over 80 characters
#91: FILE: unit/test-gatt.c:961:
+ "11111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233333444445555566666777778888899999000001111122222333334444455555666667777788888999990000011111222223333344444555556666677777888889999900000111112222233"),
WARNING:LONG_LINE: line over 80 characters
#295: FILE: unit/test-gatt.c:1165:
+ "1111122222333334444455555666667777788888999"),
WARNING:LONG_LINE: line over 80 characters
#306: FILE: unit/test-gatt.c:1176:
+ "22222333334444455555666667777788888999990000"),
WARNING:LONG_LINE: line over 80 characters
#317: FILE: unit/test-gatt.c:1187:
+ "333334444455555666667777788888999990000011111"),
--
Luiz Augusto von Dentz
Hi Michael,
On Tue, Dec 30, 2014 at 10:32 PM, Michael Janssen <[email protected]> wrote:
> Added to support the GATT discovery of services by UUID.
> Currently only works for values which are stored within the attribute
> structure (not callback-based).
> ---
> src/shared/gatt-db.c | 27 +++++++++++++++++++++++++++
> src/shared/gatt-db.h | 7 +++++++
> 2 files changed, 34 insertions(+)
>
> diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
> index d2cdacc..bef1308 100644
> --- a/src/shared/gatt-db.c
> +++ b/src/shared/gatt-db.c
> @@ -830,6 +830,8 @@ struct find_by_type_value_data {
> bt_uuid_t uuid;
> uint16_t start_handle;
> uint16_t end_handle;
> + const void *value;
> + size_t value_len;
> };
>
> static void find_by_type(void *data, void *user_data)
> @@ -855,6 +857,12 @@ static void find_by_type(void *data, void *user_data)
> if (bt_uuid_cmp(&search_data->uuid, &attribute->uuid))
> continue;
>
> + /* TODO: fix for read-callback based attributes */
> + if (search_data->value && memcmp(attribute->value,
> + search_data->value,
> + search_data->value_len))
> + continue;
> +
> queue_push_tail(search_data->queue, attribute);
> }
> }
> @@ -874,6 +882,25 @@ void gatt_db_find_by_type(struct gatt_db *db, uint16_t start_handle,
> queue_foreach(db->services, find_by_type, &data);
> }
>
> +void gatt_db_find_by_type_value(struct gatt_db *db, uint16_t start_handle,
> + uint16_t end_handle,
> + const bt_uuid_t *type,
> + const void *value,
> + size_t value_len,
> + struct queue *queue)
> +{
> + struct find_by_type_value_data data;
> +
> + data.uuid = *type;
> + data.start_handle = start_handle;
> + data.end_handle = end_handle;
> + data.queue = queue;
> + data.value = value;
> + data.value_len = value_len;
> +
> + queue_foreach(db->services, find_by_type, &data);
> +}
> +
> struct read_by_type_data {
> struct queue *queue;
> bt_uuid_t uuid;
> diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
> index f188944..9281671 100644
> --- a/src/shared/gatt-db.h
> +++ b/src/shared/gatt-db.h
> @@ -93,6 +93,13 @@ void gatt_db_find_by_type(struct gatt_db *db, uint16_t start_handle,
> const bt_uuid_t *type,
> struct queue *queue);
>
> +void gatt_db_find_by_type_value(struct gatt_db *db, uint16_t start_handle,
> + uint16_t end_handle,
> + const bt_uuid_t *type,
> + const void *value,
> + size_t value_len,
> + struct queue *queue);
> +
I thought we agreed on not exposing queues anymore so instead this
should take a callback.
> void gatt_db_read_by_type(struct gatt_db *db, uint16_t start_handle,
> uint16_t end_handle,
> const bt_uuid_t type,
> --
> 2.2.0.rc0.207.ga3a616c
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Luiz Augusto von Dentz