# Splitting NAV frames into fields

Pulling out the individual values out of the NAV frames, then converting them into the correct range of values is quite a struggle. Here is my solution!

First off, here are a few worker routines that pull a range of bits out of the NAV subfields (where the parity bits are in the lowest 6 bits of each value):

Return the lowest ‘n_bits’ bits of the value ‘u’:

```unsigned int mask(unsigned u, int n_bits) {
return u & ((1<<n_bits)-1);
}```

Bit ‘len’ is the sign, and if set it needs to be extended into all the more significant bits – note this returns an ‘int’ type:

```int sign_extend(unsigned u,int len) {
if(len < 32 && u >0)
if(u>>(len-1)&1) u |= 0xFFFFFFFF << len;
return (int)u;
}```

This is the key function to extract bits. It returns ‘len’ bits of the value ‘val’,starting with the bit at ‘offset’:

```unsigned int bits(int val, int offset, int len) {
}```

This extracts two sets of bits, from two different values, and then concatenates them together to build an unsigned value

```unsigned join_bits_u(int val1, int offset1, int len1,
int val2, int offset2, int len2) {
return (bits(val1, offset1, len1) << len2) | bits(val2, offset2, len2);
}```

This also extracts two sets of bits and concatenates them together, however it also sign-extends the leftmost bit, making a signed value:

```signed join_bits_s(int val1, int offset1, int len1,
int val2, int offset2, int len2) {
return sign_extend(join_bits_u(val1, offset1, len1, val2, offset2, len2),len1+len2);
}```

With this groundwork in place, extracting the parameters becomes pretty easy, and by always calling “join_bits” even if only one set of bits is needed makes it quite clean:

```/******** From FRAME 2 *******/
iode1     = join_bits_u(           0, 0, 0, n->frame2, 22, 8);
Crs       = join_bits_s(           0, 0, 0, n->frame2,  6,16) * pow(2.0,-5.0);
M0        = join_bits_s(n->frame2, 6, 8, n->frame2,  6,24) * pow(2.0,-31.0) * PI;
delta_n   = join_bits_s(           0, 0, 0, n->frame2, 14,16) * pow(2.0,-43.0) * PI;
Cuc       = join_bits_s(           0, 0, 0, n->frame2,  6,16) * pow(2.0,-29.0);
e         = join_bits_s(n->frame2, 6, 8, n->frame2,  6,24) * pow(2.0,-31.0);
Cus       = join_bits_s(           0, 0, 0, n->frame2, 14,16) * pow(2.0,-29.0);
sqrt_A    = join_bits_u(n->frame2, 6, 8, n->frame2,  6,24) * pow(2.0,-19.0);
Toe       = join_bits_u(           0, 0, 0, n->frame2, 14,16);
fit_flag  = join_bits_u(           0, 0, 0, n->frame2, 13, 1);
aodo      = join_bits_u(           0, 0, 0, n->frame2,  8, 6);

/******** From FRAME 3 *******/
Cic       = join_bits_s(           0, 0, 0, n->frame3, 14,16) * pow(2.0,-29.0);
omega_0   = join_bits_s(n->frame3, 6, 8, n->frame3,  6,24) * pow(2.0,-31.0) * PI;
Cis       = join_bits_s(           0, 0, 0, n->frame3, 14,16) * pow(2.0,-29.0);
i_0       = join_bits_s(n->frame3, 6, 8, n->frame3,  6,24) * pow(2.0,-31.0) * PI;
Crc       = join_bits_s(           0, 0, 0, n->frame3, 14,16) * pow(2.0,-5.0);
w         = join_bits_s(n->frame3, 6, 8, n->frame3,  6,24) * pow(2.0,-31.0) * PI;
omega_dot = join_bits_u(           0, 0, 0, n->frame3,  6,24) * pow(2.0,-43.0) * PI;
iode2     = join_bits_u(           0, 0, 0, n->frame3, 22, 8);
idot      = join_bits_s(           0, 0, 0, n->frame3,  8,14) * pow(2.0,-43.0) * PI;```