Implements the four defined tests around the Notification and Indication
functionality in the unit tests. Also includes some fixes to discovery when
no handles could be found (services with no handles).
Also adds some functionality to the unit testing, to support when there is no
action required by the client and/or the server in a test, and checks for
post data transmission.
Michael Janssen (8):
gatt-client: skip discovery with no handles
unit/test-gatt: Add support for no-actions
unit/gatt: Add TP/GAN/CL/BV-01-C test
unit/gatt: Add TP/GAN/SR/BV-01-C test
unit/gatt: add support for post-tests
unit/gatt: Add TP/GAI/SR/BV-01-C test
unit/gatt: Add TP/GAI/CL/BV-01-C test
unit/gatt: minor consistency in test data
src/shared/gatt-client.c | 9 ++
unit/test-gatt.c | 267 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 254 insertions(+), 22 deletions(-)
--
2.2.0.rc0.207.ga3a616c
Hi Michael,
On Thu, Feb 12, 2015 at 5:00 PM, Michael Janssen <[email protected]> wrote:
> Hi Luiz,
>
> On Thu, Feb 12, 2015 at 5:38 AM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Hi Michael,
>>
>> On Thu, Feb 12, 2015 at 12:20 AM, Michael Janssen <[email protected]> wrote:
>>> Hi Luiz,
>>>
>>> On Wed, Feb 11, 2015 at 5:47 AM, Luiz Augusto von Dentz
>>> <[email protected]> wrote:
>>>> Hi,
>>>>
>>>> On Wed, Feb 11, 2015 at 3:30 PM, Luiz Augusto von Dentz
>>>> <[email protected]> wrote:
>>>>> Hi Michael,
>>>>>
>>>>> On Tue, Feb 10, 2015 at 10:16 PM, Michael Janssen <[email protected]> wrote:
>>>>>> Implements the four defined tests around the Notification and Indication
>>>>>> functionality in the unit tests. Also includes some fixes to discovery when
>>>>>> no handles could be found (services with no handles).
>>>>>>
>>>>>> Also adds some functionality to the unit testing, to support when there is no
>>>>>> action required by the client and/or the server in a test, and checks for
>>>>>> post data transmission.
>>>>>>
>>>>>> --
>>>>>
>>>>> Applied, thanks.
>>>>
>>>> I gather the following number from the latest TS:
>>>>
>>>> Group Client Server
>>>> Configuration 100% (1 / 1) 100% (1 / 1)
>>>> Discovery 75% (6 / 8) 75% (6 / 8)
>>>> Read 57.5% (23 / 40) 47.6% (20 / 42)
>>>> Write 0% (0 / 40) 0% (0 / 40)
>>>> Notification/Indication 50% (1 / 2) 50% (1 / 2)
>>>> Services 0% (0 / 1) 0% (0 / 1)
>>>> Timeouts 0% (0 / 2) 0% (0 / 1)
>>>> Attributes 0% (0 / 10) 0% (0 / 10)
>>>> Total 29.8% (31 / 104) 26.7% 28 / 105
>>>>
>>>> *I did not compute any extra tests we are doing, like small vs large
>>>> databases, still these numbers are quite low.
>>>>
>>>> --
>>>> Luiz Augusto von Dentz
>>>
>>> How do you obtain these numbers? I would like to fix the tests that
>>> are not showing up. All four of the Notification / Indication ones
>>> for example were just committed, so two are not tracking in this
>>> report. I believe the read and Discovery ones are low as well.
>>
>> Yep, I had not realize the group actually have two different suffixes,
>> GAN and GAI, anyway that adds just 2 test to the coverage.
>>
>>> Also, theoretically all the server tests should be run against as many
>>> of the 4 databases that are specified in the TS. I was planning on
>>> only the small and single large to start, and come back to the other
>>> two large databases later if possible.
>>
>> That are duplicates, Im not taking into account them here since I want
>> to know how much the TS we are covering not the total number of tests.
>
> So these are just manually checking for each test that is written? If
> that's the case then would it be useful to note why some of the tests
> are not in, because it's missing functionality sometimes (for
> encryption / authorization / authentication read tests for example).
Sure, we might want to create items in the TODO list so they get
properly prioritized.
--
Luiz Augusto von Dentz
Hi Luiz,
On Thu, Feb 12, 2015 at 5:38 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Michael,
>
> On Thu, Feb 12, 2015 at 12:20 AM, Michael Janssen <[email protected]> wrote:
>> Hi Luiz,
>>
>> On Wed, Feb 11, 2015 at 5:47 AM, Luiz Augusto von Dentz
>> <[email protected]> wrote:
>>> Hi,
>>>
>>> On Wed, Feb 11, 2015 at 3:30 PM, Luiz Augusto von Dentz
>>> <[email protected]> wrote:
>>>> Hi Michael,
>>>>
>>>> On Tue, Feb 10, 2015 at 10:16 PM, Michael Janssen <[email protected]> wrote:
>>>>> Implements the four defined tests around the Notification and Indication
>>>>> functionality in the unit tests. Also includes some fixes to discovery when
>>>>> no handles could be found (services with no handles).
>>>>>
>>>>> Also adds some functionality to the unit testing, to support when there is no
>>>>> action required by the client and/or the server in a test, and checks for
>>>>> post data transmission.
>>>>>
>>>>> --
>>>>
>>>> Applied, thanks.
>>>
>>> I gather the following number from the latest TS:
>>>
>>> Group Client Server
>>> Configuration 100% (1 / 1) 100% (1 / 1)
>>> Discovery 75% (6 / 8) 75% (6 / 8)
>>> Read 57.5% (23 / 40) 47.6% (20 / 42)
>>> Write 0% (0 / 40) 0% (0 / 40)
>>> Notification/Indication 50% (1 / 2) 50% (1 / 2)
>>> Services 0% (0 / 1) 0% (0 / 1)
>>> Timeouts 0% (0 / 2) 0% (0 / 1)
>>> Attributes 0% (0 / 10) 0% (0 / 10)
>>> Total 29.8% (31 / 104) 26.7% 28 / 105
>>>
>>> *I did not compute any extra tests we are doing, like small vs large
>>> databases, still these numbers are quite low.
>>>
>>> --
>>> Luiz Augusto von Dentz
>>
>> How do you obtain these numbers? I would like to fix the tests that
>> are not showing up. All four of the Notification / Indication ones
>> for example were just committed, so two are not tracking in this
>> report. I believe the read and Discovery ones are low as well.
>
> Yep, I had not realize the group actually have two different suffixes,
> GAN and GAI, anyway that adds just 2 test to the coverage.
>
>> Also, theoretically all the server tests should be run against as many
>> of the 4 databases that are specified in the TS. I was planning on
>> only the small and single large to start, and come back to the other
>> two large databases later if possible.
>
> That are duplicates, Im not taking into account them here since I want
> to know how much the TS we are covering not the total number of tests.
So these are just manually checking for each test that is written? If
that's the case then would it be useful to note why some of the tests
are not in, because it's missing functionality sometimes (for
encryption / authorization / authentication read tests for example).
Hi Michael,
On Thu, Feb 12, 2015 at 12:20 AM, Michael Janssen <[email protected]> wrote:
> Hi Luiz,
>
> On Wed, Feb 11, 2015 at 5:47 AM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Hi,
>>
>> On Wed, Feb 11, 2015 at 3:30 PM, Luiz Augusto von Dentz
>> <[email protected]> wrote:
>>> Hi Michael,
>>>
>>> On Tue, Feb 10, 2015 at 10:16 PM, Michael Janssen <[email protected]> wrote:
>>>> Implements the four defined tests around the Notification and Indication
>>>> functionality in the unit tests. Also includes some fixes to discovery when
>>>> no handles could be found (services with no handles).
>>>>
>>>> Also adds some functionality to the unit testing, to support when there is no
>>>> action required by the client and/or the server in a test, and checks for
>>>> post data transmission.
>>>>
>>>> --
>>>
>>> Applied, thanks.
>>
>> I gather the following number from the latest TS:
>>
>> Group Client Server
>> Configuration 100% (1 / 1) 100% (1 / 1)
>> Discovery 75% (6 / 8) 75% (6 / 8)
>> Read 57.5% (23 / 40) 47.6% (20 / 42)
>> Write 0% (0 / 40) 0% (0 / 40)
>> Notification/Indication 50% (1 / 2) 50% (1 / 2)
>> Services 0% (0 / 1) 0% (0 / 1)
>> Timeouts 0% (0 / 2) 0% (0 / 1)
>> Attributes 0% (0 / 10) 0% (0 / 10)
>> Total 29.8% (31 / 104) 26.7% 28 / 105
>>
>> *I did not compute any extra tests we are doing, like small vs large
>> databases, still these numbers are quite low.
>>
>> --
>> Luiz Augusto von Dentz
>
> How do you obtain these numbers? I would like to fix the tests that
> are not showing up. All four of the Notification / Indication ones
> for example were just committed, so two are not tracking in this
> report. I believe the read and Discovery ones are low as well.
Yep, I had not realize the group actually have two different suffixes,
GAN and GAI, anyway that adds just 2 test to the coverage.
> Also, theoretically all the server tests should be run against as many
> of the 4 databases that are specified in the TS. I was planning on
> only the small and single large to start, and come back to the other
> two large databases later if possible.
That are duplicates, Im not taking into account them here since I want
to know how much the TS we are covering not the total number of tests.
--
Luiz Augusto von Dentz
Hi Luiz,
On Wed, Feb 11, 2015 at 5:47 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi,
>
> On Wed, Feb 11, 2015 at 3:30 PM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Hi Michael,
>>
>> On Tue, Feb 10, 2015 at 10:16 PM, Michael Janssen <[email protected]> wrote:
>>> Implements the four defined tests around the Notification and Indication
>>> functionality in the unit tests. Also includes some fixes to discovery when
>>> no handles could be found (services with no handles).
>>>
>>> Also adds some functionality to the unit testing, to support when there is no
>>> action required by the client and/or the server in a test, and checks for
>>> post data transmission.
>>>
>>> --
>>
>> Applied, thanks.
>
> I gather the following number from the latest TS:
>
> Group Client Server
> Configuration 100% (1 / 1) 100% (1 / 1)
> Discovery 75% (6 / 8) 75% (6 / 8)
> Read 57.5% (23 / 40) 47.6% (20 / 42)
> Write 0% (0 / 40) 0% (0 / 40)
> Notification/Indication 50% (1 / 2) 50% (1 / 2)
> Services 0% (0 / 1) 0% (0 / 1)
> Timeouts 0% (0 / 2) 0% (0 / 1)
> Attributes 0% (0 / 10) 0% (0 / 10)
> Total 29.8% (31 / 104) 26.7% 28 / 105
>
> *I did not compute any extra tests we are doing, like small vs large
> databases, still these numbers are quite low.
>
> --
> Luiz Augusto von Dentz
How do you obtain these numbers? I would like to fix the tests that
are not showing up. All four of the Notification / Indication ones
for example were just committed, so two are not tracking in this
report. I believe the read and Discovery ones are low as well.
Also, theoretically all the server tests should be run against as many
of the 4 databases that are specified in the TS. I was planning on
only the small and single large to start, and come back to the other
two large databases later if possible.
Hi,
On Wed, Feb 11, 2015 at 3:30 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Michael,
>
> On Tue, Feb 10, 2015 at 10:16 PM, Michael Janssen <[email protected]> wrote:
>> Implements the four defined tests around the Notification and Indication
>> functionality in the unit tests. Also includes some fixes to discovery when
>> no handles could be found (services with no handles).
>>
>> Also adds some functionality to the unit testing, to support when there is no
>> action required by the client and/or the server in a test, and checks for
>> post data transmission.
>>
>> --
>
> Applied, thanks.
I gather the following number from the latest TS:
Group Client Server
Configuration 100% (1 / 1) 100% (1 / 1)
Discovery 75% (6 / 8) 75% (6 / 8)
Read 57.5% (23 / 40) 47.6% (20 / 42)
Write 0% (0 / 40) 0% (0 / 40)
Notification/Indication 50% (1 / 2) 50% (1 / 2)
Services 0% (0 / 1) 0% (0 / 1)
Timeouts 0% (0 / 2) 0% (0 / 1)
Attributes 0% (0 / 10) 0% (0 / 10)
Total 29.8% (31 / 104) 26.7% 28 / 105
*I did not compute any extra tests we are doing, like small vs large
databases, still these numbers are quite low.
--
Luiz Augusto von Dentz
Hi Michael,
On Tue, Feb 10, 2015 at 10:16 PM, Michael Janssen <[email protected]> wrote:
> Implements the four defined tests around the Notification and Indication
> functionality in the unit tests. Also includes some fixes to discovery when
> no handles could be found (services with no handles).
>
> Also adds some functionality to the unit testing, to support when there is no
> action required by the client and/or the server in a test, and checks for
> post data transmission.
>
> --
Applied, thanks.
--
Luiz Augusto von Dentz
If there are no handles in a defined service, it is not useful to try to
discover anything in it, just go to the next service.
---
src/shared/gatt-client.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index d0fc054..bfb9427 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -525,6 +525,9 @@ next:
if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
goto failed;
+ if (start == end)
+ goto next;
+
if (bt_gatt_discover_included_services(client->att, start, end,
discover_incl_cb,
discovery_op_ref(op),
@@ -675,6 +678,9 @@ next:
if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
goto failed;
+ if (start == end)
+ goto next;
+
/* Move on to the next service */
op->cur_svc = attr;
if (bt_gatt_discover_characteristics(client->att, start, end,
@@ -776,6 +782,9 @@ next:
if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
goto failed;
+ if (start == end)
+ goto next;
+
/* Move on to the next service */
op->cur_svc = attr;
if (bt_gatt_discover_characteristics(client->att, start, end,
--
2.2.0.rc0.207.ga3a616c
Implements the four defined tests around the Notification and Indication
functionality in the unit tests. Also includes some fixes to discovery when
no handles could be found (services with no handles).
Also adds some functionality to the unit testing, to support when there is no
action required by the client and/or the server in a test, and checks for
post data transmission.
Sometimes a check must be made that something happened after all data is
transferred. A post function on the test step can check.
---
unit/test-gatt.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 44be64c..520b546 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -265,15 +265,32 @@ static void test_free(gconstpointer user_data)
g_free(data->pdu_list);
}
+typedef void (*test_step_t)(struct context *context);
+
+struct test_step {
+ test_step_t func;
+ test_step_t post_func;
+ uint16_t handle;
+ uint16_t end_handle;
+ uint8_t uuid[16];
+ uint8_t expected_att_ecode;
+ const uint8_t *value;
+ uint16_t length;
+};
+
static gboolean context_quit(gpointer user_data)
{
struct context *context = user_data;
+ const struct test_step *step = context->data->step;
if (context->process > 0)
g_source_remove(context->process);
g_main_loop_quit(context->main_loop);
+ if (step && step->post_func)
+ step->post_func(context);
+
return FALSE;
}
@@ -316,18 +333,6 @@ static void context_process(struct context *context)
context->process = g_idle_add(send_pdu, context);
}
-typedef void (*test_step_t)(struct context *context);
-
-struct test_step {
- test_step_t func;
- uint16_t handle;
- uint16_t end_handle;
- uint8_t uuid[16];
- uint8_t expected_att_ecode;
- const uint8_t *value;
- uint16_t length;
-};
-
static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
gpointer user_data)
{
@@ -364,7 +369,7 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
if (pdu->valid && (pdu->size == 0)) {
context->pdu_offset++;
- printf("empty client pdu, triggering\r\n");
+ printf("empty client pdu, triggering server action\r\n");
g_assert(step && step->func);
step->func(context);
return TRUE;
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile client can respond with a
Confirmation to a Characteristic Value Indication.
---
unit/test-gatt.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index c45ff3d..94e7e35 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1647,6 +1647,36 @@ static void test_server_indication_confirm(struct context *context)
g_assert(indication_received == 1);
}
+static void indication_cb(uint16_t value_handle, const uint8_t *value,
+ uint16_t length, void *user_data)
+{
+ struct context *context = user_data;
+ const struct test_step *step = context->data->step;
+
+ if (value_handle == step->handle) {
+ g_assert_cmpint(length, ==, step->length);
+
+ g_assert(memcmp(value, step->value, length) == 0);
+ }
+}
+
+static void test_indication(struct context *context)
+{
+ const struct test_step *step = context->data->step;
+
+ g_assert(bt_gatt_client_register_notify(context->client, step->handle,
+ notification_register_cb,
+ indication_cb, context,
+ NULL));
+}
+
+static const struct test_step test_indication_1 = {
+ .handle = 0x0003,
+ .func = test_indication,
+ .value = read_data_1,
+ .length = 0x03,
+};
+
static void test_server_indication(struct context *context)
{
const struct test_step *step = context->data->step;
@@ -2550,5 +2580,15 @@ int main(int argc, char *argv[])
raw_pdu(0x1D, 0x03, 0x00, 0x01, 0x02, 0x03),
raw_pdu(0x1E));
+ define_test_client("/TP/GAI/CL/BV-01-C", test_client, ts_small_db,
+ &test_indication_1,
+ MTU_EXCHANGE_CLIENT_PDUS,
+ SMALL_DB_DISCOVERY_PDUS,
+ raw_pdu(0x12, 0x04, 0x00, 0x03, 0x00),
+ raw_pdu(0x13),
+ raw_pdu(),
+ raw_pdu(0x1D, 0x03, 0x00, 0x01, 0x02, 0x03),
+ raw_pdu(0x1E));
+
return g_test_run();
}
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile client can receive a
Characteristic Value Notification and report that to the Upper Tester.
---
unit/test-gatt.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 98 insertions(+), 8 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 7bc2168..c3931ac 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -179,9 +179,52 @@ struct context {
#define SECONDARY_DISC_SMALL_DB \
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28), \
- raw_pdu(0x11, 0x06, 0x01, 0x00, 0x0F, 0x00, 0x0a, 0x18),\
- raw_pdu(0x10, 0x10, 0x00, 0xff, 0xff, 0x01, 0x28), \
- raw_pdu(0x01, 0x10, 0x10, 0x00, 0x0a)
+ raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x0a, 0x18),\
+ raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x01, 0x28), \
+ raw_pdu(0x01, 0x10, 0x11, 0x00, 0x0a)
+
+#define INCLUDE_DISC_SMALL_DB \
+ raw_pdu(0x08, 0x10, 0xf0, 0x17, 0xf0, 0x02, 0x28), \
+ raw_pdu(0x09, 0x08, 0x11, 0xf0, 0x01, 0x00, 0x0f, 0x00, \
+ 0x0a, 0x18), \
+ raw_pdu(0x08, 0x12, 0xf0, 0x17, 0xf0, 0x02, 0x28), \
+ raw_pdu(0x01, 0x08, 0x12, 0xf0, 0x0a), \
+ raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x02, 0x28), \
+ raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a)
+
+#define CHARACTERISTIC_DISC_SMALL_DB \
+ 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), \
+ raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), \
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x12, 0x03, 0x00, 0x29, \
+ 0x2a), \
+ raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), \
+ raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a)
+
+#define DESCRIPTOR_DISC_SMALL_DB \
+ raw_pdu(0x04, 0x04, 0x00, 0x10, 0x00), \
+ raw_pdu(0x05, 0x01, 0x04, 0x00, 0x02, 0x29, 0x05, 0x00, \
+ 0x01, 0x29), \
+ raw_pdu(0x04, 0x06, 0x00, 0x10, 0x00), \
+ raw_pdu(0x01, 0x04, 0x06, 0x00, 0x0a)
+
+#define SMALL_DB_DISCOVERY_PDUS \
+ PRIMARY_DISC_SMALL_DB, \
+ SECONDARY_DISC_SMALL_DB, \
+ INCLUDE_DISC_SMALL_DB, \
+ CHARACTERISTIC_DISC_SMALL_DB, \
+ DESCRIPTOR_DISC_SMALL_DB
+
#define SERVER_MTU_EXCHANGE_PDU raw_pdu(0x02, 0x17, 0x00)
@@ -905,10 +948,11 @@ static struct gatt_db *make_test_spec_small_db(void)
SECONDARY_SERVICE(0x0001, DEVICE_INFORMATION_UUID, 16),
CHARACTERISTIC_STR(GATT_CHARAC_MANUFACTURER_NAME_STRING,
BT_ATT_PERM_READ,
- BT_GATT_CHRC_PROP_READ,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_NOTIFY,
"BlueZ"),
- DESCRIPTOR(GATT_CLIENT_CHARAC_CFG_UUID, BT_ATT_PERM_READ, 0x00,
- 0x00),
+ DESCRIPTOR(GATT_CLIENT_CHARAC_CFG_UUID, BT_ATT_PERM_READ |
+ BT_ATT_PERM_WRITE, 0x00, 0x00),
DESCRIPTOR_STR(GATT_CHARAC_USER_DESC_UUID, BT_ATT_PERM_READ,
"Manufacturer Name"),
PRIMARY_SERVICE(0xF010, GAP_UUID, 8),
@@ -1517,6 +1561,43 @@ static const struct test_step test_long_read_8 = {
.expected_att_ecode = 0x0c
};
+static void notification_cb(uint16_t value_handle, const uint8_t *value,
+ uint16_t length, void *user_data)
+{
+ struct context *context = user_data;
+ const struct test_step *step = context->data->step;
+
+ if (value_handle == step->handle) {
+ g_assert_cmpint(length, ==, step->length);
+
+ g_assert(memcmp(value, step->value, length) == 0);
+
+ context_quit(context);
+ }
+}
+
+static void notification_register_cb(uint16_t att_ecode, void *user_data)
+{
+ g_assert(!att_ecode);
+}
+
+static void test_notification(struct context *context)
+{
+ const struct test_step *step = context->data->step;
+
+ g_assert(bt_gatt_client_register_notify(context->client, step->handle,
+ notification_register_cb,
+ notification_cb, context,
+ NULL));
+}
+
+static const struct test_step test_notification_1 = {
+ .handle = 0x0003,
+ .func = test_notification,
+ .value = read_data_1,
+ .length = 0x03,
+};
+
int main(int argc, char *argv[])
{
struct gatt_db *service_db_1, *ts_small_db, *ts_large_db_1;
@@ -1747,7 +1828,7 @@ int main(int argc, char *argv[])
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,
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x12, 0x03, 0x00, 0x29,
0x2a),
raw_pdu(0x08, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a));
@@ -1800,7 +1881,7 @@ int main(int argc, char *argv[])
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,
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x12, 0x03, 0x00, 0x29,
0x2a),
raw_pdu(0x08, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a));
@@ -2376,5 +2457,14 @@ int main(int argc, char *argv[])
raw_pdu(0x0C, 0xF0, 0x0F, 0x00, 0x00),
raw_pdu(0x01, 0x0C, 0xF0, 0x0F, 0x01));
+ define_test_client("/TP/GAN/CL/BV-01-C", test_client, ts_small_db,
+ &test_notification_1,
+ MTU_EXCHANGE_CLIENT_PDUS,
+ SMALL_DB_DISCOVERY_PDUS,
+ raw_pdu(0x12, 0x04, 0x00, 0x01, 0x00),
+ raw_pdu(0x13),
+ raw_pdu(),
+ raw_pdu(0x1B, 0x03, 0x00, 0x01, 0x02, 0x03));
+
return g_test_run();
}
--
2.2.0.rc0.207.ga3a616c
Add 0x for consistency
---
unit/test-gatt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 94e7e35..a4cd5e1 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -1894,7 +1894,7 @@ int main(int argc, char *argv[])
NULL,
MTU_EXCHANGE_CLIENT_PDUS,
raw_pdu(0x08, 0x10, 0x00, 0x20, 0x00, 0x03, 0x28),
- raw_pdu(0x09, 0x07, 0x11, 0x00, 02, 0x12, 0x00, 0x25,
+ raw_pdu(0x09, 0x07, 0x11, 0x00, 0x02, 0x12, 0x00, 0x25,
0x2a),
raw_pdu(0x08, 0x12, 0x00, 0x20, 0x00, 0x03, 0x28),
raw_pdu(0x09, 0x15, 0x13, 0x00, 0x02, 0x14, 0x00, 0x85,
@@ -1947,7 +1947,7 @@ int main(int argc, char *argv[])
NULL,
MTU_EXCHANGE_CLIENT_PDUS,
raw_pdu(0x08, 0x10, 0x00, 0x20, 0x00, 0x03, 0x28),
- raw_pdu(0x09, 0x07, 0x11, 0x00, 02, 0x12, 0x00, 0x25,
+ raw_pdu(0x09, 0x07, 0x11, 0x00, 0x02, 0x12, 0x00, 0x25,
0x2a),
raw_pdu(0x08, 0x12, 0x00, 0x20, 0x00, 0x03, 0x28),
raw_pdu(0x09, 0x15, 0x13, 0x00, 0x02, 0x14, 0x00, 0x85,
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can send a Characteristic
Value Notification.
---
unit/test-gatt.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 12 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index c3931ac..44be64c 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -316,10 +316,23 @@ static void context_process(struct context *context)
context->process = g_idle_add(send_pdu, context);
}
+typedef void (*test_step_t)(struct context *context);
+
+struct test_step {
+ test_step_t func;
+ uint16_t handle;
+ uint16_t end_handle;
+ uint8_t uuid[16];
+ uint8_t expected_att_ecode;
+ const uint8_t *value;
+ uint16_t length;
+};
+
static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
gpointer user_data)
{
struct context *context = user_data;
+ const struct test_step *step = context->data->step;
const struct test_pdu *pdu;
unsigned char buf[512];
ssize_t len;
@@ -346,6 +359,17 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
+ /* Empty client PDU means to trigger something out-of-band. */
+ pdu = &context->data->pdu_list[context->pdu_offset];
+
+ if (pdu->valid && (pdu->size == 0)) {
+ context->pdu_offset++;
+ printf("empty client pdu, triggering\r\n");
+ g_assert(step && step->func);
+ step->func(context);
+ return TRUE;
+ }
+
context_process(context);
return TRUE;
@@ -358,18 +382,6 @@ static void print_debug(const char *str, void *user_data)
g_print("%s%s\n", prefix, str);
}
-typedef void (*test_step_t)(struct context *context);
-
-struct test_step {
- test_step_t func;
- uint16_t handle;
- uint16_t end_handle;
- uint8_t uuid[16];
- uint8_t expected_att_ecode;
- const uint8_t *value;
- uint16_t length;
-};
-
struct db_attribute_test_data {
struct gatt_db_attribute *match;
bool found;
@@ -1598,6 +1610,21 @@ static const struct test_step test_notification_1 = {
.length = 0x03,
};
+static void test_server_notification(struct context *context)
+{
+ const struct test_step *step = context->data->step;
+
+ bt_gatt_server_send_notification(context->server, step->handle,
+ step->value, step->length);
+}
+
+static const struct test_step test_notification_server_1 = {
+ .handle = 0x0003,
+ .func = test_server_notification,
+ .value = read_data_1,
+ .length = 0x03,
+};
+
int main(int argc, char *argv[])
{
struct gatt_db *service_db_1, *ts_small_db, *ts_large_db_1;
@@ -2466,5 +2493,13 @@ int main(int argc, char *argv[])
raw_pdu(),
raw_pdu(0x1B, 0x03, 0x00, 0x01, 0x02, 0x03));
+ define_test_server("/TP/GAN/SR/BV-01-C", test_server, ts_small_db,
+ &test_notification_server_1,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x12, 0x04, 0x00, 0x01, 0x00),
+ raw_pdu(0x13),
+ raw_pdu(),
+ raw_pdu(0x1B, 0x03, 0x00, 0x01, 0x02, 0x03));
+
return g_test_run();
}
--
2.2.0.rc0.207.ga3a616c
Verify that a Generic Attribute Profile server can send a Characteristic
Value Indication.
---
unit/test-gatt.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 520b546..c45ff3d 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -206,7 +206,7 @@ struct context {
raw_pdu(0x08, 0x17, 0xf0, 0x17, 0xf0, 0x03, 0x28), \
raw_pdu(0x01, 0x08, 0x17, 0xf0, 0x0a), \
raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), \
- raw_pdu(0x09, 0x07, 0x02, 0x00, 0x12, 0x03, 0x00, 0x29, \
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x32, 0x03, 0x00, 0x29, \
0x2a), \
raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), \
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a)
@@ -966,7 +966,8 @@ static struct gatt_db *make_test_spec_small_db(void)
CHARACTERISTIC_STR(GATT_CHARAC_MANUFACTURER_NAME_STRING,
BT_ATT_PERM_READ,
BT_GATT_CHRC_PROP_READ |
- BT_GATT_CHRC_PROP_NOTIFY,
+ BT_GATT_CHRC_PROP_NOTIFY |
+ BT_GATT_CHRC_PROP_INDICATE,
"BlueZ"),
DESCRIPTOR(GATT_CLIENT_CHARAC_CFG_UUID, BT_ATT_PERM_READ |
BT_ATT_PERM_WRITE, 0x00, 0x00),
@@ -1630,6 +1631,40 @@ static const struct test_step test_notification_server_1 = {
.length = 0x03,
};
+static uint8_t indication_received;
+
+static void test_indication_cb(void *user_data)
+{
+ struct context *context = user_data;
+
+ indication_received = 1;
+
+ context_quit(context);
+}
+
+static void test_server_indication_confirm(struct context *context)
+{
+ g_assert(indication_received == 1);
+}
+
+static void test_server_indication(struct context *context)
+{
+ const struct test_step *step = context->data->step;
+
+ bt_gatt_server_send_indication(context->server, step->handle,
+ step->value, step->length,
+ test_indication_cb,
+ context, NULL);
+}
+
+static const struct test_step test_indication_server_1 = {
+ .handle = 0x0003,
+ .func = test_server_indication,
+ .post_func = test_server_indication_confirm,
+ .value = read_data_1,
+ .length = 0x03,
+};
+
int main(int argc, char *argv[])
{
struct gatt_db *service_db_1, *ts_small_db, *ts_large_db_1;
@@ -1860,7 +1895,7 @@ int main(int argc, char *argv[])
ts_small_db, NULL,
raw_pdu(0x03, 0x00, 0x02),
raw_pdu(0x08, 0x01, 0x00, 0x0f, 0x00, 0x03, 0x28),
- raw_pdu(0x09, 0x07, 0x02, 0x00, 0x12, 0x03, 0x00, 0x29,
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x32, 0x03, 0x00, 0x29,
0x2a),
raw_pdu(0x08, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a));
@@ -1913,7 +1948,7 @@ int main(int argc, char *argv[])
ts_small_db, NULL,
raw_pdu(0x03, 0x00, 0x02),
raw_pdu(0x08, 0x01, 0x00, 0x0f, 0x00, 0x03, 0x28),
- raw_pdu(0x09, 0x07, 0x02, 0x00, 0x12, 0x03, 0x00, 0x29,
+ raw_pdu(0x09, 0x07, 0x02, 0x00, 0x32, 0x03, 0x00, 0x29,
0x2a),
raw_pdu(0x08, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x28),
raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a));
@@ -2493,7 +2528,7 @@ int main(int argc, char *argv[])
&test_notification_1,
MTU_EXCHANGE_CLIENT_PDUS,
SMALL_DB_DISCOVERY_PDUS,
- raw_pdu(0x12, 0x04, 0x00, 0x01, 0x00),
+ raw_pdu(0x12, 0x04, 0x00, 0x03, 0x00),
raw_pdu(0x13),
raw_pdu(),
raw_pdu(0x1B, 0x03, 0x00, 0x01, 0x02, 0x03));
@@ -2506,5 +2541,14 @@ int main(int argc, char *argv[])
raw_pdu(),
raw_pdu(0x1B, 0x03, 0x00, 0x01, 0x02, 0x03));
+ define_test_server("/TP/GAI/SR/BV-01-C", test_server, ts_small_db,
+ &test_indication_server_1,
+ raw_pdu(0x03, 0x00, 0x02),
+ raw_pdu(0x12, 0x04, 0x00, 0x02, 0x00),
+ raw_pdu(0x13),
+ raw_pdu(),
+ raw_pdu(0x1D, 0x03, 0x00, 0x01, 0x02, 0x03),
+ raw_pdu(0x1E));
+
return g_test_run();
}
--
2.2.0.rc0.207.ga3a616c
With some tests (specifically notification / indication tests), the
client sets up a condition and then the server does something without
a message from the client. This patch makes it possible to add a
zero-length PDU which indicates that no message is expected from the
client after a server response.
---
unit/test-gatt.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index cd90d83..7bc2168 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -250,6 +250,15 @@ static gboolean send_pdu(gpointer user_data)
g_assert_cmpint(len, ==, pdu->size);
context->process = 0;
+
+ pdu = &context->data->pdu_list[context->pdu_offset];
+ if (pdu->valid && (pdu->size == 0)) {
+ if (g_test_verbose())
+ test_debug("(no action expected)", "GATT: ");
+ context->pdu_offset++;
+ return send_pdu(context);
+ }
+
return FALSE;
}
--
2.2.0.rc0.207.ga3a616c