For a specified communication standard RTCM SC104 3.1, I need to split data across bytes as a pair of 12 bit data segments. So for a given message I need to place the message type number on the first byte and half of the second byte. Then I need to start an ID integer on the half of second byte and continue to the third byte. This sort of pattern continues to the end of the message shaving down other integers in 20bit, 5bit, and other sizes essentially cutting of the 0's that would normally fill out the MSB end of the integer values.
I have not seen a clear definition but I assume it must go out in network byte order so before copying bits I would have to reverse my integers in memory. I am still quite new to cpp and am wondering how do I get to the individual bytes making up an integer in memory? If I can access the bytes then I could use bitwise or to split the bits from 2 bytes onto one for the message.
Here's the start of building a message before adding the data:
//build message 1002 gps 00111110 1010
char buf1002[BUFFERSIZE];
buf1002[0] = 0x3E; //00111110
buf1002[1] = 0xA0; //10100000
//ref station id 12 bits of 16
//ex unsigned short m = 1100;
//m would be byte2 00000100 byte1 01001100
//buf1002[1] would be 10100100
//buf1002[2] would be 01001100
//reverse bit order for network after building?
The reference station will be from an unsigned short, so a 2 byte integer. So how do I go about reading a single byte from it? Do I start with a memory location pointer? If so then what?
Any help would be greatly appreciated.
You can use bit fields, like this - some caveats at the end:
typedef union packet {
struct {
unsigned int msgno : 12; // creates a 12 bit wide integral field
unsigned int msgtype : 12;
unsigned int somefield2 : 3;
unsigned int somefield3 : 5;
} fields;
unsigned char asbytes[4];
} packet;
...
packet p;
// fill it, by using the field side of the union
p.fields.msgno = 16;
p.fields.msgtype = 12;
p.fields.somefield2 = 6;
// and retrieving them as regular bytes
unsigned char abyte = p.asbytes[0];
abyte = p.asbytes[1];
// and so on
For me the main advantage is readability: all operations behave like regular operations on albeit narrower integral type variables. There are limitations (eg portability) but if you don't have to target multiple architectures or compilers or different endians it can help make your program a lot easier to read.
If you have your integer looking like 00001000 00000000 11000000 00110000 for example (i'm making spaces to difference each single bytes), contained in example in an int a:
int a;
int single_byte;
a = the_number;
You could do a function like
int get_byte_in_integer(int byte_number, int integer);
So that:
single_byte = get_byte_in_integer(1, a); // That would give you the 11000000 byte
with
int get_byte_in_integer(int byte_number, int integer)
{
return (integer >> (byte_number << 3)) & 0xff);
}
Hope this helps, for the byte part.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With