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

📄 device.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct btd_adapter *adapter = device_get_adapter(device);	sdp_list_t *seq;	char srcaddr[18], dstaddr[18];	bdaddr_t src;	adapter_get_address(adapter, &src);	ba2str(&src, srcaddr);	ba2str(&device->bdaddr, dstaddr);	for (seq = recs; seq; seq = seq->next) {		sdp_record_t *rec = (sdp_record_t *) seq->data;		sdp_list_t *svcclass = NULL;		gchar *profile_uuid;		GSList *l;		if (!rec)			break;		if (sdp_get_service_classes(rec, &svcclass) < 0)			continue;		/* Extract the first element and skip the remainning */		profile_uuid = bt_uuid2string(svcclass->data);		if (!profile_uuid) {			sdp_list_free(svcclass, free);			continue;		}		if (!strcasecmp(profile_uuid, PNP_UUID)) {			uint16_t source, vendor, product, version;			sdp_data_t *pdlist;			pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);			source = pdlist ? pdlist->val.uint16 : 0x0000;			pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);			vendor = pdlist ? pdlist->val.uint16 : 0x0000;			pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);			product = pdlist ? pdlist->val.uint16 : 0x0000;			pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);			version = pdlist ? pdlist->val.uint16 : 0x0000;			if (source || vendor || product || version)				store_device_id(srcaddr, dstaddr, source,						vendor, product, version);		}		/* Check for duplicates */		if (sdp_list_find(req->records, rec, rec_cmp)) {			g_free(profile_uuid);			sdp_list_free(svcclass, free);			continue;		}		store_record(srcaddr, dstaddr, rec);		/* Copy record */		req->records = sdp_list_append(req->records, sdp_copy_record(rec));		l = g_slist_find_custom(device->uuids, profile_uuid,							(GCompareFunc) strcmp);		if (!l)			req->profiles_added =					g_slist_append(req->profiles_added,							profile_uuid);		else {			req->profiles_removed =					g_slist_remove(req->profiles_removed,							l->data);			g_free(profile_uuid);		}		sdp_list_free(svcclass, free);	}}static void store_profiles(struct btd_device *device){	struct btd_adapter *adapter = device->adapter;	bdaddr_t src;	char *str;	adapter_get_address(adapter, &src);	if (!device->uuids) {		write_device_profiles(&src, &device->bdaddr, "");		return;	}	str = bt_list2string(device->uuids);	write_device_profiles(&src, &device->bdaddr, str);	g_free(str);}static void browse_req_free(struct browse_req *req){	struct btd_device *device = req->device;	device->discov_active = 0;	if (device->discov_requestor) {		g_dbus_remove_watch(req->conn, device->discov_listener);		device->discov_listener = 0;		g_free(device->discov_requestor);		device->discov_requestor = NULL;	}	if (req->msg)		dbus_message_unref(req->msg);	if (req->conn)		dbus_connection_unref(req->conn);	g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL);	g_slist_free(req->profiles_added);	g_slist_free(req->profiles_removed);	if (req->records)		sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);	g_free(req);}static void search_cb(sdp_list_t *recs, int err, gpointer user_data){	struct browse_req *req = user_data;	struct btd_device *device = req->device;	DBusMessage *reply;	if (err < 0) {		error("%s: error updating services: %s (%d)",				device->path, strerror(-err), -err);		goto proceed;	}	update_services(req, recs);	if (!req->profiles_added && !req->profiles_removed) {		debug("%s: No service update", device->path);		goto proceed;	}	if (device->tmp_records && req->records) {		sdp_list_free(device->tmp_records, (sdp_free_func_t) sdp_record_free);		device->tmp_records = req->records;		req->records = NULL;	}	/* Probe matching drivers for services added */	if (req->profiles_added)		device_probe_drivers(device, req->profiles_added);	/* Remove drivers for services removed */	if (req->profiles_removed)		device_remove_drivers(device, req->profiles_removed);	/* Propagate services changes */	services_changed(req->device);proceed:	/* Store the device's profiles in the filesystem */	store_profiles(device);	if (!req->msg)		goto cleanup;	if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,					"DiscoverServices")) {		discover_device_reply(req, req->records);		goto cleanup;	}	/* Reply create device request */	reply = dbus_message_new_method_return(req->msg);	if (!reply)		goto cleanup;	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,							DBUS_TYPE_INVALID);	g_dbus_send_message(req->conn, reply);cleanup:	browse_req_free(req);}static void browse_cb(sdp_list_t *recs, int err, gpointer user_data){	struct browse_req *req = user_data;	struct btd_device *device = req->device;	struct btd_adapter *adapter = device->adapter;	bdaddr_t src;	uuid_t uuid;	/* If we have a valid response and req->search_uuid == 2, then	   L2CAP UUID & PNP searching was successful -- we are done */	if (err < 0 || (req->search_uuid == 2 && req->records))		goto done;	update_services(req, recs);	adapter_get_address(adapter, &src);	/* Search for mandatory uuids */	if (uuid_list[req->search_uuid]) {		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);		bt_search_service(&src, &device->bdaddr, &uuid,						browse_cb, user_data, NULL);		return;	}done:	search_cb(recs, err, user_data);}static void init_browse(struct browse_req *req, gboolean reverse){	GSList *l;	/* If we are doing reverse-SDP don't try to detect removed profiles	 * since some devices hide their service records while they are	 * connected	 */	if (reverse)		return;	for (l = req->device->uuids; l; l = l->next)		req->profiles_removed = g_slist_append(req->profiles_removed,						l->data);}int device_browse(struct btd_device *device, DBusConnection *conn,			DBusMessage *msg, uuid_t *search, gboolean reverse){	struct btd_adapter *adapter = device->adapter;	struct browse_req *req;	bdaddr_t src;	uuid_t uuid;	bt_callback_t cb;	int err;	if (device->discov_active)		return -EBUSY;	adapter_get_address(adapter, &src);	req = g_new0(struct browse_req, 1);	req->conn = conn ? dbus_connection_ref(conn) : get_dbus_connection();	req->device = device;	if (search) {		memcpy(&uuid, search, sizeof(uuid_t));		cb = search_cb;	} else {		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);		init_browse(req, reverse);		cb = browse_cb;	}	device->discov_active = 1;	if (msg) {		req->msg = dbus_message_ref(msg);		device->discov_requestor = g_strdup(dbus_message_get_sender(msg));		/* Track the request owner to cancel it		 * automatically if the owner exits */		device->discov_listener = g_dbus_add_disconnect_watch(conn,						dbus_message_get_sender(msg),						discover_services_req_exit,						device, NULL);	}	err = bt_search_service(&src, &device->bdaddr,				&uuid, cb, req, NULL);	if (err < 0)		browse_req_free(req);	return err;}struct btd_adapter *device_get_adapter(struct btd_device *device){	if (!device)		return NULL;	return device->adapter;}void device_get_address(struct btd_device *device, bdaddr_t *bdaddr){	bacpy(bdaddr, &device->bdaddr);}const gchar *device_get_path(struct btd_device *device){	if (!device)		return NULL;	return device->path;}struct agent *device_get_agent(struct btd_device *device){	if (!device)		return NULL;	return  device->agent;}void device_set_agent(struct btd_device *device, struct agent *agent){	if (!device)		return;	device->agent = agent;}gboolean device_is_busy(struct btd_device *device){	return device->discov_active ? TRUE : FALSE;}gboolean device_is_temporary(struct btd_device *device){	return device->temporary;}void device_set_temporary(struct btd_device *device, gboolean temporary){	if (!device)		return;	device->temporary = temporary;}void device_set_cap(struct btd_device *device, uint8_t cap){	if (!device)		return;	device->cap = cap;}void device_set_auth(struct btd_device *device, uint8_t auth){	if (!device)		return;	device->auth = auth;}uint8_t device_get_auth(struct btd_device *device){	return device->auth;}static gboolean start_discovery(gpointer user_data){	struct btd_device *device = user_data;	device_browse(device, NULL, NULL, NULL, TRUE);	device->discov_timer = 0;	return FALSE;}int device_set_paired(DBusConnection *conn, struct btd_device *device,			struct bonding_request_info *bonding){	dbus_bool_t paired = TRUE;	device_set_temporary(device, FALSE);	emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired",				DBUS_TYPE_BOOLEAN, &paired);	/* If we were initiators start service discovery immediately.	 * However if the other end was the initator wait a few seconds	 * before SDP. This is due to potential IOP issues if the other	 * end starts doing SDP at the same time as us */	if (bonding) {		/* If we are initiators remove any discovery timer and just		 * start discovering services directly */		if (device->discov_timer) {			g_source_remove(device->discov_timer);			device->discov_timer = 0;		}		return device_browse(device, bonding->conn, bonding->msg,					NULL, FALSE);	}	/* If we are not initiators and there is no currently active discovery	 * or discovery timer, set the discovery timer */	if (!device->discov_active && !device->discov_timer)		device->discov_timer = g_timeout_add_seconds(DISCOVERY_TIMER,							start_discovery,							device);	return 0;}void btd_device_add_uuid(struct btd_device *device, const char *uuid){	GSList *uuid_list;	char *new_uuid;	if (g_slist_find_custom(device->uuids, uuid,				(GCompareFunc) strcasecmp))		return;	new_uuid = g_strdup(uuid);	uuid_list = g_slist_append(NULL, new_uuid);	device_probe_drivers(device, uuid_list);	g_free(new_uuid);	g_slist_free(uuid_list);	store_profiles(device);	services_changed(device);}const sdp_record_t *btd_device_get_record(struct btd_device *device,						const char *uuid){	bdaddr_t src;	if (device->tmp_records)		return find_record_in_list(device->tmp_records, uuid);	adapter_get_address(device->adapter, &src);	device->tmp_records = read_records(&src, &device->bdaddr);	if (!device->tmp_records)		return NULL;	return find_record_in_list(device->tmp_records, uuid);}int btd_register_device_driver(struct btd_device_driver *driver){	device_drivers = g_slist_append(device_drivers, driver);	return 0;}void btd_unregister_device_driver(struct btd_device_driver *driver){	device_drivers = g_slist_remove(device_drivers, driver);}

⌨️ 快捷键说明

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