diff options
| author | Josh Blum <josh@joshknows.com> | 2010-03-16 17:54:54 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2010-03-16 17:54:54 -0700 | 
| commit | 6458eca9540f11fb8dd5bee184e6124998023c4f (patch) | |
| tree | 17d69f06e918b346e50e4b3aad24a1da071fd2cf | |
| parent | 52dc73891474827a9c686f73cbfe70618a2dd6e4 (diff) | |
| download | uhd-6458eca9540f11fb8dd5bee184e6124998023c4f.tar.gz uhd-6458eca9540f11fb8dd5bee184e6124998023c4f.tar.bz2 uhd-6458eca9540f11fb8dd5bee184e6124998023c4f.zip | |
Added recovery app to use raw socket to burn known ip addr.
Fixed up fw so the device can reply after new addrs are set.
| -rw-r--r-- | firmware/microblaze/apps/txrx.c | 30 | ||||
| -rw-r--r-- | firmware/microblaze/lib/ethernet.c | 2 | ||||
| -rw-r--r-- | firmware/microblaze/lib/net_common.c | 23 | ||||
| -rw-r--r-- | firmware/microblaze/lib/net_common.h | 13 | ||||
| -rw-r--r-- | host/apps/usrp2_burner.cpp | 1 | ||||
| -rwxr-xr-x | host/apps/usrp2_recovery.py | 50 | ||||
| -rw-r--r-- | host/lib/device.cpp | 4 | ||||
| -rw-r--r-- | host/lib/transport/udp_simple.cpp | 2 | 
8 files changed, 86 insertions, 39 deletions
| diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c index 8949f1263..b82c7702b 100644 --- a/firmware/microblaze/apps/txrx.c +++ b/firmware/microblaze/apps/txrx.c @@ -148,14 +148,6 @@ static struct socket_address fp_socket_src, fp_socket_dst;  void start_rx_streaming_cmd(void);  void stop_rx_cmd(void); -static eth_mac_addr_t get_my_eth_mac_addr(void){ -    return *ethernet_mac_addr(); -} - -static struct ip_addr get_my_ip_addr(void){ -    return *get_ip_addr(); -} -  static void print_ip_addr(const void *t){      uint8_t *p = (uint8_t *)t;      printf("%d.%d.%d.%d", p[0], p[1], p[2], p[3]); @@ -166,7 +158,7 @@ void handle_udp_data_packet(      unsigned char *payload, int payload_len  ){      //its a tiny payload, load the fast-path variables -    fp_mac_addr_src = get_my_eth_mac_addr(); +    fp_mac_addr_src = *ethernet_mac_addr();      arp_cache_lookup_mac(&src.addr, &fp_mac_addr_dst);      fp_socket_src = dst;      fp_socket_dst = src; @@ -540,6 +532,21 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)        ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[0] != 0)    ) return false; +  //test if its an ip recovery packet +  typedef struct{ +      padded_eth_hdr_t eth_hdr; +      char code[4]; +      union { +        struct ip_addr ip_addr; +      } data; +  }recovery_packet_t; +  recovery_packet_t *recovery_packet = (recovery_packet_t *)buff; +  if (recovery_packet->eth_hdr.ethertype == 0xbeee && strncmp(recovery_packet->code, "addr", 4) == 0){ +      printf("Got ip recovery packet: "); print_ip_addr(&recovery_packet->data.ip_addr); newline(); +      set_ip_addr(&recovery_packet->data.ip_addr); +      return true; +  } +    //pass it to the slow-path handler    size_t len = buffer_pool_status->last_line[bufno] - 3;    handle_eth_packet(buff, len); @@ -737,8 +744,9 @@ main(void)    ethernet_register_link_changed_callback(link_changed_callback);    ethernet_init(); -  register_get_eth_mac_addr(get_my_eth_mac_addr); -  register_get_ip_addr(get_my_ip_addr); +  register_mac_addr(ethernet_mac_addr()); +  register_ip_addr(get_ip_addr()); +    register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet);    register_udp_listener(USRP2_UDP_DATA_PORT, handle_udp_data_packet); diff --git a/firmware/microblaze/lib/ethernet.c b/firmware/microblaze/lib/ethernet.c index 0e731c68c..34a3ad7c1 100644 --- a/firmware/microblaze/lib/ethernet.c +++ b/firmware/microblaze/lib/ethernet.c @@ -320,7 +320,7 @@ ethernet_set_mac_addr(const eth_mac_addr_t *t)    if (ok){      src_mac_addr = *t;      src_mac_addr_initialized = true; -    eth_mac_set_addr(t); +    //eth_mac_set_addr(t); //this breaks the link    }    return ok; diff --git a/firmware/microblaze/lib/net_common.c b/firmware/microblaze/lib/net_common.c index 693502d18..67a3ff964 100644 --- a/firmware/microblaze/lib/net_common.c +++ b/firmware/microblaze/lib/net_common.c @@ -51,16 +51,14 @@ ip_addr_eq(const struct ip_addr a, const struct ip_addr b)  // ------------------------------------------------------------------------ -get_eth_mac_addr_t _get_eth_mac_addr = NULL; - -void register_get_eth_mac_addr(get_eth_mac_addr_t get_eth_mac_addr){ -    _get_eth_mac_addr = get_eth_mac_addr; +static eth_mac_addr_t _local_mac_addr; +void register_mac_addr(const eth_mac_addr_t *mac_addr){ +    _local_mac_addr = *mac_addr;  } -get_ip_addr_t _get_ip_addr = NULL; - -void register_get_ip_addr(get_ip_addr_t get_ip_addr){ -    _get_ip_addr = get_ip_addr; +static struct ip_addr _local_ip_addr; +void register_ip_addr(const struct ip_addr *ip_addr){ +    _local_ip_addr = *ip_addr;  }  //------------------------------------------------------------------------- @@ -140,7 +138,7 @@ send_pkt(eth_mac_addr_t dst, int ethertype,    padded_eth_hdr_t	ehdr;    ehdr.pad = 0;    ehdr.dst = dst; -  ehdr.src = _get_eth_mac_addr(); +  ehdr.src = _local_mac_addr;    ehdr.ethertype = ethertype;    uint32_t *p = buffer_ram(CPU_TX_BUF); @@ -218,7 +216,6 @@ send_ip_pkt(struct ip_addr dst, int protocol,  	    const void *buf0, size_t len0,  	    const void *buf1, size_t len1)  { -  struct ip_addr src = _get_ip_addr();    int ttl = 32;    struct ip_hdr ip; @@ -228,7 +225,7 @@ send_ip_pkt(struct ip_addr dst, int protocol,    IPH_OFFSET_SET(&ip, IP_DF);	/* don't fragment */    ip._ttl_proto = (ttl << 8) | (protocol & 0xff);    ip._chksum = 0; -  ip.src = src; +  ip.src = _local_ip_addr;    ip.dest = dst;    ip._chksum = ~chksum_buffer((unsigned short *) &ip, @@ -373,8 +370,8 @@ handle_arp_packet(struct arp_eth_ipv4 *p, size_t size)    sip.addr = get_int32(p->ar_sip);    tip.addr = get_int32(p->ar_tip); -  if (ip_addr_eq(tip, _get_ip_addr())){	// They're looking for us... -    send_arp_reply(p, _get_eth_mac_addr()); +  if (ip_addr_eq(tip, _local_ip_addr)){	// They're looking for us... +    send_arp_reply(p, _local_mac_addr);    }  } diff --git a/firmware/microblaze/lib/net_common.h b/firmware/microblaze/lib/net_common.h index 6cd45bf69..112669b46 100644 --- a/firmware/microblaze/lib/net_common.h +++ b/firmware/microblaze/lib/net_common.h @@ -33,21 +33,12 @@ extern dbsm_t *ac_could_be_sending_to_eth;  void stop_streaming(void); -/*! - * Helpful typedefs for callback - */  typedef void (*udp_receiver_t)(struct socket_address src, struct socket_address dst,  			       unsigned char *payload, int payload_len); -typedef eth_mac_addr_t (*get_eth_mac_addr_t)(void); -typedef struct ip_addr (*get_ip_addr_t)(void); - -/*! - * Functions to register callbacks - */ -void register_get_eth_mac_addr(get_eth_mac_addr_t get_eth_mac_addr); +void register_mac_addr(const eth_mac_addr_t *mac_addr); -void register_get_ip_addr(get_ip_addr_t get_ip_addr); +void register_ip_addr(const struct ip_addr *ip_addr);  void register_udp_listener(int port, udp_receiver_t rcvr); diff --git a/host/apps/usrp2_burner.cpp b/host/apps/usrp2_burner.cpp index 08ec8daf9..941e71d0c 100644 --- a/host/apps/usrp2_burner.cpp +++ b/host/apps/usrp2_burner.cpp @@ -79,5 +79,6 @@ int main(int argc, char *argv[]){          std::cout << "  Done" << std::endl;      } +    std::cout << "Power-cycle the usrp2 for the changes to take effect." << std::endl;      return 0;  } diff --git a/host/apps/usrp2_recovery.py b/host/apps/usrp2_recovery.py new file mode 100755 index 000000000..00d231cdb --- /dev/null +++ b/host/apps/usrp2_recovery.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +""" +The usrp2 recovery app: + +When the usrp2 has an unknown or bad ip address in its eeprom, +it may not be possible to communicate with the usrp2 over ip/udp. + +This app will send a raw ethernet packet to bypass the ip layer. +The packet will contain a known ip address to burn into eeprom. +Because the recovery packet is sent with a broadcast mac address, +only one usrp2 should be present on the interface upon execution. + +This app requires super-user privileges and only works on linux.  +""" + +import socket +import struct +import optparse + +BCAST_MAC_ADDR = 'ff:ff:ff:ff:ff:ff' +RECOVERY_ETHERTYPE = 0xbeee +IP_RECOVERY_CODE = 'addr' + +def mac_addr_repr_to_binary_string(mac_addr): +    return ''.join(map(lambda x: chr(int(x, 16)), mac_addr.split(':'))) + +if __name__ == '__main__': +    parser = optparse.OptionParser() +    parser.add_option('--ifc', type='string', help='ethernet interface name [default=%default]', default='eth0') +    parser.add_option('--new-ip', type='string', help='ip address to set [default=%default]', default='192.168.10.2') +    (options, args) = parser.parse_args() + +    #create the raw socket +    print "Opening raw socket on interface: ", options.ifc +    soc = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) +    soc.bind((options.ifc, RECOVERY_ETHERTYPE)) + +    #create the recovery packet +    print "Loading packet with new ip address: ", options.new_ip +    packet = struct.pack( +        '!6s6sH4s4s', +        mac_addr_repr_to_binary_string(BCAST_MAC_ADDR), +        mac_addr_repr_to_binary_string(BCAST_MAC_ADDR), +        RECOVERY_ETHERTYPE, +        IP_RECOVERY_CODE, +        socket.inet_aton(options.new_ip), +    ) +    soc.send(packet) +    print "Done" diff --git a/host/lib/device.cpp b/host/lib/device.cpp index a87ba83eb..897084427 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -109,14 +109,14 @@ device::sptr device::make(const device_addr_t &hint, size_t which){      //check that we found any devices      if (dev_addr_makers.size() == 0){          throw std::runtime_error(str( -            boost::format("No devices found for %s") % device_addr::to_string(hint) +            boost::format("No devices found for ----->\n%s") % device_addr::to_string(hint)          ));      }      //check that the which index is valid      if (dev_addr_makers.size() <= which){          throw std::runtime_error(str( -            boost::format("No device at index %d for %s") % which % device_addr::to_string(hint) +            boost::format("No device at index %d for ----->\n%s") % which % device_addr::to_string(hint)          ));      } diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index 7004bdfdf..3c8ecb70d 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -38,7 +38,7 @@ static void reasonable_recv_timeout(      boost::asio::ip::udp::socket &socket  ){      boost::asio::deadline_timer timer(socket.get_io_service()); -    timer.expires_from_now(boost::posix_time::milliseconds(50)); +    timer.expires_from_now(boost::posix_time::milliseconds(100));      while (not (socket.available() or timer.expires_from_now().is_negative())){          boost::this_thread::sleep(boost::posix_time::milliseconds(1));      } | 
