Ejemplo n.º 1
0
static void setup_powered_client(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_LE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
	mgmt_send(data->mgmt, MGMT_OP_SET_PAIRABLE, 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_client_callback,
			NULL, NULL);
}
Ejemplo n.º 2
0
static void test_client(const void *test_data)
{
	struct test_data *data = tester_get_data();
	const struct smp_data *smp = data->test_data;
	struct mgmt_cp_pair_device cp;
	struct bthost *bthost;

	init_bdaddr(data);

	bthost = hciemu_client_get_host(data->hciemu);
	bthost_set_connect_cb(bthost, smp_new_conn, data);
	test_add_condition(data);

	if (smp->expect_hci_command) {
		tester_print("Registering HCI command callback");
		hciemu_add_master_post_command_hook(data->hciemu,
						command_hci_callback, data);
		test_add_condition(data);
	}

	memcpy(&cp.addr.bdaddr, data->ra, sizeof(data->ra));
	cp.addr.type = BDADDR_LE_PUBLIC;
	if (smp->mitm)
		cp.io_cap = 0x04; /* KeyboardDisplay */
	else
		cp.io_cap = 0x03; /* NoInputNoOutput */

	mgmt_send(data->mgmt, MGMT_OP_PAIR_DEVICE, data->mgmt_index,
			sizeof(cp), &cp, pair_device_complete, NULL, NULL);

	tester_print("Pairing in progress");
}
Ejemplo n.º 3
0
struct bt_gap *bt_gap_new(void)
{
	struct bt_gap *gap;

	gap = new0(struct bt_gap, 1);
	if (!gap)
		return NULL;

	gap->mgmt = mgmt_new_default();
	if (!gap->mgmt) {
		free(gap);
		return NULL;
	}

	gap->mgmt_ready = false;

	if (!mgmt_send(gap->mgmt, MGMT_OP_READ_VERSION,
					MGMT_INDEX_NONE, 0, NULL,
					read_version_complete, gap, NULL)) {
		mgmt_unref(gap->mgmt);
		return NULL;
	}

	return bt_gap_ref(gap);
}
Ejemplo n.º 4
0
static struct btd_advertising *
advertising_manager_create(struct btd_adapter *adapter)
{
	struct btd_advertising *manager;

	manager = new0(struct btd_advertising, 1);
	if (!manager)
		return NULL;

	manager->adapter = adapter;

	manager->mgmt = mgmt_new_default();

	if (!manager->mgmt) {
		error("Failed to access management interface");
		free(manager);
		return NULL;
	}

	manager->mgmt_index = btd_adapter_get_index(adapter);

	if (!mgmt_send(manager->mgmt, MGMT_OP_READ_ADV_FEATURES,
				manager->mgmt_index, 0, NULL,
				read_adv_features_callback, manager, NULL)) {
		error("Failed to read advertising features");
		advertising_manager_destroy(manager);
		return NULL;
	}

	manager->ads = queue_new();

	return manager;
}
Ejemplo n.º 5
0
static void cmd_discoverable(int argcp, char **argvp)
{
    struct mgmt_cp_set_discoverable cp = {0, 0};
    uint16_t opcode = MGMT_OP_SET_DISCOVERABLE;

    if (argcp < 2) {
        resp_mgmt(err_BAD_PARAM);
        return;
    }

    if (!on_or_off(argvp[1], &cp.val)) {
        resp_mgmt(err_BAD_PARAM);
        return;
    }

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return;
    }

    if (mgmt_send(mgmt_master, opcode, opt_src_idx, sizeof(cp),
        &cp, set_mode_complete, NULL, NULL) == 0)
    {
        DBG("mgmt_send(MGMT_OP_SET_DISCOVERABLE) failed");
        resp_mgmt(err_PROTO_ERR);
        return;
    }
}
Ejemplo n.º 6
0
struct bt_gap *bt_gap_new_index(uint16_t index)
{
	struct bt_gap *gap;

	if (index == MGMT_INDEX_NONE)
		return NULL;

	gap = new0(struct bt_gap, 1);
	gap->index = index;

	gap->mgmt = mgmt_new_default();
	if (!gap->mgmt) {
		free(gap);
		return NULL;
	}

	gap->irk_list = queue_new();
	gap->mgmt_ready = false;

	if (!mgmt_send(gap->mgmt, MGMT_OP_READ_VERSION,
					MGMT_INDEX_NONE, 0, NULL,
					read_version_complete, gap, NULL)) {
		mgmt_unref(gap->mgmt);
		return NULL;
	}

	return bt_gap_ref(gap);
}
Ejemplo n.º 7
0
static void test_pre_setup(const void *test_data)
{
	struct test_data *data = tester_get_data();

	data->crypto = bt_crypto_new();
	if (!data->crypto) {
		tester_warn("Failed to setup crypto");
		tester_pre_setup_failed();
		return;
	}

	data->mgmt = mgmt_new_default();
	if (!data->mgmt) {
		tester_warn("Failed to setup management interface");
		bt_crypto_unref(data->crypto);
		tester_pre_setup_failed();
		return;
	}

	if (tester_use_debug())
		mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL);

	mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
					read_index_list_callback, NULL, NULL);
}
Ejemplo n.º 8
0
static bool set_mode_with_cb(uint16_t opcode, char *p_mode, mgmt_request_func_t callback)
{
    struct mgmt_mode cp;
    uintptr_t user_data;

    memset(&cp, 0, sizeof(cp));

    if (!on_or_off(p_mode, &cp.val))
        return false;

    /* Save the configured value in the user_data */
    if (cp.val) user_data = 1;
    else user_data = 0;

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return true;
    }

    if (mgmt_send(mgmt_master, opcode,
            opt_src_idx, sizeof(cp), &cp,
            callback, (void *)user_data, NULL) == 0) {
        resp_mgmt(err_SUCCESS);
    }
    return true;
}
Ejemplo n.º 9
0
static void read_version_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	struct bt_gap *gap = user_data;
	const struct mgmt_rp_read_version *rp = param;

	if (status != MGMT_STATUS_SUCCESS) {
		ready_status(gap, false);
		return;
	}

	if (length < sizeof(*rp)) {
		ready_status(gap, false);
		return;
	}

	gap->mgmt_version = rp->version;
	gap->mgmt_revision = le16_to_cpu(rp->revision);

	if (!mgmt_send(gap->mgmt, MGMT_OP_READ_COMMANDS,
				MGMT_INDEX_NONE, 0, NULL,
				read_commands_complete, gap, NULL)) {
		ready_status(gap, false);
		return;
	}
}
Ejemplo n.º 10
0
static DBusMessage *refresh_advertisement(struct advertisement *ad)
{
	struct mgmt_cp_add_advertising *cp;
	uint8_t param_len;
	uint8_t *adv_data;
	size_t adv_data_len;
	uint32_t flags = 0;

	DBG("Refreshing advertisement: %s", ad->path);

	if (ad->type == AD_TYPE_PERIPHERAL)
		flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;

	if (ad->include_tx_power)
		flags |= MGMT_ADV_FLAG_TX_POWER;

	adv_data = bt_ad_generate(ad->data, &adv_data_len);

	if (!adv_data || (adv_data_len > calc_max_adv_len(ad, flags))) {
		error("Advertising data too long or couldn't be generated.");

		return g_dbus_create_error(ad->reg, ERROR_INTERFACE
						".InvalidLength",
						"Advertising data too long.");
	}

	param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len;

	cp = malloc0(param_len);

	if (!cp) {
		error("Couldn't allocate for MGMT!");

		free(adv_data);

		return btd_error_failed(ad->reg, "Failed");
	}

	cp->flags = flags;
	cp->instance = ad->instance;
	cp->adv_data_len = adv_data_len;
	memcpy(cp->data, adv_data, adv_data_len);

	free(adv_data);

	if (!mgmt_send(ad->manager->mgmt, MGMT_OP_ADD_ADVERTISING,
					ad->manager->mgmt_index, param_len, cp,
					add_advertising_callback, ad, NULL)) {
		error("Failed to add Advertising Data");

		free(cp);

		return btd_error_failed(ad->reg, "Failed");
	}

	free(cp);

	return NULL;
}
Ejemplo n.º 11
0
static void setup_powered_client(const void *test_data)
{
	struct test_data *data = tester_get_data();
	unsigned char param[] = { 0x01 };

	tester_print("Powering on controller");

	if (data->hciemu_type == HCIEMU_TYPE_BREDR)
		mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
	else
		mgmt_send(data->mgmt, MGMT_OP_SET_LE, 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_client_callback,
			NULL, NULL);
}
Ejemplo n.º 12
0
int main(int argc ,char *argv[])
{
	int exit_status;

	for (;;) {
		int opt;

		opt = getopt_long(argc, argv, "vh", main_options, NULL);
		if (opt < 0)
			break;

		switch (opt) {
		case 'v':
			printf("%s\n", VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage();
			return EXIT_SUCCESS;
		default:
			return EXIT_FAILURE;
		}
	}

	if (argc - optind > 0) {
		fprintf(stderr, "Invalid command line parameters\n");
		return EXIT_FAILURE;
	}

	mainloop_init();

	mgmt = mgmt_new_default();
	if (!mgmt) {
		fprintf(stderr, "Failed to open management socket\n");
		return EXIT_FAILURE;
	}

	if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST,
					MGMT_INDEX_NONE, 0, NULL,
					read_index_list, NULL, NULL)) {
		fprintf(stderr, "Failed to read index list\n");
		exit_status = EXIT_FAILURE;
		goto done;
	}

	exit_status = mainloop_run_with_signal(signal_callback, NULL);

	bt_hci_unref(adv_dev);
	bt_hci_unref(scan_dev);

	bt_crypto_unref(crypto);

done:
	mgmt_unref(mgmt);

	return exit_status;
}
Ejemplo n.º 13
0
static void setup_powered_server(const void *test_data)
{
	struct test_data *data = tester_get_data();
	unsigned char param[] = { 0x01 };

	setup_powered_common();

	tester_print("Powering on controller");

	mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);

	if (data->hciemu_type != HCIEMU_TYPE_BREDR)
		mgmt_send(data->mgmt, MGMT_OP_SET_ADVERTISING,
				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);
}
Ejemplo n.º 14
0
static void setup_powered_server(const void *test_data)
{
	struct test_data *data = tester_get_data();
	const struct smp_data *smp = data->test_data;
	unsigned char param[] = { 0x01 };

	mgmt_register(data->mgmt, MGMT_EV_USER_CONFIRM_REQUEST,
			data->mgmt_index, user_confirm_request_callback,
			data, NULL);

	tester_print("Powering on controller");

	mgmt_send(data->mgmt, MGMT_OP_SET_LE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
	mgmt_send(data->mgmt, MGMT_OP_SET_BONDABLE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
	mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
	mgmt_send(data->mgmt, MGMT_OP_SET_ADVERTISING, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
	if (smp->sc) {
		mgmt_send(data->mgmt, MGMT_OP_SET_SECURE_CONN,
				data->mgmt_index, sizeof(param), param, NULL,
				NULL, NULL);
		make_pk(data);
	}

	mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
			sizeof(param), param, setup_powered_server_callback,
			NULL, NULL);
}
Ejemplo n.º 15
0
static void index_added_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	struct test_data *data = tester_get_data();

	tester_print("Index Added callback");
	tester_print("  Index: 0x%04x", index);

	data->mgmt_index = index;

	mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
					read_info_callback, NULL, NULL);
}
Ejemplo n.º 16
0
static void toggle_powered(const void *test_data)
{
	struct test_data *data = tester_get_data();
	bool power = PTR_TO_INT(test_data);
	unsigned char param[1];

	param[0] = power ? 0x01 : 0x00;

	tester_print("Powering %s controller", power ? "on" : "off");

	mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
			sizeof(param), param, toggle_powered_client_callback,
			INT_TO_PTR(power), NULL);
}
Ejemplo n.º 17
0
static void setup_powered_common(void)
{
	struct test_data *data = tester_get_data();
	const struct l2cap_data *test = data->test_data;
	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
	unsigned char param[] = { 0x01 };

	mgmt_register(data->mgmt, MGMT_EV_USER_CONFIRM_REQUEST,
			data->mgmt_index, user_confirm_request_callback,
			NULL, NULL);

	if (test && (test->pin || test->expect_pin))
		mgmt_register(data->mgmt, MGMT_EV_PIN_CODE_REQUEST,
				data->mgmt_index, pin_code_request_callback,
				data, NULL);

	if (test && test->client_io_cap)
		bthost_set_io_capability(bthost, test->client_io_cap);

	if (test && test->client_pin)
		bthost_set_pin_code(bthost, test->client_pin,
							test->client_pin_len);
	if (test && test->reject_ssp)
		bthost_set_reject_user_confirm(bthost, true);

	if (data->hciemu_type == HCIEMU_TYPE_LE)
		mgmt_send(data->mgmt, MGMT_OP_SET_LE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);

	if (test && test->enable_ssp)
		mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);

	mgmt_send(data->mgmt, MGMT_OP_SET_BONDABLE, data->mgmt_index,
				sizeof(param), param, NULL, NULL, NULL);
}
Ejemplo n.º 18
0
static void setup_powered_client(const void *test_data)
{
	struct test_data *data = tester_get_data();
	const struct l2cap_data *test = data->test_data;
	unsigned char param[] = { 0x01 };

	setup_powered_common();

	tester_print("Powering on controller");

	if (test && (test->expect_cmd || test->send_cmd)) {
		struct bthost *bthost = hciemu_client_get_host(data->hciemu);
		bthost_set_connect_cb(bthost, send_rsp_new_conn, data);
	}

	if (test && test->direct_advertising)
		mgmt_send(data->mgmt, MGMT_OP_SET_ADVERTISING,
				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_client_callback,
			NULL, NULL);
}
Ejemplo n.º 19
0
static void test_pre_setup(const void *data)
{
	struct test_data *test_data = tester_get_data();

	if (!tester_use_debug())
		fclose(stderr);

	test_data->mgmt = mgmt_new_default();
	if (!test_data->mgmt) {
		tester_warn("Failed to setup management interface");
		tester_pre_setup_failed();
		return;
	}

	mgmt_send(test_data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
				NULL, read_index_list_callback, NULL, NULL);
}
Ejemplo n.º 20
0
static void cmd_settings(int argcp, char **argvp)
{
    if (1 < argcp) {
        resp_mgmt(err_BAD_PARAM);
    }

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return;
    }

    if (mgmt_send(mgmt_master, MGMT_OP_READ_INFO,
            opt_src_idx, 0, NULL,
            read_info_complete, NULL, NULL) == 0) {
        DBG("mgmt_send(MGMT_OP_READ_INFO) failed");
        resp_mgmt(err_PROTO_ERR);
    }
}
Ejemplo n.º 21
0
static void advertisement_remove(void *data)
{
	struct advertisement *ad = data;
	struct mgmt_cp_remove_advertising cp;

	g_dbus_client_set_disconnect_watch(ad->client, NULL, NULL);

	cp.instance = ad->instance;

	mgmt_send(ad->manager->mgmt, MGMT_OP_REMOVE_ADVERTISING,
			ad->manager->mgmt_index, sizeof(cp), &cp, NULL, NULL,
			NULL);

	queue_remove(ad->manager->ads, ad);

	util_clear_uid(&ad->manager->instance_bitmap, ad->instance);

	g_idle_add(advertisement_free_idle_cb, ad);
}
Ejemplo n.º 22
0
// Unlike Bluez, we follow BT 4.0 spec which renammed Device Discovery by Scan
static void scan(bool start)
{
    // mgmt_cp_start_discovery and mgmt_cp_stop_discovery are the same
    struct mgmt_cp_start_discovery cp = { (1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM) };
    uint16_t opcode = start? MGMT_OP_START_DISCOVERY : MGMT_OP_STOP_DISCOVERY;

    DBG("Scan %s", start? "start" : "stop");

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return;
    }

    if (mgmt_send(mgmt_master, opcode, opt_src_idx, sizeof(cp),
        &cp, scan_cb, NULL, NULL) == 0)
    {
        DBG("mgmt_send(MGMT_OP_%s_DISCOVERY) failed", start? "START" : "STOP");
        resp_mgmt(err_PROTO_ERR);
        return;
    }
}
Ejemplo n.º 23
0
static void cmd_pair(int argcp, char **argvp)
{
    struct mgmt_cp_pair_device cp;
    bdaddr_t bdaddr;
    uint8_t io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
    uint8_t addr_type = BDADDR_LE_RANDOM;

    if (conn_state != STATE_CONNECTED) {
        resp_mgmt(err_BAD_STATE);
        return;
    }

    if (str2ba(opt_dst, &bdaddr)) {
        resp_mgmt(err_NOT_FOUND);
        return;
    }

    if (!memcmp(opt_dst_type, "public", 6)) {
        addr_type = BDADDR_LE_PUBLIC;
    }

    memset(&cp, 0, sizeof(cp));
    bacpy(&cp.addr.bdaddr, &bdaddr);
    cp.addr.type = addr_type;
    cp.io_cap = io_cap;

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return;
    }

    if (mgmt_send(mgmt_master, MGMT_OP_PAIR_DEVICE,
                opt_src_idx, sizeof(cp), &cp,
                pair_device_complete, NULL,
                NULL) == 0) {
        DBG("mgmt_send(MGMT_OP_PAIR_DEVICE) failed for %s for hci%u", opt_dst, MGMT_INDEX_NONE);
        resp_mgmt(err_PROTO_ERR);
        return;
    }
}
Ejemplo n.º 24
0
static void cmd_unpair(int argcp, char **argvp)
{
    struct mgmt_cp_unpair_device cp;
    bdaddr_t bdaddr;
    uint8_t addr_type = BDADDR_LE_RANDOM;

    if (argcp != 3) {
        resp_mgmt(err_BAD_PARAM);
        return;
    }

    if (str2ba(argvp[1], &bdaddr)) {
        DBG("str2ba failed");
        resp_mgmt(err_NOT_FOUND);
        return;
    }

    if (!memcmp(argvp[2], "public", 6)) {
            addr_type = BDADDR_LE_PUBLIC;
    }

    memset(&cp, 0, sizeof(cp));
    bacpy(&cp.addr.bdaddr, &bdaddr);
    cp.addr.type = addr_type;
    cp.disconnect = 1;

    if (!mgmt_master) {
        resp_error(err_NO_MGMT);
        return;
    }

    if (mgmt_send(mgmt_master, MGMT_OP_UNPAIR_DEVICE,
                opt_src_idx, sizeof(cp), &cp,
                unpair_device_complete, NULL,
                NULL) == 0) {
        DBG("mgmt_send(MGMT_OP_UNPAIR_DEVICE) failed for %s for hci%u", opt_dst, MGMT_INDEX_NONE);
        resp_mgmt(err_PROTO_ERR);
        return;
    }
}
Ejemplo n.º 25
0
static void mgmt_setup(void)
{
    mgmt_master = mgmt_new_default();

    if (!mgmt_master) {
        DBG("Could not connect to the BT management interface, try with su rights");

    } else {
        mgmt_set_debug(mgmt_master, mgmt_debug, "mgmt: ", NULL);

        /* For READ_VERSION, it is mandatory to use INDEX_NONE */
        if (!mgmt_send(mgmt_master, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
                0, NULL, read_version_complete, NULL, NULL)) {
            DBG("mgmt_send(MGMT_OP_READ_VERSION) failed");
        }

        if (!mgmt_register(mgmt_master, MGMT_EV_DEVICE_CONNECTED, opt_src_idx,
                mgmt_device_connected, NULL, NULL)) {
            DBG("mgmt_register(MGMT_EV_DEVICE_CONNECTED) failed");
        }

        if (!mgmt_register(mgmt_master, MGMT_EV_DEVICE_DISCONNECTED, opt_src_idx,
                mgmt_device_disconnected, NULL, NULL)) {
            DBG("mgmt_register(MGMT_EV_DEVICE_DISCONNECTED) failed");
        }

        if (!mgmt_register(mgmt_master, MGMT_EV_DISCOVERING, opt_src_idx,
                mgmt_scanning, NULL, NULL)) {
            DBG("mgmt_register(MGMT_EV_DISCOVERING) failed");
        }

        if (!mgmt_register(mgmt_master, MGMT_EV_DEVICE_FOUND, opt_src_idx,
                mgmt_device_found, NULL, NULL)) {
            DBG("mgmt_register(MGMT_EV_DEVICE_FOUND) failed");
        }
    }
}