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); } }
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; }