Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: Re: [Wireshark-dev] Dissect data on a bit-by-bit basis

From: Tomasz Moń <desowin@xxxxxxxxx>
Date: Thu, 23 Jul 2020 09:07:01 +0200
On Thu, Jul 23, 2020 at 8:18 AM Guy Harris <gharris@xxxxxxxxx> wrote:
> On Jul 21, 2020, at 6:04 PM, Filipe Laíns <lains@xxxxxxxxxxxxx> wrote:
> > I am working on the USB HID dissector and I need to dissect data on a
> > bit by bit basis, instead of byte. The data structure is completely
> > dynamic (described by the HID descriptor) and the basic data block is
> > the bit. Any bit or sequence of bits can have a meaning, the data can
> > be completely unaligned. See the following example which shows
> > different fields distributed in a 2 byte packet.
> >
> >
> > 0110000000011111
> > ^^^\__^___/\_^_/
> > |||   |      |
> > |||   |      | Y axis (5 bit wide)
> > |||   |
> > |||   | X axis (8 bit wide)
> > |||
> > ||| button 3
> > ||
> > || button 2
> > |
> > | button 1
>
> That's 16 bits, so, while individual data *items* may be completely unaligned, the mouse report itself can be aligned on a byte or possibly even 16-bit boundary.
>
> If that's the case, then this is fairly easy.  You can just define Boolean (FT_BOOLEAN) button1, button2, and button3 fields, an 8-bit integral (FT_UINT16 if unsigned, FT_INT16 if unsigned) x field, and a 5-bit integral (again, FT_UINT16 or FT_INT16) y field, with bitfields in the field definition.  proto_tree_add_item() will handle extracting the relevant bits and displaying them as, for example:
>
>         0... .... .... .... = Button 1: up
>         .0.. .... .... .... = Button 2: up
>         ..1. .... .... .... = Button 3: down
>         ...0 0000 111. .... = X: 7
>         .... .... ...0 1111 = Y: 15
>
> If, however, the position and button information is *not* aligned on a 16-bit boundary, so that any of those fields can begin on an *arbitrary* bit boundary, you will have to use more complicated APIs, such as the ones described in John Thacker's message.

In this case, I think using proto_tree_add_bits_item() is actually
less complicated. The reason for that is that the actual bit positions
are only known at runtime, after dissecting the HID descriptor - the
order is determined by the HID report descriptor stored in USB HID
device firmware. The generic header field definitions can be created
beforehand, but the bit positions will only be known at runtime.