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

📄 core.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst){	struct rfcomm_session *s;	struct list_head *p, *n;	struct bt_sock *sk;	list_for_each_safe(p, n, &session_list) {		s = list_entry(p, struct rfcomm_session, list);		sk = bt_sk(s->sock->sk); 		if ((!bacmp(src, BDADDR_ANY) || !bacmp(&sk->src, src)) &&				!bacmp(&sk->dst, dst))			return s;	}	return NULL;}static void rfcomm_session_close(struct rfcomm_session *s, int err){	struct rfcomm_dlc *d;	struct list_head *p, *n;	BT_DBG("session %p state %ld err %d", s, s->state, err);	rfcomm_session_hold(s);	s->state = BT_CLOSED;	/* Close all dlcs */	list_for_each_safe(p, n, &s->dlcs) {		d = list_entry(p, struct rfcomm_dlc, list);		d->state = BT_CLOSED;		__rfcomm_dlc_close(d, err);	}	rfcomm_session_put(s);}static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err){	struct rfcomm_session *s = NULL;	struct sockaddr_l2 addr;	struct socket *sock;	struct sock *sk;	BT_DBG("%s %s", batostr(src), batostr(dst));	*err = rfcomm_l2sock_create(&sock);	if (*err < 0)		return NULL;	bacpy(&addr.l2_bdaddr, src);	addr.l2_family = AF_BLUETOOTH;	addr.l2_psm    = 0;	*err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));	if (*err < 0)		goto failed;	/* Set L2CAP options */	sk = sock->sk;	lock_sock(sk);	l2cap_pi(sk)->imtu = RFCOMM_MAX_L2CAP_MTU;	release_sock(sk);	s = rfcomm_session_add(sock, BT_BOUND);	if (!s) {		*err = -ENOMEM;		goto failed;	}	s->initiator = 1;	bacpy(&addr.l2_bdaddr, dst);	addr.l2_family = AF_BLUETOOTH;	addr.l2_psm    = htobs(RFCOMM_PSM);	*err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);	if (*err == 0 || *err == -EAGAIN)		return s;	rfcomm_session_del(s);	return NULL;failed:	sock_release(sock);	return NULL;}void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst){	struct sock *sk = s->sock->sk;	if (src)		bacpy(src, &bt_sk(sk)->src);	if (dst)		bacpy(dst, &bt_sk(sk)->dst);}/* ---- RFCOMM frame sending ---- */static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len){	struct socket *sock = s->sock;	struct kvec iv = { data, len };	struct msghdr msg;	BT_DBG("session %p len %d", s, len);	memset(&msg, 0, sizeof(msg));	return kernel_sendmsg(sock, &msg, &iv, 1, len);}static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci){	struct rfcomm_cmd cmd;	BT_DBG("%p dlci %d", s, dlci);	cmd.addr = __addr(s->initiator, dlci);	cmd.ctrl = __ctrl(RFCOMM_SABM, 1);	cmd.len  = __len8(0);	cmd.fcs  = __fcs2((u8 *) &cmd);	return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));}static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci){	struct rfcomm_cmd cmd;	BT_DBG("%p dlci %d", s, dlci);	cmd.addr = __addr(!s->initiator, dlci);	cmd.ctrl = __ctrl(RFCOMM_UA, 1);	cmd.len  = __len8(0);	cmd.fcs  = __fcs2((u8 *) &cmd);	return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));}static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci){	struct rfcomm_cmd cmd;	BT_DBG("%p dlci %d", s, dlci);	cmd.addr = __addr(s->initiator, dlci);	cmd.ctrl = __ctrl(RFCOMM_DISC, 1);	cmd.len  = __len8(0);	cmd.fcs  = __fcs2((u8 *) &cmd);	return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));}static int rfcomm_queue_disc(struct rfcomm_dlc *d){	struct rfcomm_cmd *cmd;	struct sk_buff *skb;	BT_DBG("dlc %p dlci %d", d, d->dlci);	skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);	if (!skb)		return -ENOMEM;	cmd = (void *) __skb_put(skb, sizeof(*cmd));	cmd->addr = d->addr;	cmd->ctrl = __ctrl(RFCOMM_DISC, 1);	cmd->len  = __len8(0);	cmd->fcs  = __fcs2((u8 *) cmd);	skb_queue_tail(&d->tx_queue, skb);	rfcomm_schedule(RFCOMM_SCHED_TX);	return 0;}static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci){	struct rfcomm_cmd cmd;	BT_DBG("%p dlci %d", s, dlci);	cmd.addr = __addr(!s->initiator, dlci);	cmd.ctrl = __ctrl(RFCOMM_DM, 1);	cmd.len  = __len8(0);	cmd.fcs  = __fcs2((u8 *) &cmd);	return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));}static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d type %d", s, cr, type);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc) + 1);	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_NSC);	mcc->len  = __len8(1);	/* Type that we didn't like */	*ptr = __mcc_type(cr, type); ptr++;	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	struct rfcomm_pn  *pn;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc) + sizeof(*pn));	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_PN);	mcc->len  = __len8(sizeof(*pn));	pn = (void *) ptr; ptr += sizeof(*pn);	pn->dlci        = d->dlci;	pn->priority    = d->priority;	pn->ack_timer   = 0;	pn->max_retrans = 0;	if (s->cfc) {		pn->flow_ctrl = cr ? 0xf0 : 0xe0;		pn->credits = RFCOMM_DEFAULT_CREDITS;	} else {		pn->flow_ctrl = 0;		pn->credits   = 0;	}	pn->mtu = htobs(d->mtu);	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,			   u8 bit_rate, u8 data_bits, u8 stop_bits,			   u8 parity, u8 flow_ctrl_settings, 			   u8 xon_char, u8 xoff_char, u16 param_mask){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	struct rfcomm_rpn *rpn;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"	       "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x", 			s, cr, dlci, bit_rate, data_bits, stop_bits, parity, 			flow_ctrl_settings, xon_char, xoff_char, param_mask);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc) + sizeof(*rpn));	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_RPN);	mcc->len  = __len8(sizeof(*rpn));	rpn = (void *) ptr; ptr += sizeof(*rpn);	rpn->dlci          = __addr(1, dlci);	rpn->bit_rate      = bit_rate;	rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);	rpn->flow_ctrl     = flow_ctrl_settings;	rpn->xon_char      = xon_char;	rpn->xoff_char     = xoff_char;	rpn->param_mask    = param_mask;	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	struct rfcomm_rls *rls;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d status 0x%x", s, cr, status);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc) + sizeof(*rls));	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_RLS);	mcc->len  = __len8(sizeof(*rls));	rls = (void *) ptr; ptr += sizeof(*rls);	rls->dlci   = __addr(1, dlci);	rls->status = status;	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	struct rfcomm_msc *msc;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc) + sizeof(*msc));	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_MSC);	mcc->len  = __len8(sizeof(*msc));	msc = (void *) ptr; ptr += sizeof(*msc);	msc->dlci    = __addr(1, dlci);	msc->v24_sig = v24_sig | 0x01;	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d", s, cr);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc));	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_FCOFF);	mcc->len  = __len8(0);	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_fcon(struct rfcomm_session *s, int cr){	struct rfcomm_hdr *hdr;	struct rfcomm_mcc *mcc;	u8 buf[16], *ptr = buf;	BT_DBG("%p cr %d", s, cr);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = __addr(s->initiator, 0);	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	hdr->len  = __len8(sizeof(*mcc));	mcc = (void *) ptr; ptr += sizeof(*mcc);	mcc->type = __mcc_type(cr, RFCOMM_FCON);	mcc->len  = __len8(0);	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len){	struct socket *sock = s->sock;	struct kvec iv[3];	struct msghdr msg;	unsigned char hdr[5], crc[1];	if (len > 125)		return -EINVAL;	BT_DBG("%p cr %d", s, cr);	hdr[0] = __addr(s->initiator, 0);	hdr[1] = __ctrl(RFCOMM_UIH, 0);	hdr[2] = 0x01 | ((len + 2) << 1);	hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);	hdr[4] = 0x01 | (len << 1);	crc[0] = __fcs(hdr);	iv[0].iov_base = hdr;	iv[0].iov_len  = 5;	iv[1].iov_base = pattern;	iv[1].iov_len  = len;	iv[2].iov_base = crc;	iv[2].iov_len  = 1;	memset(&msg, 0, sizeof(msg));	return kernel_sendmsg(sock, &msg, iv, 3, 6 + len);}static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits){	struct rfcomm_hdr *hdr;	u8 buf[16], *ptr = buf;	BT_DBG("%p addr %d credits %d", s, addr, credits);	hdr = (void *) ptr; ptr += sizeof(*hdr);	hdr->addr = addr;	hdr->ctrl = __ctrl(RFCOMM_UIH, 1);	hdr->len  = __len8(0);	*ptr = credits; ptr++;	*ptr = __fcs(buf); ptr++;	return rfcomm_send_frame(s, buf, ptr - buf);}static void rfcomm_make_uih(struct sk_buff *skb, u8 addr){	struct rfcomm_hdr *hdr;	int len = skb->len;	u8 *crc;	if (len > 127) {		hdr = (void *) skb_push(skb, 4);		put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);	} else {		hdr = (void *) skb_push(skb, 3);		hdr->len = __len8(len);	}	hdr->addr = addr;	hdr->ctrl = __ctrl(RFCOMM_UIH, 0);	crc = skb_put(skb, 1);	*crc = __fcs((void *) hdr);}/* ---- RFCOMM frame reception ---- */static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci){	BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);	if (dlci) {		/* Data channel */		struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);		if (!d) {			rfcomm_send_dm(s, dlci);			return 0;		}		switch (d->state) {		case BT_CONNECT:			rfcomm_dlc_clear_timer(d);			rfcomm_dlc_lock(d);			d->state = BT_CONNECTED;			d->state_change(d, 0);			rfcomm_dlc_unlock(d);			rfcomm_send_msc(s, 1, dlci, d->v24_sig);			break;		case BT_DISCONN:			d->state = BT_CLOSED;			__rfcomm_dlc_close(d, 0);			break;		}	} else {		/* Control channel */		switch (s->state) {		case BT_CONNECT:			s->state = BT_CONNECTED;			rfcomm_process_connect(s);			break;		}	}	return 0;}static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci){	int err = 0;	BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);	if (dlci) {		/* Data DLC */		struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);		if (d) {			if (d->state == BT_CONNECT || d->state == BT_CONFIG)				err = ECONNREFUSED;			else				err = ECONNRESET;			d->state = BT_CLOSED;			__rfcomm_dlc_close(d, err);		}	} else {		if (s->state == BT_CONNECT)			err = ECONNREFUSED;		else			err = ECONNRESET;		s->state = BT_CLOSED;		rfcomm_session_close(s, err);	}	return 0;}static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)

⌨️ 快捷键说明

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