int expected_connect_err;
};
+struct rfcomm_server_data {
+ uint8_t server_channel;
+ uint8_t client_channel;
+ bool expected_status;
+};
+
static void mgmt_debug(const char *str, void *user_data)
{
const char *prefix = user_data;
NULL, NULL);
}
+static void setup_powered_server_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ tester_setup_failed();
+ return;
+ }
+
+ tester_print("Controller powered on");
+
+ tester_setup_complete();
+}
+
+static void setup_powered_server(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ unsigned char param[] = { 0x01 };
+
+ tester_print("Powering on controller");
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
+ sizeof(param), param,
+ NULL, NULL, NULL);
+ mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
+ sizeof(param), param, NULL, NULL, NULL);
+
+ mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
+ sizeof(param), param, setup_powered_server_callback,
+ NULL, NULL);
+}
+
const struct rfcomm_client_data connect_success = {
.server_channel = 0x0c,
.client_channel = 0x0c
.expected_connect_err = -ECONNREFUSED
};
+const struct rfcomm_server_data listen_success = {
+ .server_channel = 0x0c,
+ .client_channel = 0x0c,
+ .expected_status = true
+};
+
static void test_basic(const void *test_data)
{
int sk;
tester_print("Connect in progress %d", sk);
}
+static gboolean rfcomm_listen_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ int sk, new_sk;
+
+ data->io_id = 0;
+
+ sk = g_io_channel_unix_get_fd(io);
+
+ new_sk = accept(sk, NULL, NULL);
+ if (new_sk < 0) {
+ tester_test_failed();
+ return false;
+ }
+
+ close(new_sk);
+
+ tester_test_passed();
+
+ return false;
+}
+
+static void connection_cb(uint16_t handle, uint16_t cid,
+ uint8_t channel, void *user_data,
+ bool status)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_server_data *server_data = data->test_data;
+
+ if (server_data->expected_status == status)
+ tester_test_passed();
+ else
+ tester_test_failed();
+}
+
+static void client_new_conn(uint16_t handle, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_server_data *server_data = data->test_data;
+ struct bthost *bthost;
+
+ bthost = hciemu_client_get_host(data->hciemu);
+ bthost_connect_rfcomm(bthost, handle, server_data->client_channel,
+ connection_cb, NULL);
+}
+
+static void test_server(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct rfcomm_server_data *server_data = data->test_data;
+ const uint8_t *master_bdaddr;
+ uint8_t addr_type;
+ struct bthost *bthost;
+ GIOChannel *io;
+ int sk;
+
+ sk = create_rfcomm_sock((bdaddr_t *)
+ hciemu_get_master_bdaddr(data->hciemu),
+ server_data->server_channel);
+ if (sk < 0) {
+ tester_test_failed();
+ return;
+ }
+
+ if (listen(sk, 5) < 0) {
+ tester_warn("listening on socket failed: %s (%u)",
+ strerror(errno), errno);
+ tester_test_failed();
+ close(sk);
+ return;
+ }
+
+ io = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ data->io_id = g_io_add_watch(io, G_IO_IN, rfcomm_listen_cb, NULL);
+ g_io_channel_unref(io);
+
+ tester_print("Listening for connections");
+
+ master_bdaddr = hciemu_get_master_bdaddr(data->hciemu);
+ if (!master_bdaddr) {
+ tester_warn("No master bdaddr");
+ tester_test_failed();
+ return;
+ }
+
+ bthost = hciemu_client_get_host(data->hciemu);
+ bthost_set_connect_cb(bthost, client_new_conn, data);
+
+ if (data->hciemu_type == HCIEMU_TYPE_BREDR)
+ addr_type = BDADDR_BREDR;
+ else
+ addr_type = BDADDR_LE_PUBLIC;
+
+ bthost_hci_connect(bthost, master_bdaddr, addr_type);
+}
+
#define test_rfcomm(name, data, setup, func) \
do { \
struct test_data *user; \
setup_powered_client, test_connect);
test_rfcomm("Basic RFCOMM Socket Client - Conn Refused",
&connect_nval, setup_powered_client, test_connect);
+ test_rfcomm("Basic RFCOMM Socket Server - Success", &listen_success,
+ setup_powered_server, test_server);
return tester_run();
}