From f8966f0d105b59a3c526201747d2ca9d934e060f Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sat, 20 Nov 2010 17:06:48 -0800 Subject: [PATCH] All tags, all the time. Still some weirdness with set_history() that requires using the check widths in the framer & slicer. --- src/lib/air_modes_framer.cc | 21 +- src/lib/air_modes_framer.h | 1 + src/lib/air_modes_preamble.cc | 4 +- src/lib/air_modes_slicer.cc | 366 +++++++++++++++++----------------- src/python/uhd_modes.py | 17 +- 5 files changed, 203 insertions(+), 206 deletions(-) diff --git a/src/lib/air_modes_framer.cc b/src/lib/air_modes_framer.cc index 565ceea..a167a31 100644 --- a/src/lib/air_modes_framer.cc +++ b/src/lib/air_modes_framer.cc @@ -40,7 +40,7 @@ air_modes_framer_sptr air_make_modes_framer(int channel_rate) air_modes_framer::air_modes_framer(int channel_rate) : gr_sync_block ("modes_framer", gr_make_io_signature (1, 1, sizeof(float)), //stream 0 is received data - gr_make_io_signature (1, 1, sizeof(unsigned char))) //output is [0, 1, 2]: [no frame, short frame, long frame] + gr_make_io_signature (1, 1, sizeof(float))) //raw samples passed back out { //initialize private data here d_chip_rate = 2000000; //2Mchips per second @@ -49,6 +49,11 @@ air_modes_framer::air_modes_framer(int channel_rate) : d_check_width = 120 * d_samples_per_symbol; //gotta be able to look at two long frame lengths at a time //in the event that FRUIT occurs near the end of the first frame //set_history(d_check_width*2); + + std::stringstream str; + str << name() << unique_id(); + d_me = pmt::pmt_string_to_symbol(str.str()); + d_key = pmt::pmt_string_to_symbol("frame_info"); } int air_modes_framer::work(int noutput_items, @@ -57,8 +62,8 @@ int air_modes_framer::work(int noutput_items, { //do things! const float *inraw = (const float *) input_items[0]; - //float *outraw = (float *) output_items[0]; - unsigned char *outattrib = (unsigned char *) output_items[0]; + float *outraw = (float *) output_items[0]; + //unsigned char *outattrib = (unsigned char *) output_items[0]; int size = noutput_items - d_check_width*2; float reference_level; framer_packet_type packet_attrib; @@ -68,7 +73,7 @@ int air_modes_framer::work(int noutput_items, get_tags_in_range(tags, 0, abs_sample_cnt, abs_sample_cnt + size, pmt::pmt_string_to_symbol("preamble_found")); std::vector::iterator tag_iter; - memset(outattrib, 0x00, size * sizeof(unsigned char)); + memcpy(outraw, inraw, size * sizeof(float)); for(tag_iter = tags.begin(); tag_iter != tags.end(); tag_iter++) { uint64_t i = gr_tags::get_nitems(*tag_iter) - abs_sample_cnt; @@ -106,7 +111,13 @@ int air_modes_framer::work(int noutput_items, get_tags_in_range(fruit_tags, 0, abs_sample_cnt+i+1, abs_sample_cnt+i+lookahead, pmt::pmt_string_to_symbol("preamble_found")); if(fruit_tags.size() > 0) packet_attrib = Fruited_Packet; - outattrib[i] = packet_attrib; + //insert tag here + add_item_tag(0, //stream ID + nitems_written(0)+i, //sample + d_key, //preamble_found + pmt::pmt_from_long((long)packet_attrib), + d_me //block src id + ); } return size; diff --git a/src/lib/air_modes_framer.h b/src/lib/air_modes_framer.h index f5214c9..067a09c 100644 --- a/src/lib/air_modes_framer.h +++ b/src/lib/air_modes_framer.h @@ -44,6 +44,7 @@ private: int d_chip_rate; int d_samples_per_chip; int d_samples_per_symbol; + pmt::pmt_t d_me, d_key; public: int work (int noutput_items, diff --git a/src/lib/air_modes_preamble.cc b/src/lib/air_modes_preamble.cc index 97d65ba..b7593b9 100644 --- a/src/lib/air_modes_preamble.cc +++ b/src/lib/air_modes_preamble.cc @@ -51,7 +51,7 @@ air_modes_preamble::air_modes_preamble(int channel_rate, float threshold_db) : str << name() << unique_id(); d_me = pmt::pmt_string_to_symbol(str.str()); d_key = pmt::pmt_string_to_symbol("preamble_found"); - //set_history(d_check_width); + set_history(d_check_width); } int air_modes_preamble::work(int noutput_items, @@ -64,7 +64,7 @@ int air_modes_preamble::work(int noutput_items, float *outraw = (float *) output_items[0]; - int size = noutput_items - d_check_width; + int size = noutput_items;// - d_check_width; int pulse_offsets[4]; float bit_energies[4]; diff --git a/src/lib/air_modes_slicer.cc b/src/lib/air_modes_slicer.cc index 6f1a8bb..7913414 100644 --- a/src/lib/air_modes_slicer.cc +++ b/src/lib/air_modes_slicer.cc @@ -46,7 +46,7 @@ air_modes_slicer_sptr air_make_modes_slicer(int channel_rate, gr_msg_queue_sptr air_modes_slicer::air_modes_slicer(int channel_rate, gr_msg_queue_sptr queue) : gr_sync_block ("modes_slicer", - gr_make_io_signature2 (2, 2, sizeof(float), sizeof(unsigned char)), //stream 0 is received data, stream 1 is binary preamble detector output + gr_make_io_signature (1, 1, sizeof(float)), //stream 0 is received data, stream 1 is binary preamble detector output gr_make_io_signature (0, 0, 0) ) { //initialize private data here @@ -74,222 +74,222 @@ int air_modes_slicer::work(int noutput_items, { //do things! const float *inraw = (const float *) input_items[0]; - const unsigned char *inattrib = (const unsigned char *) input_items[1]; int size = noutput_items - d_check_width; //since it's a sync block, i assume that it runs with ninput_items = noutput_items int i; + + std::vector tags; + uint64_t abs_sample_cnt = nitems_read(0); + get_tags_in_range(tags, 0, abs_sample_cnt, abs_sample_cnt + size, pmt::pmt_string_to_symbol("frame_info")); + std::vector::iterator tag_iter; + + for(tag_iter = tags.begin(); tag_iter != tags.end(); tag_iter++) { + uint64_t i = gr_tags::get_nitems(*tag_iter) - abs_sample_cnt; + modes_packet rx_packet; + framer_packet_type packet_type = framer_packet_type(pmt::pmt_to_long(gr_tags::get_value(*tag_iter))); - for(i = 0; i < size; i++) { - if(inattrib[i] == framer_packet_type(Short_Packet) || inattrib[i] == framer_packet_type(Long_Packet)) { //if there's a packet starting here.... - modes_packet rx_packet; + int packet_length; + packet_length = packet_type == framer_packet_type(Short_Packet) ? 56 : 112; - int packet_length = 112; - if(inattrib[i] == framer_packet_type(Short_Packet)) packet_length = 56; - - rx_packet.type = framer_packet_type(inattrib[i]); - memset(&rx_packet.data, 0x00, 14 * sizeof(unsigned char)); - memset(&rx_packet.lowconfbits, 0x00, 24 * sizeof(unsigned char)); - rx_packet.numlowconf = 0; + rx_packet.type = packet_type; + memset(&rx_packet.data, 0x00, 14 * sizeof(unsigned char)); + memset(&rx_packet.lowconfbits, 0x00, 24 * sizeof(unsigned char)); + rx_packet.numlowconf = 0; //let's use the preamble marker to get a reference level for the packet - rx_packet.reference_level = (bit_energy(&inraw[i], d_samples_per_chip) - + bit_energy(&inraw[i+int(1.0*d_samples_per_symbol)], d_samples_per_chip) - + bit_energy(&inraw[i+int(3.5*d_samples_per_symbol)], d_samples_per_chip) - + bit_energy(&inraw[i+int(4.5*d_samples_per_symbol)], d_samples_per_chip)) / 4; + rx_packet.reference_level = (bit_energy(&inraw[i], d_samples_per_chip) + + bit_energy(&inraw[i+int(1.0*d_samples_per_symbol)], d_samples_per_chip) + + bit_energy(&inraw[i+int(3.5*d_samples_per_symbol)], d_samples_per_chip) + + bit_energy(&inraw[i+int(4.5*d_samples_per_symbol)], d_samples_per_chip)) / 4; - i += 8 * d_samples_per_symbol; //move to the center of the first bit of the data + i += 8 * d_samples_per_symbol; //move to the center of the first bit of the data - //here we calculate the total energy contained in each chip of the symbol - for(int j = 0; j < packet_length; j++) { - int firstchip = i+j*d_samples_per_symbol; - int secondchip = firstchip + d_samples_per_chip; - bool slice, confidence; - float firstchip_energy=0, secondchip_energy=0; + //here we calculate the total energy contained in each chip of the symbol + for(int j = 0; j < packet_length; j++) { + int firstchip = i+j*d_samples_per_symbol; + int secondchip = firstchip + d_samples_per_chip; + bool slice, confidence; + float firstchip_energy=0, secondchip_energy=0; - firstchip_energy = bit_energy(&inraw[firstchip], d_samples_per_chip); - secondchip_energy = bit_energy(&inraw[secondchip], d_samples_per_chip); + firstchip_energy = bit_energy(&inraw[firstchip], d_samples_per_chip); + secondchip_energy = bit_energy(&inraw[secondchip], d_samples_per_chip); - //3dB limits for bit slicing and confidence measurement - float highlimit=rx_packet.reference_level*2; - float lowlimit=rx_packet.reference_level*0.5; - bool firstchip_inref = ((firstchip_energy > lowlimit) && (firstchip_energy < highlimit)); - bool secondchip_inref = ((secondchip_energy > lowlimit) && (secondchip_energy < highlimit)); + //3dB limits for bit slicing and confidence measurement + float highlimit=rx_packet.reference_level*2; + float lowlimit=rx_packet.reference_level*0.5; + bool firstchip_inref = ((firstchip_energy > lowlimit) && (firstchip_energy < highlimit)); + bool secondchip_inref = ((secondchip_energy > lowlimit) && (secondchip_energy < highlimit)); - //these two lines for a super simple naive slicer. -// slice = firstchip_energy > secondchip_energy; -// confidence = bool(int(firstchip_inref) + int(secondchip_inref)); //one and only one chip in the reference zone + //these two lines for a super simple naive slicer. +// slice = firstchip_energy > secondchip_energy; +// confidence = bool(int(firstchip_inref) + int(secondchip_inref)); //one and only one chip in the reference zone - //below is the Lincoln Labs slicer. it may produce greater bit errors. supposedly it is more resistant to mode A/C FRUIT. + //below is the Lincoln Labs slicer. it may produce greater bit errors. supposedly it is more resistant to mode A/C FRUIT. //see http://adsb.tc.faa.gov/WG3_Meetings/Meeting8/Squitter-Lon.pdf - if(firstchip_inref && !secondchip_inref) { - slice = 1; - confidence = 1; - } - else if(secondchip_inref && !firstchip_inref) { - slice = 0; - confidence = 1; - } - else if(firstchip_inref && secondchip_inref) { - slice = firstchip_energy > secondchip_energy; - confidence = 0; - } - else if(!firstchip_inref && !secondchip_inref) { //in this case, we determine the bit by whichever is larger, and we determine high confidence if the low chip is 6dB below reference. - slice = firstchip_energy > secondchip_energy; - if(slice) { - if(secondchip_energy < lowlimit * 0.5) confidence = 1; - else confidence = 0; - } else { - if(firstchip_energy < lowlimit * 0.5) confidence = 1; - else confidence = 0; - } - } - - //put the data into the packet + if(firstchip_inref && !secondchip_inref) { + slice = 1; + confidence = 1; + } + else if(secondchip_inref && !firstchip_inref) { + slice = 0; + confidence = 1; + } + else if(firstchip_inref && secondchip_inref) { + slice = firstchip_energy > secondchip_energy; + confidence = 0; + } + else if(!firstchip_inref && !secondchip_inref) { //in this case, we determine the bit by whichever is larger, and we determine high confidence if the low chip is 6dB below reference. + slice = firstchip_energy > secondchip_energy; if(slice) { - rx_packet.data[j/8] += 1 << (7-(j%8)); - } - //put the confidence decision into the packet - if(confidence) { - //rx_packet.confidence[j/8] += 1 << (7-(j%8)); + if(secondchip_energy < lowlimit * 0.5) confidence = 1; + else confidence = 0; } else { - if(rx_packet.numlowconf < 24) rx_packet.lowconfbits[rx_packet.numlowconf++] = j; + if(firstchip_energy < lowlimit * 0.5) confidence = 1; + else confidence = 0; } } - - /******************** BEGIN TIMESTAMP BS ******************/ - rx_packet.timestamp_secs = 0; - rx_packet.timestamp_frac = 0; - - uint64_t abs_sample_cnt = nitems_read(0); - std::vector tags; - uint64_t timestamp_secs, timestamp_sample, timestamp_delta; - double timestamp_frac; - - pmt::pmt_t timestamp; - - get_tags_in_range(tags, 0, abs_sample_cnt, abs_sample_cnt + i, pmt::pmt_string_to_symbol("packet_time_stamp")); - //tags.back() is the most recent timestamp, then. - if(tags.size() > 0) { - //if nobody but the USRP is producing timestamps this isn't necessary - //std::sort(tags.begin(), tags.end(), pmtcompare); - timestamp = tags.back(); - - timestamp_secs = pmt_to_uint64(pmt_tuple_ref(gr_tags::get_value(timestamp), 0)); - timestamp_frac = pmt_to_double(pmt_tuple_ref(gr_tags::get_value(timestamp), 1)); - timestamp_sample = gr_tags::get_nitems(timestamp); - //now we have to offset the timestamp based on the current sample number - timestamp_delta = (abs_sample_cnt + i) - timestamp_sample; - - timestamp_frac += timestamp_delta * d_secs_per_sample; - if(timestamp_frac > 1.0) { - timestamp_frac -= 1.0; - timestamp_secs++; - } - - rx_packet.timestamp_secs = timestamp_secs; - rx_packet.timestamp_frac = timestamp_frac; + //put the data into the packet + if(slice) { + rx_packet.data[j/8] += 1 << (7-(j%8)); } - - /******************* END TIMESTAMP BS *********************/ - - //increment for the next round - i += packet_length * d_samples_per_symbol; - - //here you might want to traverse the whole packet and if you find all 0's, just toss it. don't know why these packets turn up, but they pass ECC. - bool zeroes = 1; - for(int m = 0; m < 14; m++) { - if(rx_packet.data[m]) zeroes = 0; + //put the confidence decision into the packet + if(confidence) { + //rx_packet.confidence[j/8] += 1 << (7-(j%8)); + } else { + if(rx_packet.numlowconf < 24) rx_packet.lowconfbits[rx_packet.numlowconf++] = j; } - if(zeroes) continue; //toss it - - rx_packet.message_type = (rx_packet.data[0] >> 3) & 0x1F; //get the message type for the parser to conveniently use, and to make decisions on ECC methods - - //we note that short packets other than type 11 CANNOT be reliably decoded, since the a/c address is encoded with the parity bits. - //mode S in production ATC use relies on the fact that these short packets are reply squitters to transponder requests, - //and so the radar should already know the expected a/c reply address. so, error-correction makes no sense on short packets (other than type 11) - //this means two things: first, we will DROP short packets (other than type 11) with ANY low-confidence bits, since we can't be confident that we're seeing real data - //second, we will only perform error correction on LONG type S packets. - - //the limitation on short packets means in practice a short packet has to be at least 6dB above the noise floor in order to be output. long packets can theoretically - //be decoded at the 3dB SNR point. below that and the preamble detector won't fire. + } - //in practice, this limitation causes you to see a HUGE number of type 11 packets which pass CRC through random luck. - //these packets necessarily have large numbers of low-confidence bits, so we toss them with an arbitrary limit of 10. - //that's a pretty dang low threshold so i don't think we'll drop many legit packets - - if(rx_packet.type == Short_Packet && rx_packet.message_type != 11 && rx_packet.numlowconf != 0) continue; - if(rx_packet.type == Short_Packet && rx_packet.message_type == 11 && rx_packet.numlowconf >= 10) continue; + /******************** BEGIN TIMESTAMP BS ******************/ + rx_packet.timestamp_secs = 0; + rx_packet.timestamp_frac = 0; + + uint64_t abs_sample_cnt = nitems_read(0); + std::vector tags; + uint64_t timestamp_secs, timestamp_sample, timestamp_delta; + double timestamp_frac; + pmt::pmt_t timestamp; + + get_tags_in_range(tags, 0, abs_sample_cnt, abs_sample_cnt + i, pmt::pmt_string_to_symbol("packet_time_stamp")); + //tags.back() is the most recent timestamp, then. + if(tags.size() > 0) { + //if nobody but the USRP is producing timestamps this isn't necessary + //std::sort(tags.begin(), tags.end(), pmtcompare); + timestamp = tags.back(); + + timestamp_secs = pmt_to_uint64(pmt_tuple_ref(gr_tags::get_value(timestamp), 0)); + timestamp_frac = pmt_to_double(pmt_tuple_ref(gr_tags::get_value(timestamp), 1)); + timestamp_sample = gr_tags::get_nitems(timestamp); + //now we have to offset the timestamp based on the current sample number + timestamp_delta = (abs_sample_cnt + i) - timestamp_sample; - //if(rx_packet.numlowconf >= 24) continue; //don't even try, this is the maximum number of errors ECC could possibly correct - //the above line should be part of ECC, and only checked if the message has parity errors - - rx_packet.parity = modes_check_parity(rx_packet.data, packet_length); - - if(rx_packet.parity && rx_packet.type == Long_Packet) { -// long before = rx_packet.parity; - bruteResultTypeDef bruteResult = modes_ec_brute(rx_packet); - - if(bruteResult == No_Solution) { - //printf("No solution!\n"); - continue; - } else if(bruteResult == Multiple_Solutions) { -// printf("Multiple solutions!\n"); - continue; - } else if(bruteResult == Too_Many_LCBs) { - //printf("Too many LCBs (%i)!\n", rx_packet.numlowconf); - continue; - } else if(bruteResult == No_Error) { -// printf("No error!\n"); - } else if(bruteResult == Solution_Found) { -// printf("Solution found for %i LCBs!\n", rx_packet.numlowconf); - } -// rx_packet.parity = modes_check_parity(rx_packet.data, packet_length); -// if(rx_packet.parity) printf("Error: packet fails parity check after correction, was %x, now %x\n", before, rx_packet.parity); + timestamp_frac += timestamp_delta * d_secs_per_sample; + if(timestamp_frac > 1.0) { + timestamp_frac -= 1.0; + timestamp_secs++; } + + rx_packet.timestamp_secs = timestamp_secs; + rx_packet.timestamp_frac = timestamp_frac; + } -// if(rx_packet.parity && rx_packet.type == Long_Packet) printf("Error! Bad packet forwarded to the queue.\n"); - //now we have a complete packet with confidence data, let's print it to the message queue - //here, rather than send the entire packet, since we've already done parity checking and ECC in C++, we'll - //send just the data (no confidence bits), separated into fields for easier parsing. + /******************* END TIMESTAMP BS *********************/ + + //increment for the next round - //we'll replicate some data by sending the message type as the first field, followed by the first 8+24=32 bits of the packet, followed by - //56 long packet data bits if applicable (zero-padded if not), followed by parity + //here you might want to traverse the whole packet and if you find all 0's, just toss it. don't know why these packets turn up, but they pass ECC. + bool zeroes = 1; + for(int m = 0; m < 14; m++) { + if(rx_packet.data[m]) zeroes = 0; + } + if(zeroes) continue; //toss it - d_payload.str(""); + rx_packet.message_type = (rx_packet.data[0] >> 3) & 0x1F; //get the message type for the parser to conveniently use, and to make decisions on ECC methods - d_payload << std::dec << std::setw(2) << std::setfill('0') << rx_packet.message_type << std::hex << " "; + //we note that short packets other than type 11 CANNOT be reliably decoded, since the a/c address is encoded with the parity bits. + //mode S in production ATC use relies on the fact that these short packets are reply squitters to transponder requests, + //and so the radar should already know the expected a/c reply address. so, error-correction makes no sense on short packets (other than type 11) + //this means two things: first, we will DROP short packets (other than type 11) with ANY low-confidence bits, since we can't be confident that we're seeing real data + //second, we will only perform error correction on LONG type S packets. - for(int m = 0; m < 4; m++) { + //the limitation on short packets means in practice a short packet has to be at least 6dB above the noise floor in order to be output. long packets can theoretically + //be decoded at the 3dB SNR point. below that and the preamble detector won't fire. + + //in practice, this limitation causes you to see a HUGE number of type 11 packets which pass CRC through random luck. + //these packets necessarily have large numbers of low-confidence bits, so we toss them with an arbitrary limit of 10. + //that's a pretty dang low threshold so i don't think we'll drop many legit packets + + if(rx_packet.type == Short_Packet && rx_packet.message_type != 11 && rx_packet.numlowconf != 0) continue; + if(rx_packet.type == Short_Packet && rx_packet.message_type == 11 && rx_packet.numlowconf >= 10) continue; + + + //if(rx_packet.numlowconf >= 24) continue; //don't even try, this is the maximum number of errors ECC could possibly correct + //the above line should be part of ECC, and only checked if the message has parity errors + + rx_packet.parity = modes_check_parity(rx_packet.data, packet_length); + + if(rx_packet.parity && rx_packet.type == Long_Packet) { +// long before = rx_packet.parity; + bruteResultTypeDef bruteResult = modes_ec_brute(rx_packet); + + if(bruteResult == No_Solution) { + //printf("No solution!\n"); + continue; + } else if(bruteResult == Multiple_Solutions) { +// printf("Multiple solutions!\n"); + continue; + } else if(bruteResult == Too_Many_LCBs) { + //printf("Too many LCBs (%i)!\n", rx_packet.numlowconf); + continue; + } else if(bruteResult == No_Error) { +// printf("No error!\n"); + } else if(bruteResult == Solution_Found) { +// printf("Solution found for %i LCBs!\n", rx_packet.numlowconf); + } +// rx_packet.parity = modes_check_parity(rx_packet.data, packet_length); +// if(rx_packet.parity) printf("Error: packet fails parity check after correction, was %x, now %x\n", before, rx_packet.parity); + } + +// if(rx_packet.parity && rx_packet.type == Long_Packet) printf("Error! Bad packet forwarded to the queue.\n"); + //now we have a complete packet with confidence data, let's print it to the message queue + //here, rather than send the entire packet, since we've already done parity checking and ECC in C++, we'll + //send just the data (no confidence bits), separated into fields for easier parsing. + //we'll replicate some data by sending the message type as the first field, followed by the first 8+24=32 bits of the packet, followed by + //56 long packet data bits if applicable (zero-padded if not), followed by parity + + d_payload.str(""); + + d_payload << std::dec << std::setw(2) << std::setfill('0') << rx_packet.message_type << std::hex << " "; + + for(int m = 0; m < 4; m++) { + d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); + } + d_payload << " "; + if(packet_length == 112) { + for(int m = 4; m < 11; m++) { d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); } d_payload << " "; - if(packet_length == 112) { - for(int m = 4; m < 11; m++) { - d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); - } - d_payload << " "; - for(int m = 11; m < 14; m++) { - d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); - } - } else { - for(int m = 4; m < 11; m++) { - d_payload << std::setw(2) << std::setfill('0') << unsigned(0); - } - d_payload << " "; - for(int m = 4; m < 7; m++) { - d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); - } + for(int m = 11; m < 14; m++) { + d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); + } + } else { + for(int m = 4; m < 11; m++) { + d_payload << std::setw(2) << std::setfill('0') << unsigned(0); + } + d_payload << " "; + for(int m = 4; m < 7; m++) { + d_payload << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); } - - d_payload << " " << std::setw(6) << rx_packet.parity << " " << std::dec << rx_packet.reference_level - << " " << rx_packet.timestamp_secs - << " " << std::setprecision(10) << std::setw(10) << rx_packet.timestamp_frac; - - gr_message_sptr msg = gr_make_message_from_string(std::string(d_payload.str())); - d_queue->handle(msg); - } + + d_payload << " " << std::setw(6) << rx_packet.parity << " " << std::dec << rx_packet.reference_level + << " " << rx_packet.timestamp_secs + << " " << std::setprecision(10) << std::setw(10) << rx_packet.timestamp_frac; + gr_message_sptr msg = gr_make_message_from_string(std::string(d_payload.str())); + d_queue->handle(msg); + } return size; diff --git a/src/python/uhd_modes.py b/src/python/uhd_modes.py index cfb5d40..20bcad3 100755 --- a/src/python/uhd_modes.py +++ b/src/python/uhd_modes.py @@ -96,28 +96,13 @@ class adsb_rx_block (gr.top_block): self.preamble = air.modes_preamble(rate, options.threshold) self.framer = air.modes_framer(rate) self.slicer = air.modes_slicer(rate, queue) - - #self.nullsink = gr.file_sink(gr.sizeof_gr_complex, "/dev/null") - - #self.connect(self.u, self.nullsink) - -# self.connect(self.u, self.demod, self.filter) -# self.connect(self.filter, self.avg) -# self.connect(self.filter, (self.preamble, 0)) -# self.connect(self.avg, (self.preamble, 1)) -# self.connect(self.filter, (self.framer, 0)) -# self.connect(self.preamble, (self.framer, 1)) -# self.connect(self.filter, (self.slicer, 0)) -# self.connect(self.framer, (self.slicer, 1)) -#use this flowgraph instead to omit the filter self.connect(self.u, self.demod) self.connect(self.demod, self.avg) self.connect(self.demod, (self.preamble, 0)) self.connect(self.avg, (self.preamble, 1)) self.connect((self.preamble, 0), (self.framer, 0)) - self.connect(self.demod, (self.slicer, 0)) - self.connect(self.framer, (self.slicer, 1)) + self.connect(self.framer, self.slicer) def tune(self, freq): result = self.u.set_center_freq(freq, 0)