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

📄 l2cap.c

📁 Bluezan implementation of the Bluetooth&#8482 wireless standards specifications for Linux. The code
💻 C
📖 第 1 页 / 共 2 页
字号:
				mode = *h->val;				set_mode(in, cid, mode);				printf(" 0x%02x (%s)", mode, mode2str(mode));			}			break;		default:			printf("Unknown (type %2.2x, len %d)", h->type & 0x7f, h->len);			break;		}		if (h->type & 0x80)			printf("] ");		else			printf(" ");	}	printf("\n");}static inline void conf_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm){	l2cap_conf_req *h = frm->ptr;	uint16_t dcid = btohs(h->dcid);	int clen = btohs(cmd->len) - L2CAP_CONF_REQ_SIZE;	if (p_filter(FILT_L2CAP))		return;	printf("Config req: dcid 0x%4.4x flags 0x%2.2x clen %d\n",			dcid, btohs(h->flags), clen);	if (clen > 0)		conf_opt(level + 1, h->data, clen, frm->in, dcid);}static inline void conf_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm){	l2cap_conf_rsp *h = frm->ptr;	uint16_t scid = btohs(h->scid);	uint16_t result = btohs(h->result);	int clen = btohs(cmd->len) - L2CAP_CONF_RSP_SIZE;	if (p_filter(FILT_L2CAP))		return;	printf("Config rsp: scid 0x%4.4x flags 0x%2.2x result %d clen %d\n",			scid, btohs(h->flags), result, clen);	if (clen > 0) {		if (!result) {			p_indent(level + 1, frm);			printf("%s\n", confresult2str(result));		}		conf_opt(level + 1, h->data, clen, frm->in, scid);	} else {		p_indent(level + 1, frm);		printf("%s\n", confresult2str(result));	}}static inline void disconn_req(int level, struct frame *frm){	l2cap_disconn_req *h = frm->ptr;	if (p_filter(FILT_L2CAP))		return;	printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n",			btohs(h->dcid), btohs(h->scid));}static inline void disconn_rsp(int level, struct frame *frm){	l2cap_disconn_rsp *h = frm->ptr;	uint16_t dcid = btohs(h->dcid);	uint16_t scid = btohs(h->scid);	del_cid(frm->in, dcid, scid);	if (p_filter(FILT_L2CAP))		return;	printf("Disconn rsp: dcid 0x%4.4x scid 0x%4.4x\n",			btohs(h->dcid), btohs(h->scid));}static inline void echo_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm){	if (p_filter(FILT_L2CAP))		return;	printf("Echo req: dlen %d\n", btohs(cmd->len));	raw_dump(level, frm);}static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm){	if (p_filter(FILT_L2CAP))		return;	printf("Echo rsp: dlen %d\n", btohs(cmd->len));	raw_dump(level, frm);}static void info_opt(int level, int type, void *ptr, int len){	uint32_t mask;	p_indent(level, 0);	switch (type) {	case 0x0001:		printf("Connectionless MTU %d\n", get_val(ptr, len));		break;	case 0x0002:		mask = get_val(ptr, len);		printf("Extended feature mask 0x%4.4x\n", mask);		if (parser.flags & DUMP_VERBOSE) {			if (mask & 0x01) {				p_indent(level + 1, 0);				printf("Flow control mode\n");			}			if (mask & 0x02) {				p_indent(level + 1, 0);				printf("Retransmission mode\n");			}			if (mask & 0x04) {				p_indent(level + 1, 0);				printf("Bi-directional QoS\n");			}		}		break;	default:		printf("Unknown (len %d)\n", len);		break;	}}static inline void info_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm){	l2cap_info_req *h = frm->ptr;	if (p_filter(FILT_L2CAP))		return;	printf("Info req: type %d\n", btohs(h->type));}static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm){	l2cap_info_rsp *h = frm->ptr;	uint16_t type = btohs(h->type);	uint16_t result = btohs(h->result);	int ilen = btohs(cmd->len) - L2CAP_INFO_RSP_SIZE;	if (p_filter(FILT_L2CAP))		return;	printf("Info rsp: type %d result %d\n", type, result);	if (ilen > 0) {		info_opt(level + 1, type, h->data, ilen);	} else {		p_indent(level + 1, frm);		printf("%s\n", inforesult2str(result));	}}static void l2cap_parse(int level, struct frame *frm){	l2cap_hdr *hdr = (void *)frm->ptr;	uint16_t dlen = btohs(hdr->len);	uint16_t cid  = btohs(hdr->cid);	uint16_t psm;	frm->ptr += L2CAP_HDR_SIZE;	frm->len -= L2CAP_HDR_SIZE;	if (cid == 0x1) {		/* Signaling channel */		while (frm->len >= L2CAP_CMD_HDR_SIZE) {			l2cap_cmd_hdr *hdr = frm->ptr;			frm->ptr += L2CAP_CMD_HDR_SIZE;			frm->len -= L2CAP_CMD_HDR_SIZE;			if (!p_filter(FILT_L2CAP)) {				p_indent(level, frm);				printf("L2CAP(s): ");			}			switch (hdr->code) {			case L2CAP_COMMAND_REJ:				command_rej(level, frm);				break;						case L2CAP_CONN_REQ:				conn_req(level, frm);				break;				case L2CAP_CONN_RSP:				conn_rsp(level, frm);				break;			case L2CAP_CONF_REQ:				conf_req(level, hdr, frm);				break;			case L2CAP_CONF_RSP:				conf_rsp(level, hdr, frm);				break;			case L2CAP_DISCONN_REQ:				disconn_req(level, frm);				break;			case L2CAP_DISCONN_RSP:				disconn_rsp(level, frm);				break;				case L2CAP_ECHO_REQ:				echo_req(level, hdr, frm);				break;			case L2CAP_ECHO_RSP:				echo_rsp(level, hdr, frm);				break;			case L2CAP_INFO_REQ:				info_req(level, hdr, frm);				break;			case L2CAP_INFO_RSP:				info_rsp(level, hdr, frm);				break;			default:				if (p_filter(FILT_L2CAP))					break;				printf("code 0x%2.2x ident %d len %d\n", 					hdr->code, hdr->ident, btohs(hdr->len));				raw_dump(level, frm);			}			frm->ptr += btohs(hdr->len);			frm->len -= btohs(hdr->len);		}	} else if (cid == 0x2) {		/* Connectionless channel */		if (p_filter(FILT_L2CAP))			return;		psm = btohs(bt_get_unaligned((uint16_t *) frm->ptr));		frm->ptr += 2;		frm->len -= 2;		p_indent(level, frm);		printf("L2CAP(c): len %d psm %d\n", dlen, psm);		raw_dump(level, frm);	} else {		/* Connection oriented channel */		uint8_t mode = get_mode(!frm->in, cid);		uint16_t psm = get_psm(!frm->in, cid);		uint16_t ctrl = 0, fcs = 0;		uint32_t proto;		frm->cid = cid;		frm->num = get_num(!frm->in, cid);		if (mode > 0) {			ctrl = btohs(bt_get_unaligned((uint16_t *) frm->ptr));			frm->ptr += 2;			frm->len -= 4;			fcs = btohs(bt_get_unaligned((uint16_t *) (frm->ptr + frm->len)));		}		if (!p_filter(FILT_L2CAP)) {			p_indent(level, frm);			printf("L2CAP(d): cid 0x%4.4x len %d", cid, dlen);			if (mode > 0)				printf(" ctrl 0x%4.4x fcs 0x%4.4x", ctrl, fcs);			printf(" [psm %d]\n", psm);			level++;			if (mode > 0) {				p_indent(level, frm);				printf("%s:", ctrl & 0x01 ? "S-frame" : "I-frame");				if (ctrl & 0x01) {					printf(" %s", supervisory2str((ctrl & 0x0c) >> 2));				} else {					uint8_t sar = (ctrl & 0xc000) >> 14;					printf(" %s", sar2str(sar));					if (sar == 1) {						uint16_t len;						len = btohs(bt_get_unaligned((uint16_t *) frm->ptr));						frm->ptr += 2;						frm->len -= 2;						printf(" (len %d)", len);					}					printf(" TxSeq %d", (ctrl & 0x7e) >> 1);				}				printf(" ReqSeq %d", (ctrl & 0x3f00) >> 8);				if (ctrl & 0x80)					printf(" Retransmission Disable");				printf("\n");			}		}		switch (psm) {		case 0x01:			if (!p_filter(FILT_SDP))				sdp_dump(level + 1, frm);			else				raw_dump(level + 1, frm);			break;		case 0x03:			if (!p_filter(FILT_RFCOMM))				rfcomm_dump(level, frm);			else				raw_dump(level + 1, frm);			break;		case 0x0f:			if (!p_filter(FILT_BNEP))				bnep_dump(level, frm);			else				raw_dump(level + 1, frm);			break;		case 0x11:		case 0x13:			if (!p_filter(FILT_HIDP))				hidp_dump(level, frm);			else				raw_dump(level + 1, frm);			break;		case 0x19:			if (!p_filter(FILT_AVDTP))				avdtp_dump(level, frm);			else				raw_dump(level + 1, frm);			break;		default:			proto = get_proto(frm->handle, psm, 0);			switch (proto) {			case SDP_UUID_CMTP:				if (!p_filter(FILT_CMTP))					cmtp_dump(level, frm);				else					raw_dump(level + 1, frm);				break;			case SDP_UUID_HARDCOPY_CONTROL_CHANNEL:				if (!p_filter(FILT_HCRP))					hcrp_dump(level, frm);				else					raw_dump(level + 1, frm);				break;			default:				if (p_filter(FILT_L2CAP))					break;				raw_dump(level, frm);				break;			}			break;		}	}}void l2cap_dump(int level, struct frame *frm){	struct frame *fr;	l2cap_hdr *hdr;	uint16_t dlen;	if (frm->flags & ACL_START) {		hdr  = frm->ptr;		dlen = btohs(hdr->len);		if (frm->len == (dlen + L2CAP_HDR_SIZE)) {			/* Complete frame */			l2cap_parse(level, frm);			return;		}		if (!(fr = get_frame(frm->handle))) {			fprintf(stderr, "Not enough connection handles\n");			raw_dump(level, frm);			return;		}		if (fr->data)			free(fr->data);		if (!(fr->data = malloc(dlen + L2CAP_HDR_SIZE))) {			perror("Can't allocate L2CAP reassembly buffer");			return;		}		memcpy(fr->data, frm->ptr, frm->len);		fr->data_len = dlen + L2CAP_HDR_SIZE;		fr->len = frm->len;		fr->ptr = fr->data;		fr->in  = frm->in;		fr->ts  = frm->ts;		fr->handle  = frm->handle;		fr->cid     = frm->cid;		fr->num     = frm->num;		fr->dlci    = frm->dlci;		fr->channel = frm->channel;	} else {		if (!(fr = get_frame(frm->handle))) {			fprintf(stderr, "Not enough connection handles\n");			raw_dump(level, frm);			return;		}		if (!fr->data) {			/* Unexpected fragment */			raw_dump(level, frm);			return;		}		if (frm->len > (fr->data_len - fr->len)) {			/* Bad fragment */			raw_dump(level, frm);			free(fr->data); fr->data = NULL;			return;		}		memcpy(fr->data + fr->len, frm->ptr, frm->len);		fr->len += frm->len;		if (fr->len == fr->data_len) {			/* Complete frame */			l2cap_parse(level, fr);			free(fr->data); fr->data = NULL;			return;		}	}}void l2cap_clear(uint16_t handle){	del_handle(handle);}

⌨️ 快捷键说明

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