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

📄 glib-helper.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	err = listen(io_ctxt->fd, 5);	if (err < 0)		return -errno;	io_ctxt->io = g_io_channel_unix_new(io_ctxt->fd);	if (!io_ctxt->io)		return -ENOMEM;	g_io_add_watch(io_ctxt->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,			(GIOFunc) listen_cb, io);	return 0;}static gboolean connect_cb(GIOChannel *gio, GIOCondition cond,				gpointer user_data){	BtIO *io = user_data;	struct io_context *io_ctxt = io->io_ctxt;	int err = 0, ret;	socklen_t len;	bdaddr_t src, dst;	if (cond & G_IO_NVAL)		return FALSE;	len = sizeof(ret);	if (getsockopt(io_ctxt->fd, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {		err = -errno;		goto done;	}	if (ret != 0) {		err = -ret;		goto done;	}	if (io_ctxt->resolver) {		err = io_ctxt->resolver(io_ctxt->fd, io->src, io->dst);		if (err < 0)			goto done;	}	io_ctxt->io = NULL;done:	if (io_ctxt->func)		io_ctxt->func(io, err, gio, io_ctxt->user_data);	if (io_ctxt->cb) {		str2ba(io->src, &src);		str2ba(io->dst, &dst);		io_ctxt->cb(gio, err, &src, &dst, io_ctxt->user_data);	}	if (io_ctxt->io) {		g_io_channel_close(io_ctxt->io);		g_io_channel_unref(io_ctxt->io);	}	g_free(io_ctxt);	return FALSE;}static int transport_connect(BtIO *io, struct sockaddr *addr,		socklen_t addrlen){	struct io_context *io_ctxt = io->io_ctxt;	int err;	io_ctxt->io = g_io_channel_unix_new(io_ctxt->fd);	if (!io_ctxt->io)		return -ENOMEM;	err = g_io_channel_set_flags(io_ctxt->io, G_IO_FLAG_NONBLOCK, NULL);	if (err != G_IO_STATUS_NORMAL)		return -EPERM;	err = connect(io_ctxt->fd, addr, addrlen);	if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))		return -errno;	g_io_add_watch(io_ctxt->io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,			(GIOFunc) connect_cb, io);	return 0;}static BtIOError sco_connect(BtIO *io, BtIOFunc func){	struct io_context *io_ctxt = io->io_ctxt;	struct sockaddr_sco addr;	int sk, err;	io_ctxt->func = func;	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);	if (sk < 0)		return -errno;	memset(&addr, 0, sizeof(addr));	addr.sco_family = AF_BLUETOOTH;	str2ba(io->src, &addr.sco_bdaddr);	err = bind(sk, (struct sockaddr *) &addr, sizeof(addr));	if (err < 0) {		close(sk);		return BT_IO_FAILED;	}	io_ctxt->fd = sk;	memset(&addr, 0, sizeof(addr));	addr.sco_family = AF_BLUETOOTH;	str2ba(io->dst, &addr.sco_bdaddr);	err = transport_connect(io, (struct sockaddr *) &addr,				sizeof(addr));	if (err < 0) {		close(sk);		return BT_IO_FAILED;	}	return BT_IO_SUCCESS;}static int l2cap_bind(struct io_context *io_ctxt, const char *address,			uint16_t psm, uint16_t mtu, uint32_t flags,			struct sockaddr_l2 *addr){	int err;	struct l2cap_options l2o;	struct sockaddr_l2 l2a;	io_ctxt->fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);	if (io_ctxt->fd < 0)		return -errno;	if (mtu) {		socklen_t olen = sizeof(l2o);		memset(&l2o, 0, olen);		getsockopt(io_ctxt->fd, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);		l2o.imtu = l2o.omtu = mtu;		setsockopt(io_ctxt->fd, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));	}	if (flags) {		int opt = flags;		err = setsockopt(io_ctxt->fd, SOL_L2CAP, L2CAP_LM, &opt,				sizeof(opt));		if (err < 0) {			close(io_ctxt->fd);			return -errno;		}	}	memset(addr, 0, sizeof(*addr));	addr->l2_family = AF_BLUETOOTH;	str2ba(address, &l2a.l2_bdaddr);	addr->l2_psm = htobs(psm);	err = bind(io_ctxt->fd, (struct sockaddr *) addr, sizeof(*addr));	if (err < 0) {		close(io_ctxt->fd);		return -errno;	}	return 0;}static BtIOError l2cap_listen(BtIO *io, BtIOFunc func){	struct io_context *io_ctxt = io->io_ctxt;	struct sockaddr_l2 addr;	BtIOError err;	io_ctxt->func = func;	err = l2cap_bind(io_ctxt, io->src, io->psm, io->mtu, io->flags, &addr);	if (err < 0)		return err;	err = transport_listen(io);	if (err < 0) {		close(io_ctxt->fd);		return err;	}	return BT_IO_SUCCESS;}static BtIOError l2cap_connect(BtIO *io, BtIOFunc func){	struct io_context *io_ctxt = io->io_ctxt;	struct sockaddr_l2 l2a;	BtIOError err;	io_ctxt->func = func;	err = l2cap_bind(io_ctxt, io->src, 0, io->mtu, 0, &l2a);	if (err < 0)		return err;	memset(&l2a, 0, sizeof(l2a));	l2a.l2_family = AF_BLUETOOTH;	str2ba(io->dst, &l2a.l2_bdaddr);	l2a.l2_psm = htobs(io->psm);	err = transport_connect(io, (struct sockaddr *) &l2a,				sizeof(l2a));	if (err < 0) {		close(io_ctxt->fd);		return err;	}	return BT_IO_SUCCESS;}static BtIOError rfcomm_bind(struct io_context *io_ctxt, const char *address,				uint8_t channel, uint32_t flags,				struct sockaddr_rc *addr){	BtIOError err;	io_ctxt->fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);	if (io_ctxt->fd < 0)		return BT_IO_FAILED;	if (flags) {		int opt = flags;		err = setsockopt(io_ctxt->fd, SOL_RFCOMM, RFCOMM_LM, &opt,				sizeof(opt));		if (err < 0) {			close(io_ctxt->fd);			return BT_IO_FAILED;		}	}	memset(addr, 0, sizeof(*addr));	addr->rc_family = AF_BLUETOOTH;	str2ba(address, &addr->rc_bdaddr);	addr->rc_channel = channel;	err = bind(io_ctxt->fd, (struct sockaddr *) addr, sizeof(*addr));	if (err < 0) {		close(io_ctxt->fd);		return BT_IO_FAILED;	}	return BT_IO_SUCCESS;}static BtIOError rfcomm_listen(BtIO *io, BtIOFunc func){	struct io_context *io_ctxt = io->io_ctxt;	struct sockaddr_rc addr;	socklen_t sa_len;	BtIOError err;	io_ctxt->func = func;	err = rfcomm_bind(io_ctxt, io->src, io->channel, io->flags, &addr);	if (err < 0)		return err;	err = transport_listen(io);	if (err < 0) {		close(io_ctxt->fd);		return err;	}	sa_len = sizeof(struct sockaddr_rc);	memset(&addr, 0, sizeof(addr));	if (getsockname(io_ctxt->fd, (struct sockaddr *) &addr, &sa_len) < 0) {		err = -errno;		close(io_ctxt->fd);		return err;	}	io->channel = addr.rc_channel;	return BT_IO_SUCCESS;}static BtIOError rfcomm_connect(BtIO *io, BtIOFunc func){	struct io_context *io_ctxt = io->io_ctxt;	struct sockaddr_rc addr;	BtIOError err;	io_ctxt->func = func;	err = rfcomm_bind(io_ctxt, io->src, 0, 0, &addr);	if (err < 0)		return err;	memset(&addr, 0, sizeof(addr));	addr.rc_family = AF_BLUETOOTH;	str2ba(io->dst, &addr.rc_bdaddr);	addr.rc_channel = io->channel;	err = transport_connect(io, (struct sockaddr *) &addr,				sizeof(addr));	if (err < 0) {		close(io_ctxt->fd);		return err;	}	return BT_IO_SUCCESS;}static int create_io_context(struct io_context **io_ctxt, BtIOFunc func,			gpointer cb, gpointer resolver, gpointer user_data){	*io_ctxt = g_try_malloc0(sizeof(struct search_context));	if (!*io_ctxt)		return -ENOMEM;	(*io_ctxt)->cb = cb;	(*io_ctxt)->func = func;	(*io_ctxt)->resolver = resolver;	(*io_ctxt)->user_data = user_data;	return 0;}static void io_context_cleanup(struct io_context *io_ctxt){	if (io_ctxt->io) {		g_io_channel_close(io_ctxt->io);		g_io_channel_unref(io_ctxt->io);	}	g_free(io_ctxt);}GIOChannel *rfcomm_listen_internal(const bdaddr_t *src, uint8_t *channel,			uint32_t flags, bt_io_callback_t cb, void *user_data){	BtIO *io;	BtIOError err;	io = bt_io_create(BT_IO_RFCOMM, user_data, NULL);	if (!io)		return NULL;	ba2str(src, io->src);	io->channel = *channel;	io->flags = flags;	io->io_ctxt->cb = cb;	err = bt_io_listen(io, NULL, NULL);	if (err != BT_IO_SUCCESS) {		bt_io_unref(io);		return NULL;	}	*channel = io->channel;	return io->io_ctxt->io;}GIOChannel *bt_rfcomm_listen_allocate(const bdaddr_t *src, uint8_t *channel,			uint32_t flags, bt_io_callback_t cb, void *user_data){	if (!channel)		return NULL;	*channel = 0;	return rfcomm_listen_internal(src, channel, flags, cb, user_data);}GIOChannel *bt_rfcomm_listen(const bdaddr_t *src, uint8_t channel,			uint32_t flags, bt_io_callback_t cb, void *user_data){	if (channel < 1 || channel > 30)		return NULL;	return rfcomm_listen_internal(src, &channel, flags, cb, user_data);}int bt_rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,			uint8_t channel, bt_io_callback_t cb, void *user_data){	BtIO *io;	BtIOError err;	io = bt_io_create(BT_IO_RFCOMM, user_data, NULL);	if (!io)		return -1;	ba2str(src, io->src);	ba2str(dst, io->dst);	io->channel = channel;	io->io_ctxt->cb = cb;	err = bt_io_connect(io, NULL, NULL);	if (err != BT_IO_SUCCESS) {		bt_io_unref(io);		return -1;	}	return 0;}GIOChannel *bt_l2cap_listen(const bdaddr_t *src, uint16_t psm, uint16_t mtu,			uint32_t flags, bt_io_callback_t cb, void *user_data){	BtIO *io;	BtIOError err;	io = bt_io_create(BT_IO_L2CAP, user_data, NULL);	if (!io)		return NULL;	ba2str(src, io->src);	io->psm = psm;	io->mtu = mtu;	io->flags = flags;	io->io_ctxt->cb = cb;	err = bt_io_listen(io, NULL, NULL);	if (err != BT_IO_SUCCESS) {		bt_io_unref(io);		return NULL;	}	return io->io_ctxt->io;}int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst,			uint16_t psm, uint16_t mtu, bt_io_callback_t cb,			void *user_data){	BtIO *io;	BtIOError err;	io = bt_io_create(BT_IO_L2CAP, user_data, NULL);	if (!io)		return -1;	ba2str(src, io->src);	ba2str(dst, io->dst);	io->psm = psm;	io->mtu = mtu;	io->io_ctxt->cb = cb;	err = bt_io_connect(io, NULL, NULL);	if (err != BT_IO_SUCCESS) {		bt_io_unref(io);		return -1;	}	return 0;}int bt_sco_connect(const bdaddr_t *src, const bdaddr_t *dst,			bt_io_callback_t cb, void *user_data){	BtIO *io;	BtIOError err;	io = bt_io_create(BT_IO_SCO, user_data, NULL);	if (!io)		return -1;	ba2str(src, io->src);	ba2str(dst, io->dst);	io->io_ctxt->cb = cb;	err = bt_io_connect(io, NULL, NULL);	if (err != BT_IO_SUCCESS) {		bt_io_unref(io);		return -1;	}	return 0;}/* Experiemental bt_io API */BtIO *bt_io_create(BtIOTransport type, gpointer user_data, GDestroyNotify notify){	BtIO *io;	int err;	io = g_new0(BtIO, 1);	if (!io)		return NULL;	io->refcount = 1;	switch (type) {	case BT_IO_L2CAP:		err = create_io_context(&io->io_ctxt, NULL, NULL,				l2cap_resolver, user_data);		io->connect = l2cap_connect;		io->listen = l2cap_listen;		break;	case BT_IO_RFCOMM:		err = create_io_context(&io->io_ctxt, NULL, NULL,				rfcomm_resolver, user_data);		io->connect = rfcomm_connect;		io->listen = rfcomm_listen;		break;	case BT_IO_SCO:		err = create_io_context(&io->io_ctxt, NULL, NULL,				sco_resolver, user_data);		io->connect = sco_connect;		break;	default:		return NULL;	}	if (err < 0) {		bt_io_unref(io);		return NULL;	}	return io;}BtIO *bt_io_ref(BtIO *io){	io->refcount++;	return io;}void bt_io_unref(BtIO *io){	io->refcount--;	if (io->refcount)		return;	io_context_cleanup(io->io_ctxt);	g_free(io);}gboolean bt_io_set_source(BtIO *io, const char *address){	if (strlen(address) != sizeof(io->src))		return FALSE;	memcpy(io->src, address, sizeof(io->src));	return TRUE;}const char *bt_io_get_source(BtIO *io){	return io->src;}gboolean bt_io_set_destination(BtIO *io, const char *address){	if (strlen(address) != sizeof(io->dst))		return FALSE;	memcpy(io->dst, address, sizeof(io->dst));	return TRUE;}const char *bt_io_get_destination(BtIO *io){	return io->dst;}gboolean bt_io_set_flags(BtIO *io, guint32 flags){	io->flags = flags;	return TRUE;}guint32 bt_io_get_flags(BtIO *io){	return io->flags;}gboolean bt_io_set_channel(BtIO *io, guint8 channel){	if (io->type != BT_IO_RFCOMM)		return FALSE;	io->channel = channel;	return TRUE;}guint8 bt_io_get_channel(BtIO *io){	return io->channel;}gboolean bt_io_set_psm(BtIO *io, guint16 psm){	if (io->type != BT_IO_L2CAP)		return FALSE;	io->psm = psm;	return TRUE;}guint16 bt_io_get_psm(BtIO *io){	return io->psm;}gboolean bt_io_set_mtu(BtIO *io, guint16 mtu){	io->mtu = mtu;	return TRUE;}guint16 bt_io_get_mtu(BtIO *io){	return io->mtu;}BtIOError bt_io_connect(BtIO *io, const char *uuid, BtIOFunc func){	if (!io->connect)		return BT_IO_FAILED;	return io->connect(io, func);}BtIOError bt_io_listen(BtIO *io, const char *uuid, BtIOFunc func){	if (!io->listen)		return BT_IO_FAILED;	return io->listen(io, func);}BtIOError bt_io_shutdown(BtIO *io){	io_context_cleanup(io->io_ctxt);	return BT_IO_SUCCESS;}

⌨️ 快捷键说明

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