Skip to content

Commit

Permalink
Add random_mac feature
Browse files Browse the repository at this point in the history
- Implement random_mac feature to generate a random MAC address on startup.
- Use `cargo run --features random_mac` to enable the random MAC address functionality.
- This feature facilitates logging out of the BUPT-portal for debugging and development purposes.

Signed-off-by: YouXam <[email protected]>
  • Loading branch information
YouXam committed May 19, 2024
1 parent 6e0dcfc commit 3f3f8b2
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ alloc = ["esp-idf-svc/alloc"]
nightly = ["esp-idf-svc/nightly"]
experimental = ["esp-idf-svc/experimental"]
embassy = ["esp-idf-svc/embassy-sync", "esp-idf-svc/critical-section", "esp-idf-svc/embassy-time-driver"]
random_mac = ["rand"]

[dependencies]
log = { version = "0.4", default-features = false }
Expand All @@ -41,6 +42,7 @@ embedded-svc = "0.27.1"
urlencoding = "2.1.3"
include_dir = "0.7.3"
serde_json = "1.0.117"
rand = { version = "0.8.5", optional = true }

[patch.crates-io]
esp-idf-svc = { git = "https://github.com/YouXam/esp-idf-svc.git", branch = "fix-http-error-handling" }
Expand Down
79 changes: 72 additions & 7 deletions frontend/src/components/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,69 @@
import Loading from "../assets/loading.svg"
import { useState } from "preact/hooks"
import { useState, useRef } from "preact/hooks"

export default function Component() {
const [loading, setLoading] = useState(false)
const usernameRef = useRef(null)
const passwordRef = useRef(null)
const [errorMsg, setErrorMsg] = useState('')
const [loggedIn, setLoggedIn] = useState(false)

async function submit(e) {
e.preventDefault()
setLoading(true)
try {
const response = await fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `username=${encodeURIComponent(usernameRef.current.value)}&password=${encodeURIComponent(passwordRef.current.value)}`
})
const result = await response.json()
if (result.code) {
setErrorMsg(result.message)
} else {
setLoggedIn(true)
}
} catch (error) {
console.error(error)
setErrorMsg('连接失败: ' + error.message)
} finally {
setLoading(false)
}
}

if (loggedIn) {
return (
<div className="min-h-[75vh] flex flex-col items-center justify-center px-4 py-12">
<div className="w-full max-w-md space-y-8">
<div className="text-center">
<svg
className="mx-auto h-24 w-24 text-green-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M5 13l4 4L19 7"
></path>
</svg>
<h1 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-gray-50">
登录成功
</h1>
<p className="mt-2 text-xs text-gray-600 dark:text-gray-400">
现在您可以断开 BYR-pet Wi-Fi 连接
</p>
</div>
</div>
</div>
)
}

return (
<>
<div className="min-h-[75vh] flex flex-col items-center justify-center px-4 py-12">
Expand All @@ -15,8 +76,11 @@ export default function Component() {
输入学号和校园网密码以连接 BUPT-portal
</p>
</div>
<form className="space-y-6" action="/login" method="post">
<div className="space-y-6">
<div>
{errorMsg && (<div className="text-red-500 dark:text-red-400 text-center text-sm mb-4">
{errorMsg}
</div>)}
<label
htmlFor="username"
className="block text-sm font-medium text-gray-700 dark:text-gray-300"
Expand All @@ -31,6 +95,7 @@ export default function Component() {
className="block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-50 dark:placeholder-gray-500"
type="text"
name="username"
ref={usernameRef}
/>
</div>
</div>
Expand All @@ -49,24 +114,24 @@ export default function Component() {
className="block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 placeholder-gray-400 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-50 dark:placeholder-gray-500"
type="password"
name="password"
ref={passwordRef}
/>
</div>
</div>
<div>
<button
type="submit"
disabled={loading}
onClick={submit}
className="flex w-full justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-indigo-500 dark:hover:bg-indigo-600 dark:focus:ring-indigo-600 disabled:opacity-50 disabled:cursor-not-allowed"
>
{ loading && <img src={Loading} className="w-5 h-5 mr-2 animate-spin" alt="loading" /> }
{ loading ? "登录中..." : "连接 BUPT-portal" }
{loading && <img src={Loading} className="w-5 h-5 mr-2 animate-spin" alt="loading" />}
{loading ? "登录中..." : errorMsg ? "重试" : "连接 BUPT-portal"}
</button>
</div>
</form>
</div>
</div>
</div>
</>


)
}
2 changes: 1 addition & 1 deletion src/net/bupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ fn auth(account: BuptAccount, cookie: String) -> Result<()> {
})
},
);
fatal!("BUPT-portal authentication failed: {}", reason)
fatal!("BUPT-portal 认证失败: {}", reason)
}
},
_ => fatal!("unexpected status code: {}", response.status()),
Expand Down
24 changes: 24 additions & 0 deletions src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ fn connect_wifi_with_config(
NetConfig::NormalWifi(wifi) => (AuthMethod::WPA2Personal, wifi.ssid, wifi.password),
};
let mut esp_wifi = EspWifi::new(modem, sysloop.clone(), Some(nvs))?;

#[cfg(feature = "random_mac")]
{
use esp_idf_svc::wifi::WifiDeviceId;
let mac = generate_random_mac();
log::info!("Generated random MAC: {:02X?}", mac);
esp_wifi.set_mac(WifiDeviceId::Sta, mac)?;
log::info!(
"Set MAC address to {:02X?}",
esp_wifi.get_mac(WifiDeviceId::Sta)?
);
}

let mut wifi = BlockingWifi::wrap(&mut esp_wifi, sysloop)?;

wifi.set_configuration(&Configuration::Client(ClientConfiguration {
Expand Down Expand Up @@ -113,6 +126,17 @@ enum NetConfig {
NormalWifi(Wifi),
}

#[cfg(feature = "random_mac")]
pub fn generate_random_mac() -> [u8; 6] {
use rand::Rng;
let mut rng = rand::thread_rng();
let mut mac = [0u8; 6];
rng.fill(&mut mac);
mac[0] &= 0xFE;
mac[0] &= 0xFD;
mac
}

pub fn connect() -> Result<Box<EspWifi<'static>>> {
set_target_level("wifi", log::LevelFilter::Warn)?;
set_target_level("wifi_init", log::LevelFilter::Warn)?;
Expand Down
20 changes: 15 additions & 5 deletions src/net/provisioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,20 @@ use embedded_svc::http::Headers;
use esp_idf_hal::delay;
use esp_idf_svc::{
eventloop::EspSystemEventLoop,
hal::prelude::Peripherals,
http::{
server::{EspHttpConnection, EspHttpServer, Request},
Method,
},
io::Write,
ipv4::{self, RouterConfiguration},
ipv4::{Mask, Subnet},
netif::{EspNetif, NetifConfiguration, NetifStack},
nvs::EspDefaultNvsPartition,
wifi::{
self, AccessPointConfiguration, AuthMethod, BlockingWifi, ClientConfiguration, EspWifi,
},
};
use esp_idf_svc::{
hal::prelude::Peripherals,
ipv4::{self, RouterConfiguration},
netif::{EspNetif, NetifConfiguration, NetifStack},
};

use include_dir::{include_dir, Dir};

Expand Down Expand Up @@ -218,6 +216,18 @@ fn setup_ap() -> anyhow::Result<Box<EspWifi<'static>>> {
custom_mac: None,
})?)?;

#[cfg(feature = "random_mac")]
{
use esp_idf_svc::wifi::WifiDeviceId;
let mac = super::generate_random_mac();
log::info!("Generated random MAC: {:02X?}", mac);
esp_wifi.set_mac(WifiDeviceId::Sta, mac)?;
log::info!(
"Set MAC address to {:02X?}",
esp_wifi.get_mac(WifiDeviceId::Sta)?
);
}

let mut wifi = BlockingWifi::wrap(&mut esp_wifi, sys_loop)?;

let wifi_configuration = wifi::Configuration::Mixed(
Expand Down

0 comments on commit 3f3f8b2

Please sign in to comment.