commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r8591 - in usrp2/trunk/host-ng: apps lib


From: jcorgan
Subject: [Commit-gnuradio] r8591 - in usrp2/trunk/host-ng: apps lib
Date: Sat, 14 Jun 2008 22:00:23 -0600 (MDT)

Author: jcorgan
Date: 2008-06-14 22:00:18 -0600 (Sat, 14 Jun 2008)
New Revision: 8591

Added:
   usrp2/trunk/host-ng/lib/usrp2_impl.cc
   usrp2/trunk/host-ng/lib/usrp2_impl.h
   usrp2/trunk/host-ng/lib/usrp2_thread.cc
Modified:
   usrp2/trunk/host-ng/apps/test.sh
   usrp2/trunk/host-ng/lib/Makefile.am
   usrp2/trunk/host-ng/lib/copy_handler.cc
   usrp2/trunk/host-ng/lib/eth_common.h
   usrp2/trunk/host-ng/lib/ethernet.cc
   usrp2/trunk/host-ng/lib/ethernet.h
   usrp2/trunk/host-ng/lib/find.cc
   usrp2/trunk/host-ng/lib/pktfilter.cc
   usrp2/trunk/host-ng/lib/pktfilter.h
   usrp2/trunk/host-ng/lib/usrp2.cc
   usrp2/trunk/host-ng/lib/usrp2_thread.h
Log:
Refactoring, formatting cleanup.

Modified: usrp2/trunk/host-ng/apps/test.sh
===================================================================
--- usrp2/trunk/host-ng/apps/test.sh    2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/apps/test.sh    2008-06-15 04:00:18 UTC (rev 8591)
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-sudo ./test_usrp2 2>cerr
+sudo ./test_usrp2 1>cerr 2>&1
 
 

Modified: usrp2/trunk/host-ng/lib/Makefile.am
===================================================================
--- usrp2/trunk/host-ng/lib/Makefile.am 2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/lib/Makefile.am 2008-06-15 04:00:18 UTC (rev 8591)
@@ -28,7 +28,9 @@
        ethernet.cc \
        find.cc \
        pktfilter.cc \
-       usrp2.cc
+       usrp2.cc \
+       usrp2_impl.cc \
+       usrp2_thread.cc
 
 libusrp2ng_la_LIBADD = \
        $(GR_OMNITHREAD_LIBS)
@@ -39,4 +41,5 @@
        eth_common.h \
        ethernet.h \
        pktfilter.h \
+       usrp2_impl.h \
        usrp2_thread.h

Modified: usrp2/trunk/host-ng/lib/copy_handler.cc
===================================================================
--- usrp2/trunk/host-ng/lib/copy_handler.cc     2008-06-14 22:25:28 UTC (rev 
8590)
+++ usrp2/trunk/host-ng/lib/copy_handler.cc     2008-06-15 04:00:18 UTC (rev 
8591)
@@ -26,12 +26,12 @@
 #include <usrp2/copy_handler.h>
 
 namespace usrp2 {
-    
+  
   copy_handler::copy_handler(void *dest, unsigned int len)
     : d_dest((uint8_t *)dest), d_space(len), d_bytes(0), d_times(0)
   {
   }
-
+  
   copy_handler::~copy_handler()
   {
     // NOP
@@ -42,7 +42,7 @@
   {
     if (len > d_space)
       return KEEP|DONE; // can't do anything, retry later
-      
+    
     memcpy(&d_dest[d_bytes], base, len);
     d_space -= len;
     d_bytes += len;
@@ -51,6 +51,6 @@
     if (d_space == 0)
       return DONE; // don't call me anymore
   }
-
+  
 } // namespace usrp2
 

Modified: usrp2/trunk/host-ng/lib/eth_common.h
===================================================================
--- usrp2/trunk/host-ng/lib/eth_common.h        2008-06-14 22:25:28 UTC (rev 
8590)
+++ usrp2/trunk/host-ng/lib/eth_common.h        2008-06-15 04:00:18 UTC (rev 
8591)
@@ -25,13 +25,13 @@
 #include <sys/uio.h>                   // FIXME autoconf this
 
 namespace usrp2 {
-
+  
   enum eth_flags {
     EF_DONTWAIT        = 0x0001,
   };
-
+  
   typedef struct iovec eth_iovec;      // FIXME autoconf this
-
+  
 }  // namespace usrp2
 
 

Modified: usrp2/trunk/host-ng/lib/ethernet.cc
===================================================================
--- usrp2/trunk/host-ng/lib/ethernet.cc 2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/lib/ethernet.cc 2008-06-15 04:00:18 UTC (rev 8591)
@@ -39,163 +39,163 @@
 
 namespace usrp2 {
 
-static int
-open_packet_socket (std::string ifname, int protocol)
-{
-  if (protocol == 0)
-    protocol = htons(ETH_P_ALL);
-
-  int fd = socket (PF_PACKET, SOCK_RAW, protocol);
-  if (fd == -1){
-    fprintf (stderr, "%s: socket: %s\n", ifname.c_str(), strerror (errno));
-    return -1;
+  static int
+  open_packet_socket (std::string ifname, int protocol)
+  {
+    if (protocol == 0)
+      protocol = htons(ETH_P_ALL);
+    
+    int fd = socket (PF_PACKET, SOCK_RAW, protocol);
+    if (fd == -1){
+      fprintf (stderr, "%s: socket: %s\n", ifname.c_str(), strerror (errno));
+      return -1;
+    }
+    
+    // get interface index
+    struct ifreq ifr;
+    memset (&ifr, 0, sizeof(ifr));
+    strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name));
+    int res = ioctl (fd, SIOCGIFINDEX, &ifr);
+    if (res != 0){
+      ::close (fd);
+      fprintf (stderr, "%s: SIOCGIFINDEX: %s\n", ifname.c_str(), 
strerror(errno));
+      return -1;
+    }
+    int ifindex = ifr.ifr_ifindex;
+    
+    // bind to the specified interface
+    sockaddr_ll sa;
+    memset (&sa, 0, sizeof (sa));
+    sa.sll_family = AF_PACKET;
+    sa.sll_protocol = protocol;
+    sa.sll_ifindex = ifindex;
+    res = bind (fd, (struct sockaddr *)&sa, sizeof (sa));
+    if (res != 0){
+      ::close (fd);
+      fprintf (stderr, "%s: bind: %s\n", ifname.c_str(), strerror(errno));
+      return -1;
+    }
+    return fd;
   }
-
-  // get interface index
-  struct ifreq ifr;
-  memset (&ifr, 0, sizeof(ifr));
-  strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name));
-  int res = ioctl (fd, SIOCGIFINDEX, &ifr);
-  if (res != 0){
-    ::close (fd);
-    fprintf (stderr, "%s: SIOCGIFINDEX: %s\n", ifname.c_str(), 
strerror(errno));
-    return -1;
+  
+  static void
+  extract_mac_addr (unsigned char *mac, const unsigned char *hwaddr)
+  {
+    int        i;
+    for (i = 0; i < 6; i++)
+      mac[i] = 0xff;
+    
+    i = 0;
+    for (int j = 0; j < 14; j++){
+      if (hwaddr[j] != 0xff){
+       mac[i++] = hwaddr[j];
+       if (i == 6)
+         return;
+      }
+    }
   }
-  int ifindex = ifr.ifr_ifindex;
-
-  // bind to the specified interface
-  sockaddr_ll sa;
-  memset (&sa, 0, sizeof (sa));
-  sa.sll_family = AF_PACKET;
-  sa.sll_protocol = protocol;
-  sa.sll_ifindex = ifindex;
-  res = bind (fd, (struct sockaddr *)&sa, sizeof (sa));
-  if (res != 0){
-    ::close (fd);
-    fprintf (stderr, "%s: bind: %s\n", ifname.c_str(), strerror(errno));
-    return -1;
-  }
-  return fd;
-}
-
-static void
-extract_mac_addr (unsigned char *mac, const unsigned char *hwaddr)
-{
-  int  i;
-  for (i = 0; i < 6; i++)
-    mac[i] = 0xff;
-
-  i = 0;
-  for (int j = 0; j < 14; j++){
-    if (hwaddr[j] != 0xff){
-      mac[i++] = hwaddr[j];
-      if (i == 6)
-       return;
+  
+  static bool
+  get_mac_addr (std::string ifname, int fd, unsigned char *mac)
+  {
+    struct ifreq ifr;
+    memset (&ifr, 0, sizeof(ifr));
+    strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name));
+    int res = ioctl (fd, SIOCGIFHWADDR, &ifr);
+    if (res != 0){
+      fprintf (stderr, "%s: SIOCGIFHWADDR: %s\n", ifname.c_str(), 
strerror(errno));
+      return false;
     }
+    else {
+      if (0){
+       for (unsigned i = 0; i < sizeof (ifr.ifr_hwaddr.sa_data); i++)
+         fprintf (stderr, "%02x", ifr.ifr_hwaddr.sa_data[i]);
+       fprintf (stderr, "\n");
+      }
+    }
+    extract_mac_addr (mac, (unsigned char *)ifr.ifr_hwaddr.sa_data);
+    return true;
   }
-}
-
-static bool
-get_mac_addr (std::string ifname, int fd, unsigned char *mac)
-{
-  struct ifreq ifr;
-  memset (&ifr, 0, sizeof(ifr));
-  strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name));
-  int res = ioctl (fd, SIOCGIFHWADDR, &ifr);
-  if (res != 0){
-    fprintf (stderr, "%s: SIOCGIFHWADDR: %s\n", ifname.c_str(), 
strerror(errno));
-    return false;
+  
+  ethernet::ethernet ()
+  {
+    d_fd = -1;
+    memset (d_mac, 0, sizeof (d_mac));
   }
-  else {
-    if (0){
-      for (unsigned i = 0; i < sizeof (ifr.ifr_hwaddr.sa_data); i++)
-       fprintf (stderr, "%02x", ifr.ifr_hwaddr.sa_data[i]);
-      fprintf (stderr, "\n");
+  
+  ethernet::~ethernet ()
+  {
+    close ();
+  }
+  
+  bool
+  ethernet::open (std::string ifname, int protocol)
+  {
+    if (d_fd != -1){
+      fprintf (stderr, "ethernet: already open\n");
+      return false;
     }
+    if ((d_fd = open_packet_socket (ifname, protocol)) == -1){
+      return false;
+    }
+    get_mac_addr (ifname, d_fd, d_mac);
+    return true;
   }
-  extract_mac_addr (mac, (unsigned char *)ifr.ifr_hwaddr.sa_data);
-  return true;
-}
-
-ethernet::ethernet ()
-{
-  d_fd = -1;
-  memset (d_mac, 0, sizeof (d_mac));
-}
-
-ethernet::~ethernet ()
-{
-  close ();
-}
-
-bool
-ethernet::open (std::string ifname, int protocol)
-{
-  if (d_fd != -1){
-    fprintf (stderr, "ethernet: already open\n");
-    return false;
+  
+  bool
+  ethernet::close ()
+  {
+    if (d_fd >= 0){
+      ::close (d_fd);
+      d_fd = -1;
+    }
+    return true;
   }
-  if ((d_fd = open_packet_socket (ifname, protocol)) == -1){
-    return false;
+  
+  int
+  ethernet::read_packet (void *buf, int buflen)
+  {
+    int len = recvfrom (d_fd, buf, buflen, 0, (sockaddr *) 0, 0);
+    return len;
   }
-  get_mac_addr (ifname, d_fd, d_mac);
-  return true;
-}
-
-bool
-ethernet::close ()
-{
-  if (d_fd >= 0){
-    ::close (d_fd);
-    d_fd = -1;
+  
+  int
+  ethernet::read_packet_dont_block (void *buf, int buflen)
+  {
+    int len = recvfrom (d_fd, buf, buflen, MSG_DONTWAIT, 0, 0);
+    if (len == -1 && errno == EAGAIN)
+      return 0;
+    
+    return len;
   }
-  return true;
-}
-
-int
-ethernet::read_packet (void *buf, int buflen)
-{
-  int len = recvfrom (d_fd, buf, buflen, 0, (sockaddr *) 0, 0);
-  return len;
-}
-
-int
-ethernet::read_packet_dont_block (void *buf, int buflen)
-{
-  int len = recvfrom (d_fd, buf, buflen, MSG_DONTWAIT, 0, 0);
-  if (len == -1 && errno == EAGAIN)
-    return 0;
   
-  return len;
-}
-
-int
-ethernet::write_packet (const void *buf, int buflen)
-{
-  int retval = send (d_fd, buf, buflen, 0);
-  if (retval < 0){
-    if (errno == EINTR)
-      return write_packet (buf, buflen);
-
-    perror ("ethernet:write_packet: send");
-    return -1;
+  int
+  ethernet::write_packet (const void *buf, int buflen)
+  {
+    int retval = send (d_fd, buf, buflen, 0);
+    if (retval < 0){
+      if (errno == EINTR)
+       return write_packet (buf, buflen);
+      
+      perror ("ethernet:write_packet: send");
+      return -1;
+    }
+    return retval;
   }
-  return retval;
-}
-
-bool
-ethernet::attach_pktfilter (pktfilter *pf)
-{
-  struct sock_fprog filter;
-  filter.len = pf->d_len;
-  filter.filter = pf->d_inst;
   
-  int r = setsockopt (d_fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof 
(filter));
-  if (r < 0){
-    perror ("ethernet:attach:  SO_ATTACH_FILTER");
-    return false;
+  bool
+  ethernet::attach_pktfilter (pktfilter *pf)
+  {
+    struct sock_fprog filter;
+    filter.len = pf->d_len;
+    filter.filter = pf->d_inst;
+    
+    int r = setsockopt (d_fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof 
(filter));
+    if (r < 0){
+      perror ("ethernet:attach:  SO_ATTACH_FILTER");
+      return false;
+    }
+    return true;
   }
-  return true;
-}
-
+  
 } // namespace usrp2

Modified: usrp2/trunk/host-ng/lib/ethernet.h
===================================================================
--- usrp2/trunk/host-ng/lib/ethernet.h  2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/lib/ethernet.h  2008-06-15 04:00:18 UTC (rev 8591)
@@ -24,87 +24,87 @@
 
 namespace usrp2 {
 
-class pktfilter;
-
-/*!
- * \brief Read and write ethernet frames.
- *
- * This provides a low level interface to hardware that communicates
- * via raw (non-IP) ethernet frames.
- */
-class ethernet {
-  int    d_fd;
-  uint8_t d_mac[6];
-
-public:
-  ethernet ();
-  ~ethernet ();
-
-  static const int MAX_PKTLEN = 1512;
-  static const int MIN_PKTLEN = 64;
-
+  class pktfilter;
+  
   /*!
-   * \param ifname ethernet interface name, e.g., "eth0"
-   * \param protocol is the ethertype protocol number in network order.
-   *    Use 0 to receive all protocols.
-   */
-  bool open (std::string ifname, int protocol);
-
-  bool close ();
-
-  /*!
-   * \brief attach packet filter to socket to restrict which packets read sees.
-   * \param pf the packet filter
-   */
-  bool attach_pktfilter (pktfilter *pf);
-
-  /*!
-   * \brief return 6 byte string containing our MAC address
-   */
-  const uint8_t *mac () const { return d_mac; }
-
-  /*!
-   * \brief Return file descriptor associated with socket.
-   */
-  int fd () const { return d_fd; }
-
-  /*!
-   * \brief Read packet from interface.
+   * \brief Read and write ethernet frames.
    *
-   * \param buf                where to put the packet
-   * \param buflen     maximum length of packet in bytes (should be >= 1528)
-   *
-   * \returns number of bytes read or -1 if trouble.
-   *
-   * Returned packet includes 14-byte ethhdr
+   * This provides a low level interface to hardware that communicates
+   * via raw (non-IP) ethernet frames.
    */
-  int read_packet (void *buf, int buflen);
-
-  /*!
-   * \brief Read packet from interface, but don't block waiting
-   *
-   * \param buf                where to put the packet
-   * \param buflen     maximum length of packet in bytes (should be >= 1528)
-   *
-   * \returns number of bytes read, -1 if trouble or 0 if nothing available.
-   *
-   * Returned packet includes 14-byte ethhdr
-   */
-  int read_packet_dont_block (void *buf, int buflen);
-
-  /*
-   * \brief Write ethernet packet to interface.
-   *
-   * \param buf                the packet to write
-   * \param buflen     length of packet in bytes
-   *
-   * \returns number of bytes written or -1 if trouble.
-   *
-   * Packet must begin with 14-byte ethhdr, but does not include the FCS.
-   */
-  int write_packet (const void *buf, int buflen);
-};
-
+  class ethernet {
+    int          d_fd;
+    uint8_t d_mac[6];
+    
+  public:
+    ethernet ();
+    ~ethernet ();
+    
+    static const int MAX_PKTLEN = 1512;
+    static const int MIN_PKTLEN = 64;
+    
+    /*!
+     * \param ifname ethernet interface name, e.g., "eth0"
+     * \param protocol is the ethertype protocol number in network order.
+     *    Use 0 to receive all protocols.
+     */
+    bool open (std::string ifname, int protocol);
+    
+    bool close ();
+    
+    /*!
+     * \brief attach packet filter to socket to restrict which packets read 
sees.
+     * \param pf       the packet filter
+     */
+    bool attach_pktfilter (pktfilter *pf);
+    
+    /*!
+     * \brief return 6 byte string containing our MAC address
+     */
+    const uint8_t *mac () const { return d_mac; }
+    
+    /*!
+     * \brief Return file descriptor associated with socket.
+     */
+    int fd () const { return d_fd; }
+    
+    /*!
+     * \brief Read packet from interface.
+     *
+     * \param buf              where to put the packet
+     * \param buflen   maximum length of packet in bytes (should be >= 1528)
+     *
+     * \returns number of bytes read or -1 if trouble.
+     *
+     * Returned packet includes 14-byte ethhdr
+     */
+    int read_packet (void *buf, int buflen);
+    
+    /*!
+     * \brief Read packet from interface, but don't block waiting
+     *
+     * \param buf              where to put the packet
+     * \param buflen   maximum length of packet in bytes (should be >= 1528)
+     *
+     * \returns number of bytes read, -1 if trouble or 0 if nothing available.
+     *
+     * Returned packet includes 14-byte ethhdr
+     */
+    int read_packet_dont_block (void *buf, int buflen);
+    
+    /*
+     * \brief Write ethernet packet to interface.
+     *
+     * \param buf              the packet to write
+     * \param buflen   length of packet in bytes
+     *
+     * \returns number of bytes written or -1 if trouble.
+     *
+     * Packet must begin with 14-byte ethhdr, but does not include the FCS.
+     */
+    int write_packet (const void *buf, int buflen);
+  };
+  
 } // namespace usrp2
 
 #endif /* INCLUDED_USRP2_ETHERNET_H */

Modified: usrp2/trunk/host-ng/lib/find.cc
===================================================================
--- usrp2/trunk/host-ng/lib/find.cc     2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/lib/find.cc     2008-06-15 04:00:18 UTC (rev 8591)
@@ -31,106 +31,107 @@
 
 namespace usrp2 {
 
-props_vector_t
-find(const std::string &ifc, const std::string &addr)
-{
-  if (FIND_DEBUG) {
-    std::cerr << "usrp2::find: Searching interface " << ifc << " for "
-              << (addr == "" ? "all USRP2s" : addr)
-             << std::endl;
-  }
-  
-  props_vector_t result;
-  struct command {
-    u2_eth_packet_t    h;
-    op_id_t            op_id;
-  };
+  props_vector_t
+  find(const std::string &ifc, const std::string &addr)
+  {
+    if (FIND_DEBUG) {
+      std::cerr << "usrp2::find: Searching interface " << ifc << " for "
+               << (addr == "" ? "all USRP2s" : addr)
+               << std::endl;
+    }
     
-  struct reply {
-    u2_eth_packet_t    h;
-    op_id_reply_t      op_id_reply;
-  };
-
-  std::vector<op_id_reply_t> replies;
-  std::auto_ptr<ethernet> enet(new ethernet()); 
-
-  if (!enet->open(ifc, htons(U2_ETHERTYPE)))
-    return result;
-
-  std::auto_ptr<pktfilter> pf(pktfilter::make_ethertype_inbound(U2_ETHERTYPE, 
enet->mac()));
-  if (!enet->attach_pktfilter(pf.get()))
-    return result;
-
-  static u2_mac_addr_t broadcast_mac_addr =
-    {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
-
-  uint8_t pktbuf[ethernet::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
-
-  command *c = (command *)pktbuf;
-  c->h.ehdr.ethertype = htons(U2_ETHERTYPE);
-  c->h.ehdr.dst = broadcast_mac_addr;
-  memcpy(&c->h.ehdr.src, enet->mac(), 6);
-  c->h.thdr.flags = 0;
-  c->h.thdr.seqno = 0;
-  c->h.thdr.ack = 0;
-  u2p_set_word0(&c->h.fixed, 0, CONTROL_CHAN);
-  u2p_set_timestamp(&c->h.fixed, -1);
-  c->op_id.opcode = OP_ID;
-  c->op_id.len = sizeof(op_id_t);
-  int len = std::max((size_t) ethernet::MIN_PKTLEN, sizeof(command));
-  if (enet->write_packet(c, len) != len)
-    return result;
-
-  if (FIND_DEBUG)
-    std::cerr << "usrp2::find: broadcast ID command" << std::endl;
+    props_vector_t result;
+    struct command {
+      u2_eth_packet_t  h;
+      op_id_t          op_id;
+    };
     
-  /*
-   * Wait no longer than 10ms and read all packets available.
-   */
-  fd_set read_fds;
-  FD_ZERO(&read_fds);
-  FD_SET(enet->fd(), &read_fds);
-  struct timeval timeout;
-  timeout.tv_sec = 0;
-  timeout.tv_usec = 10 * 1000; // 10 ms
-  
-  select(enet->fd()+1, &read_fds, 0, 0, &timeout);
-  while(1) {
+    struct reply {
+      u2_eth_packet_t  h;
+      op_id_reply_t    op_id_reply;
+    };
+    
+    std::vector<op_id_reply_t> replies;
+    std::auto_ptr<ethernet> enet(new ethernet()); 
+    
+    if (!enet->open(ifc, htons(U2_ETHERTYPE)))
+      return result;
+    
+    std::auto_ptr<pktfilter> 
pf(pktfilter::make_ethertype_inbound(U2_ETHERTYPE, enet->mac()));
+    if (!enet->attach_pktfilter(pf.get()))
+      return result;
+    
+    static u2_mac_addr_t broadcast_mac_addr =
+      {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
+    
+    uint8_t pktbuf[ethernet::MAX_PKTLEN];
     memset(pktbuf, 0, sizeof(pktbuf));
-    len = enet->read_packet_dont_block(pktbuf, sizeof(pktbuf));
-    if (len < 0){
-      perror("usrp2_basic: read_packet_dont_block");
+    
+    command *c = (command *)pktbuf;
+    c->h.ehdr.ethertype = htons(U2_ETHERTYPE);
+    c->h.ehdr.dst = broadcast_mac_addr;
+    memcpy(&c->h.ehdr.src, enet->mac(), 6);
+    c->h.thdr.flags = 0;
+    c->h.thdr.seqno = 0;
+    c->h.thdr.ack = 0;
+    u2p_set_word0(&c->h.fixed, 0, CONTROL_CHAN);
+    u2p_set_timestamp(&c->h.fixed, -1);
+    c->op_id.opcode = OP_ID;
+    c->op_id.len = sizeof(op_id_t);
+    int len = std::max((size_t) ethernet::MIN_PKTLEN, sizeof(command));
+    if (enet->write_packet(c, len) != len)
+      return result;
+    
+    if (FIND_DEBUG)
+      std::cerr << "usrp2::find: broadcast ID command" << std::endl;
+    
+    /*
+     * Wait no longer than 10ms and read all packets available.
+     */
+    fd_set read_fds;
+    FD_ZERO(&read_fds);
+    FD_SET(enet->fd(), &read_fds);
+    struct timeval timeout;
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 10 * 1000;       // 10 ms
+    
+    select(enet->fd()+1, &read_fds, 0, 0, &timeout);
+    while(1) {
+      memset(pktbuf, 0, sizeof(pktbuf));
+      len = enet->read_packet_dont_block(pktbuf, sizeof(pktbuf));
+      if (len < 0){
+       perror("usrp2_basic: read_packet_dont_block");
         return result;
+      }
+      if (len == 0)
+       break;
+      
+      reply *rp = (reply *)pktbuf;
+      if (u2p_chan(&rp->h.fixed) != CONTROL_CHAN)  // ignore
+       continue;
+      if (rp->op_id_reply.opcode != OP_ID_REPLY)       // ignore
+       continue;
+      
+      const uint8_t *mac = (const uint8_t *)&rp->op_id_reply.addr;
+      char addr_buf[128];
+      snprintf(addr_buf, sizeof(addr_buf), "%02x:%02x:%02x:%02x:%02x:%02x",
+              mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+      
+      props p;
+      p.addr = std::string(addr_buf);  
+      p.hw_rev = ntohs(rp->op_id_reply.hw_rev);
+      memcpy(&p.fpga_md5sum, &rp->op_id_reply.fpga_md5sum, 
sizeof(p.fpga_md5sum));
+      memcpy(&p.sw_md5sum, &rp->op_id_reply.sw_md5sum, sizeof(p.sw_md5sum));
+      
+      if (FIND_DEBUG)
+       std::cerr << "usrp2::find: response from " << p.addr << std::endl;
+      
+      if ((addr == "") || (addr == p.addr))
+       result.push_back(p);
     }
-    if (len == 0)
-      break;
-
-    reply *rp = (reply *)pktbuf;
-    if (u2p_chan(&rp->h.fixed) != CONTROL_CHAN)  // ignore
-      continue;
-    if (rp->op_id_reply.opcode != OP_ID_REPLY) // ignore
-      continue;
-
-    const uint8_t *mac = (const uint8_t *)&rp->op_id_reply.addr;
-    char addr_buf[128];
-    snprintf(addr_buf, sizeof(addr_buf), "%02x:%02x:%02x:%02x:%02x:%02x",
-            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-
-    props p;
-    p.addr = std::string(addr_buf);  
-    p.hw_rev = ntohs(rp->op_id_reply.hw_rev);
-    memcpy(&p.fpga_md5sum, &rp->op_id_reply.fpga_md5sum, 
sizeof(p.fpga_md5sum));
-    memcpy(&p.sw_md5sum, &rp->op_id_reply.sw_md5sum, sizeof(p.sw_md5sum));
     
-    if (FIND_DEBUG)
-      std::cerr << "usrp2::find: response from " << p.addr << std::endl;
-
-    if ((addr == "") || (addr == p.addr))
-      result.push_back(p);
+    return result;
   }
-      
-  return result;
-}
+  
+} // namespace usrp2
 
-}

Modified: usrp2/trunk/host-ng/lib/pktfilter.cc
===================================================================
--- usrp2/trunk/host-ng/lib/pktfilter.cc        2008-06-14 22:25:28 UTC (rev 
8590)
+++ usrp2/trunk/host-ng/lib/pktfilter.cc        2008-06-15 04:00:18 UTC (rev 
8591)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005,2007 Free Software Foundation, Inc.
+ * Copyright 2005,2007,2008 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,119 +34,119 @@
 #include <linux/filter.h>      // packet filter
 
 namespace usrp2 {
-
-/*
- * This is all based on the Berkeley Packet Filter (BPF) as implemented on 
Linux.
- *
- * The BPF allows you to run an interpreted program (a filter) in the
- * kernel that sorts through the packets looking for ones you are
- * interested in.  This eliminates the overhead of passing all of the
- * networking packets up into user space for filtering there.
- *
- * For documentation on this see
- * /usr/src/linux/Documentation/networking/filter.txt, The BSD
- * Berkeley Packet Filter manual page, and "The BSD Packet Filter: A
- * New Architecture for User-level Packet Capture", by Steven McCanne
- * and Van Jacobson.
- */
-
-pktfilter::pktfilter ()
-  : d_len (0), d_inst (0)
-{
-  // NOP
-}
-
-pktfilter::~pktfilter ()
-{
-  delete [] d_inst;
-}
-
-inline static sock_filter
-make_stmt (__u16 code, __u32 k)
-{
-  sock_filter  f;
-  f.code = code;
-  f.jt = 0;
-  f.jf = 0;
-  f.k = k;
-  return f;
-}
-
-inline static sock_filter
-make_jump (__u16 code, __u32 k, __u8 jt, __u8 jf)
-{
-  sock_filter  f;
-  f.code = code;
-  f.jt = jt;
-  f.jf = jf;
-  f.k = k;
-  return f;
-}
-
-/*
- * Return a filter that harvests packets with the specified ethertype.
- */
-pktfilter *
-pktfilter::make_ethertype (unsigned short ethertype)
-{
-  static const int MAX_LEN = 20;
-  sock_filter  *inst = new sock_filter [MAX_LEN];
-  pktfilter    *pf = new pktfilter ();
   
-  // nothing quite like coding in assembly without the benefit of an assembler 
;-)
-
-  // ignore packets that don't have the right ethertype
-
-  int i = 0;
-  inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12);    // load ethertype
-  inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 1, 0);
-  inst[i++] = make_stmt (BPF_RET|BPF_K, 0);            // return 0 (ignore 
packet)
-  inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1);        // return whole 
packet
-
-  assert (i <= MAX_LEN);
-
-  pf->d_inst = inst;
-  pf->d_len = i;
-
-  return pf;
-}
-
-/*
- * Return a filter that harvests inbound packets with the specified ethertype.
- * \param ethertype    the ethertype we're looking for
- * \param our_mac      our ethernet MAC address so we can avoid pkts we sent
- */
-pktfilter *
-pktfilter::make_ethertype_inbound (unsigned short ethertype, const unsigned 
char *our_mac)
-{
-  static const int MAX_LEN = 20;
-  sock_filter  *inst = new sock_filter [MAX_LEN];
-  pktfilter    *pf = new pktfilter ();
+  /*
+   * This is all based on the Berkeley Packet Filter (BPF) as implemented on 
Linux.
+   *
+   * The BPF allows you to run an interpreted program (a filter) in the
+   * kernel that sorts through the packets looking for ones you are
+   * interested in.  This eliminates the overhead of passing all of the
+   * networking packets up into user space for filtering there.
+   *
+   * For documentation on this see
+   * /usr/src/linux/Documentation/networking/filter.txt, The BSD
+   * Berkeley Packet Filter manual page, and "The BSD Packet Filter: A
+   * New Architecture for User-level Packet Capture", by Steven McCanne
+   * and Van Jacobson.
+   */
   
-  __u16 smac_hi = (our_mac[0] << 8) | our_mac[1];
-  __u32 smac_lo = (our_mac[2] << 24) | (our_mac[3] << 16) | (our_mac[4] << 8) 
| our_mac[5];
-
-  // nothing quite like coding in assembly without the benefit of an assembler 
;-)
-
-  // ignore packets that have a different ethertype
-  // and packets that have a source mac address == our_mac (packets we sent)
+  pktfilter::pktfilter ()
+    : d_len (0), d_inst (0)
+  {
+    // NOP
+  }
   
-  int i = 0;
-  inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12);    // load ethertype
-  inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 0, 5);
-  inst[i++] = make_stmt (BPF_LD|BPF_W|BPF_ABS, 8);     // load low 32-bit of 
src mac
-  inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_lo, 0, 2);
-  inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 6);     // load high 16-bits of 
src mac
-  inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_hi, 1, 0);
-  inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1);        // return whole 
packet
-  inst[i++] = make_stmt (BPF_RET|BPF_K, 0);            // return 0 (ignore 
packet)
-
-  assert (i <= MAX_LEN);
-
-  pf->d_inst = inst;
-  pf->d_len = i;
-
-  return pf;
-}
-
+  pktfilter::~pktfilter ()
+  {
+    delete [] d_inst;
+  }
+  
+  inline static sock_filter
+  make_stmt (__u16 code, __u32 k)
+  {
+    sock_filter        f;
+    f.code = code;
+    f.jt = 0;
+    f.jf = 0;
+    f.k = k;
+    return f;
+  }
+  
+  inline static sock_filter
+  make_jump (__u16 code, __u32 k, __u8 jt, __u8 jf)
+  {
+    sock_filter        f;
+    f.code = code;
+    f.jt = jt;
+    f.jf = jf;
+    f.k = k;
+    return f;
+  }
+  
+  /*
+   * Return a filter that harvests packets with the specified ethertype.
+   */
+  pktfilter *
+  pktfilter::make_ethertype (unsigned short ethertype)
+  {
+    static const int MAX_LEN = 20;
+    sock_filter        *inst = new sock_filter [MAX_LEN];
+    pktfilter  *pf = new pktfilter ();
+    
+    // nothing quite like coding in assembly without the benefit of an 
assembler ;-)
+    
+    // ignore packets that don't have the right ethertype
+    
+    int i = 0;
+    inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12);  // load ethertype
+    inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 1, 0);
+    inst[i++] = make_stmt (BPF_RET|BPF_K, 0);          // return 0 (ignore 
packet)
+    inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1);      // return whole 
packet
+    
+    assert (i <= MAX_LEN);
+    
+    pf->d_inst = inst;
+    pf->d_len = i;
+    
+    return pf;
+  }
+  
+  /*
+   * Return a filter that harvests inbound packets with the specified 
ethertype.
+   * \param ethertype  the ethertype we're looking for
+   * \param our_mac    our ethernet MAC address so we can avoid pkts we sent
+   */
+  pktfilter *
+  pktfilter::make_ethertype_inbound (unsigned short ethertype, const unsigned 
char *our_mac)
+  {
+    static const int MAX_LEN = 20;
+    sock_filter        *inst = new sock_filter [MAX_LEN];
+    pktfilter  *pf = new pktfilter ();
+    
+    __u16 smac_hi = (our_mac[0] << 8) | our_mac[1];
+    __u32 smac_lo = (our_mac[2] << 24) | (our_mac[3] << 16) | (our_mac[4] << 
8) | our_mac[5];
+    
+    // nothing quite like coding in assembly without the benefit of an 
assembler ;-)
+    
+    // ignore packets that have a different ethertype
+    // and packets that have a source mac address == our_mac (packets we sent)
+    
+    int i = 0;
+    inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12);  // load ethertype
+    inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 0, 5);
+    inst[i++] = make_stmt (BPF_LD|BPF_W|BPF_ABS, 8);   // load low 32-bit of 
src mac
+    inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_lo, 0, 2);
+    inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 6);   // load high 16-bits of 
src mac
+    inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_hi, 1, 0);
+    inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1);      // return whole 
packet
+    inst[i++] = make_stmt (BPF_RET|BPF_K, 0);          // return 0 (ignore 
packet)
+    
+    assert (i <= MAX_LEN);
+    
+    pf->d_inst = inst;
+    pf->d_len = i;
+    
+    return pf;
+  }
+  
 } // namespace usrp2

Modified: usrp2/trunk/host-ng/lib/pktfilter.h
===================================================================
--- usrp2/trunk/host-ng/lib/pktfilter.h 2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/lib/pktfilter.h 2008-06-15 04:00:18 UTC (rev 8591)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005,2007 Free Software Foundation, Inc.
+ * Copyright 2005,2007,2008 Free Software Foundation, Inc.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,33 +23,33 @@
 
 namespace usrp2 {
 
-/*
- * \brief Compile programs for the Berkeley Packet Filter
- */
-class pktfilter {
-public:
-
-  unsigned              d_len;         // # of instructions
-  struct sock_filter   *d_inst;        // the instructions
-
-  pktfilter ();
-  ~pktfilter ();
+  /*
+   * \brief Compile programs for the Berkeley Packet Filter
+   */
+  class pktfilter {
+  public:
+    
+    unsigned            d_len;         // # of instructions
+    struct sock_filter *d_inst;        // the instructions
+    
+    pktfilter ();
+    ~pktfilter ();
+    
+    /*!
+     * \brief Return a filter that harvests packets with the specified 
ethertype.
+     * \param ethertype        the ethertype we're looking for.
+     */
+    static pktfilter *make_ethertype (unsigned short ethertype);
+    
+    /*!
+     * \brief Return a filter that harvests inbound packets with the specified 
ethertype.
+     * \param ethertype        the ethertype we're looking for
+     * \param our_mac  our MAC address so we can avoid pkts we sent
+     */
+    static pktfilter *make_ethertype_inbound (unsigned short ethertype,
+                                             const unsigned char *our_mac);
+  };
   
-  /*!
-   * \brief Return a filter that harvests packets with the specified ethertype.
-   * \param ethertype  the ethertype we're looking for.
-   */
-  static pktfilter *make_ethertype (unsigned short ethertype);
-
-  /*!
-   * \brief Return a filter that harvests inbound packets with the specified 
ethertype.
-   * \param ethertype  the ethertype we're looking for
-   * \param our_mac    our MAC address so we can avoid pkts we sent
-   */
-  static pktfilter *make_ethertype_inbound (unsigned short ethertype,
-                                               const unsigned char *our_mac);
-};
-
 } // namespace usrp2
 
 #endif /* INCLUDED_USRP2_PKTFILTER_H */

Modified: usrp2/trunk/host-ng/lib/usrp2.cc
===================================================================
--- usrp2/trunk/host-ng/lib/usrp2.cc    2008-06-14 22:25:28 UTC (rev 8590)
+++ usrp2/trunk/host-ng/lib/usrp2.cc    2008-06-15 04:00:18 UTC (rev 8591)
@@ -21,520 +21,64 @@
 #endif
 
 #include <usrp2/usrp2.h>
-#include <usrp2/data_handler.h>
-#include <usrp2_eth_packet.h>
-#include <usrp2_types.h>
-#include "eth_buffer.h"
-#include "pktfilter.h"
-#include "usrp2_thread.h"
+#include "usrp2_impl.h"
 
-#include <iostream>
-#include <stdexcept>
-#include <netinet/in.h>
-#include <errno.h>
-
-#define USRP2_DEBUG 1
-
-#if USRP2_DEBUG
-#define DEBUG_LOG(x) ::write(2, x, 1)
-#else
-#define DEBUG_LOG(x)
-#endif
-
 namespace usrp2 {
 
-// --- Private implementation class -------------------------------------
+  // Shared pointer factory function, wraps constructor call
+  usrp2::sptr
+  usrp2::make(const std::string &ifc, const std::string &addr)
+  {
+    return usrp2::sptr(new usrp2(ifc, addr));
+  }
 
-class usrp2::impl : data_handler
-{
-  eth_buffer   *d_buffer;
-  pktfilter    *d_pf;
-  std::string   d_addr;
-  usrp2_thread *d_bg_thread;
-  volatile bool d_bg_running; // TODO: multistate if needed
-
-  int           d_rx_decim;
-  int           d_rx_seqno;
-  int           d_tx_seqno;
-  int          d_next_rid;
-  unsigned int  d_num_rx_frames;
-  unsigned int  d_num_rx_lost;
-  unsigned int  d_num_rx_bytes;
-      
-public:
-  impl(const std::string &ifc, const std::string &addr);
-  ~impl();
+  // Private constructor.  Sole function is to create an impl.
+  usrp2::usrp2(const std::string &ifc, const std::string &addr)
+    : d_impl(new usrp2::impl(ifc, addr))
+  {
+    // NOP
+  }
   
-  static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
-  void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
-  void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
-                    int word0_flags, int chan, uint32_t timestamp);
-  void bg_loop();
-  void stop_bg();
-  bool set_rx_gain(double gain);
-  bool set_rx_freq(double frequency, usrp2_tune_result *result);
-  bool set_rx_decim(int decimation_factor);
-  bool set_rx_scale_iq(int scale_i, int scale_q);
-  bool start_rx_streaming(unsigned int items_per_frame);
-  bool stop_rx_streaming();
-
-  virtual unsigned int operator()(const void *base, unsigned int len);
-};
-
-// ----------------------------------------------------------------------
-
-// Shared pointer factory function, wraps constructor call
-usrp2::sptr
-usrp2::make(const std::string &ifc, const std::string &addr)
-{
-  return usrp2::sptr(new usrp2(ifc, addr));
-}
-
-// Private constructor.  Sole function is to create an impl.
-usrp2::usrp2(const std::string &ifc, const std::string &addr)
-  : d_impl(new usrp2::impl(ifc, addr))
-{
-  // NOP
-}
-
-// Public class destructor.  d_impl will auto-delete.
-usrp2::~usrp2()
-{
-  // NOP
-}
-
-// ----------------------------------------------------------------------
-
-bool 
-usrp2::set_rx_gain(double gain)
-{
-  return d_impl->set_rx_gain(gain);
-}
-
-bool
-usrp2::set_rx_freq(double frequency, usrp2_tune_result *result)
-{
-  return d_impl->set_rx_freq(frequency, result);
-}
-
-bool
-usrp2::set_rx_decim(int decimation_factor)
-{
-  return d_impl->set_rx_decim(decimation_factor);
-}
-
-bool
-usrp2::set_rx_scale_iq(int scale_i, int scale_q)
-{
-  return d_impl->set_rx_scale_iq(scale_i, scale_q);
-}
-
-bool
-usrp2::start_rx_streaming(unsigned int items_per_frame)
-{
-  return d_impl->start_rx_streaming(items_per_frame);
-}
-
-bool
-usrp2::stop_rx_streaming()
-{
-  return d_impl->stop_rx_streaming();
-}
-
-// ----------------------------------------------------------------------
-
-usrp2::impl::impl(const std::string &ifc, const std::string &addr)
-  : d_buffer(new eth_buffer()), d_pf(0), d_bg_thread(0), d_bg_running(false),
-    d_rx_decim(0), d_rx_seqno(-1), d_tx_seqno(0), d_next_rid(0),
-    d_num_rx_frames(0), d_num_rx_lost(0), d_num_rx_bytes(0)
-{
-  props_vector_t u2s = find(ifc, addr);
-  if (u2s.size() != 1)
-    throw std::runtime_error("Unable to find requested USRP2.");
-
-  if (!d_buffer->open(ifc, htons(U2_ETHERTYPE)))
-    throw std::runtime_error("Unable to register USRP2 protocol");
-
-  d_pf = pktfilter::make_ethertype_inbound(U2_ETHERTYPE, d_buffer->mac());
-  if (!d_pf || !d_buffer->attach_pktfilter(d_pf))
-    throw std::runtime_error("Unable to attach packet filter.");
-
-  d_addr = u2s[0].addr;
-
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2 constructor: using USRP2 at " << d_addr << std::endl;
-
-  d_bg_thread = new usrp2_thread(this);
-  d_bg_thread->start();
-}
-
-usrp2::impl::~impl()
-{
-
-  stop_bg();
-  d_bg_thread = 0; // thread class deletes itself
-  delete d_pf;
-  d_buffer->close();
-  delete d_buffer;
-
-  if (USRP2_DEBUG) {
-    std::cerr << "usrp2 destructor: received " << d_num_rx_frames 
-              << " frames, with " << d_num_rx_lost << " lost ("
-             << (int)(100.0*d_num_rx_lost/d_num_rx_frames)
-             << "%), totaling " << d_num_rx_bytes
-              << " bytes" << std::endl;
+  // Public class destructor.  d_impl will auto-delete.
+  usrp2::~usrp2()
+  {
+    // NOP
   }
-}
-
-bool
-usrp2::impl::parse_mac_addr(const std::string &s, u2_mac_addr_t *p)
-{
-  p->addr[0] = 0x00;           // Matt's IAB
-  p->addr[1] = 0x50;
-  p->addr[2] = 0xC2;
-  p->addr[3] = 0x85;
-  p->addr[4] = 0x30;
-  p->addr[5] = 0x00;
-
-  int len = s.size();
   
-  switch (len){
-
-  case 5:
-    return sscanf(s.c_str(), "%hhx:%hhx", &p->addr[4], &p->addr[5]) == 2;
-
-  case 17:
-    return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-                 &p->addr[0], &p->addr[1], &p->addr[2],
-                 &p->addr[3], &p->addr[4], &p->addr[5]) == 6;
-  default:
-    return false;
+  bool 
+  usrp2::set_rx_gain(double gain)
+  {
+    return d_impl->set_rx_gain(gain);
   }
-}
-
-void
-usrp2::impl::init_et_hdrs(u2_eth_packet_t *p, const std::string &dst)
-{
-  p->ehdr.ethertype = htons(U2_ETHERTYPE);
-  parse_mac_addr(dst, &p->ehdr.dst); 
-  memcpy(&p->ehdr.src, d_buffer->mac(), 6);
-  p->thdr.flags = 0; // FIXME transport header values?
-  p->thdr.seqno = d_tx_seqno++;
-  p->thdr.ack = 0;
-}
-
-void 
-usrp2::impl::init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
-              int word0_flags, int chan, uint32_t timestamp)
-{
-  init_et_hdrs(p, dst);
-  u2p_set_word0(&p->fixed, 0, chan);
-  u2p_set_timestamp(&p->fixed, timestamp);
   
-  if (chan == CONTROL_CHAN) { // no sequence numbers, back it out
-    p->thdr.seqno = 0;
-    d_tx_seqno--;
+  bool
+  usrp2::set_rx_freq(double frequency, usrp2_tune_result *result)
+  {
+    return d_impl->set_rx_freq(frequency, result);
   }
-}
-
-bool 
-usrp2::impl::set_rx_gain(double gain)
-{
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2: setting receive gain to " << gain << std::endl;
-
-  uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
-
-  struct command {
-    u2_eth_packet_t    h;
-    op_config_rx_v2_t  op;
-    op_eop_t           eop;
-  };
-
-  command *c = (command *) pktbuf;
-  init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
   
-  c->op.opcode = OP_CONFIG_RX_V2;
-  c->op.len = sizeof(op_config_rx_v2_t);
-  c->op.rid = d_next_rid++;
+  bool
+  usrp2::set_rx_decim(int decimation_factor)
+  {
+    return d_impl->set_rx_decim(decimation_factor);
+  }
   
-  c->op.valid = htons(CFGV_GAIN);
-  c->op.gain = htons(u2_double_to_fxpt_gain(gain));
+  bool
+  usrp2::set_rx_scale_iq(int scale_i, int scale_q)
+  {
+    return d_impl->set_rx_scale_iq(scale_i, scale_q);
+  }
   
-  c->eop.opcode = OP_EOP;
-  c->eop.len = sizeof(op_eop_t);
-  
-  int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
-  if (d_buffer->tx_frame(c, len) != len)
-    return false;
-  
-  // FIXME wait for corresponding reply, etc.
-
-  return true;
-}
-
-bool
-usrp2::impl::set_rx_freq(double frequency, usrp2_tune_result *result)
-{
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2: setting frequency to " << frequency << std::endl;
-
-  uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
-
-  struct command {
-    u2_eth_packet_t    h;
-    op_config_rx_v2_t  op;
-    op_eop_t           eop;
-  };
-
-  command *c = (command *) pktbuf;
-  init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
-
-  c->op.opcode = OP_CONFIG_RX_V2;
-  c->op.len = sizeof(op_config_rx_v2_t);
-  c->op.rid = d_next_rid++;
-
-  c->op.valid = htons(CFGV_FREQ);
-  u2_fxpt_freq_t  fxpt = u2_double_to_fxpt_freq(frequency);
-  c->op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
-  c->op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-
-  c->eop.opcode = OP_EOP;
-  c->eop.len = sizeof(op_eop_t);
-
-  int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
-  if (d_buffer->tx_frame(c, len) == len) {
-    // FIXME: wait for corresponding reply, set tune result members
+  bool
+  usrp2::start_rx_streaming(unsigned int items_per_frame)
+  {
+    return d_impl->start_rx_streaming(items_per_frame);
   }
-
-  return true;
-}
-
-bool
-usrp2::impl::set_rx_decim(int decimation_factor)
-{
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2: setting receive decimation rate to " 
-             << decimation_factor << std::endl;
-  uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
-
-  struct command {
-    u2_eth_packet_t    h;
-    op_config_rx_v2_t  op;
-    op_eop_t           eop;
-  };
-
-  command *c = (command *) pktbuf;
-  init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
-
-  c->op.opcode = OP_CONFIG_RX_V2;
-  c->op.len = sizeof(op_config_rx_v2_t);
-  c->op.rid = d_next_rid++;
-
-  c->op.valid = htons(CFGV_INTERP_DECIM);
-  c->op.decim = htonl(decimation_factor);
-
-  c->eop.opcode = OP_EOP;
-  c->eop.len = sizeof(op_eop_t);
-
-  int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
-  if (d_buffer->tx_frame(c, len) != len)
-    return false;
-
-  // FIXME wait for corresponding reply, etc.
-
-  d_rx_decim = decimation_factor;
-  return true;
-}
-
-bool
-usrp2::impl::set_rx_scale_iq(int scale_i, int scale_q)
-{
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2: setting RX IQ scaling to " 
-             << scale_i << ", " << scale_q << std::endl;
-
-  uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
-
-  struct command {
-    u2_eth_packet_t    h;
-    op_config_rx_v2_t  op;
-    op_eop_t           eop;
-  };
-
-  command *c = (command *) pktbuf;
-  init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
-
-  c->op.opcode = OP_CONFIG_RX_V2;
-  c->op.len = sizeof(op_config_rx_v2_t);
-  c->op.rid = d_next_rid++;
-
-  c->op.valid = htons(CFGV_SCALE_IQ);
-  c->op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
-
-  c->eop.opcode = OP_EOP;
-  c->eop.len = sizeof(op_eop_t);
-
-  int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
-  if (d_buffer->tx_frame(c, len) != len)
-    return false;
-
-  // FIXME wait for corresponding reply, etc.
-
-  return true;
-}
-
-bool
-usrp2::impl::start_rx_streaming(unsigned int items_per_frame)
-{
-  // Assume for now rx format is complex floats
-  if (items_per_frame == 0)
-    items_per_frame = 250; // TODO: calculate from d_itemsize;
-    
-  uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
   
-  struct command {
-    u2_eth_packet_t            h;
-    op_start_rx_streaming_t    op;
-    op_eop_t                   eop;
-  };
-
-  command *c = (command *) pktbuf;
-  init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
-
-  c->op.opcode = OP_START_RX_STREAMING;
-  c->op.len = sizeof(op_start_rx_streaming_t);
-  c->op.items_per_frame = htonl(items_per_frame);
-
-  c->eop.opcode = OP_EOP;
-  c->eop.len = sizeof(op_eop_t);
-
-  int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
-  if (d_buffer->tx_frame(c, len) != len)
-    return false;
-
-  return true;
-}
-
-bool
-usrp2::impl::stop_rx_streaming()
-{
-  uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
-  memset(pktbuf, 0, sizeof(pktbuf));
-
-  struct command {
-    u2_eth_packet_t    h;
-    op_id_t            op_stop_rx;
-  };
-    
-  command *c = (command *) pktbuf;
-  init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
-
-  c->op_stop_rx.opcode = OP_STOP_RX;
-  c->op_stop_rx.len = sizeof(op_stop_rx_t);
-  int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
-  if (d_buffer->tx_frame(c, len) != len)
-    return false;
-
-  return true;
-}
-
-void
-usrp2::impl::bg_loop()
-{
-  d_bg_running = true;
-  while(d_bg_running) {
-    int res = d_buffer->rx_frames(this, 1000);
-    if (res == -1)
-      break;  
+  bool
+  usrp2::stop_rx_streaming()
+  {
+    return d_impl->stop_rx_streaming();
   }
-}
 
-unsigned int
-usrp2::impl::operator()(const void *base, unsigned int len)
-{
-  u2_eth_samples_t *pkt = (u2_eth_samples_t *)base;
-
-  d_num_rx_frames++;
-  d_num_rx_bytes += len;
-
-  if (d_rx_seqno != -1) {
-    int expected_seqno = (d_rx_seqno + 1) & 0xFF;
-    int seqno = pkt->hdrs.thdr.seqno; 
-    
-    if (seqno != expected_seqno) {
-      ::write(2, "uS", 2); // missing sequence number
-      int missing = expected_seqno - seqno;
-      if (missing < 0)
-       missing += 256;
-      
-      d_num_rx_lost += missing;
-    }
-  }
-  
-  d_rx_seqno = pkt->hdrs.thdr.seqno;
-  return 0;
-}
-
-void
-usrp2::impl::stop_bg()
-{
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2_thread::stop: joining background thread "
-             << this << std::endl;
-  d_bg_running = false;
-
-  void *dummy_status;
-  d_bg_thread->join(&dummy_status);  
-
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2_thread::stop: join returned" << std::endl;
-}
-
-// ----------------------------------------------------------------------
-
-usrp2_thread::usrp2_thread(usrp2::impl *u2) :
-  omni_thread(NULL, PRIORITY_HIGH),
-  d_u2(u2)
-{
-}
-
-usrp2_thread::~usrp2_thread()
-{
-  // we don't own this, just forget it
-  d_u2 = 0;
-}
-
-void
-usrp2_thread::start()
-{
-  if (USRP2_DEBUG)
-    std::cerr << "usrp2_thread::start() "
-             << this << std::endl;
-
-  start_undetached();
-}
-
-void *
-usrp2_thread::run_undetached(void *arg)
-{
-#if 0
-  // FIXME hoist this from gnuradio-core into another library.
-  gr_rt_status_t rt = gr_enable_realtime_scheduling();
-  if (rt != RT_OK)
-    std::cerr << "failed to enable realtime scheduling\n";
-#endif
-  
-  // This is the first code to run in the new thread context.
-  d_u2->bg_loop();
-
-  return 0;
-}
-
 } // namespace usrp2
-

Added: usrp2/trunk/host-ng/lib/usrp2_impl.cc
===================================================================
--- usrp2/trunk/host-ng/lib/usrp2_impl.cc                               (rev 0)
+++ usrp2/trunk/host-ng/lib/usrp2_impl.cc       2008-06-15 04:00:18 UTC (rev 
8591)
@@ -0,0 +1,394 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <usrp2/usrp2.h>
+#include <usrp2_types.h>
+#include "usrp2_impl.h"
+#include "usrp2_thread.h"
+#include "eth_buffer.h"
+#include "pktfilter.h"
+#include <stdexcept>
+#include <iostream>
+
+#define USRP2_IMPL_DEBUG 1
+#if USRP2_IMPL_DEBUG
+#define DEBUG_LOG(x) ::write(2, x, 1)
+#else
+#define DEBUG_LOG(x)
+#endif
+
+namespace usrp2 {
+
+  usrp2::impl::impl(const std::string &ifc, const std::string &addr)
+    : d_buffer(new eth_buffer()), d_pf(0), d_bg_thread(0), d_bg_running(false),
+      d_rx_decim(0), d_rx_seqno(-1), d_tx_seqno(0), d_next_rid(0),
+      d_num_rx_frames(0), d_num_rx_lost(0), d_num_rx_bytes(0)
+  {
+    props_vector_t u2s = find(ifc, addr);
+    if (u2s.size() != 1)
+      throw std::runtime_error("Unable to find requested USRP2.");
+    
+    if (!d_buffer->open(ifc, htons(U2_ETHERTYPE)))
+      throw std::runtime_error("Unable to register USRP2 protocol");
+    
+    d_pf = pktfilter::make_ethertype_inbound(U2_ETHERTYPE, d_buffer->mac());
+    if (!d_pf || !d_buffer->attach_pktfilter(d_pf))
+      throw std::runtime_error("Unable to attach packet filter.");
+    
+    d_addr = u2s[0].addr;
+    
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2 constructor: using USRP2 at " << d_addr << std::endl;
+    
+    d_bg_thread = new usrp2_thread(this);
+    d_bg_thread->start();
+  }
+  
+  usrp2::impl::~impl()
+  {
+    
+    stop_bg();
+    d_bg_thread = 0; // thread class deletes itself
+    delete d_pf;
+    d_buffer->close();
+    delete d_buffer;
+    
+    if (USRP2_IMPL_DEBUG) {
+      std::cerr << "usrp2 destructor: received " << d_num_rx_frames 
+               << " frames, with " << d_num_rx_lost << " lost ("
+               << (int)(100.0*d_num_rx_lost/d_num_rx_frames)
+               << "%), totaling " << d_num_rx_bytes
+               << " bytes" << std::endl;
+    }
+  }
+  
+  bool
+  usrp2::impl::parse_mac_addr(const std::string &s, u2_mac_addr_t *p)
+  {
+    p->addr[0] = 0x00;         // Matt's IAB
+    p->addr[1] = 0x50;
+    p->addr[2] = 0xC2;
+    p->addr[3] = 0x85;
+    p->addr[4] = 0x30;
+    p->addr[5] = 0x00;
+    
+    int len = s.size();
+    
+    switch (len){
+      
+    case 5:
+      return sscanf(s.c_str(), "%hhx:%hhx", &p->addr[4], &p->addr[5]) == 2;
+      
+    case 17:
+      return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+                   &p->addr[0], &p->addr[1], &p->addr[2],
+                   &p->addr[3], &p->addr[4], &p->addr[5]) == 6;
+    default:
+      return false;
+    }
+  }
+  
+  void
+  usrp2::impl::init_et_hdrs(u2_eth_packet_t *p, const std::string &dst)
+  {
+    p->ehdr.ethertype = htons(U2_ETHERTYPE);
+    parse_mac_addr(dst, &p->ehdr.dst); 
+    memcpy(&p->ehdr.src, d_buffer->mac(), 6);
+    p->thdr.flags = 0; // FIXME transport header values?
+    p->thdr.seqno = d_tx_seqno++;
+    p->thdr.ack = 0;
+  }
+  
+  void 
+  usrp2::impl::init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
+                            int word0_flags, int chan, uint32_t timestamp)
+  {
+    init_et_hdrs(p, dst);
+    u2p_set_word0(&p->fixed, 0, chan);
+    u2p_set_timestamp(&p->fixed, timestamp);
+    
+    if (chan == CONTROL_CHAN) { // no sequence numbers, back it out
+      p->thdr.seqno = 0;
+      d_tx_seqno--;
+    }
+  }
+  
+  bool 
+  usrp2::impl::set_rx_gain(double gain)
+  {
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2: setting receive gain to " << gain << std::endl;
+    
+    uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
+    memset(pktbuf, 0, sizeof(pktbuf));
+    
+    struct command {
+      u2_eth_packet_t  h;
+      op_config_rx_v2_t        op;
+      op_eop_t         eop;
+    };
+    
+    command *c = (command *) pktbuf;
+    init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
+    
+    c->op.opcode = OP_CONFIG_RX_V2;
+    c->op.len = sizeof(op_config_rx_v2_t);
+    c->op.rid = d_next_rid++;
+    
+    c->op.valid = htons(CFGV_GAIN);
+    c->op.gain = htons(u2_double_to_fxpt_gain(gain));
+    
+    c->eop.opcode = OP_EOP;
+    c->eop.len = sizeof(op_eop_t);
+    
+    int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
+    if (d_buffer->tx_frame(c, len) != len)
+      return false;
+    
+    // FIXME wait for corresponding reply, etc.
+    
+    return true;
+  }
+  
+  bool
+  usrp2::impl::set_rx_freq(double frequency, usrp2_tune_result *result)
+  {
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2: setting frequency to " << frequency << std::endl;
+    
+    uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
+    memset(pktbuf, 0, sizeof(pktbuf));
+    
+    struct command {
+      u2_eth_packet_t  h;
+      op_config_rx_v2_t        op;
+      op_eop_t         eop;
+    };
+    
+    command *c = (command *) pktbuf;
+    init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
+    
+    c->op.opcode = OP_CONFIG_RX_V2;
+    c->op.len = sizeof(op_config_rx_v2_t);
+    c->op.rid = d_next_rid++;
+    
+    c->op.valid = htons(CFGV_FREQ);
+    u2_fxpt_freq_t  fxpt = u2_double_to_fxpt_freq(frequency);
+    c->op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
+    c->op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
+    
+    c->eop.opcode = OP_EOP;
+    c->eop.len = sizeof(op_eop_t);
+    
+    int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
+    if (d_buffer->tx_frame(c, len) == len) {
+      // FIXME: wait for corresponding reply, set tune result members
+    }
+    
+    return true;
+  }
+  
+  bool
+  usrp2::impl::set_rx_decim(int decimation_factor)
+  {
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2: setting receive decimation rate to " 
+               << decimation_factor << std::endl;
+    uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
+    memset(pktbuf, 0, sizeof(pktbuf));
+    
+    struct command {
+      u2_eth_packet_t  h;
+      op_config_rx_v2_t        op;
+      op_eop_t         eop;
+    };
+    
+    command *c = (command *) pktbuf;
+    init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
+    
+    c->op.opcode = OP_CONFIG_RX_V2;
+    c->op.len = sizeof(op_config_rx_v2_t);
+    c->op.rid = d_next_rid++;
+    
+    c->op.valid = htons(CFGV_INTERP_DECIM);
+    c->op.decim = htonl(decimation_factor);
+    
+    c->eop.opcode = OP_EOP;
+    c->eop.len = sizeof(op_eop_t);
+    
+    int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
+    if (d_buffer->tx_frame(c, len) != len)
+      return false;
+    
+    // FIXME wait for corresponding reply, etc.
+    
+    d_rx_decim = decimation_factor;
+    return true;
+  }
+  
+  bool
+  usrp2::impl::set_rx_scale_iq(int scale_i, int scale_q)
+  {
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2: setting RX IQ scaling to " 
+               << scale_i << ", " << scale_q << std::endl;
+    
+    uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
+    memset(pktbuf, 0, sizeof(pktbuf));
+    
+    struct command {
+      u2_eth_packet_t  h;
+      op_config_rx_v2_t        op;
+      op_eop_t         eop;
+    };
+    
+    command *c = (command *) pktbuf;
+    init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
+    
+    c->op.opcode = OP_CONFIG_RX_V2;
+    c->op.len = sizeof(op_config_rx_v2_t);
+    c->op.rid = d_next_rid++;
+    
+    c->op.valid = htons(CFGV_SCALE_IQ);
+    c->op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
+    
+    c->eop.opcode = OP_EOP;
+    c->eop.len = sizeof(op_eop_t);
+    
+    int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
+    if (d_buffer->tx_frame(c, len) != len)
+      return false;
+    
+    // FIXME wait for corresponding reply, etc.
+    
+    return true;
+  }
+  
+  bool
+  usrp2::impl::start_rx_streaming(unsigned int items_per_frame)
+  {
+    // Assume for now rx format is complex floats
+    if (items_per_frame == 0)
+      items_per_frame = 250; // TODO: calculate from d_itemsize;
+    
+    uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
+    memset(pktbuf, 0, sizeof(pktbuf));
+    
+    struct command {
+      u2_eth_packet_t          h;
+      op_start_rx_streaming_t  op;
+      op_eop_t                 eop;
+    };
+    
+    command *c = (command *) pktbuf;
+    init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
+    
+    c->op.opcode = OP_START_RX_STREAMING;
+    c->op.len = sizeof(op_start_rx_streaming_t);
+    c->op.items_per_frame = htonl(items_per_frame);
+    
+    c->eop.opcode = OP_EOP;
+    c->eop.len = sizeof(op_eop_t);
+    
+    int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
+    if (d_buffer->tx_frame(c, len) != len)
+      return false;
+    
+    return true;
+  }
+  
+  bool
+  usrp2::impl::stop_rx_streaming()
+  {
+    uint8_t pktbuf[eth_buffer::MAX_PKTLEN];
+    memset(pktbuf, 0, sizeof(pktbuf));
+    
+    struct command {
+      u2_eth_packet_t  h;
+      op_id_t          op_stop_rx;
+    };
+    
+    command *c = (command *) pktbuf;
+    init_etf_hdrs(&c->h, d_addr, 0, CONTROL_CHAN, -1);
+    
+    c->op_stop_rx.opcode = OP_STOP_RX;
+    c->op_stop_rx.len = sizeof(op_stop_rx_t);
+    int len = std::max((size_t) eth_buffer::MIN_PKTLEN, sizeof(command));
+    if (d_buffer->tx_frame(c, len) != len)
+      return false;
+    
+    return true;
+  }
+  
+  void
+  usrp2::impl::bg_loop()
+  {
+    d_bg_running = true;
+    while(d_bg_running) {
+      int res = d_buffer->rx_frames(this, 1000);
+      if (res == -1)
+       break;  
+    }
+  }
+  
+  unsigned int
+  usrp2::impl::operator()(const void *base, unsigned int len)
+  {
+    u2_eth_samples_t *pkt = (u2_eth_samples_t *)base;
+    
+    d_num_rx_frames++;
+    d_num_rx_bytes += len;
+    
+    if (d_rx_seqno != -1) {
+      int expected_seqno = (d_rx_seqno + 1) & 0xFF;
+      int seqno = pkt->hdrs.thdr.seqno; 
+      
+      if (seqno != expected_seqno) {
+       ::write(2, "uS", 2); // missing sequence number
+       int missing = expected_seqno - seqno;
+       if (missing < 0)
+         missing += 256;
+       
+       d_num_rx_lost += missing;
+      }
+    }
+    
+    d_rx_seqno = pkt->hdrs.thdr.seqno;
+    return 0;
+  }
+  
+  void
+  usrp2::impl::stop_bg()
+  {
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2_thread::stop: joining background thread "
+               << this << std::endl;
+    d_bg_running = false;
+    
+    void *dummy_status;
+    d_bg_thread->join(&dummy_status);  
+    
+    if (USRP2_IMPL_DEBUG)
+      std::cerr << "usrp2_thread::stop: join returned" << std::endl;
+  }
+  
+} // namespace usrp2

Added: usrp2/trunk/host-ng/lib/usrp2_impl.h
===================================================================
--- usrp2/trunk/host-ng/lib/usrp2_impl.h                                (rev 0)
+++ usrp2/trunk/host-ng/lib/usrp2_impl.h        2008-06-15 04:00:18 UTC (rev 
8591)
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDED_USRP2_IMPL_H
+#define INCLUDED_USRP2_IMPL_H
+
+#include <usrp2/usrp2.h>
+#include <usrp2/data_handler.h>
+#include <usrp2_eth_packet.h>
+#include <string>
+
+namespace usrp2 {
+  
+  class eth_buffer;
+  class pktfilter;
+  class usrp2_thread;
+  class usrp2_tune_result;
+  
+  class usrp2::impl : public data_handler
+  {
+    eth_buffer   *d_buffer;
+    pktfilter    *d_pf;
+    std::string   d_addr;
+    usrp2_thread *d_bg_thread;
+    volatile bool d_bg_running; // TODO: multistate if needed
+    
+    int           d_rx_decim;
+    int           d_rx_seqno;
+    int           d_tx_seqno;
+    int                d_next_rid;
+    unsigned int  d_num_rx_frames;
+    unsigned int  d_num_rx_lost;
+    unsigned int  d_num_rx_bytes;
+    
+  public:
+    impl(const std::string &ifc, const std::string &addr);
+    ~impl();
+    
+    static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
+    void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
+    void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
+                      int word0_flags, int chan, uint32_t timestamp);
+    void bg_loop();
+    void stop_bg();
+    bool set_rx_gain(double gain);
+    bool set_rx_freq(double frequency, usrp2_tune_result *result);
+    bool set_rx_decim(int decimation_factor);
+    bool set_rx_scale_iq(int scale_i, int scale_q);
+    bool start_rx_streaming(unsigned int items_per_frame);
+    bool stop_rx_streaming();
+    
+    virtual unsigned int operator()(const void *base, unsigned int len);
+  };
+  
+} // namespace usrp2
+
+#endif /* INCLUDED_USRP2_IMPL_H */

Added: usrp2/trunk/host-ng/lib/usrp2_thread.cc
===================================================================
--- usrp2/trunk/host-ng/lib/usrp2_thread.cc                             (rev 0)
+++ usrp2/trunk/host-ng/lib/usrp2_thread.cc     2008-06-15 04:00:18 UTC (rev 
8591)
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "usrp2_thread.h"
+#include "usrp2_impl.h"
+#include <iostream>
+
+#define USRP2_THREAD_DEBUG 1
+
+namespace usrp2 {
+
+  usrp2_thread::usrp2_thread(usrp2::impl *u2) :
+    omni_thread(NULL, PRIORITY_HIGH),
+    d_u2(u2)
+  {
+  }
+  
+  usrp2_thread::~usrp2_thread()
+  {
+    // we don't own this, just forget it
+    d_u2 = 0;
+  }
+  
+  void
+  usrp2_thread::start()
+  {
+    if (USRP2_THREAD_DEBUG)
+      std::cerr << "usrp2_thread::start() "
+               << this << std::endl;
+    
+    start_undetached();
+  }
+  
+  void *
+  usrp2_thread::run_undetached(void *arg)
+  {
+#if 0
+    // FIXME hoist this from gnuradio-core into another library.
+    gr_rt_status_t rt = gr_enable_realtime_scheduling();
+    if (rt != RT_OK)
+      std::cerr << "failed to enable realtime scheduling\n";
+#endif
+    
+    // This is the first code to run in the new thread context.
+    d_u2->bg_loop();
+    
+    return 0;
+  }
+
+} // namespace usrp2
+

Modified: usrp2/trunk/host-ng/lib/usrp2_thread.h
===================================================================
--- usrp2/trunk/host-ng/lib/usrp2_thread.h      2008-06-14 22:25:28 UTC (rev 
8590)
+++ usrp2/trunk/host-ng/lib/usrp2_thread.h      2008-06-15 04:00:18 UTC (rev 
8591)
@@ -24,25 +24,24 @@
 #define INCLUDED_USRP2_THREAD_H
 
 #include <omnithread.h>
+#include <usrp2_impl.h>
 
 namespace usrp2 {
 
-class usrp2::impl;
-
-class usrp2_thread : public omni_thread
-{
-private:
-  usrp2::impl *d_u2;    
-
-public:
-  usrp2_thread(usrp2::impl *u2);
-  ~usrp2_thread();
-
-  void start();
-
-  virtual void *run_undetached(void *arg);
-};
-
+  class usrp2_thread : public omni_thread
+  {
+  private:
+    usrp2::impl *d_u2;    
+    
+  public:
+    usrp2_thread(usrp2::impl *u2);
+    ~usrp2_thread();
+    
+    void start();
+    
+    virtual void *run_undetached(void *arg);
+  };
+  
 } // namespace usrp2
 
 #endif /* INCLUDED_USRP2_THREAD_H */





reply via email to

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