support setting IP address via web interface

This commit is contained in:
Sebastien Bourdeauducq 2017-08-08 11:05:09 +08:00
parent 1a06b524d2
commit 5c1cacbd38
3 changed files with 70 additions and 3 deletions

View File

@ -11,7 +11,7 @@ use core::cell::{Cell, RefCell};
use core::fmt; use core::fmt;
use cortex_m::interrupt::Mutex; use cortex_m::interrupt::Mutex;
use smoltcp::Error; use smoltcp::Error;
use smoltcp::wire::{EthernetAddress, IpAddress}; use smoltcp::wire::EthernetAddress;
use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface}; use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface};
use smoltcp::socket::{AsSocket, SocketSet}; use smoltcp::socket::{AsSocket, SocketSet};
use smoltcp::socket::{TcpSocket, TcpSocketBuffer}; use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
@ -156,7 +156,7 @@ fn main() {
println!("programmed MAC address is invalid, using default"); println!("programmed MAC address is invalid, using default");
hardware_addr = EthernetAddress([0x10, 0xE2, 0xD5, 0x00, 0x03, 0x00]); hardware_addr = EthernetAddress([0x10, 0xE2, 0xD5, 0x00, 0x03, 0x00]);
} }
let mut protocol_addrs = [IpAddress::v4(192, 168, 69, 1)]; let mut protocol_addrs = [config.ip];
println!("MAC {} IP {}", hardware_addr, protocol_addrs[0]); println!("MAC {} IP {}", hardware_addr, protocol_addrs[0]);
let mut arp_cache_entries: [_; 8] = Default::default(); let mut arp_cache_entries: [_; 8] = Default::default();
let mut arp_cache = SliceArpCache::new(&mut arp_cache_entries[..]); let mut arp_cache = SliceArpCache::new(&mut arp_cache_entries[..]);
@ -220,7 +220,7 @@ fn main() {
match request_status { match request_status {
Ok(true) => { Ok(true) => {
if socket.can_send() { if socket.can_send() {
pages::serve(socket, &request, &LOOP_ANODE, &LOOP_CATHODE, &ELECTROMETER); pages::serve(socket, &request, &mut config, &LOOP_ANODE, &LOOP_CATHODE, &ELECTROMETER);
} }
request.reset(); request.reset();
socket.close(); socket.close();

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<title>ionpak</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<body>
<div class="w3-sidebar w3-light-grey w3-bar-block" style="width:15%">
<h3 class="w3-bar-item"><img src="logo.svg"></h3>
<a href="/" class="w3-bar-item w3-button">Measure</a>
<a href="/gauge_settings.html" class="w3-bar-item w3-button">Gauge settings</a>
<a href="/network_settings.html" class="w3-bar-item w3-button">Network settings</a>
<a href="/firmware.html" class="w3-bar-item w3-button">Firmware</a>
</div>
<div style="margin-left:15%">
<div class="w3-container w3-teal">
<h1>Network settings</h1>
</div>
<div class="w3-container">
<p>{status}</p>
</div>
<div class="w3-container">
<form class="w3-container w3-card-4" method="GET">
<p>
<label>IP address</label>
<input class="w3-input w3-border" name="ip" type="text" value="{ip}"></p>
<p>
<button class="w3-btn w3-blue">Update</button></p>
</form>
</div>
</div>
</body>
</html>

View File

@ -1,11 +1,13 @@
use core::fmt; use core::fmt;
use core::fmt::Write; use core::fmt::Write;
use core::cell::RefCell; use core::cell::RefCell;
use core::str;
use cortex_m; use cortex_m;
use cortex_m::interrupt::Mutex; use cortex_m::interrupt::Mutex;
use smoltcp::socket::TcpSocket; use smoltcp::socket::TcpSocket;
use http; use http;
use config;
use loop_anode; use loop_anode;
use loop_cathode; use loop_cathode;
use electrometer; use electrometer;
@ -31,6 +33,7 @@ impl fmt::LowerExp for OpnFmt {
} }
pub fn serve(output: &mut TcpSocket, request: &http::Request, pub fn serve(output: &mut TcpSocket, request: &http::Request,
config: &mut config::Config,
loop_anode_m: &Mutex<RefCell<loop_anode::Controller>>, loop_anode_m: &Mutex<RefCell<loop_anode::Controller>>,
loop_cathode_m: &Mutex<RefCell<loop_cathode::Controller>>, loop_cathode_m: &Mutex<RefCell<loop_cathode::Controller>>,
electrometer_m: &Mutex<RefCell<electrometer::Electrometer>>) { electrometer_m: &Mutex<RefCell<electrometer::Electrometer>>) {
@ -61,6 +64,31 @@ pub fn serve(output: &mut TcpSocket, request: &http::Request,
cathode_fbv=OpnFmt(cathode.fbv), cathode_fbv=OpnFmt(cathode.fbv),
ion_current=OpnFmt(electrometer.ic.and_then(|x| Some(x*1.0e9)))).unwrap(); ion_current=OpnFmt(electrometer.ic.and_then(|x| Some(x*1.0e9)))).unwrap();
}, },
b"/network_settings.html" => {
let mut status = "";
let ip_arg = request.get_arg(b"ip");
if ip_arg.is_ok() {
let ip_arg = str::from_utf8(ip_arg.unwrap());
if ip_arg.is_ok() {
let ip = ip_arg.unwrap().parse();
if ip.is_ok() {
let ip = ip.unwrap();
status = "IP address has been updated and will be active after a reboot.";
config.ip = ip;
config.save();
} else {
status = "failed to parse IP address";
}
} else {
status = "IP address contains an invalid UTF-8 character";
}
}
http::write_reply_header(output, 200, "text/html; charset=utf-8", false).unwrap();
write!(output, include_str!("network_settings.html"),
status=status, ip=config.ip).unwrap();
},
b"/firmware.html" => { b"/firmware.html" => {
http::write_reply_header(output, 200, "text/html; charset=utf-8", false).unwrap(); http::write_reply_header(output, 200, "text/html; charset=utf-8", false).unwrap();
write!(output, include_str!("firmware.html"), write!(output, include_str!("firmware.html"),