⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adapter.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	device_set_temporary(device, FALSE);	adapter->devices = g_slist_append(adapter->devices, device);	src = adapter->address;	rec_list.addr = device_get_address(device);	rec_list.recs = NULL;	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");	textfile_foreach(filename, create_stored_records_from_keys, &rec_list);	device_probe_drivers(device, uuids, rec_list.recs);	if (rec_list.recs != NULL)		sdp_list_free(rec_list.recs, (sdp_free_func_t) sdp_record_free);	g_slist_free(uuids);}static void create_stored_device_from_linkkeys(char *key, char *value,						void *user_data){	struct adapter *adapter = user_data;	struct btd_device *device;	if (g_slist_find_custom(adapter->devices,				key, (GCompareFunc) device_address_cmp))		return;	device = device_create(connection, adapter, key);	if (device) {		device_set_temporary(device, FALSE);		adapter->devices = g_slist_append(adapter->devices, device);	}}static void load_devices(struct adapter *adapter){	char filename[PATH_MAX + 1];	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "profiles");	textfile_foreach(filename, create_stored_device_from_profiles, adapter);	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "linkkeys");	textfile_foreach(filename, create_stored_device_from_linkkeys, adapter);}static void adapter_up(struct adapter *adapter, int dd){	struct hci_conn_list_req *cl = NULL;	struct hci_conn_info *ci;	const char *mode;	int i;	adapter->up = 1;	adapter->discov_timeout = get_discoverable_timeout(adapter->dev_id);	adapter->discov_type = DISCOVER_TYPE_NONE;	adapter->scan_mode = get_startup_scan(adapter->dev_id);	hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,					1, &adapter->scan_mode);	adapter->mode = get_startup_mode(adapter->dev_id);	if (adapter->mode == MODE_LIMITED)		set_limited_discoverable(dd, adapter->dev.class, TRUE);	/*	 * retrieve the active connections: address the scenario where	 * the are active connections before the daemon've started	 */	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));	cl->dev_id = adapter->dev_id;	cl->conn_num = 10;	ci = cl->conn_info;	if (ioctl(dd, HCIGETCONNLIST, cl) == 0) {		for (i = 0; i < cl->conn_num; i++, ci++)			active_conn_append(&adapter->active_conn,						&ci->bdaddr, ci->handle);	}	g_free(cl);	mode = mode2str(adapter->mode);	dbus_connection_emit_property_changed(connection, adapter->path,					ADAPTER_INTERFACE, "Mode",					DBUS_TYPE_STRING, &mode);	load_devices(adapter);}int adapter_start(struct adapter *adapter){	struct hci_dev *dev = &adapter->dev;	struct hci_dev_info di;	struct hci_version ver;	uint8_t features[8];	int dd, err;	char name[249];	if (hci_devinfo(adapter->dev_id, &di) < 0)		return -errno;	if (hci_test_bit(HCI_RAW, &di.flags)) {		dev->ignore = 1;		return -1;	}	if (bacmp(&di.bdaddr, BDADDR_ANY))		ba2str(&di.bdaddr, adapter->address);	else {		int err = device_read_bdaddr(adapter->dev_id, adapter->address);		if (err < 0)			return err;	}	memcpy(dev->features, di.features, 8);	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		err = errno;		error("Can't open adapter %s: %s (%d)",					adapter->path, strerror(err), err);		return -err;	}	if (hci_read_local_version(dd, &ver, 1000) < 0) {		err = errno;		error("Can't read version info for %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return -err;	}	dev->hci_rev = ver.hci_rev;	dev->lmp_ver = ver.lmp_ver;	dev->lmp_subver = ver.lmp_subver;	dev->manufacturer = ver.manufacturer;	if (hci_read_local_features(dd, features, 1000) < 0) {		err = errno;		error("Can't read features for %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return -err;	}	memcpy(dev->features, features, 8);	if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) {		err = errno;		error("Can't read class of adapter on %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return -err;	}	if (hci_read_local_name(dd, sizeof(name), name, 2000) < 0) {		err = errno;		error("Can't read local name on %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return -err;	}	memcpy(dev->name, name, 248);	if (!(features[6] & LMP_SIMPLE_PAIR))		goto setup;	if (ioctl(dd, HCIGETAUTHINFO, NULL) < 0 && errno != EINVAL)		hci_write_simple_pairing_mode(dd, 0x01, 2000);	if (hci_read_simple_pairing_mode(dd, &dev->ssp_mode, 1000) < 0) {		err = errno;		error("Can't read simple pairing mode on %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return -err;	}setup:	if (hci_test_bit(HCI_INQUIRY, &di.flags))		adapter->discov_active = 1;	else		adapter->discov_active = 0;	adapter_setup(adapter, dd);	adapter_up(adapter, dd);	hci_close_dev(dd);	info("Adapter %s has been enabled", adapter->path);	return 0;}static void reply_pending_requests(struct adapter *adapter){	DBusMessage *reply;	if (!adapter)		return;	/* pending bonding */	if (adapter->bonding) {		reply = new_authentication_return(adapter->bonding->msg,					HCI_OE_USER_ENDED_CONNECTION);		g_dbus_send_message(connection, reply);		remove_pending_device(adapter);		g_dbus_remove_watch(adapter->bonding->conn,					adapter->bonding->listener_id);		if (adapter->bonding->io_id)			g_source_remove(adapter->bonding->io_id);		g_io_channel_close(adapter->bonding->io);		bonding_request_free(adapter->bonding);		adapter->bonding = NULL;	}	/* If there is a pending reply for discovery cancel */	if (adapter->discovery_cancel) {		reply = dbus_message_new_method_return(adapter->discovery_cancel);		dbus_connection_send(connection, reply, NULL);		dbus_message_unref(reply);		dbus_message_unref(adapter->discovery_cancel);		adapter->discovery_cancel = NULL;	}	if (adapter->discov_active) {		/* Send discovery completed signal if there isn't name		 * to resolve */		g_dbus_emit_signal(connection, adapter->path,				ADAPTER_INTERFACE, "DiscoveryCompleted",				DBUS_TYPE_INVALID);		/* Cancel inquiry initiated by D-Bus client */		if (adapter->discov_requestor)			cancel_discovery(adapter);	}	if (adapter->pdiscov_active) {		/* Stop periodic inquiry initiated by D-Bus client */		if (adapter->pdiscov_requestor)			cancel_periodic_discovery(adapter);	}}int adapter_stop(struct adapter *adapter){	const char *mode = "off";	/* cancel pending timeout */	if (adapter->discov_timeout_id) {		g_source_remove(adapter->discov_timeout_id);		adapter->discov_timeout_id = 0;	}	/* check pending requests */	reply_pending_requests(adapter);	if (adapter->discov_requestor) {		g_dbus_remove_watch(connection, adapter->discov_listener);		adapter->discov_listener = 0;		g_free(adapter->discov_requestor);		adapter->discov_requestor = NULL;	}	if (adapter->pdiscov_requestor) {		g_dbus_remove_watch(connection, adapter->pdiscov_listener);		adapter->pdiscov_listener = 0;		g_free(adapter->pdiscov_requestor);		adapter->pdiscov_requestor = NULL;	}	if (adapter->found_devices) {		g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);		g_slist_free(adapter->found_devices);		adapter->found_devices = NULL;	}	if (adapter->oor_devices) {		g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);		g_slist_free(adapter->oor_devices);		adapter->oor_devices = NULL;	}	if (adapter->auth_reqs) {		g_slist_foreach(adapter->auth_reqs, (GFunc) g_free, NULL);		g_slist_free(adapter->auth_reqs);		adapter->auth_reqs = NULL;	}	if (adapter->active_conn) {		g_slist_foreach(adapter->active_conn, (GFunc) g_free, NULL);		g_slist_free(adapter->active_conn);		adapter->active_conn = NULL;	}	dbus_connection_emit_property_changed(connection, adapter->path,					ADAPTER_INTERFACE, "Mode",					DBUS_TYPE_STRING, &mode);	adapter->up = 0;	adapter->scan_mode = SCAN_DISABLED;	adapter->mode = MODE_OFF;	adapter->discov_active = 0;	adapter->pdiscov_active = 0;	adapter->pinq_idle = 0;	adapter->discov_type = DISCOVER_TYPE_NONE;	info("Adapter %s has been disabled", adapter->path);	return 0;}int adapter_update(struct adapter *adapter){	struct hci_dev *dev = &adapter->dev;	int dd;	if (dev->ignore)		return 0;	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		int err = errno;		error("Can't open adapter %s: %s (%d)",					adapter->path, strerror(err), err);		return -err;	}	update_ext_inquiry_response(dd, dev);	hci_close_dev(dd);	return 0;}int adapter_get_class(struct adapter *adapter, uint8_t *cls){	struct hci_dev *dev = &adapter->dev;	memcpy(cls, dev->class, 3);	return 0;}int adapter_set_class(struct adapter *adapter, uint8_t *cls){	struct hci_dev *dev = &adapter->dev;	memcpy(dev->class, cls, 3);	return 0;}int adapter_update_ssp_mode(struct adapter *adapter, int dd, uint8_t mode){	struct hci_dev *dev = &adapter->dev;	dev->ssp_mode = mode;	update_ext_inquiry_response(dd, dev);	hci_close_dev(dd);	return 0;}static void adapter_free(gpointer user_data){	struct adapter *adapter = user_data;	g_free(adapter->path);	g_free(adapter);	return;}struct adapter *adapter_create(DBusConnection *conn, int id){	char path[MAX_PATH_LENGTH];	struct adapter *adapter;	if (!connection)		connection = conn;	snprintf(path, sizeof(path), "%s/hci%d", "/org/bluez", id);	adapter = g_try_new0(struct adapter, 1);	if (!adapter) {		error("Failed to alloc memory to D-Bus path register data (%s)",				path);		return NULL;	}	adapter->dev_id = id;	adapter->pdiscov_resolve_names = 1;	adapter->path = g_strdup(path);	if (!g_dbus_register_interface(conn, path, ADAPTER_INTERFACE,			adapter_methods, adapter_signals, NULL,			adapter, adapter_free)) {		error("Adapter interface init failed on path %s", path);		adapter_free(adapter);		return NULL;	}	return adapter;}void adapter_remove(struct adapter *adapter){	GSList *l;	char *path = g_strdup(adapter->path);	debug("Removing adapter %s", path);	for (l = adapter->devices; l; l = l->next)		device_remove(connection, l->data);	g_slist_free(adapter->devices);	g_dbus_unregister_interface(connection, path, ADAPTER_INTERFACE);	g_free(path);}uint16_t adapter_get_dev_id(struct adapter *adapter){	return adapter->dev_id;}const gchar *adapter_get_path(struct adapter *adapter){	if (!adapter)		return NULL;	return adapter->path;}const gchar *adapter_get_address(struct adapter *adapter){	if (!adapter)		return NULL;	return adapter->address;}gboolean discov_timeout_handler(void *data){	struct adapter *adapter = data;	struct hci_request rq;	int dd;	uint8_t scan_enable = adapter->scan_mode;	uint8_t status = 0;	gboolean retval = TRUE;	uint16_t dev_id = adapter->dev_id;	scan_enable &= ~SCAN_INQUIRY;	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("HCI device open failed: hci%d", dev_id);		return TRUE;	}	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_HOST_CTL;	rq.ocf    = OCF_WRITE_SCAN_ENABLE;	rq.cparam = &scan_enable;	rq.clen   = sizeof(scan_enable);	rq.rparam = &status;	rq.rlen   = sizeof(status);	rq.event  = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, 1000) < 0) {		error("Sending write scan enable command to hci%d failed: %s (%d)",				dev_id, strerror(errno), errno);		goto failed;	}	if (status) {		error("Setting scan enable failed with status 0x%02x", status);		goto failed;	}	set_limited_discoverable(dd, adapter->dev.class, FALSE);	adapter_remove_discov_timeout(adapter);	retval = FALSE;failed:	if (dd >= 0)		hci_close_dev(dd);	return retval;}void adapter_set_discov_timeout(struct adapter *adapter, guint interval){	if (!adapter)		return;	if (adapter->discov_timeout_id) {		error("Timeout already added for adapter %s", adapter->path);		return;	}	adapter->discov_timeout_id = g_timeout_add(interval, discov_timeout_handler, adapter);}void adapter_remove_discov_timeout(struct adapter *adapter){	if (!adapter)		return;	if(adapter->discov_timeout_id == 0)		return;	g_source_remove(adapter->discov_timeout_id);	adapter->discov_timeout_id = 0;}void adapter_set_scan_mode(struct adapter *adapter, uint8_t scan_mode){	if (!adapter)		return;	adapter->scan_mode = scan_mode;}uint8_t adapter_get_scan_mode(struct adapter *adapter){	return adapter->scan_mode;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -