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

📄 core.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
}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 iovec 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));	msg.msg_iovlen = 3;	msg.msg_iov = iv;	return sock->ops->sendmsg(sock, &msg, 6 + len, 0);}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){	int err = 0;	BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);	if (dlci) {		struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);		if (d) {			rfcomm_send_ua(s, dlci);			if (d->state == BT_CONNECT || d->state == BT_CONFIG)				err = ECONNREFUSED;			else				err = ECONNRESET;			d->state = BT_CLOSED;			__rfcomm_dlc_close(d, err);		} else 			rfcomm_send_dm(s, dlci);				} else {		rfcomm_send_ua(s, 0);		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_sabm(struct rfcomm_session *s, u8 dlci){	struct rfcomm_dlc *d;	u8 channel;	BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);	if (!dlci) {		rfcomm_send_ua(s, 0);		if (s->state == BT_OPEN) {			s->state = BT_CONNECTED;			rfcomm_process_connect(s);		}		return 0;	}	/* Check if DLC exists */	d = rfcomm_dlc_get(s, dlci);	if (d) {		if (d->state == BT_OPEN) {			/* DLC was previously opened by PN request */			rfcomm_send_ua(s, dlci);			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);		}		return 0;	}	/* Notify socket layer about incomming connection */	channel = __srv_channel(dlci);	if (rfcomm_connect_ind(s, channel, &d)) {		d->dlci = dlci;		d->addr = __addr(s->initiator, dlci);		rfcomm_dlc_link(s, d);		rfcomm_send_ua(s, dlci);		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);	} else {		rfcomm_send_dm(s, dlci);	}	return 0;}static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn){	struct rfcomm_session *s = d->session;	BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", 			d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);	if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) {		d->cfc = s->cfc = RFCOMM_CFC_ENABLED;		d->tx_credits = pn->credits;	} else {		d->cfc = s->cfc = RFCOMM_CFC_DISABLED;		set_bit(RFCOMM_TX_THROTTLED, &d->flags);	}	d->priority = pn->priority;	d->mtu = s->mtu = btohs(pn->mtu);	return 0;}static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb){	struct rfcomm_pn *pn = (void *) skb->data;	struct rfcomm_dlc *d;	u8 dlci = pn->dlci;	BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);	if (!dlci)		return 0;	d = rfcomm_dlc_get(s, dlci);	if (d) {		if (cr) {			/* PN request */			rfcomm_apply_pn(d, cr, pn);			rfcomm_send_pn(s, 0, d);		} else {			/* PN response */			switch (d->state) {			case BT_CONFIG:				rfcomm_apply_pn(d, cr, pn);				d->state = BT_CONNECT;				rfcomm_send_sabm(s, d->dlci);				break;			}		}	} else {		u8 channel = __srv_channel(dlci);		if (!cr)			return 0;		/* PN request for non existing DLC.		 * Assume incomming connection. */		if (rfcomm_connect_ind(s, channel, &d)) {			d->dlci = dlci;			d->addr = __addr(s->initiator, dlci);			rfcomm_dlc_link(s, d);			rfcomm_apply_pn(d, cr, pn);			d->state = BT_OPEN;			rfcomm_send_pn(s, 0, d);		} else {			rfcomm_send_dm(s, dlci);		}	}	return 0;}static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb){	struct rfcomm_rpn *rpn = (void *) skb->data;	u8 dlci = __get_dlci(rpn->dlci);	u8 bit_rate  = 0;	u8 data_bits = 0;	u8 stop_bits = 0;	u8 parity    = 0;	u8 flow_ctrl = 0;	u8 xon_char  = 0;	u8 xoff_char = 0;	u16 rpn_mask = RFCOMM_RPN_PM_ALL;		BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x", 	       dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,	       rpn->xon_char, rpn->xoff_char, rpn->param_mask);		if (!cr) 		return 0;		if (len == 1) {		/* request: return default setting */		bit_rate  = RFCOMM_RPN_BR_115200;		data_bits = RFCOMM_RPN_DATA_8;		stop_bits = RFCOMM_RPN_STOP_1;		parity    = RFCOMM_RPN_PARITY_NONE;		flow_ctrl = RFCOMM_RPN_FLOW_NONE;		xon_char  = RFCOMM_RPN_XON_CHAR;		xoff_char = RFCOMM_RPN_XOFF_CHAR;		goto rpn_out;	}	/* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,	                          no flow control lines, normal XON/XOFF chars */	if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {		bit_rate = rpn->bit_rate;		if (bit_rate != RFCOMM_RPN_BR_115200) {			BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);			bit_rate = RFCOMM_RPN_BR_115200;			rpn_mask ^= RFCOMM_RPN_PM_BITRATE;		}	}	if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {		data_bits = __get_rpn_data_bits(rpn->line_settings);		if (data_bits != RFCOMM_RPN_DATA_8) {			BT_DBG("RPN data bits mismatch 0x%x", data_bits);			data_bits = RFCOMM_RPN_DATA_8;			rpn_mask ^= RFCOMM_RPN_PM_DATA;		}	}	if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {		stop_bits = __get_rpn_stop_bits(rpn->line_settings);		if (stop_bits != RFCOMM_RPN_STOP_1) {			BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);			stop_bits = RFCOMM_RPN_STOP_1;			rpn_mask ^= RFCOMM_RPN_PM_STOP;		}	}	if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {		parity = __get_rpn_parity(rpn->line_settings);		if (parity != RFCOMM_RPN_PARITY_NONE) {			BT_DBG("RPN parity mismatch 0x%x", parity);			parity = RFCOMM_RPN_PARITY_NONE;			rpn_mask ^= RFCOMM_RPN_PM_PARITY;		}	}	if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {		flow_ctrl = rpn->flow_ctrl;		if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {			BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);			flow_ctrl = RFCOMM_RPN_FLOW_NONE;			rpn_mask ^= RFCOMM_RPN_PM_FLOW;		}	}	if (rpn->param_mask & RFCOMM_RPN_PM_XON) {		xon_char = rpn->xon_char;		if (xon_char != RFCOMM_RPN_XON_CHAR) {			BT_DBG("RPN XON char mismatch 0x%x", xon_char);			xon_char = RFCOMM_RPN_XON_CHAR;			rpn_mask ^= RFCOMM_RPN_PM_XON;		}	}	if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {		xoff_char = rpn->xoff_char;

⌨️ 快捷键说明

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