Skip to content

Commit 836fa82

Browse files
authored
Add mDNS advertise example (#582)
1 parent eee7b45 commit 836fa82

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- OTA: Allow specifying image size to speed up erase
2424
- Bluetooth: New methods `EspBleGap::start_scanning` and `EspBleGap::stop_scanning`
2525
- New example, `bt_ble_gap_scanner` to demonstrate usage of added ble scanning methods
26+
- New example, `mdns_advertise` to demonstrate mDNS service advertisement
2627

2728
## [0.51.0] - 2025-01-15
2829

examples/mdns_advertise.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//! Simple mDNS advertise example.
2+
//!
3+
//! See the comment below as to how to build the example with ESP IDF 5+.
4+
5+
#![allow(unknown_lints)]
6+
#![allow(unexpected_cfgs)]
7+
8+
pub fn main() {
9+
#[cfg(esp_idf_version_major = "4")]
10+
example::main().unwrap();
11+
12+
// Note that ESP IDF mDNS IS available on ESP IDF >= 5 too
13+
// It is just that it is now an external component, so to use it, you need
14+
// to put the following snippet at the end of the `Cargo.toml` file of your binary crate:
15+
//
16+
// ```toml
17+
// [[package.metadata.esp-idf-sys.extra_components]]
18+
// remote_component = { name = "espressif/mdns", version = "1.8.2" }
19+
// ```
20+
#[cfg(not(esp_idf_version_major = "4"))]
21+
panic!("This example only compiles on ESP IDF 4. Check the comments in the example how to compile it on ESP IDF 5+")
22+
}
23+
24+
#[cfg(esp_idf_version_major = "4")]
25+
pub mod example {
26+
use esp_idf_hal::io::Write;
27+
use esp_idf_svc::eventloop::EspSystemEventLoop;
28+
use esp_idf_svc::hal::peripherals::Peripherals;
29+
use esp_idf_svc::http::server::EspHttpServer;
30+
use esp_idf_svc::http::Method;
31+
use esp_idf_svc::log::EspLogger;
32+
use esp_idf_svc::mdns::EspMdns;
33+
use esp_idf_svc::nvs::EspDefaultNvsPartition;
34+
use esp_idf_svc::wifi::*;
35+
36+
use log::info;
37+
38+
const SSID: &str = env!("WIFI_SSID");
39+
const PASSWORD: &str = env!("WIFI_PASS");
40+
static INDEX_HTML: &str = include_str!("http_server_page.html");
41+
42+
pub fn main() -> anyhow::Result<()> {
43+
esp_idf_svc::sys::link_patches();
44+
EspLogger::initialize_default();
45+
46+
// Setup Wifi
47+
let peripherals = Peripherals::take()?;
48+
let sys_loop = EspSystemEventLoop::take()?;
49+
let nvs = EspDefaultNvsPartition::take()?;
50+
let mut wifi = BlockingWifi::wrap(
51+
EspWifi::new(peripherals.modem, sys_loop.clone(), Some(nvs))?,
52+
sys_loop,
53+
)?;
54+
connect_wifi(&mut wifi)?;
55+
56+
// Setup HTTP server
57+
let server_config = esp_idf_svc::http::server::Configuration::default();
58+
let mut server = EspHttpServer::new(&server_config)?;
59+
server.fn_handler("/", Method::Get, |req| {
60+
req.into_ok_response()?
61+
.write_all(INDEX_HTML.as_bytes())
62+
.map(|_| ())
63+
})?;
64+
65+
// Setup mDNS
66+
let mut mdns = EspMdns::take()?;
67+
mdns.set_hostname("esp-advertiser")?;
68+
69+
// Advertise the HTTP server
70+
mdns.add_service(
71+
Some("ESP HTTP Server"),
72+
"_http",
73+
"_tcp",
74+
server_config.http_port,
75+
&[],
76+
)?;
77+
78+
// Keep the wifi, http server, and mDNS running beyond when main() returns (forever)
79+
// Do not call this if you ever want to stop or access them later.
80+
// Otherwise you can either add an infinite loop so the main task
81+
// never returns, or you can move them to another thread.
82+
// https://doc.rust-lang.org/stable/core/mem/fn.forget.html
83+
core::mem::forget(wifi);
84+
core::mem::forget(server);
85+
core::mem::forget(mdns);
86+
87+
Ok(())
88+
}
89+
90+
fn connect_wifi(wifi: &mut BlockingWifi<EspWifi<'static>>) -> anyhow::Result<()> {
91+
let wifi_configuration: Configuration = Configuration::Client(ClientConfiguration {
92+
ssid: SSID.try_into().unwrap(),
93+
bssid: None,
94+
auth_method: AuthMethod::WPA2Personal,
95+
password: PASSWORD.try_into().unwrap(),
96+
channel: None,
97+
..Default::default()
98+
});
99+
100+
wifi.set_configuration(&wifi_configuration)?;
101+
102+
wifi.start()?;
103+
info!("Wifi started");
104+
105+
wifi.connect()?;
106+
info!("Wifi connected");
107+
108+
wifi.wait_netif_up()?;
109+
info!("Wifi netif up");
110+
111+
Ok(())
112+
}
113+
}

0 commit comments

Comments
 (0)