summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-03-16 17:54:54 -0700
committerJosh Blum <josh@joshknows.com>2010-03-16 17:54:54 -0700
commit6458eca9540f11fb8dd5bee184e6124998023c4f (patch)
tree17d69f06e918b346e50e4b3aad24a1da071fd2cf
parent52dc73891474827a9c686f73cbfe70618a2dd6e4 (diff)
downloaduhd-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.c30
-rw-r--r--firmware/microblaze/lib/ethernet.c2
-rw-r--r--firmware/microblaze/lib/net_common.c23
-rw-r--r--firmware/microblaze/lib/net_common.h13
-rw-r--r--host/apps/usrp2_burner.cpp1
-rwxr-xr-xhost/apps/usrp2_recovery.py50
-rw-r--r--host/lib/device.cpp4
-rw-r--r--host/lib/transport/udp_simple.cpp2
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));
}