[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r6113 - in gnuradio/trunk: gnuradio-core/src/lib/gener
From: |
trondeau |
Subject: |
[Commit-gnuradio] r6113 - in gnuradio/trunk: gnuradio-core/src/lib/general gnuradio-core/src/python/gnuradio/blksimpl gnuradio-core/src/python/gnuradio/gruimpl gnuradio-examples/python/ofdm |
Date: |
Sat, 4 Aug 2007 09:21:36 -0600 (MDT) |
Author: trondeau
Date: 2007-08-04 09:21:34 -0600 (Sat, 04 Aug 2007)
New Revision: 6113
Added:
gnuradio/trunk/gnuradio-examples/python/ofdm/tunnel.py
Modified:
gnuradio/trunk/gnuradio-core/src/lib/general/general.i
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/gruimpl/crc.py
gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
Log:
merged -r5966:6112 on trondeau/ofdm_mod. Allows for generic constellations
(supports bpsk, qpsk, 8psk, qam16, qam64, and qam256 currently), fixes some
bugs in the correlation and altered default parameters for over-the-air
operation. This merge fixes ticket:156 and ticket:157.
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/general.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/general.i 2007-08-04
15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/general.i 2007-08-04
15:21:34 UTC (rev 6113)
@@ -96,6 +96,7 @@
#include <gr_ofdm_correlator.h>
#include <gr_ofdm_cyclic_prefixer.h>
#include <gr_ofdm_bpsk_demapper.h>
+#include <gr_ofdm_mapper_bcv.h>
#include <gr_ofdm_bpsk_mapper.h>
#include <gr_ofdm_qpsk_mapper.h>
#include <gr_ofdm_qam_mapper.h>
@@ -203,6 +204,7 @@
%include "gr_ofdm_correlator.i"
%include "gr_ofdm_cyclic_prefixer.i"
%include "gr_ofdm_bpsk_demapper.i"
+%include "gr_ofdm_mapper_bcv.i"
%include "gr_ofdm_bpsk_mapper.i"
%include "gr_ofdm_qpsk_mapper.i"
%include "gr_ofdm_qam_mapper.i"
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
2007-08-04 15:21:34 UTC (rev 6113)
@@ -59,7 +59,7 @@
randombit()
{
int r = rand()&1;
- return (float)(-1 + 2*r);
+ return (float)(1 - 2*r);
}
int
@@ -105,7 +105,7 @@
i = 0;
while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
- out[i + zeros_on_left] = gr_complex(-1+2*(bit));
+ out[i + zeros_on_left] = gr_complex(1-2*(bit));
i++;
d_bit_offset++;
if(d_bit_offset == 8) {
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
2007-08-04 15:21:34 UTC (rev 6113)
@@ -99,12 +99,13 @@
{
// return
gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count),
// sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count));
- //return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
- assert(d_freq_shift_len + freq_delta >= 0);
- assert(symbol_count <= MAX_NUM_SYMBOLS);
+ return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
- return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) +
symbol_count];
+ //assert(d_freq_shift_len + freq_delta >= 0);
+ //assert(symbol_count <= MAX_NUM_SYMBOLS);
+
+ //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) +
symbol_count];
}
bool
@@ -118,7 +119,7 @@
gr_complex h_sqrd = gr_complex(0.0,0.0);
float power = 0.0F;
- while(!found && ((unsigned)abs(search_delta) < d_freq_shift_len)) {
+ while(!found && ((unsigned)abs(search_delta) <= d_freq_shift_len)) {
h_sqrd = gr_complex(0.0,0.0);
power = 0.0F;
@@ -126,17 +127,18 @@
h_sqrd = h_sqrd + previous[i+zeros_on_left+search_delta] *
conj(coarse_freq_comp(search_delta,1)*current[i+zeros_on_left+search_delta]) *
d_diff_corr_factor[i];
+
power = power + norm(current[i+zeros_on_left+search_delta]); // No need
to do coarse freq here
}
#if VERBOSE
- printf("bin %d\th_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t
angle = %f\n",
- search_delta, h_sqrd.real(), h_sqrd.imag(), power,
h_sqrd.real()/power, arg(h_sqrd));
-#endif
-
- // FIXME: Look at h_sqrd.read() > power
- if((h_sqrd.real() > 0.82*power) && (h_sqrd.real() < 1.1 * power)) {
+ printf("bin %d\th_sqrd = ( %f, %f )\t power = %f\t real(h)/p = %f\t angle
= %f\n",
+ search_delta, h_sqrd.real(), h_sqrd.imag(), power,
h_sqrd.real()/power, arg(h_sqrd));
+#endif
+ // FIXME: Look at h_sqrd.read() > power
+ if((h_sqrd.real() > 0.82*power) && (h_sqrd.real() < 1.1 * power)) {
found = true;
+ //printf("search delta: %d\n", search_delta);
d_coarse_freq = search_delta;
d_phase_count = 1;
//d_snr_est = 10*log10(power/(power-h_sqrd.real()));
@@ -220,6 +222,10 @@
d_phase_count++;
+ if(d_phase_count == MAX_NUM_SYMBOLS) {
+ d_phase_count = 1;
+ }
+
consume_each(1);
return 1;
}
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
2007-08-04 15:21:34 UTC (rev 6113)
@@ -35,7 +35,7 @@
unsigned int cplen,
const std::vector<gr_complex> &known_symbol1,
const std::vector<gr_complex> &known_symbol2,
- unsigned int max_fft_shift_len=4);
+ unsigned int max_fft_shift_len=10);
/*!
* \brief take a vector of complex constellation points in from an FFT
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
2007-08-04 15:21:34 UTC (rev 6113)
@@ -74,32 +74,57 @@
d_packetlen, d_packet_whitener_offset);
}
-unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
-{
- return (unsigned char)(x.real() > 0 ? 1 : 0);
-}
-unsigned char gr_ofdm_frame_sink::qpsk_slicer(gr_complex x)
+unsigned char gr_ofdm_frame_sink::slicer(const gr_complex x)
{
- unsigned char i = (x.real() > 0 ? 1 : 0);
- unsigned char q = (x.imag() > 0 ? 1 : 0);
-
- return (q << 1) | i;
+ unsigned int table_size = d_sym_value_out.size();
+ unsigned int min_index = 0;
+ float min_euclid_dist = norm(x - d_sym_position[0]);
+ float euclid_dist = 0;
+
+ for (unsigned int j = 1; j < table_size; j++){
+ euclid_dist = norm(x - d_sym_position[j]);
+ if (euclid_dist < min_euclid_dist){
+ min_euclid_dist = euclid_dist;
+ min_index = j;
+ }
+ }
+ return d_sym_value_out[min_index];
}
-unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
- unsigned char *out)
+unsigned int gr_ofdm_frame_sink::demapper(const gr_complex *in,
+ unsigned char *out)
{
unsigned int i=0, bytes_produced=0;
while(i < d_occupied_carriers) {
+ if(d_nresid > 0) {
+ d_partial_byte |= d_resid;
+ d_byte_offset += d_nresid;
+ d_nresid = 0;
+ d_resid = 0;
+ }
while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
- //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
- d_partial_byte |= bpsk_slicer(in[i++]) << (d_byte_offset++);
+ //fprintf(stderr, "%f+j%f = %d\n", in[i].real(), in[i].imag(),
slicer(in[i]));
+ unsigned char bits = slicer(in[i++]);
+ if((8 - d_byte_offset) >= d_nbits) {
+ d_partial_byte |= bits << (d_byte_offset);
+ d_byte_offset += d_nbits;
+ }
+ else {
+ d_nresid = d_nbits-(8-d_byte_offset);
+ int mask = ((1<<(8-d_byte_offset))-1);
+ d_partial_byte |= (bits & mask) << d_byte_offset;
+ d_resid = bits >> (8-d_byte_offset);
+ d_byte_offset += (d_nbits - d_nresid);
+ }
+ //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x
byte_offset: %d resid: %x nresid: %d\n",
+ // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte,
d_byte_offset, d_resid, d_nresid);
}
if(d_byte_offset == 8) {
+ //printf("demod byte: %x \n\n", d_partial_byte);
out[bytes_produced++] = d_partial_byte;
d_byte_offset = 0;
d_partial_byte = 0;
@@ -109,57 +134,31 @@
return bytes_produced;
}
-unsigned int gr_ofdm_frame_sink::qpsk_demapper(const gr_complex *in,
- unsigned char *out)
-{
- unsigned int i=0, bytes_produced=0;
- while(i < d_occupied_carriers) {
-
- while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
- //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
- d_partial_byte |= qpsk_slicer(in[i++]) << (d_byte_offset);
- d_byte_offset += 2;
- }
-
- if(d_byte_offset == 8) {
- out[bytes_produced++] = d_partial_byte;
- d_byte_offset = 0;
- d_partial_byte = 0;
- }
- }
-
- return bytes_produced;
-}
-
gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int
occupied_carriers,
- const std::string &mod)
+gr_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_carriers)
{
- return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue,
occupied_carriers, mod));
+ return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(sym_position,
sym_value_out,
+ target_queue,
occupied_carriers));
}
-gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue,
unsigned int occupied_carriers,
- const std::string &mod)
+gr_ofdm_frame_sink::gr_ofdm_frame_sink(const std::vector<gr_complex>
&sym_position,
+ const std::vector<unsigned char>
&sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned
int occupied_carriers)
: gr_sync_block ("ofdm_frame_sink",
gr_make_io_signature2 (2, 2,
sizeof(gr_complex)*occupied_carriers, sizeof(char)),
gr_make_io_signature (0, 0, 0)),
d_target_queue(target_queue), d_occupied_carriers(occupied_carriers),
- d_byte_offset(0), d_partial_byte(0)
+ d_byte_offset(0), d_partial_byte(0),
+ d_resid(0), d_nresid(0)
{
- d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/4.0)];
+ d_bytes_out = new unsigned char[d_occupied_carriers];
- if(mod == "qpsk") {
- d_demapper = &gr_ofdm_frame_sink::qpsk_demapper;
- }
- else if(mod == "bpsk") {
- d_demapper = &gr_ofdm_frame_sink::bpsk_demapper;
- }
- else {
- throw std::invalid_argument("Modulation type must be BPSK or QPSK.");
- }
-
+ set_sym_value_out(sym_position, sym_value_out);
+
enter_search();
}
@@ -168,6 +167,24 @@
delete [] d_bytes_out;
}
+bool
+gr_ofdm_frame_sink::set_sym_value_out(const std::vector<gr_complex>
&sym_position,
+ const std::vector<unsigned char>
&sym_value_out)
+{
+ if (sym_position.size() != sym_value_out.size())
+ return false;
+
+ if (sym_position.size()<1)
+ return false;
+
+ d_sym_position = sym_position;
+ d_sym_value_out = sym_value_out;
+ d_nbits = (unsigned long)(log10(d_sym_value_out.size()) / log10(2));
+
+ return true;
+}
+
+
int
gr_ofdm_frame_sink::work (int noutput_items,
gr_vector_const_void_star &input_items,
@@ -181,9 +198,8 @@
if (VERBOSE)
fprintf(stderr,">>> Entering state machine\n");
- //bytes = bpsk_demapper(&in[0], d_bytes_out);
- bytes = (this->*d_demapper)(&in[0], d_bytes_out);
-
+ bytes = demapper(&in[0], d_bytes_out);
+
switch(d_state) {
case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
2007-08-04 15:21:34 UTC (rev 6113)
@@ -30,8 +30,9 @@
typedef boost::shared_ptr<gr_ofdm_frame_sink> gr_ofdm_frame_sink_sptr;
gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
- const std::string &mod);
+gr_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
/*!
* \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs
@@ -44,8 +45,9 @@
class gr_ofdm_frame_sink : public gr_sync_block
{
friend gr_ofdm_frame_sink_sptr
- gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
- const std::string &mod);
+ gr_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
private:
enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
@@ -69,9 +71,17 @@
int d_packet_whitener_offset; // offset into whitener string
to use
int d_packetlen_cnt; // how many so far
+ std::vector<gr_complex> d_sym_position;
+ std::vector<unsigned char> d_sym_value_out;
+ unsigned int d_nbits;
+
+ unsigned char d_resid;
+ unsigned int d_nresid;
+
protected:
- gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
- const std::string &mod);
+ gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
void enter_search();
void enter_have_sync();
@@ -82,18 +92,14 @@
// confirm that two copies of header info are identical
return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
}
+
+ unsigned char slicer(const gr_complex x);
+ unsigned int demapper(const gr_complex *in,
+ unsigned char *out);
- unsigned char bpsk_slicer(gr_complex x);
- unsigned int bpsk_demapper(const gr_complex *in,
- unsigned char *out);
+ bool set_sym_value_out(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out);
- unsigned char qpsk_slicer(gr_complex x);
- unsigned int qpsk_demapper(const gr_complex *in,
- unsigned char *out);
-
- // pointer to mod-specific demapper
- unsigned int (gr_ofdm_frame_sink::*d_demapper)(const gr_complex *in,
unsigned char *out);
-
public:
~gr_ofdm_frame_sink();
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
2007-08-04 15:21:34 UTC (rev 6113)
@@ -23,14 +23,16 @@
GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink);
gr_ofdm_frame_sink_sptr
-gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
- const std::string &mod);
+gr_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
class gr_ofdm_frame_sink : public gr_sync_block
{
protected:
- gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
- const std::string &mod);
+ gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
+ const std::vector<unsigned char> &sym_value_out,
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
public:
~gr_ofdm_frame_sink();
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
2007-08-04 15:21:34 UTC (rev 6113)
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2005 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,22 +20,166 @@
* Boston, MA 02110-1301, USA.
*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gr_ofdm_mapper_bcv.h>
#include <gr_io_signature.h>
+#include <stdexcept>
+gr_ofdm_mapper_bcv_sptr
+gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
unsigned int msgq_limit,
+ unsigned int occupied_carriers, unsigned int
fft_length)
+{
+ return gr_ofdm_mapper_bcv_sptr (new gr_ofdm_mapper_bcv (constellation,
msgq_limit,
+ occupied_carriers,
fft_length));
+}
+
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold
the full packet
+gr_ofdm_mapper_bcv::gr_ofdm_mapper_bcv (const std::vector<gr_complex>
&constellation, unsigned int msgq_limit,
+ unsigned int occupied_carriers,
unsigned int fft_length)
+ : gr_sync_block ("ofdm_mapper_bcv",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length,
sizeof(char))),
+ d_constellation(constellation),
+ d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
+ d_occupied_carriers(occupied_carriers),
+ d_fft_length(fft_length),
+ d_bit_offset(0),
+ d_pending_flag(0),
+ d_resid(0),
+ d_nresid(0)
+{
+ if (!(d_occupied_carriers <= d_fft_length))
+ throw std::invalid_argument("gr_ofdm_mapper_bcv: occupied carriers must be
<= fft_length");
+
+ d_nbits = (unsigned long)(log10(d_constellation.size()) / log10(2));
+}
+
gr_ofdm_mapper_bcv::~gr_ofdm_mapper_bcv(void)
{
}
-gr_ofdm_mapper_bcv::gr_ofdm_mapper_bcv (unsigned bits_per_symbol,unsigned int
vlen)
- : gr_sync_decimator ("ofdm_mapper_bcv",
- gr_make_io_signature (1, 1, sizeof(unsigned char)),
- gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen),
- bits_per_symbol)
+int gr_ofdm_mapper_bcv::randsym()
{
+ return (rand() % d_constellation.size());
}
+int
+gr_ofdm_mapper_bcv::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ unsigned int i=0;
+ unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+ unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
+
+ //printf("OFDM BPSK Mapper: ninput_items: %d noutput_items: %d\n",
ninput_items[0], noutput_items);
+
+ if(d_eof) {
+ return -1;
+ }
+
+ if(!d_msg) {
+ d_msg = d_msgq->delete_head(); // block, waiting for a message
+ d_msg_offset = 0;
+ d_bit_offset = 0;
+ d_pending_flag = 1; // new packet, write start
of packet flag
+
+ if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+ d_msg.reset();
+ return -1; // We're done; no more messages coming.
+ }
+ }
+
+ char *out_flag = 0;
+ if(output_items.size() == 2)
+ out_flag = (char *) output_items[1];
+
+
+ // Build a single symbol:
+ // Initialize all bins to 0 to set unused carriers
+ memset(out, 0, d_fft_length*sizeof(gr_complex));
+
+ i = 0;
+ unsigned char bits = 0;
+ while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+
+ // need new data to process
+ if(d_bit_offset == 0) {
+ d_msgbytes = d_msg->msg()[d_msg_offset];
+ //printf("mod message byte: %x\n", d_msgbytes);
+ }
+
+ if(d_nresid > 0) {
+ d_resid |= (((1 << d_nresid)-1) & d_msgbytes) << (d_nbits - d_nresid);
+ bits = d_resid;
+
+ out[i + zeros_on_left] = d_constellation[bits];
+ i++;
+
+ d_bit_offset += d_nresid;
+ d_nresid = 0;
+ d_resid = 0;
+ //printf("mod bit(r): %x resid: %x nresid: %d bit_offset: %d\n",
+ // bits, d_resid, d_nresid, d_bit_offset);
+ }
+ else {
+ if((8 - d_bit_offset) >= d_nbits) {
+ bits = ((1 << d_nbits)-1) & (d_msgbytes >> d_bit_offset);
+ d_bit_offset += d_nbits;
+
+ out[i + zeros_on_left] = d_constellation[bits];
+ i++;
+
+ /*
+ printf("mod bit: %x out: %.4f + j%.4f resid: %x nresid: %d
bit_offset: %d\n",
+ bits, out[i-1 + zeros_on_left].real(), out[i-1 +
zeros_on_left].imag(),
+ d_resid, d_nresid, d_bit_offset);
+ */
+ }
+ else {
+ unsigned int extra = 8-d_bit_offset;
+ d_resid = ((1 << extra)-1) & (d_msgbytes >> d_bit_offset);
+ d_bit_offset += extra;
+ d_nresid = d_nbits - extra;
+ }
+
+ }
+
+ if(d_bit_offset == 8) {
+ d_bit_offset = 0;
+ d_msg_offset++;
+ }
+ }
+
+ // Ran out of data to put in symbol
+ if (d_msg_offset == d_msg->length()) {
+ if(d_nresid > 0) {
+ d_resid |= 0x00;
+ bits = d_resid;
+ d_nresid = 0;
+ d_resid = 0;
+ }
+
+ while(i < d_occupied_carriers) { // finish filling out the symbol
+ out[i + zeros_on_left] = d_constellation[randsym()];
+ i++;
+ }
+
+ if (d_msg->type() == 1) // type == 1 sets EOF
+ d_eof = true;
+ d_msg.reset(); // finished packet, free message
+ assert(d_bit_offset == 0);
+ }
+
+ if (out_flag)
+ out_flag[0] = d_pending_flag;
+ d_pending_flag = 0;
+
+ return 1; // produced symbol
+}
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.h
2007-08-04 15:21:34 UTC (rev 6113)
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,15 +23,17 @@
#ifndef INCLUDED_GR_OFDM_MAPPER_BCV_H
#define INCLUDED_GR_OFDM_MAPPER_BCV_H
-#include <gr_sync_decimator.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
class gr_ofdm_mapper_bcv;
typedef boost::shared_ptr<gr_ofdm_mapper_bcv> gr_ofdm_mapper_bcv_sptr;
gr_ofdm_mapper_bcv_sptr
-gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
+gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length);
-
/*!
* \brief take a stream of bytes in and map to a vector of complex
* constellation points suitable for IFFT input to be used in an ofdm
@@ -39,18 +41,44 @@
*
*/
-class gr_ofdm_mapper_bcv : public gr_sync_decimator
+class gr_ofdm_mapper_bcv : public gr_sync_block
{
friend gr_ofdm_mapper_bcv_sptr
- gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
+ gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length);
+ protected:
+ gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned
msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length);
-protected:
- gr_ofdm_mapper_bcv (unsigned int bits_per_symbol, unsigned int vlen);
+ private:
+ std::vector<gr_complex> d_constellation;
+ gr_msg_queue_sptr d_msgq;
+ gr_message_sptr d_msg;
+ unsigned d_msg_offset;
+ bool d_eof;
+
+ unsigned int d_occupied_carriers;
+ unsigned int d_fft_length;
+ unsigned int d_bit_offset;
+ int d_pending_flag;
-public:
+ unsigned long d_nbits;
+ unsigned char d_msgbytes;
+
+ unsigned char d_resid;
+ unsigned int d_nresid;
+
+ int randsym();
+
+ public:
~gr_ofdm_mapper_bcv(void);
-};
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
#endif
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i
2007-08-04 15:21:34 UTC (rev 6113)
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,17 +20,27 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,ofdm_mapper_bcv)
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_mapper_bcv);
gr_ofdm_mapper_bcv_sptr
-gr_make_ofdm_mapper_bcv (unsigned int bits_per_symbol,
- unsigned int vlen);
+gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
+ unsigned int msgq_limit,
+ unsigned int bits_per_symbol,
+ unsigned int fft_length);
-class gr_ofdm_mapper_bcv : public gr_sync_decimator
+
+class gr_ofdm_mapper_bcv : public gr_sync_block
{
protected:
- gr_ofdm_mapper_bcv (unsigned int bits_per_symbol,
- unsigned int vlen);
-
+ gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation,
+ unsigned int msgq_limit,
+ unsigned int bits_per_symbol,
+ unsigned int fft_length);
+
public:
+ gr_msg_queue_sptr msgq();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
};
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
2007-08-04 15:21:34 UTC (rev 6113)
@@ -60,7 +60,7 @@
{
int r1 = rand()&1;
int r2 = rand()&1;
- return gr_complex((0.707)*(-1 + 2*r1),(0.707)*(-1 + 2*r2));
+ return gr_complex((0.707)*(1 - 2*r1),(0.707)*(1 - 2*r2));
}
int
@@ -111,7 +111,7 @@
unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
d_bit_offset++;
- out[i + zeros_on_left] = gr_complex((0.707)*(-1+2*(bit0)),
(0.707)*(-1+2*(bit1)) );
+ out[i + zeros_on_left] = gr_complex((0.707)*(1-2*(bit0)),
(0.707)*(1-2*(bit1)) );
i++;
if(d_bit_offset == 8) {
d_bit_offset = 0;
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
2007-08-04 15:21:34 UTC (rev 6113)
@@ -69,11 +69,12 @@
int i=d_fft_length-1;
- while(!found && i<std::min(ninput_items[0],ninput_items[1]) )
+ while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) {
if(trigger[i])
found = 1;
else
i++;
+ }
if(found) {
assert(i-d_fft_length+1 >= 0);
@@ -89,6 +90,5 @@
// ninput_items[0], ninput_items[1], noutput_items, (i-d_fft_length+1),
found);
}
-
return found;
}
Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -24,6 +24,7 @@
from numpy import fft
from gnuradio import gr, ofdm_packet_utils
import gnuradio.gr.gr_threading as _threading
+import psk, qam
from gnuradio.blksimpl.ofdm_receiver import ofdm_receiver
@@ -81,16 +82,22 @@
padded_preambles.append(padded)
symbol_length = options.fft_length + options.cp_length
-
- # The next step will all us to pass a constellation into a generic
mapper function instead
- # of using these hard-coded versions
- if self._modulation == "bpsk":
- self._pkt_input = gr.ofdm_bpsk_mapper(msgq_limit,
options.occupied_tones, options.fft_length)
- elif self._modulation == "qpsk":
- self._pkt_input = gr.ofdm_qpsk_mapper(msgq_limit,
options.occupied_tones, options.fft_length)
- else:
- print "Modulation type not supported (must be \"bpsk\" or \"qpsk\""
+ mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16,
"qam64": 64, "qam256": 256}
+ arity = mods[self._modulation]
+
+ rot = 1
+ if self._modulation == "qpsk":
+ rot = (0.707+0.707j)
+
+ if(self._modulation.find("psk") >= 0):
+ rotated_const = map(lambda pt: pt * rot,
psk.gray_constellation[arity])
+ elif(self._modulation.find("qam") >= 0):
+ rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+ #print rotated_const
+ self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit,
+ options.occupied_tones,
options.fft_length)
+
self.preambles = gr.ofdm_insert_preamble(self._fft_length,
padded_preambles)
self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length,
symbol_length)
@@ -104,7 +111,8 @@
self._print_verbage()
if options.log:
- fg.connect(self._pkt_input,
gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat"))
+ fg.connect(self._pkt_input,
gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
+ "ofdm_mapper_c.dat"))
gr.hier_block.__init__(self, fg, None, self.scale)
@@ -119,8 +127,8 @@
msg = gr.message(1) # tell self._pkt_input we're not sending any
more packets
else:
# print "original_payload =", string_to_hex_list(payload)
- pkt = ofdm_packet_utils.make_packet(payload, 1, 1,
self._pad_for_usrp)
-
+ pkt = ofdm_packet_utils.make_packet(payload, 1, 1,
self._pad_for_usrp, whitening=True)
+
#print "pkt =", string_to_hex_list(pkt)
msg = gr.message_from_string(pkt)
self._pkt_input.msgq().insert_tail(msg)
@@ -208,10 +216,23 @@
self.ofdm_recv = ofdm_receiver(fg, self._fft_length, self._cp_length,
self._occupied_tones, self._snr,
preambles,
options.log)
- self.ofdm_demod = gr.ofdm_frame_sink(self._rcvd_pktq,
- self._occupied_tones,
- self._modulation)
+
+ mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16,
"qam64": 64, "qam256": 256}
+ arity = mods[self._modulation]
+ rot = 1
+ if self._modulation == "qpsk":
+ rot = (0.707+0.707j)
+
+ if(self._modulation.find("psk") >= 0):
+ rotated_const = map(lambda pt: pt * rot,
psk.gray_constellation[arity])
+ elif(self._modulation.find("qam") >= 0):
+ rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+ #print rotated_const
+ self.ofdm_demod = gr.ofdm_frame_sink(rotated_const, range(arity),
+ self._rcvd_pktq,
+ self._occupied_tones)
+
fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/psk.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -53,6 +53,12 @@
8 : make_constellation(8) # 8PSK
}
+gray_constellation = {
+ 2 : make_gray_constellation(2), # BPSK
+ 4 : make_gray_constellation(4), # QPSK
+ 8 : make_gray_constellation(8) # 8PSK
+ }
+
# -----------------------
# Do Gray code
# -----------------------
Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/gruimpl/crc.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/gruimpl/crc.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/gruimpl/crc.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -1,5 +1,5 @@
#
-# Copyright 2005 Free Software Foundation, Inc.
+# Copyright 2005,2007 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -25,7 +25,7 @@
def gen_and_append_crc32(s):
crc = gr.crc32(s)
- return s + struct.pack(">I", hexint(crc))
+ return s + struct.pack(">I", hexint(crc) & 0xFFFFFFFF)
def check_crc32(s):
if len(s) < 4:
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -36,14 +36,15 @@
def __init__(self, callback, options):
gr.flow_graph.__init__(self)
- if options.channel_on:
+ if not options.channel_off:
SNR = 10.0**(options.snr/10.0)
- power_in_signal = 1.0
+ power_in_signal = abs(options.tx_amplitude)**2.0
noise_power_in_channel = power_in_signal/SNR
noise_voltage = math.sqrt(noise_power_in_channel/2.0)
print "Noise voltage: ", noise_voltage
frequency_offset = options.frequency_offset / options.fft_length
+ print "Frequency offset: ", frequency_offset
if options.multipath_on:
taps = [1.0, .2, 0.0, .1, .08, -.4, .12, -.2, 0, 0, 0, .3]
@@ -70,7 +71,8 @@
self.mux = gr.stream_mux(gr.sizeof_gr_complex, stream_size)
self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate)
- self.channel = blks.channel_model(self, noise_voltage,
frequency_offset, options.clockrate_ratio, taps)
+ self.channel = blks.channel_model(self, noise_voltage,
frequency_offset,
+ options.clockrate_ratio, taps)
self.rxpath = receive_path(self, callback, options)
self.connect(self.zeros, (self.mux,0))
@@ -116,7 +118,7 @@
parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
expert_grp = parser.add_option_group("Expert")
- parser.add_option("-s", "--size", type="eng_float", default=1450,
+ parser.add_option("-s", "--size", type="eng_float", default=400,
help="set packet size [default=%default]")
parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
help="set megabytes to transmit [default=%default]")
@@ -130,8 +132,8 @@
help="set clock rate ratio (sample rate difference)
between two systems [default=%default]")
parser.add_option("","--discontinuous", type="int", default=0,
help="enable discontinous transmission, burst of N
packets [Default is continuous]")
- parser.add_option("","--channel-on", action="store_true", default=True,
- help="Enables AWGN, freq offset")
+ parser.add_option("","--channel-off", action="store_true", default=False,
+ help="Turns AWGN, freq offset channel off")
parser.add_option("","--multipath-on", action="store_true", default=False,
help="enable multipath")
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -128,7 +128,7 @@
expert.add_option("", "--rx-freq", type="eng_float", default=None,
help="set Rx frequency to FREQ [default=%default]",
metavar="FREQ")
- expert.add_option("-d", "--decim", type="intx", default=32,
+ expert.add_option("-d", "--decim", type="intx", default=128,
help="set fpga decimation rate to DECIM
[default=%default]")
expert.add_option("", "--snr", type="eng_float", default=30,
help="set the SNR of the channel in dB
[default=%default]")
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -131,7 +131,7 @@
expert.add_option("", "--tx-freq", type="eng_float", default=None,
help="set transmit frequency to FREQ
[default=%default]", metavar="FREQ")
- expert.add_option("-i", "--interp", type="intx", default=64,
+ expert.add_option("-i", "--interp", type="intx", default=256,
help="set fpga interpolation rate to INTERP
[default=%default]")
# Make a static method to call before instantiation
add_options = staticmethod(add_options)
@@ -171,7 +171,7 @@
parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
expert_grp = parser.add_option_group("Expert")
- parser.add_option("-s", "--size", type="eng_float", default=1450,
+ parser.add_option("-s", "--size", type="eng_float", default=400,
help="set packet size [default=%default]")
parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
help="set megabytes to transmit [default=%default]")
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -47,10 +47,10 @@
blks.ofdm_demod(fg, options, callback=self._rx_callback)
# Carrier Sensing Blocks
- #alpha = 0.001
- #thresh = 30 # in dB, will have to adjust
- #self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
- #fg.connect(self.chan_filt, self.probe)
+ alpha = 0.001
+ thresh = 30 # in dB, will have to adjust
+ self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
+ fg.connect(self.ofdm_rx.ofdm_recv.chan_filt, self.probe)
# Display some information about the setup
if self._verbose:
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
2007-08-04 15:16:00 UTC (rev 6112)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
2007-08-04 15:21:34 UTC (rev 6113)
@@ -73,7 +73,7 @@
"""
Adds transmitter-specific options to the Options Parser
"""
- normal.add_option("", "--tx-amplitude", type="eng_float", default=1,
metavar="AMPL",
+ normal.add_option("", "--tx-amplitude", type="eng_float", default=200,
metavar="AMPL",
help="set transmitter digital amplitude: 0 <= AMPL <
32768 [default=%default]")
normal.add_option("-v", "--verbose", action="store_true",
default=False)
expert.add_option("", "--log", action="store_true", default=False,
Copied: gnuradio/trunk/gnuradio-examples/python/ofdm/tunnel.py (from rev 6111,
gnuradio/branches/developers/trondeau/ofdm_mod/gnuradio-examples/python/ofdm/tunnel.py)
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/tunnel.py
(rev 0)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/tunnel.py 2007-08-04
15:21:34 UTC (rev 6113)
@@ -0,0 +1,435 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#
+# This code sets up up a virtual ethernet interface (typically gr0),
+# and relays packets between the interface and the GNU Radio PHY+MAC
+#
+# What this means in plain language, is that if you've got a couple
+# of USRPs on different machines, and if you run this code on those
+# machines, you can talk between them using normal TCP/IP networking.
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random
+import time
+import struct
+import sys
+import os
+
+# from current dir
+from transmit_path import transmit_path
+from receive_path import receive_path
+import fusb_options
+
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#
+# Use the Universal TUN/TAP device driver to move packets to/from kernel
+#
+# See /usr/src/linux/Documentation/networking/tuntap.txt
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+# Linux specific...
+# TUNSETIFF ifr flags from <linux/tun_if.h>
+
+IFF_TUN = 0x0001 # tunnel IP packets
+IFF_TAP = 0x0002 # tunnel ethernet frames
+IFF_NO_PI = 0x1000 # don't pass extra packet info
+IFF_ONE_QUEUE = 0x2000 # beats me ;)
+
+def open_tun_interface(tun_device_filename):
+ from fcntl import ioctl
+
+ mode = IFF_TAP | IFF_NO_PI
+ TUNSETIFF = 0x400454ca
+
+ tun = os.open(tun_device_filename, os.O_RDWR)
+ ifs = ioctl(tun, TUNSETIFF, struct.pack("16sH", "gr%d", mode))
+ ifname = ifs[:16].strip("\x00")
+ return (tun, ifname)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+# the flow graph
+# /////////////////////////////////////////////////////////////////////////////
+
+class usrp_graph(gr.flow_graph):
+ def __init__(self, callback, options):
+ gr.flow_graph.__init__(self)
+
+ self._tx_freq = options.tx_freq # tranmitter's
center frequency
+ self._tx_subdev_spec = options.tx_subdev_spec # daughterboard to
use
+ self._interp = options.interp # interpolating
rate for the USRP (prelim)
+ self._rx_freq = options.rx_freq # receiver's center
frequency
+ self._rx_gain = options.rx_gain # receiver's gain
+ self._rx_subdev_spec = options.rx_subdev_spec # daughterboard to
use
+ self._decim = options.decim # Decimating rate
for the USRP (prelim)
+ self._fusb_block_size = options.fusb_block_size # usb info for USRP
+ self._fusb_nblocks = options.fusb_nblocks # usb info for USRP
+
+ if self._tx_freq is None:
+ sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be
specified\n")
+ raise SystemExit
+
+ if self._rx_freq is None:
+ sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be
specified\n")
+ raise SystemExit
+
+ # Set up USRP sink and source
+ self._setup_usrp_sink()
+ self._setup_usrp_source()
+
+ # Set center frequency of USRP
+ ok = self.set_freq(self._tx_freq)
+ if not ok:
+ print "Failed to set Tx frequency to %s" %
(eng_notation.num_to_str(self._tx_freq),)
+ raise ValueError
+
+ # copy the final answers back into options for use by modulator
+ #options.bitrate = self._bitrate
+
+ self.txpath = transmit_path(self, options)
+ self.rxpath = receive_path(self, callback, options)
+
+ self.connect(self.txpath, self.u_snk)
+ self.connect(self.u_src, self.rxpath)
+
+ def carrier_sensed(self):
+ """
+ Return True if the receive path thinks there's carrier
+ """
+ return self.rxpath.carrier_sensed()
+
+ def _setup_usrp_sink(self):
+ """
+ Creates a USRP sink, determines the settings for best bitrate,
+ and attaches to the transmitter's subdevice.
+ """
+ self.u_snk = usrp.sink_c(fusb_block_size=self._fusb_block_size,
+ fusb_nblocks=self._fusb_nblocks)
+
+ self.u_snk.set_interp_rate(self._interp)
+
+ # determine the daughterboard subdevice we're using
+ if self._tx_subdev_spec is None:
+ self._tx_subdev_spec = usrp.pick_tx_subdevice(self.u_snk)
+ self.u_snk.set_mux(usrp.determine_tx_mux_value(self.u_snk,
self._tx_subdev_spec))
+ self.subdev = usrp.selected_subdev(self.u_snk, self._tx_subdev_spec)
+
+ # Set the USRP for maximum transmit gain
+ # (Note that on the RFX cards this is a nop.)
+ self.set_gain(self.subdev.gain_range()[1])
+
+ # enable Auto Transmit/Receive switching
+ self.set_auto_tr(True)
+
+ def _setup_usrp_source(self):
+ self.u_src = usrp.source_c (fusb_block_size=self._fusb_block_size,
+ fusb_nblocks=self._fusb_nblocks)
+ adc_rate = self.u_src.adc_rate()
+
+ self.u_src.set_decim_rate(self._decim)
+
+ # determine the daughterboard subdevice we're using
+ if self._rx_subdev_spec is None:
+ self._rx_subdev_spec = usrp.pick_rx_subdevice(self.u_src)
+ self.subdev = usrp.selected_subdev(self.u_src, self._rx_subdev_spec)
+
+ self.u_src.set_mux(usrp.determine_rx_mux_value(self.u_src,
self._rx_subdev_spec))
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital up converter.
+ """
+ r_snk = self.u_snk.tune(self.subdev._which, self.subdev, target_freq)
+ r_src = self.u_src.tune(self.subdev._which, self.subdev, target_freq)
+ if r_snk and r_src:
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ """
+ Sets the analog gain in the USRP
+ """
+ self.gain = gain
+ self.subdev.set_gain(gain)
+
+ def set_auto_tr(self, enable):
+ """
+ Turns on auto transmit/receive of USRP daughterboard (if exits; else
ignored)
+ """
+ return self.subdev.set_auto_tr(enable)
+
+ def interp(self):
+ return self._interp
+
+ def add_options(normal, expert):
+ """
+ Adds usrp-specific options to the Options Parser
+ """
+ add_freq_option(normal)
+ normal.add_option("-T", "--tx-subdev-spec", type="subdev",
default=None,
+ help="select USRP Tx side A or B")
+ normal.add_option("-v", "--verbose", action="store_true",
default=False)
+
+ expert.add_option("", "--tx-freq", type="eng_float", default=None,
+ help="set transmit frequency to FREQ
[default=%default]", metavar="FREQ")
+ expert.add_option("-i", "--interp", type="intx", default=256,
+ help="set fpga interpolation rate to INTERP
[default=%default]")
+ normal.add_option("-R", "--rx-subdev-spec", type="subdev",
default=None,
+ help="select USRP Rx side A or B")
+ normal.add_option("", "--rx-gain", type="eng_float", default=None,
metavar="GAIN",
+ help="set receiver gain in dB [default=midpoint].
See also --show-rx-gain-range")
+ normal.add_option("", "--show-rx-gain-range", action="store_true",
default=False,
+ help="print min and max Rx gain available on
selected daughterboard")
+ normal.add_option("-v", "--verbose", action="store_true",
default=False)
+
+ expert.add_option("", "--rx-freq", type="eng_float", default=None,
+ help="set Rx frequency to FREQ [default=%default]",
metavar="FREQ")
+ expert.add_option("-d", "--decim", type="intx", default=128,
+ help="set fpga decimation rate to DECIM
[default=%default]")
+ expert.add_option("", "--snr", type="eng_float", default=30,
+ help="set the SNR of the channel in dB
[default=%default]")
+
+ # Make a static method to call before instantiation
+ add_options = staticmethod(add_options)
+
+ def _print_verbage(self):
+ """
+ Prints information about the transmit path
+ """
+ print "Using TX d'board %s" % (self.subdev.side_and_name(),)
+ print "modulation: %s" % (self._modulator_class.__name__)
+ print "interp: %3d" % (self._interp)
+ print "Tx Frequency: %s" %
(eng_notation.num_to_str(self._tx_freq))
+
+def add_freq_option(parser):
+ """
+ Hackery that has the -f / --freq option set both tx_freq and rx_freq
+ """
+ def freq_callback(option, opt_str, value, parser):
+ parser.values.rx_freq = value
+ parser.values.tx_freq = value
+
+ if not parser.has_option('--freq'):
+ parser.add_option('-f', '--freq', type="eng_float",
+ action="callback", callback=freq_callback,
+ help="set Tx and/or Rx frequency to FREQ
[default=%default]",
+ metavar="FREQ")
+
+
+# /////////////////////////////////////////////////////////////////////////////
+# Carrier Sense MAC
+# /////////////////////////////////////////////////////////////////////////////
+
+class cs_mac(object):
+ """
+ Prototype carrier sense MAC
+
+ Reads packets from the TUN/TAP interface, and sends them to the PHY.
+ Receives packets from the PHY via phy_rx_callback, and sends them
+ into the TUN/TAP interface.
+
+ Of course, we're not restricted to getting packets via TUN/TAP, this
+ is just an example.
+ """
+ def __init__(self, tun_fd, verbose=False):
+ self.tun_fd = tun_fd # file descriptor for TUN/TAP interface
+ self.verbose = verbose
+ self.fg = None # flow graph (access to PHY)
+
+ def set_flow_graph(self, fg):
+ self.fg = fg
+
+ def phy_rx_callback(self, ok, payload):
+ """
+ Invoked by thread associated with PHY to pass received packet up.
+
+ @param ok: bool indicating whether payload CRC was OK
+ @param payload: contents of the packet (string)
+ """
+ if self.verbose:
+ print "Rx: ok = %r len(payload) = %4d" % (ok, len(payload))
+ if ok:
+ os.write(self.tun_fd, payload)
+
+ def main_loop(self):
+ """
+ Main loop for MAC.
+ Only returns if we get an error reading from TUN.
+
+ FIXME: may want to check for EINTR and EAGAIN and reissue read
+ """
+ min_delay = 0.001 # seconds
+
+ while 1:
+ payload = os.read(self.tun_fd, 10*1024)
+ if not payload:
+ self.fg.send_pkt(eof=True)
+ break
+
+ if self.verbose:
+ print "Tx: len(payload) = %4d" % (len(payload),)
+
+ delay = min_delay
+ while self.fg.carrier_sensed():
+ sys.stderr.write('B')
+ time.sleep(delay)
+ if delay < 0.050:
+ delay = delay * 2 # exponential back-off
+
+ self.fg.send_pkt(payload)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+# main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+ parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
+ expert_grp = parser.add_option_group("Expert")
+
+ parser.add_option("-m", "--modulation", type="choice", choices=['bpsk',
'qpsk'],
+ default='bpsk',
+ help="Select modulation from: bpsk, qpsk
[default=%%default]")
+
+ parser.add_option("-v","--verbose", action="store_true", default=False)
+ expert_grp.add_option("-c", "--carrier-threshold", type="eng_float",
default=30,
+ help="set carrier detect threshold (dB)
[default=%default]")
+ expert_grp.add_option("","--tun-device-filename", default="/dev/net/tun",
+ help="path to tun device file [default=%default]")
+
+ usrp_graph.add_options(parser, expert_grp)
+ transmit_path.add_options(parser, expert_grp)
+ receive_path.add_options(parser, expert_grp)
+ blks.ofdm_mod.add_options(parser, expert_grp)
+ blks.ofdm_demod.add_options(parser, expert_grp)
+
+ fusb_options.add_options(expert_grp)
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+ if options.rx_freq is None or options.tx_freq is None:
+ sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+ # open the TUN/TAP interface
+ (tun_fd, tun_ifname) = open_tun_interface(options.tun_device_filename)
+
+ # Attempt to enable realtime scheduling
+ r = gr.enable_realtime_scheduling()
+ if r == gr.RT_OK:
+ realtime = True
+ else:
+ realtime = False
+ print "Note: failed to enable realtime scheduling"
+
+
+ # If the user hasn't set the fusb_* parameters on the command line,
+ # pick some values that will reduce latency.
+
+ if options.fusb_block_size == 0 and options.fusb_nblocks == 0:
+ if realtime: # be more aggressive
+ options.fusb_block_size = gr.prefs().get_long('fusb',
'rt_block_size', 1024)
+ options.fusb_nblocks = gr.prefs().get_long('fusb',
'rt_nblocks', 16)
+ else:
+ options.fusb_block_size = gr.prefs().get_long('fusb',
'block_size', 4096)
+ options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks',
16)
+
+ #print "fusb_block_size =", options.fusb_block_size
+ #print "fusb_nblocks =", options.fusb_nblocks
+
+ # instantiate the MAC
+ mac = cs_mac(tun_fd, verbose=True)
+
+
+ # build the graph (PHY)
+ fg = usrp_graph(mac.phy_rx_callback, options)
+
+ mac.set_flow_graph(fg) # give the MAC a handle for the PHY
+
+ #if fg.txpath.bitrate() != fg.rxpath.bitrate():
+ # print "WARNING: Transmit bitrate = %sb/sec, Receive bitrate =
%sb/sec" % (
+ # eng_notation.num_to_str(fg.txpath.bitrate()),
+ # eng_notation.num_to_str(fg.rxpath.bitrate()))
+
+ print "modulation: %s" % (options.modulation,)
+ print "freq: %s" %
(eng_notation.num_to_str(options.tx_freq))
+ #print "bitrate: %sb/sec" %
(eng_notation.num_to_str(fg.txpath.bitrate()),)
+ #print "samples/symbol: %3d" % (fg.txpath.samples_per_symbol(),)
+ #print "interp: %3d" % (fg.txpath.interp(),)
+ #print "decim: %3d" % (fg.rxpath.decim(),)
+
+ fg.rxpath.set_carrier_threshold(options.carrier_threshold)
+ print "Carrier sense threshold:", options.carrier_threshold, "dB"
+
+ print
+ print "Allocated virtual ethernet interface: %s" % (tun_ifname,)
+ print "You must now use ifconfig to set its IP address. E.g.,"
+ print
+ print " $ sudo ifconfig %s 192.168.200.1" % (tun_ifname,)
+ print
+ print "Be sure to use a different address in the same subnet for each
machine."
+ print
+
+
+ fg.start() # Start executing the flow graph (runs in separate threads)
+
+ mac.main_loop() # don't expect this to return...
+
+ fg.stop() # but if it does, tell flow graph to stop.
+ fg.wait() # wait for it to finish
+
+
+if __name__ == '__main__':
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r6113 - in gnuradio/trunk: gnuradio-core/src/lib/general gnuradio-core/src/python/gnuradio/blksimpl gnuradio-core/src/python/gnuradio/gruimpl gnuradio-examples/python/ofdm,
trondeau <=