From e4d94344b4b7d98c368e35c77a52ab3e30bce5a4 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 21:47:07 +0000 Subject: [PATCH] hcidump: Parser fixes. Header update. --- tools/parser/rfcomm.c | 88 +++++---- tools/parser/rfcomm.h | 442 +++++++++++++++++++++++++++++------------- 2 files changed, 357 insertions(+), 173 deletions(-) diff --git a/tools/parser/rfcomm.c b/tools/parser/rfcomm.c index f50e6321a..c12f6ffb7 100644 --- a/tools/parser/rfcomm.c +++ b/tools/parser/rfcomm.c @@ -40,8 +40,8 @@ #include -#include "rfcomm.h" #include "parser.h" +#include "rfcomm.h" static char *cr_str[] = { "RSP", @@ -49,12 +49,13 @@ static char *cr_str[] = { }; #define CR_STR(mcc_head) cr_str[mcc_head->type.cr] +#define GET_DLCI(addr) ((addr.server_chn << 1) | (addr.d & 1)) void print_rfcomm_hdr(long_frame_head* head, __u8 *ptr, int len) { address_field addr = head->addr; __u8 ctr = head->control; - __u16 ilen = head->length.len; + __u16 ilen = head->length.bits.len; __u8 ctr_type,pf,dlci,fcs; dlci = GET_DLCI(addr); @@ -67,7 +68,7 @@ void print_rfcomm_hdr(long_frame_head* head, __u8 *ptr, int len) void print_mcc(mcc_long_frame_head* mcc_head) { - printf("mcc_len %d\n", mcc_head->length.len); + printf("mcc_len %d\n", mcc_head->length.bits.len); } static inline void mcc_test(int level, __u8 *ptr, int len, @@ -86,6 +87,7 @@ static inline void mcc_fcon(int level, __u8 *ptr, int len, print_rfcomm_hdr(head, ptr, len); print_mcc(mcc_head); } + static inline void mcc_fcoff(int level, __u8 *ptr, int len, long_frame_head *head, mcc_long_frame_head *mcc_head) @@ -94,37 +96,48 @@ static inline void mcc_fcoff(int level, __u8 *ptr, int len, print_rfcomm_hdr(head, ptr, len); print_mcc(mcc_head); } + static inline void mcc_msc(int level, __u8 *ptr, int len, long_frame_head *head, mcc_long_frame_head *mcc_head) { - msc_data *msc = (void*) ptr; + msc_msg *msc = (void*) (ptr - STRUCT_END(msc_msg, mcc_s_head)); printf("MSC %s: ", CR_STR(mcc_head)); print_rfcomm_hdr(head, ptr, len); print_mcc(mcc_head); p_indent(level, 0); printf("dlci %d fc %d rtc %d rtr %d ic %d dv %d", - GET_DLCI(msc->addr), msc->v24_sigs.fc, msc->v24_sigs.rtc, + GET_DLCI(msc->dlci), msc->v24_sigs.fc, msc->v24_sigs.rtc, msc->v24_sigs.rtr, msc->v24_sigs.ic, msc->v24_sigs.dv ); - if (len == MSC_DATA_BREAK_SIZE) - printf(" b1 %d b2 %d b3 %d len %d\n", msc->brk_sigs.b1, - msc->brk_sigs.b2, msc->brk_sigs.b3, msc->brk_sigs.len); + + /* Assuming that break_signals field is _not declared_ in + struct msc_msg... */ + if (len > + STRUCT_OFFSET(msc_msg, fcs) - STRUCT_END(msc_msg, v24_sigs)) { + break_signals *brk = (break_signals *) + (ptr + STRUCT_END(msc_msg, v24_sigs)); + printf(" b1 %d b2 %d b3 %d len %d\n", + brk->b1, brk->b2, brk->b3, brk->len); + } else printf("\n"); } + static inline void mcc_rpn(int level, __u8 *ptr, int len, long_frame_head *head, mcc_long_frame_head *mcc_head) { - rpn_data *rpn = (void*) ptr; + rpn_msg *rpn = (void*) (ptr - STRUCT_END(rpn_msg, mcc_s_head)); printf("RPN %s: ", CR_STR(mcc_head)); print_rfcomm_hdr(head, ptr, len); print_mcc(mcc_head); - printf("dlci %d ", GET_DLCI(rpn->addr)); + printf("dlci %d ", GET_DLCI(rpn->dlci)); - if (len == RPN_DATA_NO_RPN_SIZE) { + /* Assuming that rpn_val is _declared_ as a member of rpn_msg... */ + if (len <= + STRUCT_OFFSET(rpn_msg, rpn_val) - STRUCT_END(rpn_msg, mcc_s_head)) { printf("\n"); return; } @@ -138,35 +151,38 @@ static inline void mcc_rpn(int level, __u8 *ptr, int len, printf(" rtri: %d rtro: %d rtci: %d rtco: %d xon: %d xoff: %d pm: %04x", rpn->rpn_val.rtr_input, rpn->rpn_val.rtr_output, rpn->rpn_val.rtc_input, rpn->rpn_val.rtc_output, - rpn->rpn_val.xon___u8, rpn->rpn_val.xoff___u8, - *((__u16*)&rpn->rpn_val.pm)); + rpn->rpn_val.xon, rpn->rpn_val.xoff, + btohs(*(__u16 *)&(rpn->rpn_val.pm))); } + static inline void mcc_rls(int level, __u8 *ptr, int len, long_frame_head *head, mcc_long_frame_head *mcc_head) { - rls_data* rls = (void*) ptr; + rls_msg* rls = (void*) (ptr - STRUCT_END(rls_msg, mcc_s_head)); - printf("RLS %s ", CR_STR(mcc_head)); + printf("RLS %s: ", CR_STR(mcc_head)); print_rfcomm_hdr(head, ptr, len); print_mcc(mcc_head); - printf("dlci %d error: %d", GET_DLCI(rls->addr), rls->error); + printf("dlci %d error: %d", GET_DLCI(rls->dlci), rls->error); } + static inline void mcc_pn(int level, __u8 *ptr, int len, long_frame_head *head, mcc_long_frame_head *mcc_head) { - pn_data *pn = (void*) ptr; + pn_msg *pn = (void*) (ptr - STRUCT_END(pn_msg, mcc_s_head)); - printf("PN %s", CR_STR(mcc_head)); + printf("PN %s: ", CR_STR(mcc_head)); print_rfcomm_hdr(head, ptr, len); print_mcc(mcc_head); p_indent(level, 0); - printf("dlci %d frame_type %d conv_lay %d pri %d ack_timer %d " - "frame_size %d max_retrans %d win_size %d\n", - pn->dlci, pn->frame_type, pn->conv_layer, pn->pri, - pn->ack_timer, pn->frame_size, pn->max_retrans, pn->win_size); + printf("dlci %d frame_type %d credit_flow %d pri %d ack_timer %d " + "frame_size %d max_retrans %d credits %d\n", + pn->dlci, pn->frame_type, pn->credit_flow, pn->prior, + pn->ack_timer, btohs(pn->frame_size), pn->max_nbrof_retrans, + pn->credits); } static inline void mcc_nsc(int level, __u8 *ptr, int len, @@ -174,7 +190,7 @@ static inline void mcc_nsc(int level, __u8 *ptr, int len, mcc_long_frame_head *mcc_head) { - nsc_data *nsc = (void*) ptr; + nsc_msg *nsc = (void*) (ptr - STRUCT_END(nsc_msg, mcc_s_head)); printf("NSC %s: ", CR_STR(mcc_head)); print_rfcomm_hdr(head, ptr, len); @@ -182,7 +198,7 @@ static inline void mcc_nsc(int level, __u8 *ptr, int len, p_indent(level, 0); printf("cr %d, mcc_cmd_type %x\n", - nsc->cmd_type.cr, nsc->cmd_type.type ); + nsc->command_type.cr, nsc->command_type.type ); } static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head) @@ -193,11 +209,12 @@ static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head if ( mcc_short_head_p->length.ea == EA ) { mcc_head.type = mcc_short_head_p->type; - mcc_head.length.len = mcc_short_head_p->length.len; - hdr_size = MCC_SHORT_FRAME_HEAD_SIZE; + 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; - hdr_size = MCC_LONG_FRAME_HEAD_SIZE; + mcc_head.length.val = btohs(mcc_head.length.val); + hdr_size = sizeof(mcc_long_frame_head); } frm->ptr += hdr_size; @@ -221,19 +238,19 @@ static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head mcc_msc(level, frm->ptr, frm->len, head, &mcc_head); break; case RPN: - mcc_test(level, frm->ptr, frm->len, head, &mcc_head); + mcc_rpn(level, frm->ptr, frm->len, head, &mcc_head); break; case RLS: - mcc_test(level, frm->ptr, frm->len, head, &mcc_head); + mcc_rls(level, frm->ptr, frm->len, head, &mcc_head); break; case PN: - mcc_test(level, frm->ptr, frm->len, head, &mcc_head); + mcc_pn(level, frm->ptr, frm->len, head, &mcc_head); break; case NSC: - mcc_test(level, frm->ptr, frm->len, head, &mcc_head); + mcc_nsc(level, frm->ptr, frm->len, head, &mcc_head); break; default: - printf("MCC ERR: "); + printf("MCC message type 0x%02x: ", mcc_head.type.type); print_rfcomm_hdr(head, frm->ptr, frm->len); printf("\n"); @@ -266,11 +283,12 @@ void rfcomm_dump(int level, struct frame *frm) if (short_head_p->length.ea == EA) { head.addr = short_head_p->addr; head.control = short_head_p->control; - head.length.len = short_head_p->length.len; - hdr_size = SHORT_FRAME_HEAD_SIZE; + head.length.bits.len = short_head_p->length.len; + hdr_size = sizeof(short_frame_head); } else { head = *(long_frame_head *) frm->ptr; - hdr_size = LONG_FRAME_HEAD_SIZE; + head.length.val = btohs(head.length.val); + hdr_size = sizeof(long_frame_head); } frm->ptr += hdr_size; diff --git a/tools/parser/rfcomm.h b/tools/parser/rfcomm.h index dee406c36..3823773d5 100644 --- a/tools/parser/rfcomm.h +++ b/tools/parser/rfcomm.h @@ -24,30 +24,36 @@ Copyright (C) 2001 Wayne Lee */ -/* - RFCOMM frame processing engine is based on: - Implementation of Bluetooth RFCOMM with TS 07.10, Serial Port Emulation - Copyright (C) 2000, 2001 Axis Communications AB - Author: Mats Friden -*/ - /* * $Id$ */ -#include +#include + +#define RFCOMM_PSM 3 + +#define TRUE 1 +#define FALSE 0 + +#define RFCOMM_MAX_CONN 10 +#define BT_NBR_DATAPORTS RFCOMM_MAX_CONN #define GET_BIT(pos,bitfield) ((bitfield[(pos)/32]) & (1 << ((pos) % 32))) #define SET_BIT(pos,bitfield) ((bitfield[(pos)/32]) |= (1 << ((pos) % 32))) #define CLR_BIT(pos,bitfield) ((bitfield[(pos)/32]) &= ((1 << ((pos) % 32)) ^ (~0))) #define SET_PF(ctr) ((ctr) | (1 << 4)) - /* Sets the P/F-bit in the control field */ #define CLR_PF(ctr) ((ctr) & 0xef) -/* Clears the P/F-bit in the control field */ +/* clears the P/F-bit in the control field */ #define GET_PF(ctr) (((ctr) >> 4) & 0x1) /* Returns the P/F bit */ +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* endian-swapping macros for structs */ +#define swap_long_frame(x) ((x)->h.length.val = le16_to_cpu((x)->h.length.val)) +#define swap_mcc_long_frame(x) (swap_long_frame(x)) + #define SHORT_CRC_CHECK 2 /* Used for uih packets */ #define LONG_CRC_CHECK 3 @@ -57,6 +63,7 @@ #define LONG_HDR 3 /* and long header for long uih packets */ +/* FIXME: Should thsi one be define here? */ #define SHORT_PAYLOAD_SIZE 127 #define EA 1 /* Used for setting the EA field in different packets, really neccessary? */ @@ -65,46 +72,146 @@ #define RFCOMM_MAX_HDR_SIZE 5 -#define NBROFCREDITS 6 +#define MAX_CREDITS 30 +#define START_CREDITS 7 +#define MIN_CREDITS 6 #define DEF_RFCOMM_MTU 127 /* The values in the control field when sending ordinary rfcomm packets */ -#define SABM 0x2f +#define SABM 0x2f /* set asynchronous balanced mode */ +#define UA 0x63 /* unnumbered acknolodgement */ +#define DM 0x0f /* disconnected mode */ +#define DISC 0x43 /* disconnect */ +#define UIH 0xef /* unnumbered information with header check (only) */ +#define UI 0x03 /* unnumbered information (with all data check) */ + #define SABM_SIZE 4 -#define UA 0x63 -#define UA_SIZE 4 -#define DM 0x0f -#define DISC 0x43 -#define UIH 0xef +#define UA_SIZE 4 /* The values in the type field in a multiplexer command packet */ -#define TEST 0x8 -#define FCON 0x28 -#define FCOFF 0x18 -#define MSC 0x38 -#define RPN 0x24 -#define RLS 0x14 -#define PN 0x20 -#define NSC 0x4 +#define PN (0x80 >> 2) /* parameter negotiation */ +#define PSC (0x40 >> 2) /* power saving control */ +#define CLD (0xc0 >> 2) /* close down */ +#define TEST (0x20 >> 2) /* test */ +#define FCON (0xa0 >> 2) /* flow control on */ +#define FCOFF (0x60 >> 2) /* flow control off */ +#define MSC (0xe0 >> 2) /* modem status command */ +#define NSC (0x10 >> 2) /* not supported command response */ +#define RPN (0x90 >> 2) /* remote port negotiation */ +#define RLS (0x50 >> 2) /* remote line status */ +#define SNC (0xd0 >> 2) /* service negotiation command */ /* Define of some V.24 signals modem control signals in RFCOMM */ -#define FC 0x2 -#define RTC 0x4 -#define RTR 0x8 -#define DV 0x80 +#define DV 0x80 /* data valid */ +#define IC 0x40 /* incoming call */ +#define RTR 0x08 /* ready to receive */ +#define RTC 0x04 /* ready to communicate */ +#define FC 0x02 /* flow control (unable to accept frames) */ -#define PPP_DLCI 2 /* The virtual port for ppp */ -#define CTRL_CHAN 0 /* The control channel is defined as DLCI 0 in rfcomm */ +#define CTRL_CHAN 0 /* The control channel is defined as DLCI 0 in rfcomm */ #define MCC_CMD 1 /* Multiplexer command */ #define MCC_RSP 0 /* Multiplexer response */ /****************** TYPE DEFINITION SECTION *********************************/ +#ifdef __LITTLE_ENDIAN_BITFIELD + +typedef struct parameter_mask{ + __u8 bit_rate:1; + __u8 data_bits:1; + __u8 stop_bit:1; + __u8 parity:1; + __u8 parity_type:1; + __u8 xon:1; + __u8 xoff:1; + __u8 res1:1; + __u8 xon_input:1; + __u8 xon_output:1; + __u8 rtr_input:1; + __u8 rtr_output:1; + __u8 rtc_input:1; + __u8 rtc_output:1; + __u8 res2:2; +} __attribute__ ((packed)) parameter_mask; + +typedef struct rpn_values{ + __u8 bit_rate; + __u8 data_bits:2; + __u8 stop_bit:1; + __u8 parity:1; + __u8 parity_type:2; + __u8 res1:2; + __u8 xon_input:1; + __u8 xon_output:1; + __u8 rtr_input:1; + __u8 rtr_output:1; + __u8 rtc_input:1; + __u8 rtc_output:1; + __u8 res2:2; + __u8 xon; + __u8 xoff; + parameter_mask pm; +} __attribute__ ((packed)) rpn_values; + +#elif defined(__BIG_ENDIAN_BITFIELD) + +typedef struct parameter_mask{ + __u8 res1:1; + __u8 xoff:1; + __u8 xon:1; + __u8 parity_type:1; + __u8 parity:1; + __u8 stop_bit:1; + __u8 data_bits:1; + __u8 bit_rate:1; + + __u8 res2:2; + __u8 rtc_output:1; + __u8 rtc_input:1; + __u8 rtr_output:1; + __u8 rtr_input:1; + __u8 xon_output:1; + __u8 xon_input:1; + +} __attribute__ ((packed)) parameter_mask; + +typedef struct rpn_values{ + __u8 bit_rate; + + __u8 res1:2; + __u8 parity_type:2; + __u8 parity:1; + __u8 stop_bit:1; + __u8 data_bits:2; + + __u8 res2:2; + __u8 rtc_output:1; + __u8 rtc_input:1; + __u8 rtr_output:1; + __u8 rtr_input:1; + __u8 xon_output:1; + __u8 xon_input:1; + + __u8 xon; + __u8 xoff; + parameter_mask pm; +} __attribute__ ((packed)) rpn_values; + +#else /* __XXX_BITFIELD */ +#error Processor endianness unknown! +#endif + +/****************************************************************************/ + +/****************** TYPE DEFINITION SECTION *********************************/ + /* Typedefinitions of stuctures used for creating and parsing packets, for a further description of the structures please se the bluetooth core specification part F:1 and the ETSI TS 07.10 specification */ +#ifdef __LITTLE_ENDIAN_BITFIELD + typedef struct address_field { __u8 ea:1; __u8 cr:1; @@ -112,16 +219,17 @@ typedef struct address_field { __u8 server_chn:5; } __attribute__ ((packed)) address_field; -#define GET_DLCI(addr) ((addr.server_chn << 1) | (addr.d & 1)) - typedef struct short_length { - __u8 ea:1; - __u8 len:7; + __u8 ea:1; + __u8 len:7; } __attribute__ ((packed)) short_length; -typedef struct long_length { - __u16 ea:1; - __u16 len:15; +typedef union long_length { + struct bits { + __u8 ea:1; + unsigned short len:15; + } __attribute__ ((packed)) bits ; + __u16 val ; } __attribute__ ((packed)) long_length; typedef struct short_frame_head { @@ -129,19 +237,18 @@ typedef struct short_frame_head { __u8 control; short_length length; } __attribute__ ((packed)) short_frame_head; -#define SHORT_FRAME_HEAD_SIZE 3 typedef struct short_frame { short_frame_head h; - __u8 data[0]; + __u8 data[0]; } __attribute__ ((packed)) short_frame; typedef struct long_frame_head { address_field addr; __u8 control; long_length length; + __u8 data[0]; } __attribute__ ((packed)) long_frame_head; -#define LONG_FRAME_HEAD_SIZE 4 typedef struct long_frame { long_frame_head h; @@ -151,15 +258,15 @@ typedef struct long_frame { /* Typedefinitions for structures used for the multiplexer commands */ typedef struct mcc_type { __u8 ea:1; - __u8 cr:1; + __u8 cr:1; __u8 type:6; } __attribute__ ((packed)) mcc_type; typedef struct mcc_short_frame_head { mcc_type type; short_length length; + __u8 value[0]; } __attribute__ ((packed)) mcc_short_frame_head; -#define MCC_SHORT_FRAME_HEAD_SIZE 2 typedef struct mcc_short_frame { mcc_short_frame_head h; @@ -169,8 +276,8 @@ typedef struct mcc_short_frame { typedef struct mcc_long_frame_head { mcc_type type; long_length length; + __u8 value[0]; } __attribute__ ((packed)) mcc_long_frame_head; -#define MCC_LONG_FRAME_HEAD_SIZE 3 typedef struct mcc_long_frame { mcc_long_frame_head h; @@ -188,87 +295,23 @@ typedef struct v24_signals { __u8 dv:1; } __attribute__ ((packed)) v24_signals; -typedef struct brk_signals { +typedef struct break_signals { __u8 ea:1; __u8 b1:1; __u8 b2:1; __u8 b3:1; __u8 len:4; -} __attribute__ ((packed)) brk_signals; - -typedef struct msc_data { - address_field addr; - v24_signals v24_sigs; - brk_signals brk_sigs; - __u8 fcs; -} __attribute__ ((packed)) msc_data; -#define MSC_DATA_NO_BREAK_SIZE 2 -#define MSC_DATA_BREAK_SIZE 3 +} __attribute__ ((packed)) break_signals; typedef struct msc_msg { short_frame_head s_head; mcc_short_frame_head mcc_s_head; address_field dlci; - __u8 v24_sigs; - //brk_sigs break_signals; + v24_signals v24_sigs; + //break_signals break_sigs; __u8 fcs; } __attribute__ ((packed)) msc_msg; -/* RPN command */ -#define B2400 0 -#define B4800 1 -#define B7200 2 -#define B9600 3 -#define B19200 4 -#define B38400 5 -#define B57600 6 -#define B115200 7 -#define D230400 8 - -typedef struct parameter_mask { - __u8 bit_rate:1; - __u8 data_bits:1; - __u8 stop_bit:1; - __u8 parity:1; - __u8 parity_type:1; - __u8 xon___u8:1; - __u8 xoff___u8:1; - __u8 res1:1; - __u8 xon_input:1; - __u8 xon_output:1; - __u8 rtr_input:1; - __u8 rtr_output:1; - __u8 rtc_input:1; - __u8 rtc_output:1; - __u8 res2:2; -} __attribute__ ((packed)) parameter_mask; - -typedef struct rpn_values { - __u8 bit_rate; - __u8 data_bits:2; - __u8 stop_bit:1; - __u8 parity:1; - __u8 parity_type:2; - __u8 res1:2; - __u8 xon_input:1; - __u8 xon_output:1; - __u8 rtr_input:1; - __u8 rtr_output:1; - __u8 rtc_input:1; - __u8 rtc_output:1; - __u8 res2:2; - __u8 xon___u8; - __u8 xoff___u8; - parameter_mask pm; -} __attribute__ ((packed)) rpn_values; - -typedef struct rpn_data { - address_field addr; - rpn_values rpn_val; -} __attribute__ ((packed)) rpn_data; -#define RPN_DATA_NO_RPN_SIZE 1 -#define RPN_DATA_SIZE 8 - typedef struct rpn_msg { short_frame_head s_head; mcc_short_frame_head mcc_s_head; @@ -278,13 +321,7 @@ typedef struct rpn_msg { } __attribute__ ((packed)) rpn_msg; /* RLS-command */ -typedef struct rls_data{ - address_field addr; - __u8 error:4; - __u8 res:4; -} __attribute__ ((packed)) rls_data; - -typedef struct rls_msg{ +typedef struct rls_msg { short_frame_head s_head; mcc_short_frame_head mcc_s_head; address_field dlci; @@ -293,24 +330,11 @@ typedef struct rls_msg{ __u8 fcs; } __attribute__ ((packed)) rls_msg; -/* PN-command */ -typedef struct pn_data { - __u8 dlci:6; - __u8 res1:2; - __u8 frame_type:4; - __u8 conv_layer:4; - __u8 pri:6; - __u8 res2:2; - __u8 ack_timer; - __u16 frame_size; - __u8 max_retrans; - __u8 win_size; -} __attribute__ ((packed)) pn_data; - /* PN-command */ typedef struct pn_msg { short_frame_head s_head; mcc_short_frame_head mcc_s_head; +/* The res1, res2 and res3 values have to be set to 0 by the sender */ __u8 dlci:6; __u8 res1:2; __u8 frame_type:4; @@ -318,20 +342,162 @@ typedef struct pn_msg { __u8 prior:6; __u8 res2:2; __u8 ack_timer; - __u32 frame_size:16; + __u16 frame_size:16; __u8 max_nbrof_retrans; __u8 credits; __u8 fcs; } __attribute__ ((packed)) pn_msg; /* NSC-command */ -typedef struct nsc_data{ - mcc_type cmd_type; -} __attribute__ ((packed)) nsc_data; +typedef struct nsc_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + mcc_type command_type; + __u8 fcs; +} __attribute__ ((packed)) nsc_msg; + +#elif defined(__BIG_ENDIAN_BITFIELD) + +typedef struct address_field { + __u8 server_chn:5; + __u8 d:1; + __u8 cr:1; + __u8 ea:1; +} __attribute__ ((packed)) address_field; + +typedef struct short_length { + __u8 len:7; + __u8 ea:1; +} __attribute__ ((packed)) short_length; + +typedef union long_length { + struct bits { + unsigned short len:15; + __u8 ea:1; + } __attribute__ ((packed)) bits; + __u16 val; +} __attribute__ ((packed)) long_length; + +typedef struct short_frame_head { + address_field addr; + __u8 control; + short_length length; +} __attribute__ ((packed)) short_frame_head; + +typedef struct short_frame { + short_frame_head h; + __u8 data[0]; +} __attribute__ ((packed)) short_frame; + +typedef struct long_frame_head { + address_field addr; + __u8 control; + long_length length; + __u8 data[0]; +} __attribute__ ((packed)) long_frame_head; + +typedef struct long_frame { + long_frame_head h; + __u8 data[0]; +} __attribute__ ((packed)) long_frame; + +typedef struct mcc_type { + __u8 type:6; + __u8 cr:1; + __u8 ea:1; +} __attribute__ ((packed)) mcc_type; + +typedef struct mcc_short_frame_head { + mcc_type type; + short_length length; + __u8 value[0]; +} __attribute__ ((packed)) mcc_short_frame_head; + +typedef struct mcc_short_frame { + mcc_short_frame_head h; + __u8 value[0]; +} __attribute__ ((packed)) mcc_short_frame; + +typedef struct mcc_long_frame_head { + mcc_type type; + long_length length; + __u8 value[0]; +} __attribute__ ((packed)) mcc_long_frame_head; + +typedef struct mcc_long_frame { + mcc_long_frame_head h; + __u8 value[0]; +} __attribute__ ((packed)) mcc_long_frame; + +typedef struct v24_signals { + __u8 dv:1; + __u8 ic:1; + __u8 reserved:2; + __u8 rtr:1; + __u8 rtc:1; + __u8 fc:1; + __u8 ea:1; +} __attribute__ ((packed)) v24_signals; + +typedef struct break_signals { + __u8 len:4; + __u8 b3:1; + __u8 b2:1; + __u8 b1:1; + __u8 ea:1; +} __attribute__ ((packed)) break_signals; + +typedef struct msc_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + v24_signals v24_sigs; + //break_signals break_sigs; + __u8 fcs; +} __attribute__ ((packed)) msc_msg; + +typedef struct rpn_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + rpn_values rpn_val; + __u8 fcs; +} __attribute__ ((packed)) rpn_msg; + +typedef struct rls_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + __u8 res:4; + __u8 error:4; + __u8 fcs; +} __attribute__ ((packed)) rls_msg; -typedef struct nsc_msg{ +typedef struct pn_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + __u8 res1:2; + __u8 dlci:6; + __u8 credit_flow:4; + __u8 frame_type:4; + __u8 res2:2; + __u8 prior:6; + __u8 ack_timer; + __u16 frame_size:16; + __u8 max_nbrof_retrans; + __u8 credits; + __u8 fcs; +} __attribute__ ((packed)) pn_msg; + +typedef struct nsc_msg { short_frame_head s_head; mcc_short_frame_head mcc_s_head; mcc_type command_type; __u8 fcs; } __attribute__ ((packed)) nsc_msg; + +#else /* __XXX_ENDIAN */ +#error Processor endianness unknown! +#endif /* __XXX_ENDIAN */ + +/****************************************************************************/ -- 2.47.3