static inline void test_array_item(unsigned t, struct bitvec *b, unsigned int n, uint32_t *array, unsigned int p) { unsigned int i, x, y; bitvec_zero(b); x = b->cur_bit; i = bitvec_add_array(b, array, n, true, t); y = b->cur_bit; bitvec_add_array(b, array, n, false, t); printf("\nbits: %u, est: %u, real: %u, x: %u, y: %u\n", t, i, b->cur_bit, x, y); for (i = 0; i < p; i++) { printf(OSMO_BIT_SPEC " ", OSMO_BIT_PRINT(b->data[i])); if (0 == (i + 1) % 15) printf("\n"); } }
/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */ int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts) { int rc; struct bitvec bv; if (bts->si2q_count < bts->si2q_index) return -EINVAL; bv.data = data; bv.data_len = 20; bitvec_zero(&bv); /* BA_IND: Set to '0' as that's what we use for SI2xxx type, * whereas '1' is used for SI5xxx type messages. The point here * is to be able to correlate whether a given MS measurement * report was using the neighbor cells advertised in SI2 or in * SI5, as those two could very well be different */ bitvec_set_bit(&bv, 0); /* 3G_BA_IND */ bitvec_set_bit(&bv, 1); /* MP_CHANGE_MARK */ bitvec_set_bit(&bv, 0); /* SI2quater_INDEX */ bitvec_set_uint(&bv, bts->si2q_index, 4); /* SI2quater_COUNT */ bitvec_set_uint(&bv, bts->si2q_count, 4); /* No Measurement_Parameters Description */ bitvec_set_bit(&bv, 0); /* No GPRS_Real Time Difference Description */ bitvec_set_bit(&bv, 0); /* No GPRS_BSIC Description */ bitvec_set_bit(&bv, 0); /* No GPRS_REPORT PRIORITY Description */ bitvec_set_bit(&bv, 0); /* No GPRS_MEASUREMENT_Parameters Description */ bitvec_set_bit(&bv, 0); /* No NC Measurement Parameters */ bitvec_set_bit(&bv, 0); /* No extension (length) */ bitvec_set_bit(&bv, 0); rc = SI2Q_MAX_LEN - (bv.cur_bit + 3); if (rc > 0 && bts->si_common.uarfcn_length - bts->u_offset > 0) { rc = append_uarfcns(&bv, bts, rc); if (rc < 0) { LOGP(DRR, LOGL_ERROR, "SI2quater [%u/%u]: failed to append %zu UARFCNs due to range encoding " "failure: %s\n", bts->si2q_index, bts->si2q_count, bts->si_common.uarfcn_length, strerror(-rc)); return rc; } } else /* No 3G Neighbour Cell Description */ bitvec_set_bit(&bv, 0); /* No 3G Measurement Parameters Description */ bitvec_set_bit(&bv, 0); /* No GPRS_3G_MEASUREMENT Parameters Descr. */ bitvec_set_bit(&bv, 0); rc = SI2Q_MAX_LEN - bv.cur_bit; if (rc > 0 && si2q_earfcn_count(&bts->si_common.si2quater_neigh_list) - bts->e_offset > 0) append_earfcn(&bv, bts, rc); else /* No Additions in Rel-5: */ bitvec_set_bit(&bv, L); bitvec_spare_padding(&bv, (bv.data_len * 8) - 1); return bv.data_len; }
int main(int argc, char **argv) { struct bitvec bv; uint8_t i = 8, test[i]; memset(test, 0, i); bv.data_len = i; bv.data = test; bv.cur_bit = 0; printf("test shifting...\n"); bitvec_set_uint(&bv, 0x0E, 7); test_shift(&bv, 3); test_shift(&bv, 17); bitvec_set_uint(&bv, 0, 32); bitvec_set_uint(&bv, 0x0A, 7); test_shift(&bv, 24); printf("checking RL functions...\n"); bitvec_zero(&bv); test_rl(&bv); bitvec_set_uint(&bv, 0x000F, 32); test_rl(&bv); bitvec_shiftl(&bv, 18); test_rl(&bv); bitvec_set_uint(&bv, 0x0F, 8); test_rl(&bv); bitvec_zero(&bv); bitvec_set_uint(&bv, 0xFF, 8); test_rl(&bv); bitvec_set_uint(&bv, 0xFE, 7); test_rl(&bv); bitvec_set_uint(&bv, 0, 17); test_rl(&bv); bitvec_shiftl(&bv, 18); test_rl(&bv); printf("probing bit access...\n"); bitvec_zero(&bv); bitvec_set_uint(&bv, 0x3747817, 32); bitvec_shiftl(&bv, 10); test_get(&bv, 2); test_get(&bv, 7); test_get(&bv, 9); test_get(&bv, 13); test_get(&bv, 16); test_get(&bv, 42); printf("feeling bit fills...\n"); test_set(&bv, ONE); test_fill(&bv, 3, ZERO); test_spare(&bv, 38); test_spare(&bv, 43); test_spare(&bv, 1); test_spare(&bv, 7); test_fill(&bv, 5, ONE); test_fill(&bv, 3, L); printf("byte me...\n"); test_byte_ops(); test_unhex("48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b"); test_unhex("47240c00400000000000000079eb2ac9402b2b2b2b2b2b"); test_unhex("47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b"); test_unhex("DEADFACE000000000000000000000000000000BEEFFEED"); test_unhex("FFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); printf("arrr...\n"); test_array(); printf("\nbitvec ok.\n"); return 0; }