why the msg type field is expanded upto 5 bits "<<4" and the field dup is expanded upto 4 bits "<<3" ?
<<
doesn't "expand" the field, it shifts it left.
Initially, each of our numbers looks like this:
bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
======================================================================
|------------- type ------------|
|- dup -|
|----- qos -----|
| retain|
Assuming that each of the numbers is in a valid range for that field, then they are already the correct width. Specifically, type
can have a value from 0 to 15, so it is (up to) 4 bits wide; dup
and retain
must be 0 or 1 so are only 1 bit wide; qos
can have a value from 0 to 3, which is 2 bits wide.
But, they are in the wrong place. They are stuck down in the low bits (3,2,1,0). We need to shift them left to get them to the correct positions:
bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
======================================================================
|----------- type<<4 -----------|
| dup<<3|
|---- qos<<1 ---|
| retain|
For example, dup
is shifted left 3 bits because we want 3 spaces (actually bits of value 0) below it. retain
does not need to be shifted because it happened to be in the correct place already.
Once all the bits are in the correct place, they are ORed together using |
to give this byte:
bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
======================================================================
|----------- type<<4 -----------| dup<<3|---- qos<<1 ---| retain|
Which is what is wanted.