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

📄 dbus-sdp.c

📁 实现bluez蓝牙profile需要的库
💻 C
📖 第 1 页 / 共 3 页
字号:
	c = pending_connect_new(conn, msg, dst, cb);	if (!c) {		if (err)			*err = ENOMEM;		return NULL;	}	hci_devba(dev_id, &srcba);	str2ba(dst, &dstba);	c->session = get_sdp_session(&srcba, &dstba);	if (!c->session) {		if (err)			*err = errno;		error("sdp_connect() failed: %s (%d)", strerror(errno), errno);		pending_connect_free(c);		return NULL;	}	chan = g_io_channel_unix_new(sdp_get_socket(c->session));	g_io_add_watch(chan, G_IO_OUT, sdp_client_connect_cb, c);	g_io_channel_unref(chan);	pending_connects = g_slist_append(pending_connects, c);	return c;}static int remote_svc_rec_conn_cb(struct transaction_context *ctxt){	sdp_list_t *attrids;	uint32_t range = 0x0000ffff;	const char *dst;	uint32_t handle;	if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_cb, ctxt) < 0)		return -EINVAL;	dbus_message_get_args(ctxt->rq, NULL,			DBUS_TYPE_STRING, &dst,			DBUS_TYPE_UINT32, &handle,			DBUS_TYPE_INVALID);	attrids = sdp_list_append(NULL, &range);	/*	 * Create/send the search request and set the	 * callback to indicate the request completion	 */	if (sdp_service_attr_async(ctxt->session, handle,				SDP_ATTR_REQ_RANGE, attrids) < 0) {		sdp_list_free(attrids, NULL);		return -sdp_get_error(ctxt->session);	}	sdp_list_free(attrids, NULL);	return 0;}static int remote_svc_rec_conn_xml_cb(struct transaction_context *ctxt){	sdp_list_t *attrids;	uint32_t range = 0x0000ffff;	const char *dst;	uint32_t handle;	if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_xml_cb, ctxt) < 0)		return -EINVAL;	dbus_message_get_args(ctxt->rq, NULL,			DBUS_TYPE_STRING, &dst,			DBUS_TYPE_UINT32, &handle,			DBUS_TYPE_INVALID);	attrids = sdp_list_append(NULL, &range);	/* 	 * Create/send the search request and set the	 * callback to indicate the request completion	 */	if (sdp_service_attr_async(ctxt->session, handle,				SDP_ATTR_REQ_RANGE, attrids) < 0) {		sdp_list_free(attrids, NULL);		return -sdp_get_error(ctxt->session);	}	sdp_list_free(attrids, NULL);	return 0;}DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg,				void *data, sdp_format_t format){	struct adapter *adapter = data;	const char *dst;	uint32_t handle;	int err;	connect_cb_t *cb;	if (!adapter->up)		return error_not_ready(conn, msg);	if (!dbus_message_get_args(msg, NULL,			DBUS_TYPE_STRING, &dst,			DBUS_TYPE_UINT32, &handle,			DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg);	if (find_pending_connect(dst))		return error_service_search_in_progress(conn, msg);	cb = remote_svc_rec_conn_cb;	if (format == SDP_FORMAT_XML)		cb = remote_svc_rec_conn_xml_cb;	if (!connect_request(conn, msg, adapter->dev_id,				dst, cb, &err)) {		error("Search request failed: %s (%d)", strerror(err), err);		return error_failed(conn, msg, err);	}	return DBUS_HANDLER_RESULT_HANDLED;}static int remote_svc_handles_conn_cb(struct transaction_context *ctxt){	sdp_list_t *search = NULL;	const char *dst, *svc;	if (sdp_set_notify(ctxt->session, remote_svc_handles_completed_cb, ctxt) < 0)		return -EINVAL;	dbus_message_get_args(ctxt->rq, NULL,			DBUS_TYPE_STRING, &dst,			DBUS_TYPE_STRING, &svc,			DBUS_TYPE_INVALID);	if (strlen(svc) > 0)		str2uuid(&ctxt->uuid, svc);	else		sdp_uuid16_create(&ctxt->uuid, PUBLIC_BROWSE_GROUP);	search = sdp_list_append(0, &ctxt->uuid);	/* Create/send the search request and set the callback to indicate the request completion */	if (sdp_service_search_async(ctxt->session, search, 64) < 0) {		error("send request failed: %s (%d)", strerror(errno), errno);		sdp_list_free(search, NULL);		return -sdp_get_error(ctxt->session);	}	sdp_list_free(search, NULL);	return 0;}static int remote_svc_identifiers_conn_cb(struct transaction_context *ctxt){	if (sdp_set_notify(ctxt->session,			remote_svc_identifiers_completed_cb, ctxt) < 0)		return -EINVAL;	return service_search_attr(ctxt, PUBLIC_BROWSE_GROUP);}DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg, void *data){	struct adapter *adapter = data;	const char *dst, *svc;	int err;	uuid_t uuid;	if (!adapter->up)		return error_not_ready(conn, msg);	if (!dbus_message_get_args(msg, NULL,			DBUS_TYPE_STRING, &dst,			DBUS_TYPE_STRING, &svc,			DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg);	if (strlen(svc) > 0) {		/* Check if it is a service name string */		if (str2uuid(&uuid, svc) < 0) {			error("Invalid service class name");			return error_invalid_arguments(conn, msg);		}	}	if (find_pending_connect(dst))		return error_service_search_in_progress(conn, msg);	if (!connect_request(conn, msg, adapter->dev_id,				dst, remote_svc_handles_conn_cb, &err)) {		error("Search request failed: %s (%d)", strerror(err), err);		return error_failed(conn, msg, err);	}	return DBUS_HANDLER_RESULT_HANDLED;}DBusHandlerResult get_remote_svc_identifiers(DBusConnection *conn, DBusMessage *msg, void *data){	struct adapter *adapter = data;	const char *dst;	int err;	if (!adapter->up)		return error_not_ready(conn, msg);	if (!dbus_message_get_args(msg, NULL,			DBUS_TYPE_STRING, &dst,			DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg);	if (find_pending_connect(dst))		return error_service_search_in_progress(conn, msg);	if (!connect_request(conn, msg, adapter->dev_id,				dst, remote_svc_identifiers_conn_cb, &err)) {		error("Search request failed: %s (%d)", strerror(err), err);		return error_failed(conn, msg, err);	}	return DBUS_HANDLER_RESULT_HANDLED;}DBusHandlerResult finish_remote_svc_transact(DBusConnection *conn,						DBusMessage *msg, void *data){	struct cached_session *s;	const char *address;	struct adapter *adapter = data;	DBusMessage *reply;	bdaddr_t sba, dba;	if (!dbus_message_get_args(msg, NULL,			DBUS_TYPE_STRING, &address,			DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	str2ba(adapter->address, &sba);	str2ba(address, &dba);	while ((s = get_cached_session(&sba, &dba))) {		sdp_close(s->session);		g_source_remove(s->timeout_id);		g_source_remove(s->io_id);		g_free(s);	}	return send_message_and_unref(conn, reply);}/* * Internal async get remote service record implementation */static void get_rec_with_handle_comp_cb(uint8_t type, uint16_t err,					uint8_t *rsp, size_t size, void *udata){	struct transaction_context *ctxt = udata;	int scanned, cb_err = 0;	sdp_record_t *rec = NULL;	if (err == 0xffff) {		int sdp_err = sdp_get_error(ctxt->session);		if (sdp_err < 0) {			error("search failed: Invalid session!");			cb_err = EINVAL;			goto failed;		}		error("search failed :%s (%d)", strerror(sdp_err), sdp_err);		cb_err = sdp_err;		goto failed;	}	if (type == SDP_ERROR_RSP || type != SDP_SVC_ATTR_RSP) {		error("SDP error: %s(%d)", strerror(EPROTO), EPROTO);		cb_err = EPROTO;		goto failed;	}	rec = sdp_extract_pdu(rsp, &scanned);	if (!rec) {		error("Service record is NULL");		cb_err = EPROTO;		goto failed;	}failed:	get_record_data_call_cb(ctxt->call, rec, cb_err);	if (rec)		sdp_record_free(rec);	get_record_data_free(ctxt->call);	transaction_context_free(ctxt, TRUE);}static int get_rec_with_handle_conn_cb(struct transaction_context *ctxt){	uint32_t range = 0x0000ffff;	sdp_list_t *attrids;	uint32_t handle;	if (sdp_set_notify(ctxt->session,				get_rec_with_handle_comp_cb, ctxt) < 0) {		error("Invalid session data!");		return -EINVAL;	}	handle = *((uint32_t *)ctxt->call->search_data);	attrids = sdp_list_append(NULL, &range);	if (sdp_service_attr_async(ctxt->session, handle,					SDP_ATTR_REQ_RANGE, attrids) < 0) {		error("send request failed: %s (%d)", strerror(errno), errno);		sdp_list_free(attrids, NULL);		return -errno;	}	sdp_list_free(attrids, NULL);	return 0;}int get_record_with_handle(DBusConnection *conn, DBusMessage *msg,			uint16_t dev_id, const char *dst,			uint32_t handle, get_record_cb_t *cb, void *data){	struct pending_connect *c;	get_record_data_t *d;	uint32_t *rec_handle;	int err;	if (find_pending_connect(dst)) {		error("SDP search in progress!");		return -EINPROGRESS;	}	rec_handle = g_new(uint32_t, 1);	*rec_handle = handle;	d = get_record_data_new(dev_id, dst, rec_handle, cb, data);	if (!(c = connect_request(conn, msg, dev_id, dst,				get_rec_with_handle_conn_cb, &err))) {		error("Search request failed: %s (%d)", strerror(err), err);		get_record_data_free(d);		return -err;	}	c->call = d;	return 0;}static void get_rec_with_uuid_comp_cb(uint8_t type, uint16_t err,					uint8_t *rsp, size_t size, void *udata){	struct transaction_context *ctxt = udata;	get_record_data_t *d = ctxt->call;	int csrc, tsrc, cb_err = 0;	uint32_t *handle;	uint8_t *pdata;	if (err == 0xffff) {		int sdp_err = sdp_get_error(ctxt->session);		if (sdp_err < 0) {			error("search failed: Invalid session!");			cb_err = EINVAL;			goto failed;		}		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);		cb_err = sdp_err;		goto failed;	}	if (type == SDP_ERROR_RSP || type != SDP_SVC_SEARCH_RSP) {		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);		cb_err = EPROTO;		goto failed;	}	pdata = rsp;	tsrc = ntohs(bt_get_unaligned((uint16_t *) pdata));	if (tsrc <= 0)		goto failed;	pdata += sizeof(uint16_t);	csrc = ntohs(bt_get_unaligned((uint16_t *) pdata));	if (csrc <= 0)		goto failed;	pdata += sizeof(uint16_t);	handle = g_new(uint32_t, 1);	*handle = ntohl(bt_get_unaligned((uint32_t*) pdata));	g_free(d->search_data);	d->search_data = handle;	cb_err = get_rec_with_handle_conn_cb(ctxt);	if (cb_err)		goto failed;	return;failed:	get_record_data_call_cb(d, NULL, cb_err);	get_record_data_free(d);	transaction_context_free(ctxt, TRUE);}static int get_rec_with_uuid_conn_cb(struct transaction_context *ctxt){	get_record_data_t *d = ctxt->call;	sdp_list_t *search = NULL;	uuid_t *uuid;	int err = 0;	if (sdp_set_notify(ctxt->session,			get_rec_with_uuid_comp_cb, ctxt) < 0) {		err = -EINVAL;		goto failed;	}	uuid = (uuid_t *)d->search_data;	search = sdp_list_append(NULL, uuid);	if (sdp_service_search_async(ctxt->session, search, 1) < 0) {		error("send request failed: %s (%d)", strerror(errno), errno);		err = -sdp_get_error(ctxt->session);		goto failed;	}failed:	if (search)		sdp_list_free(search, NULL);	return err;}int get_record_with_uuid(DBusConnection *conn, DBusMessage *msg,			uint16_t dev_id, const char *dst,			const uuid_t *uuid, get_record_cb_t *cb, void *data){	struct pending_connect *c;	get_record_data_t *d;	int err;	uuid_t *sdp_uuid;	if (find_pending_connect(dst)) {		error("SDP search in progress!");		return -EINPROGRESS;	}	sdp_uuid = g_new(uuid_t, 1);	memcpy(sdp_uuid, uuid, sizeof(uuid_t));	d = get_record_data_new(dev_id, dst, sdp_uuid, cb, data);	if (!(c = connect_request(conn, msg, dev_id, dst,				get_rec_with_uuid_conn_cb, &err))) {		error("Search request failed: %s (%d)", strerror(err), err);		get_record_data_free(d);		return -err;	}	c->call = d;	return 0;}

⌨️ 快捷键说明

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