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

📄 glib-helper.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	err = sco_bind(io_ctxt, io->src, io->mtu, &addr);	if (err < 0)		return err;	err = transport_listen(io);	if (err < 0) {		close(io_ctxt->fd);		return err;	}	return BT_IO_SUCCESS;}static gboolean hci_event_watch(GIOChannel *io,			GIOCondition cond, gpointer user_data){	unsigned char buf[HCI_MAX_EVENT_SIZE], *body;	struct hci_cmd_data *cmd = user_data;	evt_cmd_status *evt_status;	evt_auth_complete *evt_auth;	evt_encrypt_change *evt_enc;	hci_event_hdr *hdr;	set_conn_encrypt_cp cp;	int dd;	uint16_t ocf;	uint8_t status = HCI_OE_POWER_OFF;	if (cond & G_IO_NVAL) {		cmd->cb(status, cmd->caller_data);		return FALSE;	}	if (cond & (G_IO_ERR | G_IO_HUP))		goto failed;	dd = g_io_channel_unix_get_fd(io);	if (read(dd, buf, sizeof(buf)) < 0)		goto failed;	hdr = (hci_event_hdr *) (buf + 1);	body = buf + (1 + HCI_EVENT_HDR_SIZE);	switch (hdr->evt) {	case EVT_CMD_STATUS:		evt_status = (evt_cmd_status *) body;		ocf = cmd_opcode_ocf(evt_status->opcode);		if (ocf != cmd->ocf)			return TRUE;		switch (ocf) {		case OCF_AUTH_REQUESTED:		case OCF_SET_CONN_ENCRYPT:			if (evt_status->status != 0) {				/* Baseband rejected command */				status = evt_status->status;				goto failed;			}			break;		default:			return TRUE;		}		/* Wait for the next event */		return TRUE;	case EVT_AUTH_COMPLETE:		evt_auth = (evt_auth_complete *) body;		if (evt_auth->handle != cmd->handle) {			/* Skipping */			return TRUE;		}		if (evt_auth->status != 0x00) {			status = evt_auth->status;			/* Abort encryption */			goto failed;		}		memset(&cp, 0, sizeof(cp));		cp.handle  = cmd->handle;		cp.encrypt = 1;		cmd->ocf = OCF_SET_CONN_ENCRYPT;		if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,					SET_CONN_ENCRYPT_CP_SIZE, &cp) < 0) {			status = HCI_COMMAND_DISALLOWED;			goto failed;		}		/* Wait for encrypt change event */		return TRUE;	case EVT_ENCRYPT_CHANGE:		evt_enc = (evt_encrypt_change *) body;		if (evt_enc->handle != cmd->handle)			return TRUE;		/* Procedure finished: reporting status */		status = evt_enc->status;		break;	default:		/* Skipping */		return TRUE;	}failed:	cmd->cb(status, cmd->caller_data);	g_io_channel_close(io);	return FALSE;}int bt_acl_encrypt(const bdaddr_t *src, const bdaddr_t *dst,			bt_hci_result_t cb, gpointer user_data){	GIOChannel *io;	struct hci_cmd_data *cmd;	struct hci_conn_info_req *cr;	auth_requested_cp cp;	struct hci_filter nf;	int dd, dev_id, err;	char src_addr[18];	uint32_t link_mode;	uint16_t handle;	ba2str(src, src_addr);	dev_id = hci_devid(src_addr);	if (dev_id < 0)		return -errno;	dd = hci_open_dev(dev_id);	if (dd < 0)		return -errno;	cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));	cr->type = ACL_LINK;	bacpy(&cr->bdaddr, dst);	err = ioctl(dd, HCIGETCONNINFO, cr);	link_mode = cr->conn_info->link_mode;	handle = cr->conn_info->handle;	g_free(cr);	if (err < 0) {		err = errno;		goto failed;	}	if (link_mode & HCI_LM_ENCRYPT) {		/* Already encrypted */		err = EALREADY;		goto failed;	}	memset(&cp, 0, sizeof(cp));	cp.handle = htobs(handle);	if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_AUTH_REQUESTED,				AUTH_REQUESTED_CP_SIZE, &cp) < 0) {		err = errno;		goto failed;	}	cmd = g_new0(struct hci_cmd_data, 1);	cmd->handle = handle;	cmd->ocf = OCF_AUTH_REQUESTED;	cmd->cb	= cb;	cmd->caller_data = user_data;	hci_filter_clear(&nf);	hci_filter_set_ptype(HCI_EVENT_PKT, &nf);	hci_filter_set_event(EVT_CMD_STATUS, &nf);	hci_filter_set_event(EVT_AUTH_COMPLETE, &nf);	hci_filter_set_event(EVT_ENCRYPT_CHANGE, &nf);	if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) {		err = errno;		goto failed;	}	io = g_io_channel_unix_new(dd);	g_io_channel_set_close_on_unref(io, FALSE);	g_io_add_watch_full(io, G_PRIORITY_DEFAULT,			G_IO_HUP | G_IO_ERR | G_IO_NVAL | G_IO_IN,			hci_event_watch, cmd, g_free);	g_io_channel_unref(io);	return 0;failed:	close(dd);	return -err;}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;}GIOChannel *bt_sco_listen(const bdaddr_t *src, uint16_t mtu,				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 NULL;	ba2str(src, io->src);	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_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;		io->listen = sco_listen;		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 + -