示例#1
0
文件: avctp.c 项目: ghent360/bluez
int avctp_register(struct btd_adapter *adapter, gboolean master)
{
	struct avctp_server *server;
	const bdaddr_t *src = btd_adapter_get_address(adapter);

	server = g_new0(struct avctp_server, 1);

	server->control_io = avctp_server_socket(src, master, L2CAP_MODE_BASIC,
							AVCTP_CONTROL_PSM);
	if (!server->control_io) {
		g_free(server);
		return -1;
	}
	server->browsing_io = avctp_server_socket(src, master, L2CAP_MODE_ERTM,
							AVCTP_BROWSING_PSM);
	if (!server->browsing_io) {
		if (server->control_io) {
			g_io_channel_shutdown(server->control_io, TRUE, NULL);
			g_io_channel_unref(server->control_io);
			server->control_io = NULL;
		}
		g_free(server);
		return -1;
	}

	server->adapter = btd_adapter_ref(adapter);

	servers = g_slist_append(servers, server);

	return 0;
}
示例#2
0
文件: device.c 项目: padelt/bluez
static struct input_device *input_device_new(struct btd_service *service)
{
    struct btd_device *device = btd_service_get_device(service);
    struct btd_profile *p = btd_service_get_profile(service);
    const char *path = device_get_path(device);
    const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid);
    struct btd_adapter *adapter = device_get_adapter(device);
    struct input_device *idev;
    char name[HCI_MAX_NAME_LENGTH + 1];

    idev = g_new0(struct input_device, 1);
    bacpy(&idev->src, btd_adapter_get_address(adapter));
    bacpy(&idev->dst, device_get_address(device));
    idev->service = btd_service_ref(service);
    idev->device = btd_device_ref(device);
    idev->path = g_strdup(path);
    idev->handle = rec->handle;
    idev->disable_sdp = is_device_sdp_disable(rec);

    device_get_name(device, name, HCI_MAX_NAME_LENGTH);
    if (strlen(name) > 0)
        idev->name = g_strdup(name);

    /* Initialize device properties */
    extract_hid_props(idev, rec);

    return idev;
}
示例#3
0
文件: hdp_util.c 项目: ghent360/bluez
gboolean hdp_get_mdep(struct hdp_device *device, struct hdp_application *app,
				hdp_continue_mdep_f func, gpointer data,
				GDestroyNotify destroy, GError **err)
{
	struct get_mdep_data *mdep_data;
	const bdaddr_t *src;
	const bdaddr_t *dst;
	uuid_t uuid;

	src = btd_adapter_get_address(device_get_adapter(device->dev));
	dst = device_get_address(device->dev);

	mdep_data = g_new0(struct get_mdep_data, 1);
	mdep_data->app = hdp_application_ref(app);
	mdep_data->func = func;
	mdep_data->data = data;
	mdep_data->destroy = destroy;

	bt_string2uuid(&uuid, HDP_UUID);
	if (bt_search_service(src, dst, &uuid, get_mdep_cb, mdep_data,
						free_mdep_data, 0) < 0) {
		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
						"Can't get remote SDP record");
		g_free(mdep_data);
		return FALSE;
	}

	return TRUE;
}
static void sixaxis_sdp_cb(struct btd_device *dev, int err, void *user_data)
{
	struct sixaxis_data *data = user_data;
	const bdaddr_t *src;

	DBG("err %d (%s)", err, strerror(-err));

	if (err < 0)
		goto fail;

	src = btd_adapter_get_address(device_get_adapter(dev));

	if (input_device_set_channel(src, device_get_address(dev), data->psm,
								data->chan) < 0)
		goto fail;

	g_io_channel_unref(data->chan);
	g_free(data);

	return;

fail:
	g_io_channel_shutdown(data->chan, TRUE, NULL);
	g_io_channel_unref(data->chan);
	g_free(data);
}
示例#5
0
文件: hdp_util.c 项目: ghent360/bluez
gboolean hdp_establish_mcl(struct hdp_device *device,
						hdp_continue_proc_f func,
						gpointer data,
						GDestroyNotify destroy,
						GError **err)
{
	struct conn_mcl_data *conn_data;
	const bdaddr_t *src;
	const bdaddr_t *dst;
	uuid_t uuid;

	src = btd_adapter_get_address(device_get_adapter(device->dev));
	dst = device_get_address(device->dev);

	conn_data = g_new0(struct conn_mcl_data, 1);
	conn_data->refs = 1;
	conn_data->func = func;
	conn_data->data = data;
	conn_data->destroy = destroy;
	conn_data->dev = health_device_ref(device);

	bt_string2uuid(&uuid, HDP_UUID);
	if (bt_search_service(src, dst, &uuid, search_cb, conn_data,
					destroy_con_mcl_data, 0) < 0) {
		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
						"Can't get remote SDP record");
		g_free(conn_data);
		return FALSE;
	}

	return TRUE;
}
示例#6
0
文件: server.c 项目: luetzel/bluez
static struct network_adapter *create_adapter(struct btd_adapter *adapter)
{
	struct network_adapter *na;
	GError *err = NULL;

	na = g_new0(struct network_adapter, 1);
	na->adapter = btd_adapter_ref(adapter);

	na->io = bt_io_listen(NULL, confirm_event, na, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR,
				btd_adapter_get_address(adapter),
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_SEC_LEVEL,
				security ? BT_IO_SEC_MEDIUM : BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (!na->io) {
		error("%s", err->message);
		g_error_free(err);
		adapter_free(na);
		return NULL;
	}

	return na;
}
示例#7
0
/* Connect and initiate BNEP session */
int connection_connect(struct btd_service *service)
{
	struct network_conn *nc = btd_service_get_user_data(service);
	struct network_peer *peer = nc->peer;
	uint16_t id = get_service_id(service);
	GError *err = NULL;
	const bdaddr_t *src;
	const bdaddr_t *dst;

	DBG("id %u", id);

	if (nc->state != DISCONNECTED)
		return -EALREADY;

	src = btd_adapter_get_address(device_get_adapter(peer->device));
	dst = device_get_address(peer->device);

	nc->io = bt_io_connect(connect_cb, nc,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_INVALID);
	if (!nc->io)
		return -EIO;

	nc->state = CONNECTING;

	return 0;
}
示例#8
0
static bool setup_device(int fd, int index, struct btd_adapter *adapter)
{
	char device_addr[18], master_addr[18], adapter_addr[18];
	bdaddr_t device_bdaddr, master_bdaddr;
	const bdaddr_t *adapter_bdaddr;
	struct btd_device *device;

	if (get_device_bdaddr(fd, &device_bdaddr) < 0)
		return false;

	if (get_master_bdaddr(fd, &master_bdaddr) < 0)
		return false;

	/* This can happen if controller was plugged while already connected
	 * eg. to charge up battery.
	 * Don't set LEDs in that case, hence return false */
	device = btd_adapter_find_device(adapter, &device_bdaddr,
							BDADDR_BREDR);
	if (device && btd_device_is_connected(device))
		return false;

	adapter_bdaddr = btd_adapter_get_address(adapter);

	if (bacmp(adapter_bdaddr, &master_bdaddr)) {
		if (set_master_bdaddr(fd, adapter_bdaddr) < 0)
			return false;
	}

	ba2str(&device_bdaddr, device_addr);
	ba2str(&master_bdaddr, master_addr);
	ba2str(adapter_bdaddr, adapter_addr);
	DBG("remote %s old_master %s new_master %s",
				device_addr, master_addr, adapter_addr);

	device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR);

	if (g_slist_find_custom(btd_device_get_uuids(device), HID_UUID,
						(GCompareFunc)strcasecmp)) {
		DBG("device %s already known, skipping", device_addr);
		return true;
	}

	info("sixaxis: setting up new device");

	btd_device_device_set_name(device, devices[index].name);
	btd_device_set_pnpid(device, devices[index].source, devices[index].vid,
				devices[index].pid, devices[index].version);
	btd_device_set_temporary(device, FALSE);

	return true;
}
示例#9
0
文件: server.c 项目: luetzel/bluez
int server_register(struct btd_adapter *adapter, uint16_t id)
{
	struct network_adapter *na;
	struct network_server *ns;
	const char *path;

	na = find_adapter(adapters, adapter);
	if (!na) {
		na = create_adapter(adapter);
		if (!na)
			return -EINVAL;
		adapters = g_slist_append(adapters, na);
	}

	ns = find_server(na->servers, id);
	if (ns)
		return 0;

	ns = g_new0(struct network_server, 1);

	ns->name = g_strdup("Network service");

	path = adapter_get_path(adapter);

	if (g_slist_length(na->servers) > 0)
		goto done;

	if (!g_dbus_register_interface(btd_get_dbus_connection(), path,
						NETWORK_SERVER_INTERFACE,
						server_methods, NULL, NULL, na,
						path_unregister)) {
		error("D-Bus failed to register %s interface",
						NETWORK_SERVER_INTERFACE);
		server_free(ns);
		return -1;
	}

	DBG("Registered interface %s on path %s", NETWORK_SERVER_INTERFACE,
									path);

done:
	bacpy(&ns->src, btd_adapter_get_address(adapter));
	ns->id = id;
	ns->na = na;
	ns->record_id = 0;
	na->servers = g_slist_append(na->servers, ns);

	return 0;
}
示例#10
0
文件: avctp.c 项目: ghent360/bluez
struct avctp *avctp_connect(struct btd_device *device)
{
	struct avctp *session;
	GError *err = NULL;
	GIOChannel *io;
	const bdaddr_t *src;

	session = avctp_get_internal(device);
	if (!session)
		return NULL;

	if (session->state > AVCTP_STATE_DISCONNECTED)
		return session;

	avctp_set_state(session, AVCTP_STATE_CONNECTING, 0);

	src = btd_adapter_get_address(session->server->adapter);

	io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR,
				device_get_address(session->device),
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
				BT_IO_OPT_INVALID);
	if (err) {
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
		error("%s", err->message);
		g_error_free(err);
		return NULL;
	}

	session->control = avctp_channel_create(session, io, 2, NULL);
	session->initiator = true;
	g_io_channel_unref(io);

	return session;
}
示例#11
0
文件: avctp.c 项目: ghent360/bluez
static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
						struct btd_device *dev)
{
	const bdaddr_t *src;
	const bdaddr_t *dst;

	if (session->control != NULL) {
		error("Control: Refusing unexpected connect");
		g_io_channel_shutdown(chan, TRUE, NULL);

		/*
		 * Close AVCTP channel if remote tried connect
		 * at the same time
		 * AVRCP SPEC V1.5 4.1.1 Connection Establishment
		 */
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EAGAIN);
		return;
	}

	avctp_set_state(session, AVCTP_STATE_CONNECTING, 0);
	session->control = avctp_channel_create(session, chan, 2, NULL);

	src = btd_adapter_get_address(device_get_adapter(dev));
	dst = device_get_address(dev);

	session->auth_id = btd_request_authorization(src, dst,
							AVRCP_REMOTE_UUID,
							auth_cb, session);
	if (session->auth_id == 0)
		goto drop;

	session->control->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
						G_IO_NVAL, session_cb, session);
	return;

drop:
	avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
}
示例#12
0
static ssize_t wii_pincb(struct btd_adapter *adapter, struct btd_device *device,
						char *pinbuf, bool *display,
						unsigned int attempt)
{
	uint16_t vendor, product;
	char addr[18], name[25];
	unsigned int i;

	/* Only try the pin code once per device. If it's not correct then it's
	 * an unknown device. */
	if (attempt > 1)
		return 0;

	ba2str(device_get_address(device), addr);

	vendor = btd_device_get_vendor(device);
	product = btd_device_get_product(device);

	device_get_name(device, name, sizeof(name));

	for (i = 0; i < G_N_ELEMENTS(wii_ids); ++i) {
		if (vendor == wii_ids[i][0] && product == wii_ids[i][1])
			goto found;
	}

	for (i = 0; i < G_N_ELEMENTS(wii_names); ++i) {
		if (g_str_equal(name, wii_names[i]))
			goto found;
	}

	return 0;

found:
	DBG("Forcing fixed pin on detected wiimote %s", addr);
	memcpy(pinbuf, btd_adapter_get_address(adapter), 6);
	return 6;
}
示例#13
0
文件: avctp.c 项目: ghent360/bluez
int avctp_connect_browsing(struct avctp *session)
{
	const bdaddr_t *src;
	GError *err = NULL;
	GIOChannel *io;

	if (session->state != AVCTP_STATE_CONNECTED)
		return -ENOTCONN;

	if (session->browsing != NULL)
		return 0;

	avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTING, 0);

	src = btd_adapter_get_address(session->server->adapter);

	io = bt_io_connect(avctp_connect_browsing_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR,
				device_get_address(session->device),
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_PSM, AVCTP_BROWSING_PSM,
				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
				BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		return -EIO;
	}

	session->browsing = avctp_channel_create(session, io, 1,
						avctp_destroy_browsing);
	g_io_channel_unref(io);

	return 0;
}
int sap_server_register(struct btd_adapter *adapter)
{
	sdp_record_t *record = NULL;
	GError *gerr = NULL;
	GIOChannel *io;
	struct sap_server *server;

	if (sap_init() < 0) {
		error("Sap driver initialization failed.");
		return -1;
	}

	record = create_sap_record(SAP_SERVER_CHANNEL);
	if (!record) {
		error("Creating SAP SDP record failed.");
		goto sdp_err;
	}

	if (adapter_service_add(adapter, record) < 0) {
		error("Adding SAP SDP record to the SDP server failed.");
		sdp_record_free(record);
		goto sdp_err;
	}

	server = g_new0(struct sap_server, 1);
	server->adapter = btd_adapter_ref(adapter);
	server->record_id = record->handle;

	io = bt_io_listen(NULL, connect_confirm_cb, server,
			NULL, &gerr,
			BT_IO_OPT_SOURCE_BDADDR,
			btd_adapter_get_address(adapter),
			BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL,
			BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
			BT_IO_OPT_MASTER, TRUE,
			BT_IO_OPT_INVALID);
	if (!io) {
		error("Can't listen at channel %d.", SAP_SERVER_CHANNEL);
		g_error_free(gerr);
		goto server_err;
	}
	server->listen_io = io;

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
					adapter_get_path(server->adapter),
					SAP_SERVER_INTERFACE,
					server_methods, NULL,
					server_properties, server,
					destroy_sap_interface)) {
		error("D-Bus failed to register %s interface",
							SAP_SERVER_INTERFACE);
		goto server_err;
	}

	DBG("server %p, listen socket 0x%02x", server,
						g_io_channel_unix_get_fd(io));

	return 0;

server_err:
	server_remove(server);
sdp_err:
	sap_exit();

	return -1;
}
示例#15
0
static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct hog_device *hogdev = user_data;
	struct btd_adapter *adapter = device_get_adapter(hogdev->device);
	uint8_t value[HOG_REPORT_MAP_MAX_SIZE];
	struct uhid_event ev;
	uint16_t vendor_src, vendor, product, version;
	ssize_t vlen;
	char itemstr[20]; /* 5x3 (data) + 4 (continuation) + 1 (null) */
	int i, err;

	if (status != 0) {
		error("Report Map read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("ATT protocol error");
		return;
	}

	DBG("Report MAP:");
	for (i = 0; i < vlen;) {
		ssize_t ilen = 0;
		bool long_item = false;

		if (get_descriptor_item_info(&value[i], vlen - i, &ilen,
								&long_item)) {
			/* Report ID is short item with prefix 100001xx */
			if (!long_item && (value[i] & 0xfc) == 0x84)
				hogdev->has_report_id = TRUE;

			DBG("\t%s", item2string(itemstr, &value[i], ilen));

			i += ilen;
		} else {
			error("Report Map parsing failed at %d", i);

			/* Just print remaining items at once and break */
			DBG("\t%s", item2string(itemstr, &value[i], vlen - i));
			break;
		}
	}

	vendor_src = btd_device_get_vendor_src(hogdev->device);
	vendor = btd_device_get_vendor(hogdev->device);
	product = btd_device_get_product(hogdev->device);
	version = btd_device_get_version(hogdev->device);
	DBG("DIS information: vendor_src=0x%X, vendor=0x%X, product=0x%X, "
			"version=0x%X",	vendor_src, vendor, product, version);

	/* create uHID device */
	memset(&ev, 0, sizeof(ev));
	ev.type = UHID_CREATE;
	if (device_name_known(hogdev->device))
		device_get_name(hogdev->device, (char *) ev.u.create.name,
						sizeof(ev.u.create.name));
	else
		strcpy((char *) ev.u.create.name, "bluez-hog-device");
	ba2str(btd_adapter_get_address(adapter), (char *) ev.u.create.phys);
	ba2str(device_get_address(hogdev->device), (char *) ev.u.create.uniq);
	ev.u.create.vendor = vendor;
	ev.u.create.product = product;
	ev.u.create.version = version;
	ev.u.create.country = hogdev->bcountrycode;
	ev.u.create.bus = BUS_BLUETOOTH;
	ev.u.create.rd_data = value;
	ev.u.create.rd_size = vlen;

	err = bt_uhid_send(hogdev->uhid, &ev);
	if (err < 0) {
		error("bt_uhid_send: %s", strerror(-err));
		return;
	}

	bt_uhid_register(hogdev->uhid, UHID_OUTPUT, forward_report, hogdev);
	bt_uhid_register(hogdev->uhid, UHID_SET_REPORT, set_report, hogdev);
	bt_uhid_register(hogdev->uhid, UHID_GET_REPORT, get_report, hogdev);
}
static void hid_server_remove(struct btd_profile *p,
						struct btd_adapter *adapter)
{
	server_stop(btd_adapter_get_address(adapter));
}
static int hid_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
	return server_start(btd_adapter_get_address(adapter));
}