scan wireless networks & publish over ble
does not actually connect yet
This commit is contained in:
+41
-8
@@ -3,26 +3,59 @@ import readline
|
||||
import rlcompleter
|
||||
import asyncio
|
||||
from bleak import BleakClient,BleakScanner
|
||||
import sys
|
||||
|
||||
readline.parse_and_bind("tab: complete")
|
||||
|
||||
address = "FF:E4:05:1A:8F:FF"
|
||||
CURRENT_INDEX_UUID = "76be25c2-0803-44fc-a97c-bcb56c69c926"
|
||||
|
||||
UUIDS = {
|
||||
'connection_state': "76be25c2-0801-44fc-a97c-bcb56c69c926",
|
||||
'max_index': "76be25c2-0802-44fc-a97c-bcb56c69c926",
|
||||
'current_index': "76be25c2-0803-44fc-a97c-bcb56c69c926",
|
||||
'current_network': "76be25c2-0804-44fc-a97c-bcb56c69c926",
|
||||
'secret': "76be25c2-0805-44fc-a97c-bcb56c69c926",
|
||||
}
|
||||
|
||||
networks = []
|
||||
max_index = 0
|
||||
|
||||
async def show_networks(client):
|
||||
global max_index
|
||||
global networks
|
||||
max_index = ord(await client.read_gatt_char(UUIDS['max_index']))
|
||||
print(f"{max_index} networks available")
|
||||
networks = [None]
|
||||
|
||||
for i in range(1, max_index + 1):
|
||||
await client.write_gatt_char(UUIDS['current_index'], bytes([i]))
|
||||
current_network = await client.read_gatt_char(UUIDS['current_network'])
|
||||
networks.append(current_network)
|
||||
print(f"{i}: {current_network}")
|
||||
|
||||
async def choose_network(client, name):
|
||||
for i in range(1, max_index + 1):
|
||||
if networks[i].find(name) >= 0:
|
||||
print(f"found {name} in {networks[i]}")
|
||||
chosen = i
|
||||
break
|
||||
if chosen:
|
||||
await client.write_gatt_char(UUIDS['current_index'], bytes([chosen]))
|
||||
new_index = await client.read_gatt_char(UUIDS['current_index'])
|
||||
print(f"set to {new_index[0]}")
|
||||
|
||||
|
||||
async def main(address):
|
||||
print("go")
|
||||
preferred = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
print(f"choose {preferred}")
|
||||
devices = await BleakScanner.discover()
|
||||
for d in devices:
|
||||
print(d)
|
||||
|
||||
async with BleakClient(address, timeout=30) as client:
|
||||
current_index = await client.read_gatt_char(CURRENT_INDEX_UUID)
|
||||
print(f"Model Number: {current_index}")
|
||||
current_index = ord(current_index) + 1
|
||||
await client.write_gatt_char(CURRENT_INDEX_UUID, bytes([current_index]))
|
||||
current_index = await client.read_gatt_char(CURRENT_INDEX_UUID)
|
||||
print(f"Model Number: {current_index}")
|
||||
await show_networks(client)
|
||||
if preferred != None:
|
||||
await choose_network(client, preferred.encode(encoding="utf-8"))
|
||||
|
||||
|
||||
asyncio.run(main(address))
|
||||
|
||||
+29
-6
@@ -10,6 +10,7 @@ use esp_backtrace as _;
|
||||
use esp_println as _;
|
||||
use esp_alloc as _;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub mod ecu;
|
||||
pub mod wifi;
|
||||
@@ -27,15 +28,19 @@ use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join3;
|
||||
use embassy_time::Timer;
|
||||
|
||||
use esp_radio::Controller;
|
||||
use esp_radio::{
|
||||
Controller,
|
||||
wifi::{
|
||||
ClientConfig,
|
||||
ModeConfig,
|
||||
}
|
||||
};
|
||||
|
||||
use log::{info};
|
||||
|
||||
use crate::ecu::Ecu;
|
||||
use crate::ota::Flasher;
|
||||
|
||||
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
// This creates a default app-descriptor required by the esp-idf bootloader.
|
||||
@@ -86,13 +91,31 @@ async fn main(s : Spawner) {
|
||||
let esp_radio_ctrl = // esp_radio::init().expect("esp_radio init failed");
|
||||
&*mk_static!(Controller<'static>, esp_radio::init().unwrap());
|
||||
|
||||
let (mut wifi_controller, interfaces) =
|
||||
esp_radio::wifi::new(esp_radio_ctrl, peripherals.WIFI, Default::default()).unwrap();
|
||||
let wifi_interface = interfaces.sta;
|
||||
let station_config = ModeConfig::Client(ClientConfig::default());
|
||||
wifi_controller.set_config(&station_config).expect("can't config wifi");
|
||||
wifi_controller.start_async().await.expect("wifi failed to start");
|
||||
|
||||
let wifi_networks : Vec<[u8;40]> =
|
||||
crate::wifi::scan_networks(&mut wifi_controller).await.into_iter().map(
|
||||
|ap| {
|
||||
let mut s : [u8; 40] = [0u8; 40];
|
||||
s[0] = (ap.signal_strength & 0x7f) as u8;
|
||||
s[1..7].copy_from_slice(&ap.bssid);
|
||||
let name = ap.ssid.as_bytes();
|
||||
s[8..(8+name.len())].copy_from_slice(name);
|
||||
s
|
||||
}
|
||||
).collect();
|
||||
|
||||
join3(
|
||||
crate::wifi::start_wifi(&s,
|
||||
esp_radio_ctrl,
|
||||
wifi_controller, wifi_interface,
|
||||
flasher,
|
||||
peripherals.WIFI,
|
||||
&mut ecu),
|
||||
wibble::run_ble(&esp_radio_ctrl, peripherals.BT),
|
||||
wibble::run_ble(&esp_radio_ctrl, peripherals.BT, wifi_networks),
|
||||
async {
|
||||
loop {
|
||||
Timer::after_millis(1000).await;
|
||||
|
||||
+27
-8
@@ -6,7 +6,7 @@ use log::{warn,info};
|
||||
use embassy_futures::join::join;
|
||||
use embassy_futures::select::select;
|
||||
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// Max number of connections
|
||||
const CONNECTIONS_MAX: usize = 1;
|
||||
@@ -48,7 +48,8 @@ struct WifiProvisioningService {
|
||||
|
||||
|
||||
pub async fn run_ble(radio_init: &RadioController<'static>,
|
||||
peripheral: esp_hal::peripherals::BT<'_>) {
|
||||
peripheral: esp_hal::peripherals::BT<'_>,
|
||||
networks: Vec<[u8; 40]>) {
|
||||
// let radio_init = esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller");
|
||||
let connector = BleConnector::new(&radio_init, peripheral, Default::default()).expect("connector");
|
||||
let controller: ExternalController<_, 20> = ExternalController::new(connector);
|
||||
@@ -78,7 +79,7 @@ pub async fn run_ble(radio_init: &RadioController<'static>,
|
||||
match advertise("Eculocate", &mut peripheral, &server).await {
|
||||
Ok(conn) => {
|
||||
// set up tasks when the connection is established to a central, so they don't run when no one is connected.
|
||||
let a = gatt_events_task(&server, &conn);
|
||||
let a = gatt_events_task(&server, &conn, &networks);
|
||||
let b = custom_task(&server, &conn, &stack);
|
||||
// run until any task ends (usually because the connection has been closed),
|
||||
// then return to advertising state.
|
||||
@@ -107,8 +108,16 @@ async fn ble_task<C: Controller, P: PacketPool>(mut runner: Runner<'_, C, P>) {
|
||||
///
|
||||
/// This function will handle the GATT events and process them.
|
||||
/// This is how we interact with read and write requests.
|
||||
async fn gatt_events_task<P: PacketPool>(server: &Server<'_>, conn: &GattConnection<'_, '_, P>) -> Result<(), Error> {
|
||||
let current_index = server.wifi_provisioning_service.current_network_index;
|
||||
async fn gatt_events_task<P: PacketPool>(server: &Server<'_>,
|
||||
conn: &GattConnection<'_, '_, P>,
|
||||
networks: &Vec<[u8; 40]> ) -> Result<(), Error> {
|
||||
let wps = &server.wifi_provisioning_service;
|
||||
for ap in networks {
|
||||
info!("ap {:?}", ap)
|
||||
};
|
||||
let max_index : u8 = (networks.len() & 0xff).try_into().unwrap();
|
||||
server.set(&wps.max_network_index, &max_index);
|
||||
let current_index = wps.current_network_index;
|
||||
let reason = loop {
|
||||
match conn.next().await {
|
||||
GattConnectionEvent::Disconnected { reason } => break reason,
|
||||
@@ -123,10 +132,20 @@ async fn gatt_events_task<P: PacketPool>(server: &Server<'_>, conn: &GattConnect
|
||||
// }
|
||||
// }
|
||||
GattEvent::Write(event) => {
|
||||
info!("[gatt] write handle {:?}", event.handle());
|
||||
info!("[gatt] write handle {:?} {:?}", event.handle(),
|
||||
event.data());
|
||||
if event.handle() == current_index.handle {
|
||||
info!("[gatt] switch current index: {:?}", event.data());
|
||||
}
|
||||
let i = (event.data()[0]) as usize;
|
||||
info!("[gatt] switch current index: {:?}", i);
|
||||
if i == 0 {
|
||||
server.set(&wps.current_network, &[0u8;40]);
|
||||
} else if i <= networks.len() {
|
||||
server.set(&wps.current_network,
|
||||
&(networks[i - 1]));
|
||||
} else {
|
||||
warn!("index {:?} out of range", i);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
|
||||
+13
-20
@@ -28,7 +28,7 @@ use esp_hal::{
|
||||
};
|
||||
use esp_println::println;
|
||||
use esp_radio::{
|
||||
Controller,
|
||||
// Controller,
|
||||
wifi::{
|
||||
ClientConfig,
|
||||
ModeConfig,
|
||||
@@ -37,6 +37,7 @@ use esp_radio::{
|
||||
WifiDevice,
|
||||
WifiEvent,
|
||||
WifiStaState,
|
||||
AccessPointInfo
|
||||
},
|
||||
};
|
||||
|
||||
@@ -130,26 +131,27 @@ impl SessionStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn scan_networks(controller: &mut WifiController<'_>) -> Vec<AccessPointInfo> {
|
||||
println!("Scan");
|
||||
let scan_config = ScanConfig::default().with_max(10);
|
||||
let result = controller
|
||||
.scan_with_config_async(scan_config)
|
||||
.await
|
||||
.expect("scan failed");
|
||||
result
|
||||
}
|
||||
|
||||
pub async fn start_wifi(spawner: &Spawner,
|
||||
esp_radio_ctrl: &'static Controller<'static>,
|
||||
controller: WifiController<'static>,
|
||||
wifi_interface: WifiDevice<'static>,
|
||||
flasher: crate::ota::Flasher<'_>,
|
||||
wifi_peripheral: esp_hal::peripherals::WIFI<'static>,
|
||||
ecu: &mut crate::ecu::Ecu<'_>) {
|
||||
|
||||
|
||||
|
||||
let (controller, interfaces) =
|
||||
esp_radio::wifi::new(esp_radio_ctrl, wifi_peripheral, Default::default()).unwrap();
|
||||
|
||||
let wifi_interface = interfaces.sta;
|
||||
|
||||
let config = embassy_net::Config::dhcpv4(Default::default());
|
||||
|
||||
let rng = Rng::new();
|
||||
let seed = (rng.random() as u64) << 32 | rng.random() as u64;
|
||||
|
||||
|
||||
// Init network stack
|
||||
let (stack, runner) = embassy_net::new(
|
||||
wifi_interface,
|
||||
@@ -227,15 +229,6 @@ async fn connection(mut controller: WifiController<'static>) {
|
||||
controller.set_config(&station_config).unwrap();
|
||||
controller.start_async().await.expect("wifi controller failed to start");
|
||||
|
||||
println!("Scan");
|
||||
let scan_config = ScanConfig::default().with_max(10);
|
||||
let result = controller
|
||||
.scan_with_config_async(scan_config)
|
||||
.await
|
||||
.unwrap();
|
||||
for ap in result {
|
||||
println!("{:?}", ap);
|
||||
}
|
||||
}
|
||||
println!("About to connect...");
|
||||
let station_config = ModeConfig::Client(
|
||||
|
||||
Reference in New Issue
Block a user