예제 #1
0
파일: hciemu.c 프로젝트: BirdAndEarth/RPi
static bool create_stack(struct hciemu *hciemu)
{
	struct btdev *btdev;
	struct bthost *bthost;
	int sv[2];

	btdev = btdev_create(hciemu->btdev_type, 0x00);
	if (!btdev)
		return false;

	bthost = bthost_create();
	if (!bthost) {
		btdev_destroy(btdev);
		return false;
	}

	btdev_set_command_handler(btdev, client_command_callback, hciemu);

	if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC,
								0, sv) < 0) {
		bthost_destroy(bthost);
		btdev_destroy(btdev);
		return false;
	}

	hciemu->client_dev = btdev;
	hciemu->host_stack = bthost;

	hciemu->client_source = create_source_btdev(sv[0], btdev);
	hciemu->host_source = create_source_bthost(sv[1], bthost);

	return true;
}
예제 #2
0
파일: hciemu.c 프로젝트: BirdAndEarth/RPi
static bool create_vhci(struct hciemu *hciemu)
{
	struct btdev *btdev;
	uint8_t create_req[2];
	ssize_t written;
	int fd;

	btdev = btdev_create(hciemu->btdev_type, 0x00);
	if (!btdev)
		return false;

	btdev_set_command_handler(btdev, master_command_callback, hciemu);

	fd = open("/dev/vhci", O_RDWR | O_NONBLOCK | O_CLOEXEC);
	if (fd < 0) {
		perror("Opening /dev/vhci failed");
		btdev_destroy(btdev);
		return false;
	}

	create_req[0] = HCI_VENDOR_PKT;
	create_req[1] = HCI_BREDR;
	written = write(fd, create_req, sizeof(create_req));
	if (written < 0) {
		close(fd);
		btdev_destroy(btdev);
		return false;
	}

	hciemu->master_dev = btdev;

	hciemu->master_source = create_source_btdev(fd, btdev);

	return true;
}
예제 #3
0
static bool create_vhci(struct hciemu *hciemu)
{
	struct btdev *btdev;
	uint8_t bdaddr[6];
	const char *str;
	int fd, i;

	btdev = btdev_create(hciemu->btdev_type, 0x00);
	if (!btdev)
		return false;

	str = hciemu_get_address(hciemu);

	for (i = 5; i >= 0; i--, str += 3)
		bdaddr[i] = strtol(str, NULL, 16);

	btdev_set_bdaddr(btdev, bdaddr);
	btdev_set_command_handler(btdev, master_command_callback, hciemu);

	fd = open("/dev/vhci", O_RDWR | O_NONBLOCK | O_CLOEXEC);
	if (fd < 0) {
		btdev_destroy(btdev);
		return false;
	}

	hciemu->master_dev = btdev;

	hciemu->master_source = create_source_btdev(fd, btdev);

	return true;
}
예제 #4
0
파일: server.c 프로젝트: DaisyPi/sensortag
static void server_accept_callback(int fd, uint32_t events, void *user_data)
{
	struct server *server = user_data;
	struct client *client;
	enum btdev_type uninitialized_var(type);

	if (events & (EPOLLERR | EPOLLHUP)) {
		mainloop_remove_fd(server->fd);
		return;
	}

	client = malloc(sizeof(*client));
	if (!client)
		return;

	memset(client, 0, sizeof(*client));

	client->fd = accept_client(server->fd);
	if (client->fd < 0) {
		free(client);
		return;
	}

	switch (server->type) {
	case SERVER_TYPE_BREDRLE:
		type = BTDEV_TYPE_BREDRLE;
		break;
	case SERVER_TYPE_BREDR:
		type = BTDEV_TYPE_BREDR;
		break;
	case SERVER_TYPE_LE:
		type = BTDEV_TYPE_LE;
		break;
	case SERVER_TYPE_AMP:
		type = BTDEV_TYPE_AMP;
		break;
	case SERVER_TYPE_MONITOR:
		goto done;
	}

	client->btdev = btdev_create(type, server->id);
	if (!client->btdev) {
		close(client->fd);
		free(client);
		return;
	}

	btdev_set_send_handler(client->btdev, client_write_callback, client);

done:
	if (mainloop_add_fd(client->fd, EPOLLIN, client_read_callback,
						client, client_destroy) < 0) {
		btdev_destroy(client->btdev);
		close(client->fd);
		free(client);
	}
}
예제 #5
0
파일: server.c 프로젝트: 520lly/bluez
static void client_destroy(void *user_data)
{
	struct client *client = user_data;

	btdev_destroy(client->btdev);

	close(client->fd);

	free(client);
}
예제 #6
0
void hciemu_unref(struct hciemu *hciemu)
{
	if (!hciemu)
		return;

	if (__sync_sub_and_fetch(&hciemu->ref_count, 1))
		return;

	queue_destroy(hciemu->post_command_hooks, destroy_command_hook);

	g_source_remove(hciemu->host_source);
	g_source_remove(hciemu->client_source);
	g_source_remove(hciemu->master_source);

	bthost_destroy(hciemu->host_stack);
	btdev_destroy(hciemu->client_dev);
	btdev_destroy(hciemu->master_dev);

	free(hciemu);
}
예제 #7
0
void hciemu_unref(struct hciemu *hciemu)
{
	if (!hciemu)
		return;

	if (__sync_sub_and_fetch(&hciemu->ref_count, 1) > 0)
		return;

	g_list_foreach(hciemu->post_command_hooks, destroy_command_hook, NULL);
	g_list_free(hciemu->post_command_hooks);

	bthost_stop(hciemu->host_stack);

	g_source_remove(hciemu->host_source);
	g_source_remove(hciemu->client_source);
	g_source_remove(hciemu->master_source);

	bthost_destroy(hciemu->host_stack);
	btdev_destroy(hciemu->client_dev);
	btdev_destroy(hciemu->master_dev);

	g_free(hciemu);
}
예제 #8
0
struct hciemu *hciemu_new(enum hciemu_type type)
{
	struct hciemu *hciemu;

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

	switch (type) {
	case HCIEMU_TYPE_BREDRLE:
		hciemu->btdev_type = BTDEV_TYPE_BREDRLE;
		break;
	case HCIEMU_TYPE_BREDR:
		hciemu->btdev_type = BTDEV_TYPE_BREDR;
		break;
	case HCIEMU_TYPE_LE:
		hciemu->btdev_type = BTDEV_TYPE_LE;
		break;
	case HCIEMU_TYPE_LEGACY:
		hciemu->btdev_type = BTDEV_TYPE_BREDR20;
		break;
	default:
		return NULL;
	}

	hciemu->post_command_hooks = queue_new();
	if (!hciemu->post_command_hooks) {
		free(hciemu);
		return NULL;
	}

	if (!create_vhci(hciemu)) {
		queue_destroy(hciemu->post_command_hooks, NULL);
		free(hciemu);
		return NULL;
	}

	if (!create_stack(hciemu)) {
		g_source_remove(hciemu->master_source);
		btdev_destroy(hciemu->master_dev);
		queue_destroy(hciemu->post_command_hooks, NULL);
		free(hciemu);
		return NULL;
	}

	g_idle_add(start_stack, hciemu);

	return hciemu_ref(hciemu);
}
예제 #9
0
struct hciemu *hciemu_new(enum hciemu_type type)
{
	struct hciemu *hciemu;

	hciemu = g_try_new0(struct hciemu, 1);
	if (!hciemu)
		return NULL;

	switch (type) {
	case HCIEMU_TYPE_BREDRLE:
		hciemu->btdev_type = BTDEV_TYPE_BREDRLE;
		break;
	case HCIEMU_TYPE_BREDR:
		hciemu->btdev_type = BTDEV_TYPE_BREDR;
		break;
	case HCIEMU_TYPE_LE:
		hciemu->btdev_type = BTDEV_TYPE_LE;
		break;
	default:
		return NULL;
	}

	if (!create_vhci(hciemu)) {
		g_free(hciemu);
		return NULL;
	}

	if (!create_stack(hciemu)) {
		g_source_remove(hciemu->master_source);
		btdev_destroy(hciemu->master_dev);
		g_free(hciemu);
		return NULL;
	}

	g_idle_add(start_stack, hciemu);

	return hciemu_ref(hciemu);
}
예제 #10
0
파일: server.c 프로젝트: 520lly/bluez
static void server_accept_callback(int fd, uint32_t events, void *user_data)
{
	struct server *server = user_data;
	struct client *client;

	if (events & (EPOLLERR | EPOLLHUP))
		return;

	client = malloc(sizeof(*client));
	if (!client)
		return;

	memset(client, 0, sizeof(*client));

	client->fd = accept_client(server->fd);
	if (client->fd < 0) {
		free(client);
		return;
	}

	client->btdev = btdev_create(server->id);
	if (!client->btdev) {
		close(client->fd);
		free(client);
		return;
	}

	btdev_set_send_handler(client->btdev, client_write_callback, client);

	if (mainloop_add_fd(client->fd, EPOLLIN, client_read_callback,
						client, client_destroy) < 0) {
		btdev_destroy(client->btdev);
		close(client->fd);
		free(client);
	}
}