commit-gnuradio
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]