From 9ca3787bc5e2f6bfe7acb828a126a8ce417f6138 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sat, 13 Jul 2024 15:54:04 -0400 Subject: [PATCH 01/12] experimenting with small change to make sure no issue with pybind --- break.sh | 4 ++++ build.sh | 7 +++++++ grc/ieee802_11_frame_equalizer.block.yml | 2 +- grc/ieee802_11_sync_long.block.yml | 2 +- grc/ieee802_11_sync_short.block.yml | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) create mode 100755 break.sh create mode 100755 build.sh diff --git a/break.sh b/break.sh new file mode 100755 index 00000000..9b37acb8 --- /dev/null +++ b/break.sh @@ -0,0 +1,4 @@ +cd build +sudo make uninstall +cd .. +sudo rm -rf build \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..2807d1b6 --- /dev/null +++ b/build.sh @@ -0,0 +1,7 @@ +mkdir build +cd build +cmake .. +make -j4 +sudo make install +sudo ldconfig +cd .. \ No newline at end of file diff --git a/grc/ieee802_11_frame_equalizer.block.yml b/grc/ieee802_11_frame_equalizer.block.yml index cdc099e1..abc7713b 100644 --- a/grc/ieee802_11_frame_equalizer.block.yml +++ b/grc/ieee802_11_frame_equalizer.block.yml @@ -1,7 +1,7 @@ # auto-generated by grc.converter id: ieee802_11_frame_equalizer -label: WiFi Frame Equalizer +label: HaLow Frame Equalizer category: '[IEEE802.11]' parameters: diff --git a/grc/ieee802_11_sync_long.block.yml b/grc/ieee802_11_sync_long.block.yml index fe9f48df..d6c68fc3 100644 --- a/grc/ieee802_11_sync_long.block.yml +++ b/grc/ieee802_11_sync_long.block.yml @@ -1,7 +1,7 @@ # auto-generated by grc.converter id: ieee802_11_sync_long -label: WiFi Sync Long +label: HaLow Sync Long category: '[IEEE802.11]' parameters: diff --git a/grc/ieee802_11_sync_short.block.yml b/grc/ieee802_11_sync_short.block.yml index daea6ff2..25f6ef0f 100644 --- a/grc/ieee802_11_sync_short.block.yml +++ b/grc/ieee802_11_sync_short.block.yml @@ -1,7 +1,7 @@ # auto-generated by grc.converter id: ieee802_11_sync_short -label: WiFi Sync Short +label: HaLow Sync Short category: '[IEEE802.11]' parameters: From 3d51453d0371b58708c97f30ed2d6f7327179dea Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sat, 13 Jul 2024 18:24:02 -0400 Subject: [PATCH 02/12] updating frame equalizer with constants that are relevant to halow. Parsing signal field differently. --- lib/equalizer/base.h | 15 +++- lib/equalizer/ls.cc | 14 ++-- lib/frame_equalizer_impl.cc | 163 +++++++++++++++++++----------------- lib/frame_equalizer_impl.h | 8 +- 4 files changed, 111 insertions(+), 89 deletions(-) diff --git a/lib/equalizer/base.h b/lib/equalizer/base.h index aa2b02ef..f4990c00 100644 --- a/lib/equalizer/base.h +++ b/lib/equalizer/base.h @@ -18,6 +18,17 @@ #ifndef INCLUDED_IEEE802_11_EQUALIZER_BASE_H #define INCLUDED_IEEE802_11_EQUALIZER_BASE_H +#define SAMPLES_PER_OFDM_SYMBOL 32 //there are 32 HaLow subcarriers +#define CODED_BITS_PER_OFDM_SYMBOL 24 // there are 26 effective HaLow subcarriers. 2 are pilots, bringing the number of data subcarriers to 24 +#define NUM_PILOTS 2 //2 HaLow pilots. p.3253 of spec +#define PILOT1_INDEX 9 //technically -7 in the spec, but that is a range of [-16, 15). We're operating in range of [0, 31). p.3253 of spec +#define PILOT2_INDEX 23 //technically +7 in the spec, but see above ^. p.3253 of spec. +#define NUM_BITS_SIG_FIELD 36 //p.3246 of spec +#define NUM_SIG_FIELD_REPETITIONS 2 //p.3246 of spec +#define NUM_BITS_PER_REPETITION 6 //p.3246 of spec +#define MCS_FIRST_BIT_INDEX 7 //p.3246 of spec +#define MCS_LAST_BIT_INDEX 10 //p.3246 of spec, inclusive + #include #include @@ -41,9 +52,9 @@ class base std::vector get_csi(); protected: - static const gr_complex LONG[64]; + static const gr_complex LONG[SAMPLES_PER_OFDM_SYMBOL]; - gr_complex d_H[64]; + gr_complex d_H[SAMPLES_PER_OFDM_SYMBOL]; }; } // namespace equalizer diff --git a/lib/equalizer/ls.cc b/lib/equalizer/ls.cc index 23bf3968..7a28e53b 100644 --- a/lib/equalizer/ls.cc +++ b/lib/equalizer/ls.cc @@ -29,13 +29,13 @@ void ls::equalize(gr_complex* in, { if (n == 0) { - std::memcpy(d_H, in, 64 * sizeof(gr_complex)); + std::memcpy(d_H, in, SAMPLES_PER_OFDM_SYMBOL * sizeof(gr_complex)); } else if (n == 1) { double signal = 0; double noise = 0; - for (int i = 0; i < 64; i++) { - if ((i == 32) || (i < 6) || (i > 58)) { + for (int i = 0; i < SAMPLES_PER_OFDM_SYMBOL; i++) { + if ((i == 16) || (i < 3) || (i > 29)) { //dividing by two gets you the dead DC pilot subcarrier, the other indices correspond to dead lower and upper subcarriers. 3 dead lower ones, 2 dead upper ones continue; } noise += std::pow(std::abs(d_H[i] - in[i]), 2); @@ -49,10 +49,10 @@ void ls::equalize(gr_complex* in, } else { int c = 0; - for (int i = 0; i < 64; i++) { - if ((i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || - (i < 6) || (i > 58)) { - continue; + for (int i = 0; i < SAMPLES_PER_OFDM_SYMBOL; i++) { + if ((i == PILOT1_INDEX) || (i == 16) || (i == PILOT2_INDEX) || + (i < 3) || (i > 29)) { + continue; //ignore all pilots and dead subcarriers } else { symbols[c] = in[i] / d_H[i]; bits[c] = mod->decision_maker(&symbols[c]); diff --git a/lib/frame_equalizer_impl.cc b/lib/frame_equalizer_impl.cc index 253489af..bcd67715 100644 --- a/lib/frame_equalizer_impl.cc +++ b/lib/frame_equalizer_impl.cc @@ -38,8 +38,8 @@ frame_equalizer::make(Equalizer algo, double freq, double bw, bool log, bool deb frame_equalizer_impl::frame_equalizer_impl( Equalizer algo, double freq, double bw, bool log, bool debug) : gr::block("frame_equalizer", - gr::io_signature::make(1, 1, 64 * sizeof(gr_complex)), - gr::io_signature::make(1, 1, 48)), + gr::io_signature::make(1, 1, SAMPLES_PER_OFDM_SYMBOL * sizeof(gr_complex)), + gr::io_signature::make(1, 1, CODED_BITS_PER_OFDM_SYMBOL)), d_current_symbol(0), d_log(log), d_debug(debug), @@ -126,8 +126,8 @@ int frame_equalizer_impl::general_work(int noutput_items, int i = 0; int o = 0; - gr_complex symbols[48]; - gr_complex current_symbol[64]; + gr_complex symbols[CODED_BITS_PER_OFDM_SYMBOL]; + gr_complex current_symbol[SAMPLES_PER_OFDM_SYMBOL]; dout << "FRAME EQUALIZER: input " << ninput_items[0] << " output " << noutput_items << std::endl; @@ -156,48 +156,42 @@ int frame_equalizer_impl::general_work(int noutput_items, continue; } - std::memcpy(current_symbol, in + i * 64, 64 * sizeof(gr_complex)); + std::memcpy(current_symbol, in + i * SAMPLES_PER_OFDM_SYMBOL, SAMPLES_PER_OFDM_SYMBOL * sizeof(gr_complex)); // compensate sampling offset - for (int i = 0; i < 64; i++) { + for (int i = 0; i < SAMPLES_PER_OFDM_SYMBOL; i++) { current_symbol[i] *= exp(gr_complex(0, - 2 * M_PI * d_current_symbol * 80 * - (d_epsilon0 + d_er) * (i - 32) / 64)); + 2 * M_PI * d_current_symbol * 80 * //what is 80? + (d_epsilon0 + d_er) * (i - 32) / SAMPLES_PER_OFDM_SYMBOL)); //what is 32? Half of the 802.11a number of subcarriers? } - gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; + gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; //where does polarity come from? double beta; if (d_current_symbol < 2) { - beta = arg(current_symbol[11] - current_symbol[25] + current_symbol[39] + - current_symbol[53]); + beta = arg(current_symbol[PILOT2_INDEX] + - current_symbol[PILOT1_INDEX]); //unsure whether to add/subtract the pilot? } else { - beta = arg((current_symbol[11] * p) + (current_symbol[39] * p) + - (current_symbol[25] * p) + (current_symbol[53] * -p)); + beta = arg((current_symbol[PILOT2_INDEX] * p) + + (current_symbol[PILOT1_INDEX] * p)); //unsure whether to multiply by p or -p? } - double er = arg((conj(d_prev_pilots[0]) * current_symbol[11] * p) + - (conj(d_prev_pilots[1]) * current_symbol[25] * p) + - (conj(d_prev_pilots[2]) * current_symbol[39] * p) + - (conj(d_prev_pilots[3]) * current_symbol[53] * -p)); + double er = arg((conj(d_prev_pilots[1]) * current_symbol[PILOT1_INDEX] * p) + + (conj(d_prev_pilots[2]) * current_symbol[PILOT2_INDEX] * p)); //unsure whether to multiply by p or -p? - er *= d_bw / (2 * M_PI * d_freq * 80); + er *= d_bw / (2 * M_PI * d_freq * 80); //again, what is 80? if (d_current_symbol < 2) { - d_prev_pilots[0] = current_symbol[11]; - d_prev_pilots[1] = -current_symbol[25]; - d_prev_pilots[2] = current_symbol[39]; - d_prev_pilots[3] = current_symbol[53]; + d_prev_pilots[0] = current_symbol[PILOT1_INDEX]; + d_prev_pilots[1] = -current_symbol[PILOT2_INDEX]; } else { - d_prev_pilots[0] = current_symbol[11] * p; - d_prev_pilots[1] = current_symbol[25] * p; - d_prev_pilots[2] = current_symbol[39] * p; - d_prev_pilots[3] = current_symbol[53] * -p; + d_prev_pilots[0] = current_symbol[PILOT1_INDEX] * p; + d_prev_pilots[1] = current_symbol[PILOT2_INDEX] * p; } // compensate residual frequency offset - for (int i = 0; i < 64; i++) { + for (int i = 0; i < SAMPLES_PER_OFDM_SYMBOL; i++) { current_symbol[i] *= exp(gr_complex(0, -beta)); } @@ -210,12 +204,15 @@ int frame_equalizer_impl::general_work(int noutput_items, // do equalization d_equalizer->equalize( - current_symbol, d_current_symbol, symbols, out + o * 48, d_frame_mod); + current_symbol, d_current_symbol, symbols, out + o * CODED_BITS_PER_OFDM_SYMBOL, d_frame_mod); - // signal field - if (d_current_symbol == 2) { + // signal field, it takes 6 OFDM symbols to make the SIG field + if (d_current_symbol >= 2 && d_current_symbol < 8) { + o++; + } + if (d_current_symbol == 7){ - if (decode_signal_field(out + o * 48)) { + if (decode_signal_field(out + o * CODED_BITS_PER_OFDM_SYMBOL)) { pmt::pmt_t dict = pmt::make_dict(); dict = pmt::dict_add( @@ -247,12 +244,13 @@ int frame_equalizer_impl::general_work(int noutput_items, } } - if (d_current_symbol > 2) { + // data + if (d_current_symbol >= 8) { o++; pmt::pmt_t pdu = pmt::make_dict(); message_port_pub( pmt::mp("symbols"), - pmt::cons(pmt::make_dict(), pmt::init_c32vector(48, symbols))); + pmt::cons(pmt::make_dict(), pmt::init_c32vector(CODED_BITS_PER_OFDM_SYMBOL, symbols))); } i++; @@ -277,85 +275,98 @@ bool frame_equalizer_impl::decode_signal_field(uint8_t* rx_bits) void frame_equalizer_impl::deinterleave(uint8_t* rx_bits) { - for (int i = 0; i < 48; i++) { + for (int i = 0; i < CODED_BITS_PER_OFDM_SYMBOL; i++) { d_deinterleaved[i] = rx_bits[interleaver_pattern[i]]; } } +//p.3246 wifi spec bool frame_equalizer_impl::parse_signal(uint8_t* decoded_bits) { - int r = 0; + int mcs = 0; + int frame_bit_index = 0; d_frame_bytes = 0; bool parity = false; - for (int i = 0; i < 17; i++) { + for (int i = 0; i < NUM_BITS_SIG_FIELD * NUM_SIG_FIELD_REPETITIONS; i++) { parity ^= decoded_bits[i]; - if ((i < 4) && decoded_bits[i]) { - r = r | (1 << i); + //only accounts for the first repetition + if ((i >= MCS_FIRST_BIT_INDEX * NUM_SIG_FIELD_REPETITIONS) && (i <= MCS_LAST_BIT_INDEX * NUM_SIG_FIELD_REPETITIONS) && decoded_bits[i]) { + mcs = mcs | (1 << (MCS_LAST_BIT_INDEX * NUM_SIG_FIELD_REPETITIONS - i)); } - if (decoded_bits[i] && (i > 4) && (i < 17)) { - d_frame_bytes = d_frame_bytes | (1 << (i - 5)); - } + // separate if statement because d_frame_bytes is int and can only store 32 bits + /*need to account for repetition + if (decoded_bits[i] && (i < MCS_FIRST_BIT_INDEX) && (i > MCS_LAST_BIT_INDEX)) { + d_frame_bytes = d_frame_bytes | (1 << (32 - frame_bit_index)); + frame_bit_index++; + }*/ } + /* unused with HaLow, CRC instead if (parity != decoded_bits[17]) { dout << "SIGNAL: wrong parity" << std::endl; return false; - } + }*/ - switch (r) { - case 11: + switch (mcs) { //table 23-41 + case 0: d_frame_encoding = 0; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)24); + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)24); //idk what this is doing d_frame_mod = d_bpsk; - dout << "Encoding: 3 Mbit/s "; + dout << "Encoding: 300 kbit/s "; break; - case 15: + case 1: d_frame_encoding = 1; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)36); - d_frame_mod = d_bpsk; - dout << "Encoding: 4.5 Mbit/s "; + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)36); //idk what this is doing + d_frame_mod = d_qpsk; + dout << "Encoding: 600 kbit/s "; break; - case 10: + case 2: d_frame_encoding = 2; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)48); + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)48); //idk what this is doing d_frame_mod = d_qpsk; - dout << "Encoding: 6 Mbit/s "; + dout << "Encoding: 900 kbit/s "; break; - case 14: + case 3: d_frame_encoding = 3; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)72); - d_frame_mod = d_qpsk; - dout << "Encoding: 9 Mbit/s "; + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)72); //idk what this is doing + d_frame_mod = d_16qam; + dout << "Encoding: 1200 kbit/s "; break; - case 9: + case 4: d_frame_encoding = 4; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)96); + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)96); //idk what this is doing d_frame_mod = d_16qam; - dout << "Encoding: 12 Mbit/s "; + dout << "Encoding: 1800 kbit/s "; break; - case 13: + case 5: d_frame_encoding = 5; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)144); - d_frame_mod = d_16qam; - dout << "Encoding: 18 Mbit/s "; + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)144); //idk what this is doing + d_frame_mod = d_64qam; + dout << "Encoding: 2400 kbit/s "; break; - case 8: + case 6: d_frame_encoding = 6; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)192); + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)192); //idk what this is doing d_frame_mod = d_64qam; - dout << "Encoding: 24 Mbit/s "; + dout << "Encoding: 2700 kbit/s "; break; - case 12: + case 7: d_frame_encoding = 7; - d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)216); + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)216); //idk what this is doing d_frame_mod = d_64qam; - dout << "Encoding: 27 Mbit/s "; + dout << "Encoding: 3000 kbit/s "; + break; + case 10: + d_frame_encoding = 10; + d_frame_symbols = (int)ceil((16 + 8 * d_frame_bytes + 6) / (double)240); //idk what this is doing, just added 24 to case 7 + d_frame_mod = d_bpsk; + dout << "Encoding: 150 kbit/s "; break; default: - dout << "unknown encoding" << std::endl; + dout << "unsupported encoding" << std::endl; return false; } @@ -366,11 +377,11 @@ bool frame_equalizer_impl::parse_signal(uint8_t* decoded_bits) return true; } -const int frame_equalizer_impl::interleaver_pattern[48] = { - 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, - 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, - 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47 -}; +const int frame_equalizer_impl::interleaver_pattern[CODED_BITS_PER_OFDM_SYMBOL] = { + 0, 3, 6, 9, 12, 15, 18, 21, + 1, 4, 7, 10, 13, 16, 19, 22, + 2, 5, 8, 11, 14, 17, 20, 23 +}; //table 23-20 and table 23-41 } /* namespace ieee802_11 */ } /* namespace gr */ diff --git a/lib/frame_equalizer_impl.h b/lib/frame_equalizer_impl.h index b9fe9319..6f470636 100644 --- a/lib/frame_equalizer_impl.h +++ b/lib/frame_equalizer_impl.h @@ -62,14 +62,14 @@ class frame_equalizer_impl : virtual public frame_equalizer double d_bw; // Hz double d_er; double d_epsilon0; - gr_complex d_prev_pilots[4]; + gr_complex d_prev_pilots[NUM_PILOTS]; int d_frame_bytes; int d_frame_symbols; int d_frame_encoding; - uint8_t d_deinterleaved[48]; - gr_complex symbols[48]; + uint8_t d_deinterleaved[CODED_BITS_PER_OFDM_SYMBOL]; + gr_complex symbols[CODED_BITS_PER_OFDM_SYMBOL]; std::shared_ptr d_frame_mod; constellation_bpsk::sptr d_bpsk; @@ -77,7 +77,7 @@ class frame_equalizer_impl : virtual public frame_equalizer constellation_16qam::sptr d_16qam; constellation_64qam::sptr d_64qam; - static const int interleaver_pattern[48]; + static const int interleaver_pattern[CODED_BITS_PER_OFDM_SYMBOL]; }; } // namespace ieee802_11 From 2606f802f9e2beec9ed3d9842d2edc8371a862c3 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sat, 13 Jul 2024 19:07:08 -0400 Subject: [PATCH 03/12] adjusting length of the LONG field to match number of samples per OFDM signal in halow --- lib/equalizer/base.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/equalizer/base.cc b/lib/equalizer/base.cc index 4d54282d..9fb254ed 100644 --- a/lib/equalizer/base.cc +++ b/lib/equalizer/base.cc @@ -21,11 +21,10 @@ using namespace gr::ieee802_11::equalizer; -const gr_complex base::LONG[] = { 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 1, 1, -1, - 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, - 1, -1, 1, 1, 1, 1, 0, 1, -1, -1, 1, 1, -1, - 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, - -1, 1, -1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; +const gr_complex base::LONG[] = { 0, 0, 0, 1, 1, -1, -1, 1, 1, -1, + 1, -1, 1, 1, 1, 1, 0, 1, -1, -1, //make sure 0 is in center + 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, + 0, 0};//maybe this is the first 48 (24 in the case of HaLow) values from the polarity field below, after the SIG const gr_complex base::POLARITY[127] = { 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, @@ -34,7 +33,7 @@ const gr_complex base::POLARITY[127] = { 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1 -}; +}; //original from p.2826 std::vector base::get_csi() { From 11dc40b6aa43bd60e6b3622dc1923b92aa43a8c0 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sat, 13 Jul 2024 19:16:38 -0400 Subject: [PATCH 04/12] updating length of inputs and outputs of the frame equalizer based off of what halow expects --- grc/ieee802_11_frame_equalizer.block.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grc/ieee802_11_frame_equalizer.block.yml b/grc/ieee802_11_frame_equalizer.block.yml index abc7713b..7bbb99d1 100644 --- a/grc/ieee802_11_frame_equalizer.block.yml +++ b/grc/ieee802_11_frame_equalizer.block.yml @@ -12,11 +12,11 @@ parameters: - id: freq label: Frequency dtype: real - default: 5.89e9 + default: 920.5e6 - id: bw label: Bandwidth dtype: real - default: 10e6 + default: 1e6 - id: log label: Log dtype: bool @@ -33,13 +33,13 @@ parameters: inputs: - domain: stream dtype: complex - vlen: 64 + vlen: 32 multiplicity: '1' outputs: - domain: stream dtype: byte - vlen: 48 + vlen: 24 multiplicity: '1' - domain: message id: symbols From ab574a7f4cced3067c5bdae08766ff75f2b8b010 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sat, 27 Jul 2024 14:09:24 -0400 Subject: [PATCH 05/12] updating constants in sync long and sync short files --- lib/equalizer/base.h | 12 +----------- lib/sync_long.cc | 22 +++++++++++----------- lib/sync_short.cc | 6 +++--- lib/utils.h | 12 ++++++++++++ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/lib/equalizer/base.h b/lib/equalizer/base.h index f4990c00..c6586815 100644 --- a/lib/equalizer/base.h +++ b/lib/equalizer/base.h @@ -18,19 +18,9 @@ #ifndef INCLUDED_IEEE802_11_EQUALIZER_BASE_H #define INCLUDED_IEEE802_11_EQUALIZER_BASE_H -#define SAMPLES_PER_OFDM_SYMBOL 32 //there are 32 HaLow subcarriers -#define CODED_BITS_PER_OFDM_SYMBOL 24 // there are 26 effective HaLow subcarriers. 2 are pilots, bringing the number of data subcarriers to 24 -#define NUM_PILOTS 2 //2 HaLow pilots. p.3253 of spec -#define PILOT1_INDEX 9 //technically -7 in the spec, but that is a range of [-16, 15). We're operating in range of [0, 31). p.3253 of spec -#define PILOT2_INDEX 23 //technically +7 in the spec, but see above ^. p.3253 of spec. -#define NUM_BITS_SIG_FIELD 36 //p.3246 of spec -#define NUM_SIG_FIELD_REPETITIONS 2 //p.3246 of spec -#define NUM_BITS_PER_REPETITION 6 //p.3246 of spec -#define MCS_FIRST_BIT_INDEX 7 //p.3246 of spec -#define MCS_LAST_BIT_INDEX 10 //p.3246 of spec, inclusive - #include #include +#include "utils.h" namespace gr { namespace ieee802_11 { diff --git a/lib/sync_long.cc b/lib/sync_long.cc index 544fcfd3..5ec1e615 100644 --- a/lib/sync_long.cc +++ b/lib/sync_long.cc @@ -101,9 +101,9 @@ class sync_long_impl : public sync_long case SYNC: d_fir.filterN( - d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - 63, 0))); + d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - (SAMPLES_PER_OFDM_SYMBOL - 1), 0))); - while (i + 63 < ninput) { + while (i + (SAMPLES_PER_OFDM_SYMBOL - 1) < ninput) { d_cor.push_back(pair(d_correlation[i], d_offset)); @@ -136,7 +136,7 @@ class sync_long_impl : public sync_long pmt::string_to_symbol(name())); } - if (rel >= 0 && (rel < 128 || ((rel - 128) % 80) > 15)) { + if (rel >= 0 && (rel < 128 || ((rel - 128) % (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)) > 15)) { out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset)); o++; } @@ -149,7 +149,7 @@ class sync_long_impl : public sync_long case RESET: { while (o < noutput) { - if (((d_count + o) % 64) == 0) { + if (((d_count + o) % SAMPLES_PER_OFDM_SYMBOL) == 0) { d_offset = 0; d_state = SYNC; break; @@ -177,8 +177,8 @@ class sync_long_impl : public sync_long // in sync state we need at least a symbol to correlate // with the pattern if (d_state == SYNC) { - ninput_items_required[0] = 64; - ninput_items_required[1] = 64; + ninput_items_required[0] = SAMPLES_PER_OFDM_SYMBOL; + ninput_items_required[1] = SAMPLES_PER_OFDM_SYMBOL; } else { ninput_items_required[0] = noutput_items; @@ -214,16 +214,16 @@ class sync_long_impl : public sync_long int diff = abs(get<1>(vec[i]) - get<1>(vec[k])); if (diff == 64) { d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); - d_freq_offset = arg(first * conj(second)) / 64; + d_freq_offset = arg(first * conj(second)) / SAMPLES_PER_OFDM_SYMBOL; // nice match found, return immediately return; - } else if (diff == 63) { + } else if (diff == (SAMPLES_PER_OFDM_SYMBOL + 1)) { d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); - d_freq_offset = arg(first * conj(second)) / 63; - } else if (diff == 65) { + d_freq_offset = arg(first * conj(second)) / (SAMPLES_PER_OFDM_SYMBOL - 1); + } else if (diff == (SAMPLES_PER_OFDM_SYMBOL + 1)) { d_frame_start = min(get<1>(vec[i]), get<1>(vec[k])); - d_freq_offset = arg(first * conj(second)) / 65; + d_freq_offset = arg(first * conj(second)) / (SAMPLES_PER_OFDM_SYMBOL + 1); } } } diff --git a/lib/sync_short.cc b/lib/sync_short.cc index af0988b9..18bd7dcb 100644 --- a/lib/sync_short.cc +++ b/lib/sync_short.cc @@ -23,7 +23,7 @@ using namespace gr::ieee802_11; static const int MIN_GAP = 480; -static const int MAX_SAMPLES = 540 * 80; +static const int MAX_SAMPLES = 540 * (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI); class sync_short_impl : public sync_short { @@ -78,7 +78,7 @@ class sync_short_impl : public sync_short } else { d_state = COPY; d_copied = 0; - d_freq_offset = arg(in_abs[i]) / 16; + d_freq_offset = arg(in_abs[i]) / 16; // 16 = samples per GI? d_plateau = 0; insert_tag(nitems_written(0), d_freq_offset, nitems_read(0) + i); dout << "SHORT Frame!" << std::endl; @@ -105,7 +105,7 @@ class sync_short_impl : public sync_short } else if (d_copied > MIN_GAP) { d_copied = 0; d_plateau = 0; - d_freq_offset = arg(in_abs[o]) / 16; + d_freq_offset = arg(in_abs[o]) / 16; //16 = samples per GI? insert_tag( nitems_written(0) + o, d_freq_offset, nitems_read(0) + o); dout << "SHORT Frame!" << std::endl; diff --git a/lib/utils.h b/lib/utils.h index be18f65b..53fbb78a 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -25,6 +25,18 @@ using gr::ieee802_11::Encoding; +#define SAMPLES_PER_OFDM_SYMBOL 32 //there are 32 HaLow subcarriers +#define CODED_BITS_PER_OFDM_SYMBOL 24 // there are 26 effective HaLow subcarriers. 2 are pilots, bringing the number of data subcarriers to 24 +#define NUM_PILOTS 2 //2 HaLow pilots. p.3253 of spec +#define PILOT1_INDEX 9 //technically -7 in the spec, but that is a range of [-16, 15). We're operating in range of [0, 31). p.3253 of spec +#define PILOT2_INDEX 23 //technically +7 in the spec, but see above ^. p.3253 of spec. +#define NUM_BITS_SIG_FIELD 36 //p.3246 of spec +#define NUM_SIG_FIELD_REPETITIONS 2 //p.3246 of spec +#define NUM_BITS_PER_REPETITION 6 //p.3246 of spec +#define MCS_FIRST_BIT_INDEX 7 //p.3246 of spec +#define MCS_LAST_BIT_INDEX 10 //p.3246 of spec, inclusive +#define SAMPLES_PER_GI 16 //??? I think this is just SAMPLES_PER_OFDM_SYMBOL plus the number of samples with the guard interval length. For 802.11a is 3.2us (64 samples at 20MHz) plus 0.8us GI which yields 80 samples + #define MAX_PAYLOAD_SIZE 1500 #define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC #define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) From 65a9bb5ed2ba9994c1f747192077d9b3192adfd9 Mon Sep 17 00:00:00 2001 From: smiller2 Date: Sat, 27 Jul 2024 15:02:57 -0400 Subject: [PATCH 06/12] modifying some more constants --- lib/frame_equalizer_impl.cc | 8 ++++---- lib/sync_long.cc | 2 +- lib/sync_short.cc | 4 ++-- lib/utils.h | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/frame_equalizer_impl.cc b/lib/frame_equalizer_impl.cc index bcd67715..bc8b29eb 100644 --- a/lib/frame_equalizer_impl.cc +++ b/lib/frame_equalizer_impl.cc @@ -161,11 +161,11 @@ int frame_equalizer_impl::general_work(int noutput_items, // compensate sampling offset for (int i = 0; i < SAMPLES_PER_OFDM_SYMBOL; i++) { current_symbol[i] *= exp(gr_complex(0, - 2 * M_PI * d_current_symbol * 80 * //what is 80? + 2 * M_PI * d_current_symbol * (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI) * (d_epsilon0 + d_er) * (i - 32) / SAMPLES_PER_OFDM_SYMBOL)); //what is 32? Half of the 802.11a number of subcarriers? } - gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; //where does polarity come from? + gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; double beta; if (d_current_symbol < 2) { @@ -180,13 +180,13 @@ int frame_equalizer_impl::general_work(int noutput_items, double er = arg((conj(d_prev_pilots[1]) * current_symbol[PILOT1_INDEX] * p) + (conj(d_prev_pilots[2]) * current_symbol[PILOT2_INDEX] * p)); //unsure whether to multiply by p or -p? - er *= d_bw / (2 * M_PI * d_freq * 80); //again, what is 80? + er *= d_bw / (2 * M_PI * d_freq * (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)); if (d_current_symbol < 2) { d_prev_pilots[0] = current_symbol[PILOT1_INDEX]; d_prev_pilots[1] = -current_symbol[PILOT2_INDEX]; } else { - d_prev_pilots[0] = current_symbol[PILOT1_INDEX] * p; + d_prev_pilots[0] = current_symbol[PILOT1_INDEX] * p; //unsure whether to multiply by p or -p? d_prev_pilots[1] = current_symbol[PILOT2_INDEX] * p; } diff --git a/lib/sync_long.cc b/lib/sync_long.cc index 5ec1e615..b668d623 100644 --- a/lib/sync_long.cc +++ b/lib/sync_long.cc @@ -136,7 +136,7 @@ class sync_long_impl : public sync_long pmt::string_to_symbol(name())); } - if (rel >= 0 && (rel < 128 || ((rel - 128) % (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)) > 15)) { + if (rel >= 0 && (rel < 128 || ((rel - 128) % (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)) > (SAMPLES_PER_GI - 1))) { out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset)); o++; } diff --git a/lib/sync_short.cc b/lib/sync_short.cc index 18bd7dcb..ddb8ac5b 100644 --- a/lib/sync_short.cc +++ b/lib/sync_short.cc @@ -78,7 +78,7 @@ class sync_short_impl : public sync_short } else { d_state = COPY; d_copied = 0; - d_freq_offset = arg(in_abs[i]) / 16; // 16 = samples per GI? + d_freq_offset = arg(in_abs[i]) / SAMPLES_PER_GI; d_plateau = 0; insert_tag(nitems_written(0), d_freq_offset, nitems_read(0) + i); dout << "SHORT Frame!" << std::endl; @@ -105,7 +105,7 @@ class sync_short_impl : public sync_short } else if (d_copied > MIN_GAP) { d_copied = 0; d_plateau = 0; - d_freq_offset = arg(in_abs[o]) / 16; //16 = samples per GI? + d_freq_offset = arg(in_abs[o]) / SAMPLES_PER_GI; //16 = samples per GI? insert_tag( nitems_written(0) + o, d_freq_offset, nitems_read(0) + o); dout << "SHORT Frame!" << std::endl; diff --git a/lib/utils.h b/lib/utils.h index 53fbb78a..2c67f1b3 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -35,13 +35,13 @@ using gr::ieee802_11::Encoding; #define NUM_BITS_PER_REPETITION 6 //p.3246 of spec #define MCS_FIRST_BIT_INDEX 7 //p.3246 of spec #define MCS_LAST_BIT_INDEX 10 //p.3246 of spec, inclusive -#define SAMPLES_PER_GI 16 //??? I think this is just SAMPLES_PER_OFDM_SYMBOL plus the number of samples with the guard interval length. For 802.11a is 3.2us (64 samples at 20MHz) plus 0.8us GI which yields 80 samples +#define SAMPLES_PER_GI 8 //for ieee802.11a/g, the GI is 0.8us. For 802.11ah, GI is 8us #define MAX_PAYLOAD_SIZE 1500 -#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC -#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) -#define MAX_BITS_PER_SYM 288 -#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + MAX_BITS_PER_SYM) +#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC. What is 28?? +#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) //16 is samples per GI? What is 24? +#define MAX_BITS_PER_SYM 288 //is this true for HaLow? +#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + MAX_BITS_PER_SYM) //is 16 samples per GI? #define dout d_debug&& std::cout #define mylog(...) \ From c1f1b1e6b730083f1a1103803ebd6a719bc757e8 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sun, 28 Jul 2024 13:34:40 -0400 Subject: [PATCH 07/12] adding comment above unknown array --- lib/sync_long.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sync_long.cc b/lib/sync_long.cc index b668d623..71906db5 100644 --- a/lib/sync_long.cc +++ b/lib/sync_long.cc @@ -254,6 +254,7 @@ sync_long::sptr sync_long::make(unsigned int sync_length, bool log, bool debug) return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, debug)); } +//where does this array come from? const std::vector sync_long_impl::LONG = { gr_complex(-0.0455, -1.0679), gr_complex(0.3528, -0.9865), gr_complex(0.8594, 0.7348), gr_complex(0.1874, 0.2475), From ef66318257fdfba0914792cbccbcf6e319b918e1 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sun, 28 Jul 2024 20:05:49 -0400 Subject: [PATCH 08/12] modifying include to enable this to buid --- lib/equalizer/base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/equalizer/base.h b/lib/equalizer/base.h index c6586815..da44214c 100644 --- a/lib/equalizer/base.h +++ b/lib/equalizer/base.h @@ -20,7 +20,7 @@ #include #include -#include "utils.h" +#include "../utils.h" namespace gr { namespace ieee802_11 { From dce6f595cd1439e12b46164ad5befab3078cdb6f Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Mon, 5 Aug 2024 19:53:53 -0400 Subject: [PATCH 09/12] modifying synchronization sequences for halow --- lib/sync_long.cc | 47 +++++++++++---------------------------- lib/sync_short.cc | 4 ++-- utils/channels.py | 4 ++-- utils/constellations.py | 12 +++++----- utils/create_long.R | 6 ++--- utils/create_long_halow.R | 28 +++++++++++++++++++++++ utils/pilots.py | 8 +++---- utils/sync_words.py | 10 ++++----- 8 files changed, 63 insertions(+), 56 deletions(-) create mode 100644 utils/create_long_halow.R diff --git a/lib/sync_long.cc b/lib/sync_long.cc index 71906db5..fbfcd0d5 100644 --- a/lib/sync_long.cc +++ b/lib/sync_long.cc @@ -47,7 +47,8 @@ class sync_long_impl : public sync_long d_debug(debug), d_offset(0), d_state(SYNC), - SYNC_LENGTH(sync_length) + SYNC_LENGTH(sync_length) //usually 320 samples for ieee802.11a/g (8us for the short field, 8us for the long field @20Mhz) + //also 320 samples for ieee802.11ah (160us for short field, 160us for long field @1MHz) { set_tag_propagation_policy(block::TPP_DONT); @@ -136,6 +137,7 @@ class sync_long_impl : public sync_long pmt::string_to_symbol(name())); } + // 128 is 2*64. What is this from? if (rel >= 0 && (rel < 128 || ((rel - 128) % (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)) > (SAMPLES_PER_GI - 1))) { out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset)); o++; @@ -254,38 +256,15 @@ sync_long::sptr sync_long::make(unsigned int sync_length, bool log, bool debug) return gnuradio::get_initial_sptr(new sync_long_impl(sync_length, log, debug)); } -//where does this array come from? +// from root of project directory: +// Rscript utils/create_long_halow.R const std::vector sync_long_impl::LONG = { - gr_complex(-0.0455, -1.0679), gr_complex(0.3528, -0.9865), - gr_complex(0.8594, 0.7348), gr_complex(0.1874, 0.2475), - gr_complex(0.5309, -0.7784), gr_complex(-1.0218, -0.4897), - gr_complex(-0.3401, -0.9423), gr_complex(0.8657, -0.2298), - gr_complex(0.4734, 0.0362), gr_complex(0.0088, -1.0207), - gr_complex(-1.2142, -0.4205), gr_complex(0.2172, -0.5195), - gr_complex(0.5207, -0.1326), gr_complex(-0.1995, 1.4259), - gr_complex(1.0583, -0.0363), gr_complex(0.5547, -0.5547), - gr_complex(0.3277, 0.8728), gr_complex(-0.5077, 0.3488), - gr_complex(-1.1650, 0.5789), gr_complex(0.7297, 0.8197), - gr_complex(0.6173, 0.1253), gr_complex(-0.5353, 0.7214), - gr_complex(-0.5011, -0.1935), gr_complex(-0.3110, -1.3392), - gr_complex(-1.0818, -0.1470), gr_complex(-1.1300, -0.1820), - gr_complex(0.6663, -0.6571), gr_complex(-0.0249, 0.4773), - gr_complex(-0.8155, 1.0218), gr_complex(0.8140, 0.9396), - gr_complex(0.1090, 0.8662), gr_complex(-1.3868, -0.0000), - gr_complex(0.1090, -0.8662), gr_complex(0.8140, -0.9396), - gr_complex(-0.8155, -1.0218), gr_complex(-0.0249, -0.4773), - gr_complex(0.6663, 0.6571), gr_complex(-1.1300, 0.1820), - gr_complex(-1.0818, 0.1470), gr_complex(-0.3110, 1.3392), - gr_complex(-0.5011, 0.1935), gr_complex(-0.5353, -0.7214), - gr_complex(0.6173, -0.1253), gr_complex(0.7297, -0.8197), - gr_complex(-1.1650, -0.5789), gr_complex(-0.5077, -0.3488), - gr_complex(0.3277, -0.8728), gr_complex(0.5547, 0.5547), - gr_complex(1.0583, 0.0363), gr_complex(-0.1995, -1.4259), - gr_complex(0.5207, 0.1326), gr_complex(0.2172, 0.5195), - gr_complex(-1.2142, 0.4205), gr_complex(0.0088, 1.0207), - gr_complex(0.4734, -0.0362), gr_complex(0.8657, 0.2298), - gr_complex(-0.3401, 0.9423), gr_complex(-1.0218, 0.4897), - gr_complex(0.5309, 0.7784), gr_complex(0.1874, -0.2475), - gr_complex(0.8594, -0.7348), gr_complex(0.3528, 0.9865), - gr_complex(-0.0455, 1.0679), gr_complex(1.3868, -0.0000), + gr_complex(-0.2179, -0.4339), gr_complex( 0.1824, -1.3445), gr_complex( 0.3847, -0.8715), gr_complex(-0.4398, 0.3922), + gr_complex(-0.0765, -1.0116), gr_complex( 0.2703, -1.0443), gr_complex(-0.3261, -0.6552), gr_complex( 0.3922, -0.7845), + gr_complex( 0.3261, 0.7545), gr_complex(-1.0548, 0.6198), gr_complex( 0.0765, 0.8226), gr_complex( 1.2243, -0.3922), + gr_complex(-0.3847, -1.2561), gr_complex(-0.9669, 0.3196), gr_complex( 0.2179, -1.2431), gr_complex( 0.7845, -0.0000), + gr_complex( 0.2179, 1.2431), gr_complex(-0.9669, -0.3196), gr_complex(-0.3847, 1.2561), gr_complex( 1.2243, 0.3922), + gr_complex( 0.0765, -0.8226), gr_complex(-1.0548, -0.6198), gr_complex( 0.3261, -0.7545), gr_complex( 0.3922, 0.7845), + gr_complex(-0.3261, 0.6552), gr_complex( 0.2703, 1.0443), gr_complex(-0.0765, 1.0116), gr_complex(-0.4398, -0.3922), + gr_complex( 0.3847, 0.8715), gr_complex( 0.1824, 1.3445), gr_complex(-0.2179, 0.4339), gr_complex( 0.0000, -0.0000) }; diff --git a/lib/sync_short.cc b/lib/sync_short.cc index ddb8ac5b..59c0907a 100644 --- a/lib/sync_short.cc +++ b/lib/sync_short.cc @@ -22,8 +22,8 @@ using namespace gr::ieee802_11; -static const int MIN_GAP = 480; -static const int MAX_SAMPLES = 540 * (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI); +static const int MIN_GAP = 480; // what is the equivalent for HaLow? +static const int MAX_SAMPLES = 540 * (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI); // what is the equivalent for HaLow? class sync_short_impl : public sync_short { diff --git a/utils/channels.py b/utils/channels.py index 57f812db..5e188c88 100644 --- a/utils/channels.py +++ b/utils/channels.py @@ -88,5 +88,5 @@ freqs.append(channels[i+1]) -print labels -print freqs +print(labels) +print(freqs) diff --git a/utils/constellations.py b/utils/constellations.py index 422fae89..e1aa14be 100644 --- a/utils/constellations.py +++ b/utils/constellations.py @@ -16,7 +16,7 @@ p = np.average(np.abs(a)**2) level = .1**.5 -print "16-QAM, average power: {0:.4f}".format(p) +print("16-QAM, average power: {0:.4f}".format(p)) plt.scatter(a.real, a.imag) for i, x in enumerate(a): @@ -39,9 +39,9 @@ rx_const = a[rx] if any(rx != data): - print "16-QAM: data does not match." + print("16-QAM: data does not match.") else: - print "16-QAM: points decoded successfully." + print("16-QAM: points decoded successfully.") plt.scatter(a.real, a.imag) plt.scatter(noisy_const.real, noisy_const.imag, marker='x') @@ -61,7 +61,7 @@ p = np.average(np.abs(a)**2) level = (1.0/42)**.5 -print "64-QAM, average power: {0:.4f}".format(p) +print("64-QAM, average power: {0:.4f}".format(p)) plt.scatter(a.real, a.imag) for i, x in enumerate(a): @@ -84,9 +84,9 @@ rx_const = a[rx] if any(rx != data): - print "16-QAM: data does not match." + print("16-QAM: data does not match.") else: - print "16-QAM: points decoded successfully." + print("16-QAM: points decoded successfully.") plt.scatter(a.real, a.imag) plt.scatter(noisy_const.real, noisy_const.imag, marker='x') diff --git a/utils/create_long.R b/utils/create_long.R index 3094f08b..ca740df6 100644 --- a/utils/create_long.R +++ b/utils/create_long.R @@ -11,11 +11,11 @@ fft.shift <- function(sym) { return(cbind(m1, m2)) } -### symbols as defined in the standard +### symbols as defined in the standard p.2814 eq17-8 sym <- c(1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 0, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1) -freq <- c(rep(0, 6), sym, rep(0, 5)) +freq <- c(rep(0, 6), sym, rep(0, 5)) # fill empty subcarriers with 0 -pre <- fft(fft.shift(freq), inverse=T) / sqrt(52) +pre <- fft(fft.shift(freq), inverse=T) / sqrt(52) # 52 is the number of occupied subcarriers, data plus pilot pre <- Conj(pre) pre <- rev(pre) diff --git a/utils/create_long_halow.R b/utils/create_long_halow.R new file mode 100644 index 00000000..d8cec37b --- /dev/null +++ b/utils/create_long_halow.R @@ -0,0 +1,28 @@ + +fft.shift <- function(sym) { + + sym <- matrix(sym, ncol=32) + + # the explicit dimensions are required + # if sym contains only one row + m1 <- matrix(sym[,17:32], ncol=16) + m2 <- matrix(sym[, 1:16], ncol=16) + + return(cbind(m1, m2)) +} + +### symbols as defined in the standard p.3245 eq23-40 for 1 MHz +sym <- c(1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 0, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1) +freq <- c(rep(0, 3), sym, rep(0, 2)) # fill empty subcarriers with 0 + +pre <- fft(fft.shift(freq), inverse=T) / sqrt(26) # 26 is the number of occupied subcarriers, data plus pilot +pre <- Conj(pre) +pre <- rev(pre) + + +for(i in seq(1, 32, 4)) { + cat("\t\tgr_complex(", sprintf("% .4f", Re(pre[ i])), ", ", sprintf("% .4f", Im(pre[ i])), "), ", sep="") + cat( "gr_complex(", sprintf("% .4f", Re(pre[i+1])), ", ", sprintf("% .4f", Im(pre[i+1])), "), ", sep="") + cat( "gr_complex(", sprintf("% .4f", Re(pre[i+2])), ", ", sprintf("% .4f", Im(pre[i+2])), "), ", sep="") + cat( "gr_complex(", sprintf("% .4f", Re(pre[i+3])), ", ", sprintf("% .4f", Im(pre[i+3])), "),\n", sep="") +} diff --git a/utils/pilots.py b/utils/pilots.py index 49b19e96..dea6e923 100644 --- a/utils/pilots.py +++ b/utils/pilots.py @@ -12,9 +12,9 @@ -1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1] -print "polarity" -print tuple((x, x, x, -x) for x in polarity) +print("polarity") +print(tuple((x, x, x, -x) for x in polarity)) -print "pattern" -print tuple((-21, -7, 7, 21) for x in range(127)) +print("pattern") +print(tuple((-21, -7, 7, 21) for x in range(127))) diff --git a/utils/sync_words.py b/utils/sync_words.py index 7a9412f6..8460a7cb 100644 --- a/utils/sync_words.py +++ b/utils/sync_words.py @@ -18,12 +18,12 @@ assert(len(long_rot) == 64) assert(len(sync) == 4) -print "power short: " + str(sum([abs(x)**2 for x in short])) -print "power long: " + str(sum([abs(x)**2 for x in long_norm])) +print("power short: " + str(sum([abs(x)**2 for x in short]))) +print("power long: " + str(sum([abs(x)**2 for x in long_norm]))) -print "sync sequence" -print sync -print "len sync: " + str(len(sync)) +print("sync sequence") +print(sync) +print("len sync: " + str(len(sync))) From 09e3366d9a0d1255fd9143e347f8b0bf86c39c03 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Tue, 6 Aug 2024 10:02:49 -0400 Subject: [PATCH 10/12] updating decode MAC with HaLow constants --- grc/ieee802_11_decode_mac.block.yml | 2 +- lib/decode_mac.cc | 14 +++++++------- lib/frame_equalizer_impl.cc | 11 +++++++---- lib/sync_long.cc | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/grc/ieee802_11_decode_mac.block.yml b/grc/ieee802_11_decode_mac.block.yml index e38d5852..33c18037 100644 --- a/grc/ieee802_11_decode_mac.block.yml +++ b/grc/ieee802_11_decode_mac.block.yml @@ -21,7 +21,7 @@ parameters: inputs: - domain: stream dtype: byte - vlen: 48 + vlen: 24 outputs: - domain: message diff --git a/lib/decode_mac.cc b/lib/decode_mac.cc index a9da87f1..821c559b 100644 --- a/lib/decode_mac.cc +++ b/lib/decode_mac.cc @@ -33,7 +33,7 @@ class decode_mac_impl : public decode_mac public: decode_mac_impl(bool log, bool debug) : block("decode_mac", - gr::io_signature::make(1, 1, 48), + gr::io_signature::make(1, 1, CODED_BITS_PER_OFDM_SYMBOL), gr::io_signature::make(0, 0, 0)), d_log(log), d_debug(debug), @@ -102,20 +102,20 @@ class decode_mac_impl : public decode_mac if (copied < d_frame.n_sym) { dout << "copy one symbol, copied " << copied << " out of " << d_frame.n_sym << std::endl; - std::memcpy(d_rx_symbols + (copied * 48), in, 48); + std::memcpy(d_rx_symbols + (copied * CODED_BITS_PER_OFDM_SYMBOL), in, CODED_BITS_PER_OFDM_SYMBOL); copied++; if (copied == d_frame.n_sym) { dout << "received complete frame - decoding" << std::endl; decode(); - in += 48; + in += CODED_BITS_PER_OFDM_SYMBOL; i++; d_frame_complete = true; break; } } - in += 48; + in += CODED_BITS_PER_OFDM_SYMBOL; i++; } @@ -127,7 +127,7 @@ class decode_mac_impl : public decode_mac void decode() { - for (int i = 0; i < d_frame.n_sym * 48; i++) { + for (int i = 0; i < d_frame.n_sym * CODED_BITS_PER_OFDM_SYMBOL; i++) { for (int k = 0; k < d_ofdm.n_bpsc; k++) { d_rx_bits[i * d_ofdm.n_bpsc + k] = !!(d_rx_symbols[i] & (1 << k)); } @@ -142,7 +142,7 @@ class decode_mac_impl : public decode_mac boost::crc_32_type result; result.process_bytes(out_bytes + 2, d_frame.psdu_size); if (result.checksum() != 558161692) { - dout << "checksum wrong -- dropping" << std::endl; + dout << "checksum wrong -- dropping. expected 558161692 got: " << result.checksum() << std::endl; return; } @@ -243,7 +243,7 @@ class decode_mac_impl : public decode_mac viterbi_decoder d_decoder; - uint8_t d_rx_symbols[48 * MAX_SYM]; + uint8_t d_rx_symbols[CODED_BITS_PER_OFDM_SYMBOL * MAX_SYM]; uint8_t d_rx_bits[MAX_ENCODED_BITS]; uint8_t d_deinterleaved_bits[MAX_ENCODED_BITS]; uint8_t out_bytes[MAX_PSDU_SIZE + 2]; // 2 for signal field diff --git a/lib/frame_equalizer_impl.cc b/lib/frame_equalizer_impl.cc index bc8b29eb..654ae1c0 100644 --- a/lib/frame_equalizer_impl.cc +++ b/lib/frame_equalizer_impl.cc @@ -150,11 +150,12 @@ int frame_equalizer_impl::general_work(int noutput_items, dout << "epsilon: " << d_epsilon0 << std::endl; } - // not interesting -> skip + // not interesting -> skip. Why is this not interesting? uncommenting for now because I think it terminates too early for HaLow + /* if (d_current_symbol > (d_frame_symbols + 2)) { i++; continue; - } + }*/ std::memcpy(current_symbol, in + i * SAMPLES_PER_OFDM_SYMBOL, SAMPLES_PER_OFDM_SYMBOL * sizeof(gr_complex)); @@ -165,7 +166,7 @@ int frame_equalizer_impl::general_work(int noutput_items, (d_epsilon0 + d_er) * (i - 32) / SAMPLES_PER_OFDM_SYMBOL)); //what is 32? Half of the 802.11a number of subcarriers? } - gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; + gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; // does 127 have to do with polarity? anything to do with line 141 on sync long? double beta; if (d_current_symbol < 2) { @@ -202,10 +203,12 @@ int frame_equalizer_impl::general_work(int noutput_items, d_er = (1 - alpha) * d_er + alpha * er; } - // do equalization + // do equalization. this is what sends bytes downstream to WiFi Decode MAC d_equalizer->equalize( current_symbol, d_current_symbol, symbols, out + o * CODED_BITS_PER_OFDM_SYMBOL, d_frame_mod); + dout << "d_current_symbol: " << d_current_symbol << " i: " << i << std::endl; + // signal field, it takes 6 OFDM symbols to make the SIG field if (d_current_symbol >= 2 && d_current_symbol < 8) { o++; diff --git a/lib/sync_long.cc b/lib/sync_long.cc index fbfcd0d5..d9764282 100644 --- a/lib/sync_long.cc +++ b/lib/sync_long.cc @@ -137,7 +137,7 @@ class sync_long_impl : public sync_long pmt::string_to_symbol(name())); } - // 128 is 2*64. What is this from? + // 128 is 2*64. What is this from? Also see this on line 168 of frame_equalizer. It could have to do with polarity. if (rel >= 0 && (rel < 128 || ((rel - 128) % (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)) > (SAMPLES_PER_GI - 1))) { out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * d_freq_offset)); o++; From eebfc68e5e07d4cbb84fcf655621944d43204ed8 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Sun, 11 Aug 2024 23:00:18 -0400 Subject: [PATCH 11/12] troubleshooting signal field decoding --- lib/frame_equalizer_impl.cc | 71 +++++++++++++++++++++++++++++-------- lib/utils.cc | 15 ++++---- lib/utils.h | 2 +- 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/lib/frame_equalizer_impl.cc b/lib/frame_equalizer_impl.cc index 654ae1c0..c88f011c 100644 --- a/lib/frame_equalizer_impl.cc +++ b/lib/frame_equalizer_impl.cc @@ -166,10 +166,10 @@ int frame_equalizer_impl::general_work(int noutput_items, (d_epsilon0 + d_er) * (i - 32) / SAMPLES_PER_OFDM_SYMBOL)); //what is 32? Half of the 802.11a number of subcarriers? } - gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; // does 127 have to do with polarity? anything to do with line 141 on sync long? + gr_complex p = equalizer::base::POLARITY[(d_current_symbol - 2) % 127]; // why subtract 2 here? does 127 have to do with polarity? anything to do with line 141 on sync long? double beta; - if (d_current_symbol < 2) { + if (d_current_symbol < 8) { //used to be 2. assuming 8 b/c is 4+4 (4 symbols for STF, 4 symbols for LTF1 beta = arg(current_symbol[PILOT2_INDEX] - current_symbol[PILOT1_INDEX]); //unsure whether to add/subtract the pilot? @@ -183,7 +183,7 @@ int frame_equalizer_impl::general_work(int noutput_items, er *= d_bw / (2 * M_PI * d_freq * (SAMPLES_PER_OFDM_SYMBOL + SAMPLES_PER_GI)); - if (d_current_symbol < 2) { + if (d_current_symbol < 8) { //used to be 2. assuming 8 b/c is 4+4 (4 symbols for STF, 4 symbols for LTF1) d_prev_pilots[0] = current_symbol[PILOT1_INDEX]; d_prev_pilots[1] = -current_symbol[PILOT2_INDEX]; } else { @@ -197,25 +197,26 @@ int frame_equalizer_impl::general_work(int noutput_items, } // update estimate of residual frequency offset - if (d_current_symbol >= 2) { + if (d_current_symbol >= 8) { double alpha = 0.1; d_er = (1 - alpha) * d_er + alpha * er; } - // do equalization. this is what sends bytes downstream to WiFi Decode MAC + // do equalization. this is what sends bytes downstream to WiFi Decode MAC starting at the 0 offset relative to (out + o * CODED_BITS_PER_OFDM_SYMBOL), ending at CODED_BITS_PER_OFDM_SYMBOL offset index. d_equalizer->equalize( current_symbol, d_current_symbol, symbols, out + o * CODED_BITS_PER_OFDM_SYMBOL, d_frame_mod); - dout << "d_current_symbol: " << d_current_symbol << " i: " << i << std::endl; + dout << "d_current_symbol: " << d_current_symbol << " i: " << i << " o: " << o << std::endl; // signal field, it takes 6 OFDM symbols to make the SIG field - if (d_current_symbol >= 2 && d_current_symbol < 8) { + if (d_current_symbol >= 8 && d_current_symbol < 14) { o++; } - if (d_current_symbol == 7){ - - if (decode_signal_field(out + o * CODED_BITS_PER_OFDM_SYMBOL)) { + if (d_current_symbol == 14){ //wait until you've processed all 6 symbols of the SIG field + dout << "o: " << o << std::endl; + //add a check to make sure that o is greater than 6? + if (decode_signal_field(out + (o - 6) * CODED_BITS_PER_OFDM_SYMBOL)) { //point to the beginning of the SIG field. Skip all 8 symbols of the LTF and STF. pmt::pmt_t dict = pmt::make_dict(); dict = pmt::dict_add( @@ -248,7 +249,7 @@ int frame_equalizer_impl::general_work(int noutput_items, } // data - if (d_current_symbol >= 8) { + if (d_current_symbol >= 14) { o++; pmt::pmt_t pdu = pmt::make_dict(); message_port_pub( @@ -278,12 +279,16 @@ bool frame_equalizer_impl::decode_signal_field(uint8_t* rx_bits) void frame_equalizer_impl::deinterleave(uint8_t* rx_bits) { - for (int i = 0; i < CODED_BITS_PER_OFDM_SYMBOL; i++) { - d_deinterleaved[i] = rx_bits[interleaver_pattern[i]]; + //why does iteration 1 invoke undefined behavior? + for(int j = 0; j < 6; j++){ //because there are 6 OFDM symbols in rx_bits (or at least there should be) + for (int i = 0; i < CODED_BITS_PER_OFDM_SYMBOL; i++) { + d_deinterleaved[j*CODED_BITS_PER_OFDM_SYMBOL + i] = rx_bits[j*CODED_BITS_PER_OFDM_SYMBOL + interleaver_pattern[i]]; + } } } //p.3246 wifi spec +//should you add a parameter here to force check the size of decoded_bits? Right now it isn't clear how many you're getting bool frame_equalizer_impl::parse_signal(uint8_t* decoded_bits) { @@ -291,7 +296,33 @@ bool frame_equalizer_impl::parse_signal(uint8_t* decoded_bits) int frame_bit_index = 0; d_frame_bytes = 0; bool parity = false; - for (int i = 0; i < NUM_BITS_SIG_FIELD * NUM_SIG_FIELD_REPETITIONS; i++) { + std::unique_ptr sig_field(new char[(NUM_BITS_IN_HALOW_SIG_FIELD * NUM_SIG_FIELD_REPETITIONS)/8]); //8 bits per byte + char byte = '\0'; + if(decoded_bits[0]) + { + byte = 1 << 7; + } + int byte_counter = 0; + + //each SIG field is repeated before the next is sent. So first 6 bits should be equal to the next 6, repeated 6 times to yield 72 bits + for (int i = 0; i < NUM_BITS_IN_HALOW_SIG_FIELD * NUM_SIG_FIELD_REPETITIONS; i++) { + if(i % 8 == 0 && i != 0) //8 bits per byte + { + sig_field[byte_counter] = byte; + byte = '\0'; + if(decoded_bits[i]) + { + byte = 1 << 7; + } + byte_counter++; + } + else + { + if(decoded_bits[i]) + { + byte = byte | (1 << (7 - (i % 8))); + } + } parity ^= decoded_bits[i]; //only accounts for the first repetition @@ -306,6 +337,18 @@ bool frame_equalizer_impl::parse_signal(uint8_t* decoded_bits) frame_bit_index++; }*/ } + sig_field[byte_counter] = byte; + byte_counter++; + byte = '\0'; + + //print out the hex representation of the signal field + for(int i = 0; i < byte_counter; i++) + { + byte = sig_field[i]; + dout << std::hex << ((byte & 0xF0) >> 4) << " "; + dout << std::hex << ((byte & 0x0F)) << " "; + } + dout << std::endl; /* unused with HaLow, CRC instead if (parity != decoded_bits[17]) { diff --git a/lib/utils.cc b/lib/utils.cc index 952d1c0e..ee153d7d 100644 --- a/lib/utils.cc +++ b/lib/utils.cc @@ -36,22 +36,22 @@ ofdm_param::ofdm_param(Encoding e) switch (e) { case BPSK_1_2: n_bpsc = 1; - n_cbps = 48; - n_dbps = 24; - rate_field = 0x0D; // 0b00001101 + n_cbps = 24; + n_dbps = 12; + rate_field = 0x00; // i.e. MCS 0b00000000 break; case BPSK_3_4: n_bpsc = 1; - n_cbps = 48; - n_dbps = 36; + n_cbps = 24; + n_dbps = 18; rate_field = 0x0F; // 0b00001111 break; case QPSK_1_2: n_bpsc = 2; - n_cbps = 96; - n_dbps = 48; + n_cbps = 48; + n_dbps = 24; rate_field = 0x05; // 0b00000101 break; @@ -113,6 +113,7 @@ frame_param::frame_param(ofdm_param& ofdm, int psdu_length) psdu_size = psdu_length; // number of symbols (17-11) + //where does 16 come from? Assuming that 8*psdu_size is just converting PSDU size from bytes to bits. Where does 6 come from? Must be in the data field because the SIG field gets passed a psdu_length of 0. n_sym = (int)ceil((16 + 8 * psdu_size + 6) / (double)ofdm.n_dbps); n_data_bits = n_sym * ofdm.n_dbps; diff --git a/lib/utils.h b/lib/utils.h index 2c67f1b3..b9379afa 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -30,7 +30,7 @@ using gr::ieee802_11::Encoding; #define NUM_PILOTS 2 //2 HaLow pilots. p.3253 of spec #define PILOT1_INDEX 9 //technically -7 in the spec, but that is a range of [-16, 15). We're operating in range of [0, 31). p.3253 of spec #define PILOT2_INDEX 23 //technically +7 in the spec, but see above ^. p.3253 of spec. -#define NUM_BITS_SIG_FIELD 36 //p.3246 of spec +#define NUM_BITS_IN_HALOW_SIG_FIELD 36 //p.3246 of spec #define NUM_SIG_FIELD_REPETITIONS 2 //p.3246 of spec #define NUM_BITS_PER_REPETITION 6 //p.3246 of spec #define MCS_FIRST_BIT_INDEX 7 //p.3246 of spec From 49d3c9d52f14033ce1ffc9b62cc06897d2e15136 Mon Sep 17 00:00:00 2001 From: irongiant33 Date: Mon, 12 Aug 2024 22:08:31 -0400 Subject: [PATCH 12/12] continuing to hunt down the reason why the signal field is not producing consistent values --- lib/frame_equalizer_impl.cc | 23 +++++++++++++++++++++++ lib/frame_equalizer_impl.h | 2 +- lib/sync_short.cc | 2 +- lib/utils.cc | 10 ++++++---- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/frame_equalizer_impl.cc b/lib/frame_equalizer_impl.cc index c88f011c..572b7a3c 100644 --- a/lib/frame_equalizer_impl.cc +++ b/lib/frame_equalizer_impl.cc @@ -271,7 +271,30 @@ bool frame_equalizer_impl::decode_signal_field(uint8_t* rx_bits) static ofdm_param ofdm(BPSK_1_2); static frame_param frame(ofdm, 0); + dout << "number of data bits in frame: 0x" << frame.n_data_bits << std::endl; deinterleave(rx_bits); + + // loop over all deinterleaved bytes and print them out to see if there are similarities before decoding + dout << "Post deinterleaved: "; + for(int i = 0; i < 18; i++) + { + char byte = '\0'; + for(int j = 0; j < 8; j++) + { + if(d_deinterleaved[i*8 + j]) + { + byte = byte | (1 << (7 - j)); + } + } + dout << std::hex << ((byte & 0xF0) >> 4) << " "; + dout << std::hex << ((byte & 0x0F)) << " "; + } + dout << std::endl; + + //handle the repetitions here _before_ decoding + // ??? + + //replace viterbi decoder with BCC decoder uint8_t* decoded_bits = d_decoder.decode(&ofdm, &frame, d_deinterleaved); return parse_signal(decoded_bits); diff --git a/lib/frame_equalizer_impl.h b/lib/frame_equalizer_impl.h index 6f470636..02711385 100644 --- a/lib/frame_equalizer_impl.h +++ b/lib/frame_equalizer_impl.h @@ -68,7 +68,7 @@ class frame_equalizer_impl : virtual public frame_equalizer int d_frame_symbols; int d_frame_encoding; - uint8_t d_deinterleaved[CODED_BITS_PER_OFDM_SYMBOL]; + uint8_t d_deinterleaved[6*CODED_BITS_PER_OFDM_SYMBOL]; //because there are 6 OFDM frames in the SIG field gr_complex symbols[CODED_BITS_PER_OFDM_SYMBOL]; std::shared_ptr d_frame_mod; diff --git a/lib/sync_short.cc b/lib/sync_short.cc index 59c0907a..662891bb 100644 --- a/lib/sync_short.cc +++ b/lib/sync_short.cc @@ -105,7 +105,7 @@ class sync_short_impl : public sync_short } else if (d_copied > MIN_GAP) { d_copied = 0; d_plateau = 0; - d_freq_offset = arg(in_abs[o]) / SAMPLES_PER_GI; //16 = samples per GI? + d_freq_offset = arg(in_abs[o]) / SAMPLES_PER_GI; insert_tag( nitems_written(0) + o, d_freq_offset, nitems_read(0) + o); dout << "SHORT Frame!" << std::endl; diff --git a/lib/utils.cc b/lib/utils.cc index ee153d7d..62742397 100644 --- a/lib/utils.cc +++ b/lib/utils.cc @@ -112,13 +112,15 @@ frame_param::frame_param(ofdm_param& ofdm, int psdu_length) psdu_size = psdu_length; - // number of symbols (17-11) - //where does 16 come from? Assuming that 8*psdu_size is just converting PSDU size from bytes to bits. Where does 6 come from? Must be in the data field because the SIG field gets passed a psdu_length of 0. + // number of symbols (EQN17-11, page 2817 of spec for 802.11a/g). Possibly 16 is the number of SIG bits and 8 is the number of pad/tail bits? + // number of symbols p.3248 "Data Field" for HaLow OR EQN23-65 on p.3302 OR EQN 23-66 on p.3303 n_sym = (int)ceil((16 + 8 * psdu_size + 6) / (double)ofdm.n_dbps); - n_data_bits = n_sym * ofdm.n_dbps; + n_data_bits = 72; //hardcoding this for now to see what happens + //n_data_bits = n_sym * ofdm.n_dbps; - // number of padding bits (17-13) + // number of padding bits (EQN17-13, page 2817 of spec for 802.11a/g) + // number of symbols p.3248 "Data Field" for HaLow n_pad = n_data_bits - (16 + 8 * psdu_size + 6); n_encoded_bits = n_sym * ofdm.n_cbps;