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

📄 adapter.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	reply = dbus_message_new_method_return(msg);	if (!reply)		return NULL;	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,				DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter);	for (l = adapter->devices; l; l = l->next) {		struct btd_device *device = l->data;		if (device_is_temporary(device))			continue;		dev_path = device_get_path(device);		dbus_message_iter_append_basic(&array_iter,				DBUS_TYPE_OBJECT_PATH, &dev_path);	}	dbus_message_iter_close_container(&iter, &array_iter);	return reply;}static DBusMessage *create_device(DBusConnection *conn,					DBusMessage *msg, void *data){	struct adapter *adapter = data;	struct btd_device *device;	const gchar *address;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	if (check_address(address) < 0)		return invalid_args(msg);	if (adapter_find_device(adapter, address))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".AlreadyExists",				"Device already exists");	debug("create_device(%s)", address);	device = device_create(conn, adapter, address);	if (!device)		return NULL;	device_set_temporary(device, FALSE);	device_browse(device, conn, msg, NULL);	adapter->devices = g_slist_append(adapter->devices, device);	return NULL;}static uint8_t parse_io_capability(const char *capability){	if (g_str_equal(capability, ""))		return IO_CAPABILITY_DISPLAYYESNO;	if (g_str_equal(capability, "DisplayOnly"))		return IO_CAPABILITY_DISPLAYONLY;	if (g_str_equal(capability, "DisplayYesNo"))		return IO_CAPABILITY_DISPLAYYESNO;	if (g_str_equal(capability, "KeyboardOnly"))		return IO_CAPABILITY_KEYBOARDONLY;	if (g_str_equal(capability, "NoInputOutput"))		return IO_CAPABILITY_NOINPUTOUTPUT;	return IO_CAPABILITY_INVALID;}static DBusMessage *create_paired_device(DBusConnection *conn,					DBusMessage *msg, void *data){	const gchar *address, *agent_path, *capability;	uint8_t cap;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,					DBUS_TYPE_OBJECT_PATH, &agent_path,					DBUS_TYPE_STRING, &capability,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	if (check_address(address) < 0)		return invalid_args(msg);	cap = parse_io_capability(capability);	if (cap == IO_CAPABILITY_INVALID)		return invalid_args(msg);	return create_bonding(conn, msg, address, agent_path, cap, data);}static gint device_path_cmp(struct btd_device *device, const gchar *path){	const gchar *dev_path = device_get_path(device);	return strcasecmp(dev_path, path);}static DBusMessage *remove_device(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	struct btd_device *device;	const char *path;	GSList *l;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	l = g_slist_find_custom(adapter->devices,			path, (GCompareFunc) device_path_cmp);	if (!l)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device does not exist");	device = l->data;	if (device_is_temporary(device) || device_is_busy(device))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device creation in progress");	adapter_remove_device(conn, adapter, device);	return dbus_message_new_method_return(msg);}static DBusMessage *find_device(DBusConnection *conn,					DBusMessage *msg, void *data){	struct adapter *adapter = data;	struct btd_device *device;	DBusMessage *reply;	const gchar *address;	GSList *l;	const gchar *dev_path;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,						DBUS_TYPE_INVALID))		return invalid_args(msg);	l = g_slist_find_custom(adapter->devices,			address, (GCompareFunc) device_address_cmp);	if (!l)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device does not exist");	device = l->data;	if (device_is_temporary(device))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device creation in progress");	reply = dbus_message_new_method_return(msg);	if (!reply)		return NULL;	dev_path = device_get_path(device);	dbus_message_append_args(reply,				DBUS_TYPE_OBJECT_PATH, &dev_path,				DBUS_TYPE_INVALID);	return reply;}static void agent_removed(struct agent *agent, struct adapter *adapter){	struct pending_auth_info *auth;	GSList *l;	adapter->agent = NULL;	l = g_slist_find_custom(adapter->auth_reqs, agent,					auth_info_agent_cmp);	if (!l)		return;	auth = l->data;	auth->agent = NULL;}static DBusMessage *register_agent(DBusConnection *conn,					DBusMessage *msg, void *data){	const char *path, *name, *capability;	struct agent *agent;	struct adapter *adapter = data;	uint8_t cap;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,			DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID))		return NULL;	if (adapter->agent)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".AlreadyExists",				"Agent already exists");	cap = parse_io_capability(capability);	if (cap == IO_CAPABILITY_INVALID)		return invalid_args(msg);	name = dbus_message_get_sender(msg);	agent = agent_create(adapter, name, path, cap,				(agent_remove_cb) agent_removed, adapter);	if (!agent)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".Failed",				"Failed to create a new agent");	adapter->agent = agent;	debug("Agent registered for hci%d at %s:%s", adapter->dev_id, name,			path);	return dbus_message_new_method_return(msg);}static DBusMessage *unregister_agent(DBusConnection *conn,					DBusMessage *msg, void *data){	const char *path, *name;	struct adapter *adapter = data;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,						DBUS_TYPE_INVALID))		return NULL;	name = dbus_message_get_sender(msg);	if (!adapter->agent || !agent_matches(adapter->agent, name, path))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"No such agent");	agent_destroy(adapter->agent, FALSE);	adapter->agent = NULL;	return dbus_message_new_method_return(msg);}static DBusMessage *add_service_record(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	const char *sender, *record;	dbus_uint32_t handle;	bdaddr_t src;	int err;	if (dbus_message_get_args(msg, NULL,			DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)		return NULL;	sender = dbus_message_get_sender(msg);	str2ba(adapter->address, &src);	err = add_xml_record(conn, sender, &src, record, &handle);	if (err < 0)		return failed_strerror(msg, err);	reply = dbus_message_new_method_return(msg);	if (!reply)		return NULL;	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle,							DBUS_TYPE_INVALID);	return reply;}static DBusMessage *update_service_record(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	bdaddr_t src;	str2ba(adapter->address, &src);	return update_xml_record(conn, msg, &src);}static DBusMessage *remove_service_record(DBusConnection *conn,						DBusMessage *msg, void *data){	dbus_uint32_t handle;	const char *sender;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,						DBUS_TYPE_INVALID) == FALSE)		return NULL;	sender = dbus_message_get_sender(msg);	if (remove_record(conn, sender, handle) < 0)		return not_available(msg);	return dbus_message_new_method_return(msg);}static DBusMessage *request_authorization(DBusConnection *conn,						DBusMessage *msg, void *data){	/* FIXME implement the request */	return NULL;}static DBusMessage *cancel_authorization(DBusConnection *conn,						DBusMessage *msg, void *data){	/* FIXME implement cancel request */	return dbus_message_new_method_return(msg);}/* BlueZ 4.0 API */static GDBusMethodTable adapter_methods[] = {	{ "GetProperties",	"",	"a{sv}",get_properties		},	{ "SetProperty",	"sv",	"",	set_property,						G_DBUS_METHOD_FLAG_ASYNC},	{ "RequestMode",	"s",	"",	request_mode,						G_DBUS_METHOD_FLAG_ASYNC},	{ "ReleaseMode",	"",	"",	release_mode		},	{ "DiscoverDevices",	"",	"",	adapter_discover_devices},	{ "CancelDiscovery",	"",	"",	adapter_cancel_discovery,						G_DBUS_METHOD_FLAG_ASYNC},	{ "ListDevices",	"",	"ao",	list_devices		},	{ "CreateDevice",	"s",	"o",	create_device,						G_DBUS_METHOD_FLAG_ASYNC},	{ "CreatePairedDevice",	"sos",	"o",	create_paired_device,						G_DBUS_METHOD_FLAG_ASYNC},	{ "RemoveDevice",	"o",	"",	remove_device		},	{ "FindDevice",		"s",	"o",	find_device		},	{ "RegisterAgent",	"os",	"",	register_agent		},	{ "UnregisterAgent",	"o",	"",	unregister_agent	},	{ "AddServiceRecord",	"s",	"u",	add_service_record	},	{ "UpdateServiceRecord","us",	"",	update_service_record	},	{ "RemoveServiceRecord","u",	"",	remove_service_record	},	{ "RequestAuthorization","su",	"",	request_authorization,						G_DBUS_METHOD_FLAG_ASYNC},	{ "CancelAuthorization","",	"",	cancel_authorization	},	{ }};static GDBusSignalTable adapter_signals[] = {	{ "DiscoveryStarted",		""		},	{ "DiscoveryCompleted",		""		},	{ "DeviceCreated",		"o"		},	{ "DeviceRemoved",		"o"		},	{ "DeviceFound",		"sa{sv}"	},	{ "PropertyChanged",		"sv"		},	{ "DeviceDisappeared",		"s"		},	{ }};static inline uint8_t get_inquiry_mode(struct hci_dev *dev){	if (dev->features[6] & LMP_EXT_INQ)		return 2;	if (dev->features[3] & LMP_RSSI_INQ)		return 1;	if (dev->manufacturer == 11 &&			dev->hci_rev == 0x00 && dev->lmp_subver == 0x0757)		return 1;	if (dev->manufacturer == 15) {		if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963)			return 1;		if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963)			return 1;		if (dev->hci_rev == 0x00 && dev->lmp_subver == 0x6965)			return 1;	}	if (dev->manufacturer == 31 &&			dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805)		return 1;	return 0;}static int device_read_bdaddr(uint16_t dev_id, const char *address){	int dd, err;	bdaddr_t bdaddr;	dd = hci_open_dev(dev_id);	if (dd < 0) {		err = errno;		error("Can't open device hci%d: %s (%d)",					dev_id, strerror(err), err);		return -err;	}	str2ba(address, &bdaddr);	if (hci_read_bd_addr(dd, &bdaddr, 2000) < 0) {		err = errno;		error("Can't read address for hci%d: %s (%d)",					dev_id, strerror(err), err);		hci_close_dev(dd);		return -err;	}	hci_close_dev(dd);	return 0;}static int adapter_setup(struct adapter *adapter, int dd){	struct hci_dev *dev = &adapter->dev;	uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 };	uint8_t inqmode;	bdaddr_t bdaddr;	int err;	char name[249];	if (dev->hci_rev > 1) {		if (dev->features[5] & LMP_SNIFF_SUBR)			events[5] |= 0x20;		if (dev->features[5] & LMP_PAUSE_ENC)			events[5] |= 0x80;		if (dev->features[6] & LMP_EXT_INQ)			events[5] |= 0x40;		if (dev->features[6] & LMP_NFLUSH_PKTS)			events[7] |= 0x01;		if (dev->features[7] & LMP_LSTO)			events[6] |= 0x80;		if (dev->features[6] & LMP_SIMPLE_PAIR) {			events[6] |= 0x01;	/* IO Capability Request */			events[6] |= 0x02;	/* IO Capability Response */			events[6] |= 0x04;	/* User Confirmation Request */			events[6] |= 0x08;	/* User Passkey Request */			events[6] |= 0x10;	/* Remote OOB Data Request */			events[6] |= 0x20;	/* Simple Pairing Complete */			events[7] |= 0x04;	/* User Passkey Notification */			events[7] |= 0x08;	/* Keypress Notification */			events[7] |= 0x10;	/* Remote Host Supported Features Notification */		}		hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK,						sizeof(events), events);	}	str2ba(adapter->address, &bdaddr);	if (read_local_name(&bdaddr, name) == 0) {		memcpy(dev->name, name, 248);		hci_write_local_name(dd, name, 5000);        }	update_ext_inquiry_response(dd, dev);	inqmode = get_inquiry_mode(dev);	if (inqmode < 1)		return 0;	if (hci_write_inquiry_mode(dd, inqmode, 2000) < 0) {		err = errno;		error("Can't write inquiry mode for %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return -err;	}	return 0;}static int active_conn_append(GSList **list, bdaddr_t *bdaddr,				uint16_t handle){	struct active_conn_info *dev;	dev = g_new0(struct active_conn_info, 1);	bacpy(&dev->bdaddr, bdaddr);	dev->handle = handle;	*list = g_slist_append(*list, dev);	return 0;}static void create_stored_records_from_keys(char *key, char *value,						void *user_data){	struct record_list *rec_list = user_data;	const gchar *addr = rec_list->addr;	sdp_record_t *rec;	int size, i, len;	uint8_t *pdata;	char tmp[3] = "";	if (strstr(key, addr) == NULL)		return;	size = strlen(value)/2;	pdata = g_malloc0(size);	for (i = 0; i < size; i++) {		 memcpy(tmp, value + (i * 2), 2);		 pdata[i] = (uint8_t) strtol(tmp, NULL, 16);	}	rec = sdp_extract_pdu(pdata, size, &len);	free(pdata);	rec_list->recs = sdp_list_append(rec_list->recs, rec);}static void create_stored_device_from_profiles(char *key, char *value,						void *user_data){	char filename[PATH_MAX + 1];	struct adapter *adapter = user_data;	GSList *uuids = bt_string2list(value);	struct btd_device *device;	const gchar *src;	struct record_list rec_list;	if (g_slist_find_custom(adapter->devices,				key, (GCompareFunc) device_address_cmp))		return;	device = device_create(connection, adapter, key);	if (!device)		return;

⌨️ 快捷键说明

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