diff --git a/unit/test-gattrib.c b/unit/test-gattrib.c
index d90536b..5ee8953 100644
--- a/unit/test-gattrib.c
+++ b/unit/test-gattrib.c
g_assert(!canceled);
}
+static void send_test_pdus(gpointer context, struct test_pdu *pdus)
+{
+ struct context *cxt = context;
+ size_t len;
+ int fd;
+ struct test_pdu *cur_pdu;
+
+ fd = g_io_channel_unix_get_fd(cxt->server_io);
+
+ for (cur_pdu = pdus; cur_pdu->valid; cur_pdu++)
+ cur_pdu->sent = false;
+
+ for (cur_pdu = pdus; cur_pdu->valid; cur_pdu++) {
+ if (g_test_verbose())
+ util_hexdump('>', cur_pdu->data, cur_pdu->size,
+ test_debug, "send_test_pdus: ");
+ len = write(fd, cur_pdu->data, cur_pdu->size);
+ g_assert_cmpint(len, ==, cur_pdu->size);
+ cur_pdu->sent = true;
+ }
+
+ g_idle_add(context_stop_main_loop, cxt);
+ g_main_loop_run(cxt->main_loop);
+}
+
+#define PDU_MTU_RESP pdu(ATT_OP_MTU_RESP, 0x17)
+#define PDU_FIND_INFO_REQ pdu(ATT_OP_FIND_INFO_REQ, 0x01, 0x00, 0xFF, 0xFF)
+#define PDU_IND_NODATA pdu(ATT_OP_HANDLE_IND, 0x01, 0x00)
+#define PDU_INVALID_IND pdu(ATT_OP_HANDLE_IND, 0x14)
+#define PDU_IND_DATA pdu(ATT_OP_HANDLE_IND, 0x14, 0x00, 0x01)
+
+static void notify_canary_expect(const guint8 *pdu, guint16 len, gpointer data)
+{
+ struct test_pdu *expected = data;
+ int cmp;
+
+ if (g_test_verbose())
+ util_hexdump('<', pdu, len, test_debug,
+ "notify_canary_expect: ");
+
+ while (expected->valid && expected->received)
+ expected++;
+
+ g_assert(expected->valid);
+
+ if (g_test_verbose())
+ util_hexdump('?', expected->data, expected->size, test_debug,
+ "notify_canary_expect: ");
+
+ g_assert_cmpint(expected->size, ==, len);
+
+ cmp = memcmp(pdu, expected->data, expected->size);
+
+ g_assert(cmp == 0);
+
+ expected->received = true;
+}
+
static void test_register(struct context *cxt, gconstpointer user_data)
{
- /* TODO */
+ guint reg_id;
+ gboolean success;
+ struct test_pdu pdus[] = {
+ /* Unmatched by any (GATTRIB_ALL_EVENTS) */
+ PDU_MTU_RESP,
+ /*
+ * Unmatched PDU opcode
+ * Unmatched handle (GATTRIB_ALL_REQS) */
+ PDU_FIND_INFO_REQ,
+ /*
+ * Matched PDU opcode
+ * Unmatched handle (GATTRIB_ALL_HANDLES) */
+ PDU_IND_NODATA,
+ /*
+ * Matched PDU opcode
+ * Invalid length? */
+ PDU_INVALID_IND,
+ /*
+ * Matched PDU opcode
+ * Matched handle */
+ PDU_IND_DATA,
+ { },
+ };
+ struct test_pdu req_pdus[] = { PDU_FIND_INFO_REQ, { } };
+ struct test_pdu all_ind_pdus[] = {
+ PDU_IND_NODATA,
+ PDU_INVALID_IND,
+ PDU_IND_DATA,
+ { },
+ };
+ struct test_pdu followed_ind_pdus[] = { PDU_IND_DATA, { } };
+
+ /*
+ * Without registering anything, should be able to ignore everything but
+ * an unexpected response. */
+ send_test_pdus(cxt, pdus + 1);
+
+ reg_id = g_attrib_register(cxt->att, GATTRIB_ALL_EVENTS,
+ GATTRIB_ALL_HANDLES, notify_canary_expect,
+ pdus, NULL);
+
+ send_test_pdus(cxt, pdus);
+
+ g_attrib_unregister(cxt->att, reg_id);
+
+ if (g_test_verbose())
+ g_print("ALL_REQS, ALL_HANDLES\r\n");
+
+ reg_id = g_attrib_register(cxt->att, GATTRIB_ALL_REQS,
+ GATTRIB_ALL_HANDLES, notify_canary_expect,
+ req_pdus, NULL);
+
+ send_test_pdus(cxt, pdus);
+
+ g_attrib_unregister(cxt->att, reg_id);
+
+ if (g_test_verbose())
+ g_print("IND, ALL_HANDLES\r\n");
+
+ reg_id = g_attrib_register(cxt->att, ATT_OP_HANDLE_IND,
+ GATTRIB_ALL_HANDLES, notify_canary_expect,
+ all_ind_pdus, NULL);
+
+ send_test_pdus(cxt, pdus);
+
+ g_attrib_unregister(cxt->att, reg_id);
+
+ if (g_test_verbose())
+ g_print("IND, 0x0014\r\n");
+
+ reg_id = g_attrib_register(cxt->att, ATT_OP_HANDLE_IND, 0x0014,
+ notify_canary_expect, followed_ind_pdus,
+ NULL);
+
+ send_test_pdus(cxt, pdus);
+
+ g_attrib_unregister(cxt->att, reg_id);
+
+ success = g_attrib_unregister(cxt->att, reg_id);
+
+ g_assert(!success);
}
static void test_buffers(struct context *cxt, gconstpointer unused)