From 8be3b883f5b1a889f4f07611e8954449cc07c2b3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 16 Mar 2010 13:49:39 -0700 Subject: Added ability to set the subdevices in use for rx and tx dboards. This is used to calculate and set the ddc and duc muxes. Also, minor fix for burning addrs (wrong pointer....) --- firmware/microblaze/lib/ethernet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'firmware/microblaze/lib') diff --git a/firmware/microblaze/lib/ethernet.c b/firmware/microblaze/lib/ethernet.c index 757a36ce4..0e731c68c 100644 --- a/firmware/microblaze/lib/ethernet.c +++ b/firmware/microblaze/lib/ethernet.c @@ -316,7 +316,7 @@ ethernet_mac_addr(void) bool ethernet_set_mac_addr(const eth_mac_addr_t *t) { - bool ok = eeprom_write(I2C_ADDR_MBOARD, MBOARD_MAC_ADDR, &t, sizeof(eth_mac_addr_t)); + bool ok = eeprom_write(I2C_ADDR_MBOARD, MBOARD_MAC_ADDR, t, sizeof(eth_mac_addr_t)); if (ok){ src_mac_addr = *t; src_mac_addr_initialized = true; @@ -356,7 +356,7 @@ const struct ip_addr *get_ip_addr(void) } bool set_ip_addr(const struct ip_addr *t){ - bool ok = eeprom_write(I2C_ADDR_MBOARD, MBOARD_IP_ADDR, &t, sizeof(struct ip_addr)); + bool ok = eeprom_write(I2C_ADDR_MBOARD, MBOARD_IP_ADDR, t, sizeof(struct ip_addr)); if (ok){ src_ip_addr = *t; src_ip_addr_initialized = true; -- cgit v1.2.3 From 6458eca9540f11fb8dd5bee184e6124998023c4f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 16 Mar 2010 17:54:54 -0700 Subject: 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. --- firmware/microblaze/apps/txrx.c | 30 ++++++++++++++-------- firmware/microblaze/lib/ethernet.c | 2 +- firmware/microblaze/lib/net_common.c | 23 ++++++++--------- firmware/microblaze/lib/net_common.h | 13 ++-------- host/apps/usrp2_burner.cpp | 1 + host/apps/usrp2_recovery.py | 50 ++++++++++++++++++++++++++++++++++++ host/lib/device.cpp | 4 +-- host/lib/transport/udp_simple.cpp | 2 +- 8 files changed, 86 insertions(+), 39 deletions(-) create mode 100755 host/apps/usrp2_recovery.py (limited to 'firmware/microblaze/lib') 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)); } -- cgit v1.2.3