v3: Solved Szymon's comments.
v2: Solved rebase conflicts.
v1: Patch set contains PAN E2E client role test cases.
Ravi kumar Veeramally (7):
android/tester: Add PAN init test case
android/tester: Add PAN Connect test case
android/tester: Add PAN Disconnect test case
android/tester: Add PAN get local role test case
android/tester: Add PAN enable PANU test case
android/tester: Add PAN enable NAP test case
android/tester: Add PAN enable NONE test case
android/android-tester.c | 673 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 673 insertions(+)
--
1.8.3.2
---
android/android-tester.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 164 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index f4f5b28..4213793 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -134,6 +134,11 @@ struct test_data {
uint16_t ctrl_cid;
uint16_t intr_handle;
uint16_t intr_cid;
+
+ /* PAN */
+ uint16_t nap_handle;
+ uint16_t nap_cid;
+ uint8_t role;
};
struct bt_cb_data {
@@ -4773,6 +4778,160 @@ static void setup_pan(const void *test_data)
tester_setup_failed();
}
+static void pan_connected_cb(btpan_connection_state_t state, bt_status_t error,
+ const bt_bdaddr_t *addr, int local, int remote)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+
+ switch (state) {
+ case BTPAN_STATE_CONNECTED:
+ data->cb_count++;
+ if (data->cb_count == test->expected_cb_count &&
+ error == BT_STATUS_SUCCESS &&
+ local == BTPAN_ROLE_PANU &&
+ remote == BTPAN_ROLE_PANNAP)
+ tester_test_passed();
+ break;
+ case BTPAN_STATE_CONNECTING:
+ data->cb_count++;
+ break;
+ case BTPAN_STATE_DISCONNECTED:
+ case BTPAN_STATE_DISCONNECTING:
+ tester_test_failed();
+ break;
+ }
+}
+
+static void pan_connect_enabled_cb(btpan_control_state_t state,
+ bt_status_t error,
+ int local_role, const char *ifname)
+{
+ struct test_data *data = tester_get_data();
+
+ switch (state) {
+ case BTPAN_STATE_ENABLED:
+ data->cb_count++;
+ break;
+ case BTPAN_STATE_DISABLED:
+ tester_test_failed();
+ break;
+ }
+}
+
+static void pan_bond_create_pin_request_cb(bt_bdaddr_t *remote_bd_addr,
+ bt_bdname_t *bd_name, uint32_t cod)
+{
+ struct test_data *data = tester_get_data();
+ const bt_bdaddr_t *bdaddr = remote_bd_addr;
+ bt_pin_code_t pin_code = {
+ .pin = { 0x30, 0x30, 0x30, 0x30 },
+ };
+ uint8_t pin_len = 4;
+
+ data->cb_count++;
+ data->if_bluetooth->pin_reply(bdaddr, TRUE, pin_len, &pin_code);
+}
+
+static void pan_bond_device_found_cb(int num_properties,
+ bt_property_t *properties)
+{
+ struct test_data *data = tester_get_data();
+ uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t remote_addr;
+
+ bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+ if (data->cb_count == 0) {
+ data->cb_count++;
+ data->if_bluetooth->create_bond(&remote_addr);
+ }
+}
+
+static void pan_bond_state_bonded_changed_cb(bt_status_t status,
+ bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *pan_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ switch (state) {
+ case BT_BOND_STATE_BONDING:
+ data->cb_count++;
+ break;
+ case BT_BOND_STATE_BONDED:
+ data->cb_count++;
+ if (data->cb_count == 4) {
+ bdaddr2android((const bdaddr_t *) pan_addr, &bdaddr);
+ bt_status = data->if_pan->connect(&bdaddr,
+ BTPAN_ROLE_PANU,
+ BTPAN_ROLE_PANNAP);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_setup_failed();
+ }
+
+ break;
+ default:
+ tester_test_failed();
+ break;
+ }
+}
+
+static uint8_t pan_conn_req_pdu[] = {0x01, 0x01, 0x02, 0x11, 0x16, 0x11, 0x15};
+static uint8_t pan_conn_rsp_pdu[] = {0x01, 0x02, 0x00, 0x00};
+
+static void pan_nap_cid_hook_cb(const void *data, uint16_t len, void *user_data)
+{
+ struct test_data *t_data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+
+ if (!memcmp((uint8_t *) data, pan_conn_req_pdu,
+ sizeof(pan_conn_req_pdu)))
+ bthost_send_cid(bthost, t_data->nap_handle, t_data->nap_cid,
+ pan_conn_rsp_pdu, sizeof(pan_conn_rsp_pdu));
+}
+
+static void pan_connect_request_cb(uint16_t handle, uint16_t cid,
+ void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ data->nap_handle = handle;
+ data->nap_cid = cid;
+
+ bthost_add_cid_hook(bthost, handle, cid, pan_nap_cid_hook_cb, NULL);
+}
+
+static const struct pan_generic_data pan_test_connect = {
+ .expected_hal_cb.device_found_cb = pan_bond_device_found_cb,
+ .expected_hal_cb.bond_state_changed_cb =
+ pan_bond_state_bonded_changed_cb,
+ .expected_hal_cb.pin_request_cb = pan_bond_create_pin_request_cb,
+ .expected_cb_count = 7,
+ .expected_adapter_status = BT_STATUS_SUCCESS,
+ .expected_pan_hal_cb.control_state_cb = pan_connect_enabled_cb,
+ .expected_pan_hal_cb.connection_state_cb = pan_connected_cb,
+};
+
+static void test_pan_connect(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ static uint8_t pair_device_pin[] = { 0x30, 0x30, 0x30, 0x30 };
+ const void *pin = pair_device_pin;
+ uint8_t pin_len = 4;
+
+ /* Emulate NAP (PSM = 15) */
+ bthost_add_l2cap_server(bthost, 15, pan_connect_request_cb, NULL);
+
+ data->test_checks_valid = true;
+ data->cb_count = 0;
+ bthost_set_pin_code(bthost, pin, pin_len);
+ data->if_bluetooth->start_discovery();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -5210,5 +5369,10 @@ int main(int argc, char *argv[])
test_bredr("PAN Init", NULL, setup_pan,
test_dummy, teardown);
+
+ test_bredr("PAN Connect Success",
+ &pan_test_connect, setup_pan,
+ test_pan_connect, teardown);
+
return tester_run();
}
--
1.8.3.2
---
android/android-tester.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 106b00a..fb81fd2 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -5049,6 +5049,20 @@ static void test_pan_enable_nap(const void *test_data)
tester_test_passed();
}
+static void test_pan_enable_none(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ bt_status_t bt_status;
+
+ bt_status = data->if_pan->enable(BTPAN_ROLE_NONE);
+ if (bt_status != BT_STATUS_SUCCESS) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_test_passed();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -5507,5 +5521,9 @@ int main(int argc, char *argv[])
NULL, setup_pan,
test_pan_enable_nap, teardown);
+ test_bredr("PAN Enable NONE Success",
+ NULL, setup_pan,
+ test_pan_enable_none, teardown);
+
return tester_run();
}
--
1.8.3.2
---
android/android-tester.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 82b0541..da9bf2d 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -5007,6 +5007,20 @@ static void test_pan_disconnect(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_pan_get_local_role_none(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ int role;
+
+ role = data->if_pan->get_local_role();
+ if (role != BTPAN_ROLE_NONE) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_test_passed();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -5453,5 +5467,9 @@ int main(int argc, char *argv[])
&panu_test_disconnect, setup_pan,
test_pan_disconnect, teardown);
+ test_bredr("PAN GetLocalRole Success",
+ NULL, setup_pan,
+ test_pan_get_local_role_none, teardown);
+
return tester_run();
}
--
1.8.3.2
---
android/android-tester.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 554d2cb..106b00a 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -5035,6 +5035,20 @@ static void test_pan_enable_panu(const void *test_data)
tester_test_passed();
}
+static void test_pan_enable_nap(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ bt_status_t bt_status;
+
+ bt_status = data->if_pan->enable(BTPAN_ROLE_PANNAP);
+ if (bt_status != BT_STATUS_SUCCESS) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_test_passed();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -5489,5 +5503,9 @@ int main(int argc, char *argv[])
NULL, setup_pan,
test_pan_enable_panu, teardown);
+ test_bredr("PAN Enable NAP Success",
+ NULL, setup_pan,
+ test_pan_enable_nap, teardown);
+
return tester_run();
}
--
1.8.3.2
---
android/android-tester.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 4213793..82b0541 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -4932,6 +4932,81 @@ static void test_pan_connect(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static gboolean pan_disconnect_cb(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *pan_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ bdaddr2android((const bdaddr_t *) pan_addr, &bdaddr);
+ bt_status = data->if_pan->disconnect(&bdaddr);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_discon_connected_cb(btpan_connection_state_t state,
+ bt_status_t error, const bt_bdaddr_t *addr,
+ int local, int remote)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+
+ switch (state) {
+ case BTPAN_STATE_CONNECTING:
+ data->cb_count++;
+ break;
+ case BTPAN_STATE_CONNECTED:
+ data->cb_count++;
+ if (data->cb_count == 6) {
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_disconnect_cb, NULL);
+ }
+ break;
+ case BTPAN_STATE_DISCONNECTING:
+ data->cb_count++;
+ break;
+ case BTPAN_STATE_DISCONNECTED:
+ data->cb_count++;
+ if (data->cb_count == test->expected_cb_count &&
+ error == BT_STATUS_SUCCESS &&
+ local == BTPAN_ROLE_PANU &&
+ remote == BTPAN_ROLE_PANNAP)
+ tester_test_passed();
+ break;
+ }
+}
+
+static const struct pan_generic_data panu_test_disconnect = {
+ .expected_hal_cb.device_found_cb = pan_bond_device_found_cb,
+ .expected_hal_cb.bond_state_changed_cb =
+ pan_bond_state_bonded_changed_cb,
+ .expected_hal_cb.pin_request_cb = pan_bond_create_pin_request_cb,
+ .expected_cb_count = 7,
+ .expected_adapter_status = BT_STATUS_SUCCESS,
+ .expected_pan_hal_cb.connection_state_cb = pan_discon_connected_cb,
+};
+
+static void test_pan_disconnect(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ static uint8_t pair_device_pin[] = { 0x30, 0x30, 0x30, 0x30 };
+ const void *pin = pair_device_pin;
+ uint8_t pin_len = 4;
+
+ /* Emulate NAP (PSM = 15) */
+ bthost_add_l2cap_server(bthost, 15, pan_connect_request_cb, NULL);
+
+ data->test_checks_valid = true;
+ data->cb_count = 0;
+ bthost_set_pin_code(bthost, pin, pin_len);
+ data->if_bluetooth->start_discovery();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -5374,5 +5449,9 @@ int main(int argc, char *argv[])
&pan_test_connect, setup_pan,
test_pan_connect, teardown);
+ test_bredr("PAN Disconnect Success",
+ &panu_test_disconnect, setup_pan,
+ test_pan_disconnect, teardown);
+
return tester_run();
}
--
1.8.3.2
---
android/android-tester.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index da9bf2d..554d2cb 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -5021,6 +5021,20 @@ static void test_pan_get_local_role_none(const void *test_data)
tester_test_passed();
}
+static void test_pan_enable_panu(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ bt_status_t bt_status;
+
+ bt_status = data->if_pan->enable(BTPAN_ROLE_PANU);
+ if (bt_status != BT_STATUS_UNSUPPORTED) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_test_passed();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -5471,5 +5485,9 @@ int main(int argc, char *argv[])
NULL, setup_pan,
test_pan_get_local_role_none, teardown);
+ test_bredr("PAN Enable PANU Success",
+ NULL, setup_pan,
+ test_pan_enable_panu, teardown);
+
return tester_run();
}
--
1.8.3.2
---
android/android-tester.c | 358 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 358 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 6d2edc7..f4f5b28 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -42,6 +42,7 @@
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <hardware/bt_hh.h>
+#include <hardware/bt_pan.h>
#include "utils.h"
@@ -81,6 +82,20 @@ struct hidhost_generic_data {
int expected_report_size;
};
+struct pan_generic_data {
+ bt_status_t expected_status;
+ int expected_conn_state;
+ int expected_cb_count;
+ int expected_pan_role;
+ btpan_callbacks_t expected_pan_hal_cb;
+ bt_callbacks_t expected_hal_cb;
+ int expected_adapter_status;
+ uint32_t expect_settings_set;
+ bt_property_t set_property;
+ struct priority_property *expected_properties;
+ uint8_t expected_properties_num;
+};
+
#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
#define EMULATOR_SIGNAL "emulator_started"
@@ -100,6 +115,7 @@ struct test_data {
const bt_interface_t *if_bluetooth;
const btsock_interface_t *if_sock;
const bthh_interface_t *if_hid;
+ const btpan_interface_t *if_pan;
int conditions_left;
@@ -147,6 +163,16 @@ struct hh_cb_data {
int size;
};
+struct pan_cb_data {
+ const bt_bdaddr_t *bdaddr;
+ bt_status_t status;
+ btpan_connection_state_t conn_state;
+ btpan_control_state_t ctrl_state;
+ int local_role;
+ int remote_role;
+ const char *ifname;
+};
+
static char exec_dir[PATH_MAX + 1];
static gint scheduled_cbacks_num = 0;
@@ -2640,6 +2666,11 @@ static void teardown(const void *test_data)
data->if_hid = NULL;
}
+ if (data->if_pan) {
+ data->if_pan->cleanup();
+ data->if_pan = NULL;
+ }
+
if (data->if_bluetooth) {
data->if_bluetooth->cleanup();
data->if_bluetooth = NULL;
@@ -4418,6 +4449,330 @@ static void test_hidhost_get_report(const void *test_data)
tester_test_failed();
}
+static gboolean pan_connection_state(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct pan_cb_data *cb_data = user_data;
+
+ if (test && test->expected_pan_hal_cb.connection_state_cb)
+ test->expected_pan_hal_cb.connection_state_cb(
+ cb_data->conn_state, cb_data->status,
+ cb_data->bdaddr, cb_data->local_role,
+ cb_data->remote_role);
+
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_connection_state_cb(btpan_connection_state_t state,
+ bt_status_t error,
+ const bt_bdaddr_t *bd_addr,
+ int local_role, int remote_role)
+{
+ struct pan_cb_data *cb_data = g_new0(struct pan_cb_data, 1);
+
+ cb_data->conn_state = state;
+ cb_data->status = error;
+ cb_data->local_role = local_role;
+ cb_data->remote_role = remote_role;
+ cb_data->bdaddr = bd_addr;
+
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_connection_state, cb_data);
+}
+
+static gboolean pan_control_state(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct pan_cb_data *cb_data = user_data;
+
+ if (test && test->expected_pan_hal_cb.control_state_cb)
+ test->expected_pan_hal_cb.control_state_cb(cb_data->ctrl_state,
+ cb_data->status, cb_data->local_role, cb_data->ifname);
+
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_control_state_cb(btpan_control_state_t state,
+ bt_status_t error,
+ int local_role, const char *ifname)
+{
+ struct pan_cb_data *cb_data = g_new0(struct pan_cb_data, 1);
+
+ cb_data->ctrl_state = error;
+ cb_data->status = local_role;
+ cb_data->local_role = state;
+ cb_data->ifname = ifname;
+
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_control_state, cb_data);
+}
+
+static btpan_callbacks_t btpan_callbacks = {
+ .size = sizeof(btpan_callbacks),
+ .control_state_cb = pan_control_state_cb,
+ .connection_state_cb = pan_connection_state_cb,
+};
+
+static gboolean pan_adapter_state_changed(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (data->test_checks_valid &&
+ test->expected_hal_cb.adapter_state_changed_cb)
+ test->expected_hal_cb.adapter_state_changed_cb(cb_data->state);
+
+ if (!data->test_checks_valid && cb_data->state == BT_STATE_ON)
+ setup_powered_emulated_remote();
+
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_adapter_state_changed_cb(bt_state_t state)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->state = state;
+
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_adapter_state_changed, cb_data);
+}
+
+static gboolean pan_discovery_state_changed(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (test && test->expected_hal_cb.discovery_state_changed_cb)
+ test->expected_hal_cb.discovery_state_changed_cb(
+ cb_data->state);
+
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_discovery_state_changed_cb(bt_discovery_state_t state)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->state = state;
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_discovery_state_changed, cb_data);
+}
+
+static gboolean pan_device_found(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (data->test_checks_valid && test->expected_hal_cb.device_found_cb)
+ test->expected_hal_cb.device_found_cb(cb_data->num,
+ cb_data->props);
+
+ free_properties(cb_data->num, cb_data->props);
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_device_found_cb(int num_properties, bt_property_t *properties)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->num = num_properties;
+ cb_data->props = copy_properties(num_properties, properties);
+
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_device_found, cb_data);
+}
+
+static gboolean pan_adapter_properties(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (data->test_checks_valid &&
+ test->expected_hal_cb.adapter_properties_cb)
+ test->expected_hal_cb.adapter_properties_cb(cb_data->status,
+ cb_data->num, cb_data->props);
+
+ free_properties(cb_data->num, cb_data->props);
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_adapter_properties_cb(bt_status_t status, int num_properties,
+ bt_property_t *properties)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->status = status;
+ cb_data->num = num_properties;
+ cb_data->props = copy_properties(num_properties, properties);
+
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_adapter_properties, cb_data);
+}
+
+static gboolean pan_remote_device_properties(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (data->test_checks_valid &&
+ test->expected_hal_cb.remote_device_properties_cb)
+ test->expected_hal_cb.remote_device_properties_cb(
+ cb_data->status, &cb_data->bdaddr,
+ cb_data->num, cb_data->props);
+
+ free_properties(cb_data->num, cb_data->props);
+ g_free(cb_data);
+
+ g_atomic_int_dec_and_test(&scheduled_cbacks_num);
+ return FALSE;
+}
+
+static void pan_remote_device_properties_cb(bt_status_t status,
+ bt_bdaddr_t *bd_addr, int num_properties,
+ bt_property_t *properties)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->status = status;
+ cb_data->bdaddr = *bd_addr;
+ cb_data->num = num_properties;
+ cb_data->props = copy_properties(num_properties, properties);
+
+ g_atomic_int_inc(&scheduled_cbacks_num);
+ g_idle_add(pan_remote_device_properties, cb_data);
+}
+
+static gboolean pan_pin_request(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (data->test_checks_valid && test->expected_hal_cb.pin_request_cb) {
+ test->expected_hal_cb.pin_request_cb(&cb_data->bdaddr,
+ &cb_data->bdname, cb_data->cod);
+ }
+
+ g_free(cb_data);
+ return FALSE;
+}
+
+static void pan_pin_request_cb(bt_bdaddr_t *remote_bd_addr,
+ bt_bdname_t *bd_name, uint32_t cod)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->bdaddr = *remote_bd_addr;
+ cb_data->bdname = *bd_name;
+ cb_data->cod = cod;
+
+ g_idle_add(pan_pin_request, cb_data);
+}
+
+static gboolean pan_bond_state_changed(gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct pan_generic_data *test = data->test_data;
+ struct bt_cb_data *cb_data = user_data;
+
+ if (data->test_checks_valid &&
+ test->expected_hal_cb.bond_state_changed_cb)
+ test->expected_hal_cb.bond_state_changed_cb(cb_data->status,
+ &cb_data->bdaddr, cb_data->state);
+
+ g_free(cb_data);
+ return FALSE;
+}
+
+static void pan_bond_state_changed_cb(bt_status_t status,
+ bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
+{
+ struct bt_cb_data *cb_data = g_new0(struct bt_cb_data, 1);
+
+ cb_data->status = status;
+ cb_data->bdaddr = *remote_bd_addr;
+ cb_data->state = state;
+
+ g_idle_add(pan_bond_state_changed, cb_data);
+}
+
+static bt_callbacks_t bt_pan_cbs = {
+ .size = sizeof(bt_pan_cbs),
+ .adapter_state_changed_cb = pan_adapter_state_changed_cb,
+ .adapter_properties_cb = pan_adapter_properties_cb,
+ .remote_device_properties_cb = pan_remote_device_properties_cb,
+ .device_found_cb = pan_device_found_cb,
+ .discovery_state_changed_cb = pan_discovery_state_changed_cb,
+ .pin_request_cb = pan_pin_request_cb,
+ .ssp_request_cb = NULL,
+ .bond_state_changed_cb = pan_bond_state_changed_cb,
+ .acl_state_changed_cb = NULL,
+ .thread_evt_cb = NULL,
+ .dut_mode_recv_cb = NULL,
+ .le_test_mode_cb = NULL
+};
+
+static void setup_pan(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ bt_status_t status;
+ const void *pan;
+
+ setup(data);
+
+ status = data->if_bluetooth->init(&bt_pan_cbs);
+ if (status != BT_STATUS_SUCCESS) {
+ data->if_bluetooth = NULL;
+ tester_setup_failed();
+ return;
+ }
+
+ pan = data->if_bluetooth->get_profile_interface(BT_PROFILE_PAN_ID);
+ if (!pan) {
+ tester_setup_failed();
+ return;
+ }
+
+ data->if_pan = pan;
+
+ status = data->if_pan->init(&btpan_callbacks);
+ if (status != BT_STATUS_SUCCESS) {
+ data->if_pan = NULL;
+ tester_setup_failed();
+ return;
+ }
+
+ status = data->if_bluetooth->enable();
+ if (status != BT_STATUS_SUCCESS)
+ tester_setup_failed();
+}
+
#define test_bredr(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -4852,5 +5207,8 @@ int main(int argc, char *argv[])
test_bredrle("HIDHost SendData Success",
NULL, setup_hidhost_connect,
test_hidhost_send_data, teardown);
+
+ test_bredr("PAN Init", NULL, setup_pan,
+ test_dummy, teardown);
return tester_run();
}
--
1.8.3.2