blob: d6653e329e94e2ed7696f24ad3465a5b87060888 [file] [log] [blame]
Max98186642017-10-18 13:14:49 +02001#include <inttypes.h>
2#include <stdbool.h>
3#include <errno.h>
4#include <stdint.h>
5
6#include <osmocom/core/utils.h>
7#include <osmocom/core/bits.h>
8#include <osmocom/core/bitvec.h>
9
10#define INTRO(p) printf("=== start %s(%u) ===\n", __func__, p)
11#define OUTRO(p) printf("=== end %s(%u) ===\n\n", __func__, p)
12
13static void test_bitvec_ia_octet_encode_pkt_dl_ass(struct bitvec *dest, uint32_t ttli,
14 uint8_t tfi, uint8_t gamma, uint8_t ta_valid, uint8_t ws_enc,
15 bool use_lh)
16{
17 unsigned wp = 0;
18
19 INTRO(use_lh);
20
21 /* 3GPP TS 44.018 §10.5.2.16 IA Rest Octets */
22 if (use_lh) /* FIXME: add function to encode LH properly */
23 bitvec_write_field(dest, &wp, 3, 2); /* "HH" */
24 else
25 bitvec_write_field(dest, &wp, 3, 2); /* "HH" */
26 bitvec_write_field(dest, &wp, 1, 2); /* "01" Packet Downlink Assignment */
27 bitvec_write_field(dest, &wp, ttli, 32); /* TLLI */
28 bitvec_write_field(dest, &wp, 1, 1); /* switch TFI: on */
29 bitvec_write_field(dest, &wp, tfi, 5); /* TFI */
30 bitvec_write_field(dest, &wp, 0x0, 1); /* RLC acknowledged mode */
31 bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = not present */
32 bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power control parameter */
33 bitvec_write_field(dest, &wp, 0,1); /* Polling Bit: off */
34 bitvec_write_field(dest, &wp, ta_valid, 1); /* N. B: NOT related to TAI! */
35 bitvec_write_field(dest, &wp, 0, 1); /* No TIMING_ADVANCE_INDEX: */
36 bitvec_write_field(dest, &wp, 0, 1); /* TBF Starting TIME present */
37 bitvec_write_field(dest, &wp, 0, 1); /* P0 not present */
38 if (use_lh) { /* FIXME: add function to encode LH properly */
39 bitvec_write_field(dest, &wp, 1, 1); /* "H" - additional for R99 */
40 } else
41 bitvec_write_field(dest, &wp, 1, 1); /* "H" - additional for R99 */
42 bitvec_write_field(dest, &wp, ws_enc, 5); /* EGPRS Window Size */
43 bitvec_write_field(dest, &wp, 0, 2); /* LINK_QUALITY_MEASUREMENT_MODE */
44 bitvec_write_field(dest, &wp, 0, 1); /* BEP_PERIOD2 not present */
45
46 printf("Encoded PKT DL ASS IA Rest Octets: %s\n", osmo_hexdump(dest->data, dest->data_len));
47
48 OUTRO(use_lh);
49}
50
51static void test_bitvec_ia_octet_encode_pkt_ul_ass(struct bitvec *dest, uint32_t fn,
52 uint8_t tfi, uint8_t gamma, uint8_t usf, bool tbf, bool use_lh)
53{
54 unsigned wp = 0;
55
56 INTRO(use_lh);
57
58 /* 3GPP TS 44.018 §10.5.2.37b 10.5.2.16 */
59 if (use_lh) /* FIXME: add function to encode LH properly */
60 bitvec_write_field(dest, &wp, 3, 2); /* "HH" */
61 else
62 bitvec_write_field(dest, &wp, 3, 2); /* "HH" */
63 bitvec_write_field(dest, &wp, 0, 2); /* "0" Packet Uplink Assignment */
64 if (!tbf) {
65 bitvec_write_field(dest, &wp, 0, 1); /* Block Allocation: SBA */
66 bitvec_write_field(dest, &wp, 0, 1); /* ALPHA = not present */
67 bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power control parameter */
68 bitvec_write_field(dest, &wp, 0, 1); /* No TIMING_ADVANCE_INDEX: */
69 bitvec_write_field(dest, &wp, 1, 1); /* TBF_STARTING_TIME_FLAG */
70 bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5); /* T1' */
71 bitvec_write_field(dest, &wp, fn % 51, 6); /* T3 */
72 bitvec_write_field(dest, &wp, fn % 26, 5); /* T2 */
73 } else {
74 bitvec_write_field(dest, &wp, 1, 1); /* Block Allocation: Not SBA */
75 bitvec_write_field(dest, &wp, tfi, 5); /* TFI_ASSIGNMENT */
76 bitvec_write_field(dest, &wp, 0, 1); /* POLLING = none */
77 bitvec_write_field(dest, &wp, 0, 1); /* ALLOCATION_TYPE: dynamic */
78 bitvec_write_field(dest, &wp, usf, 3); /* USF */
79 bitvec_write_field(dest, &wp, 0, 1); /* USF_GRANULARITY */
80 bitvec_write_field(dest, &wp, 0, 1); /* "0" power control: Not Present */
81 bitvec_write_field(dest, &wp, 0, 2); /* CHANNEL_CODING_COMMAND */
82 bitvec_write_field(dest, &wp, 1, 1); /* TLLI_BLOCK_CHANNEL_CODING */
83 bitvec_write_field(dest, &wp, 0, 1); /* ALPHA = not present */
84 bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power control parameter */
85 /* note: there is no choise for TAI and no starting time */
86 bitvec_write_field(dest, &wp, 0, 1); /* switch TIMING_ADVANCE_INDEX = off */
87 bitvec_write_field(dest, &wp, 0, 1); /* TBF_STARTING_TIME_FLAG */
88 }
89
90 printf("Encoded PKT UL ASS IA Rest Octets: %s\n", osmo_hexdump(dest->data, dest->data_len));
91
92 OUTRO(use_lh);
93}
94
95static void test_bitdiff(const struct bitvec *src1, const struct bitvec *src2, unsigned len)
96{
97 unsigned int bit_err = 0, i, j;
98 uint8_t byte_err = 0;
99
100 INTRO(len);
101
102 for (i = 0; i < len; i++) {
103 /* byte compare */
104 byte_err = src1->data[i] ^ src2->data[i];
105 if (byte_err)
106 for (j = 0; j < 8; j++)
107 bit_err += (byte_err >> j) & 0x01; /* count bits which differ */
108 }
109
110
111 printf("=== total %u bits differ ===\n", bit_err);
112
113 OUTRO(len);
114}
115
116static inline void buf_init(struct bitvec *dest, struct bitvec *dest_lh)
117{
118 /* initialize buffer */
119 bitvec_unhex(dest, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
120 bitvec_unhex(dest_lh, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
121}
122
123static inline void test_enc_ul_ass(struct bitvec *dest, struct bitvec *dest_lh, uint32_t fn,
124 uint8_t tfi, uint8_t gamma, uint8_t usf, bool tbf)
125{
126 buf_init(dest, dest_lh);
127
128 test_bitvec_ia_octet_encode_pkt_ul_ass(dest, fn, tfi, gamma, usf, tbf, false);
129 test_bitvec_ia_octet_encode_pkt_ul_ass(dest_lh, fn, tfi, gamma, usf, tbf, true);
130
131 test_bitdiff(dest, dest_lh, 22);
132}
133
134int main(int argc, char **argv)
135{
136 void *tall_pcu_ctx;
137 struct bitvec *dest, *dest_lh;
138 uint8_t gamma = 0, ta_valid = 1, ws_enc = 3, usf = 1, tfi = 0; /* Temporary Flow Identity */
139 uint32_t ttli = 0xdeadbeef, fn = 1234;
140
141 tall_pcu_ctx = talloc_named_const(NULL, 1, "bitvecTest context");
142 if (!tall_pcu_ctx)
143 return EXIT_FAILURE;
144
145 dest = bitvec_alloc(22, tall_pcu_ctx);
146 dest_lh = bitvec_alloc(22, tall_pcu_ctx);
147
148 buf_init(dest, dest_lh);
149
150 test_bitvec_ia_octet_encode_pkt_dl_ass(dest, ttli, tfi, gamma, ta_valid, ws_enc, false);
151 test_bitvec_ia_octet_encode_pkt_dl_ass(dest_lh, ttli, tfi, gamma, ta_valid, ws_enc, true);
152
153 test_bitdiff(dest, dest_lh, 22);
154
155 test_enc_ul_ass(dest, dest_lh, fn, tfi, gamma, usf, false);
156 test_enc_ul_ass(dest, dest_lh, fn, tfi, gamma, usf, true);
157
158 bitvec_free(dest);
159 bitvec_free(dest_lh);
160
161 talloc_free(tall_pcu_ctx);
162
163 return EXIT_SUCCESS;
164}