static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head)
{
	mcc_short_frame_head *mcc_short_head_p = frm->ptr;
	mcc_long_frame_head mcc_head;
	uint8_t hdr_size;

	if ( mcc_short_head_p->length.ea == EA ) {
		mcc_head.type = mcc_short_head_p->type;
		mcc_head.length.bits.len = mcc_short_head_p->length.len;
		hdr_size = sizeof(mcc_short_frame_head);
	} else {
		mcc_head = *(mcc_long_frame_head *)frm->ptr;
		mcc_head.length.val = btohs(mcc_head.length.val);
		hdr_size = sizeof(mcc_long_frame_head);
	}

	frm->ptr += hdr_size;
	frm->len -= hdr_size;

	p_indent(level, frm);
	printf("RFCOMM(s): ");

	switch (mcc_head.type.type) {
	case TEST:
		mcc_test(level, frm->ptr, frm->len, head, &mcc_head);
		raw_dump(level, frm); 
		break;
	case FCON:
		mcc_fcon(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case FCOFF:
		mcc_fcoff(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case MSC:
		mcc_msc(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case RPN:
		mcc_rpn(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case RLS:
		mcc_rls(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case PN:
		mcc_pn(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	case NSC:
		mcc_nsc(level, frm->ptr, frm->len, head, &mcc_head);
		break;
	default:
		printf("MCC message type 0x%02x: ", mcc_head.type.type);
		print_rfcomm_hdr(head, frm->ptr, frm->len);
		printf("\n");

		frm->len--;
		raw_dump(level, frm); 
	}
}
Ejemplo n.º 2
0
static inline bool mcc_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
{
	uint8_t length, ex_length, type;
	const char *type_str;
	int i;
	struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
	struct rfcomm_lmcc mcc;
	const struct mcc_data *mcc_data = NULL;

	if (!l2cap_frame_get_u8(frame, &mcc.type) ||
			!l2cap_frame_get_u8(frame, &length))
		return false;

	if (RFCOMM_TEST_EA(length))
		mcc.length = (uint16_t) GET_LEN8(length);
	else {
		if (!l2cap_frame_get_u8(frame, &ex_length))
			return false;
		mcc.length = ((uint16_t) length << 8) | ex_length;
		mcc.length = GET_LEN16(mcc.length);
	}

	type = RFCOMM_GET_MCC_TYPE(mcc.type);

	for (i = 0; mcc_table[i].str; i++) {
		if (mcc_table[i].type == type) {
			mcc_data = &mcc_table[i];
			break;
		}
	}

	if (mcc_data)
		type_str = mcc_data->str;
	else
		type_str = "Unknown";

	print_field("%*cMCC Message type: %s %s (0x%2.2x)", indent, ' ',
				type_str, CR_STR(mcc.type), type);

	print_field("%*cLength: %d", indent+2, ' ', mcc.length);

	rfcomm_frame->mcc = mcc;

	switch (type) {
	case RFCOMM_TEST:
		return mcc_test(rfcomm_frame, indent+10);
	case RFCOMM_MSC:
		return mcc_msc(rfcomm_frame, indent+2);
	case RFCOMM_RPN:
		return mcc_rpn(rfcomm_frame, indent+2);
	case RFCOMM_RLS:
		return mcc_rls(rfcomm_frame, indent+2);
	case RFCOMM_PN:
		return mcc_pn(rfcomm_frame, indent+2);
	case RFCOMM_NSC:
		return mcc_nsc(rfcomm_frame, indent+2);
	default:
		packet_hexdump(frame->data, frame->size);
	}

	return true;
}