Skip to content

Commit b983fe4

Browse files
committed
feat(mdns): WIP support for rust API
1 parent 3f4a2f6 commit b983fe4

16 files changed

+746
-149
lines changed

Diff for: .github/workflows/mdns__build-target-test.yml

-84
This file was deleted.

Diff for: .github/workflows/mdns__host-tests.yml

-64
This file was deleted.

Diff for: .github/workflows/mdns__rust.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: "mdns: rust-tests"
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
types: [opened, synchronize, reopened, labeled]
9+
10+
jobs:
11+
host_test_mdns:
12+
if: contains(github.event.pull_request.labels.*.name, 'mdns') || github.event_name == 'push'
13+
name: Host test build
14+
runs-on: ubuntu-22.04
15+
container: espressif/idf:latest
16+
17+
steps:
18+
- name: Checkout esp-protocols
19+
uses: actions/checkout@v4
20+
21+
- name: Build and Test
22+
shell: bash
23+
run: |
24+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
25+
# Add Rust to the current PATH
26+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
27+
. "$HOME/.cargo/env"
28+
rustc --version
29+
cargo --version
30+
. ${IDF_PATH}/export.sh
31+
cd components/mdns/examples/simple_query/
32+
idf.py build
33+
cd ../..
34+
COMPILE_COMMANDS_DIR=examples/simple_query/build/ cargo run --example usage

Diff for: components/mdns/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ idf_build_get_property(target IDF_TARGET)
1414
if(${target} STREQUAL "linux")
1515
set(dependencies esp_netif_linux esp_event)
1616
set(private_dependencies esp_timer console esp_system)
17-
set(srcs ${MDNS_NETWORKING} ${MDNS_CONSOLE})
17+
set(srcs "mdns_stub.c" ${MDNS_NETWORKING} ${MDNS_CONSOLE})
1818
else()
1919
set(dependencies lwip console esp_netif)
2020
set(private_dependencies esp_timer esp_wifi)

Diff for: components/mdns/Cargo.toml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "mdns"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
libc = "0.2"
8+
dns-parser = "0.8"
9+
10+
[build-dependencies]
11+
cc = "1.0"
12+
serde = { version = "1.0", features = ["derive"] }
13+
serde_json = "1.0"

Diff for: components/mdns/build.rs

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use std::env;
2+
use std::fs;
3+
use std::path::{Path, PathBuf};
4+
use serde::Deserialize;
5+
6+
#[derive(Debug, Deserialize)]
7+
struct CompileCommand {
8+
directory: String,
9+
command: String,
10+
file: String,
11+
}
12+
13+
fn main() {
14+
// Get the directory for compile_commands.json from an environment variable
15+
let compile_commands_dir = env::var("COMPILE_COMMANDS_DIR")
16+
.unwrap_or_else(|_| ".".to_string()); // Default to current directory
17+
18+
// Construct the path to the compile_commands.json file
19+
let compile_commands_path = Path::new(&compile_commands_dir).join("compile_commands.json");
20+
21+
// Parse compile_commands.json
22+
let compile_commands: Vec<CompileCommand> = {
23+
let data = fs::read_to_string(&compile_commands_path)
24+
.expect("Failed to read compile_commands.json");
25+
serde_json::from_str(&data)
26+
.expect("Failed to parse compile_commands.json")
27+
};
28+
29+
// Directory of compile_commands.json, used to resolve relative paths
30+
let base_dir = compile_commands_path
31+
.parent()
32+
.expect("Failed to get base directory of compile_commands.json");
33+
34+
// List of C files to compile (only base names)
35+
let files_to_compile = vec![
36+
"mdns_networking_socket.c",
37+
"log_write.c",
38+
"log_timestamp.c",
39+
"esp_netif_linux.c",
40+
"freertos_linux.c",
41+
"tag_log_level.c",
42+
"log_linked_list.c",
43+
"log_lock.c",
44+
"log_level.c",
45+
"log_binary_heap.c",
46+
"esp_system_linux2.c",
47+
"heap_caps_linux.c",
48+
"mdns_stub.c",
49+
"log_buffers.c",
50+
"util.c"
51+
];
52+
53+
// Initialize the build
54+
let mut build = cc::Build::new();
55+
56+
for file in &files_to_compile {
57+
// Extract the base name from `file` for comparison
58+
let target_base_name = Path::new(file)
59+
.file_name()
60+
.expect("Failed to extract base name from target file")
61+
.to_str()
62+
.expect("Target file name is not valid UTF-8");
63+
64+
// Find the entry in compile_commands.json by matching the base name
65+
let cmd = compile_commands.iter()
66+
.find(|entry| {
67+
let full_path = Path::new(&entry.directory).join(&entry.file); // Resolve relative paths
68+
if let Some(base_name) = full_path.file_name().and_then(|name| name.to_str()) {
69+
// println!("Checking file: {} against {}", base_name, target_base_name); // Debug information
70+
base_name == target_base_name
71+
} else {
72+
false
73+
}
74+
})
75+
.unwrap_or_else(|| panic!("{} not found in compile_commands.json", target_base_name));
76+
77+
// Add the file to the build
78+
build.file(&cmd.file);
79+
80+
// Parse flags and include paths from the command
81+
for part in cmd.command.split_whitespace() {
82+
if part.starts_with("-I") {
83+
// Handle include directories
84+
let include_path = &part[2..];
85+
let full_include_path = if Path::new(include_path).is_relative() {
86+
base_dir.join(include_path).canonicalize()
87+
.expect("Failed to resolve relative include path")
88+
} else {
89+
PathBuf::from(include_path)
90+
};
91+
build.include(full_include_path);
92+
} else if part.starts_with("-D") || part.starts_with("-std") {
93+
// Add other compilation flags
94+
build.flag(part);
95+
}
96+
}
97+
}
98+
99+
100+
101+
102+
// Compile with the gathered information
103+
build.compile("mdns");
104+
}

Diff for: components/mdns/examples/simple_query/CMakeLists.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
4+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
5+
if(${IDF_TARGET} STREQUAL "linux")
6+
set(EXTRA_COMPONENT_DIRS "../../../../common_components/linux_compat" "../../tests/host_test/components/")
7+
set(COMPONENTS main)
8+
endif()
9+
10+
project(mdns_host)
11+
12+
# Enable sanitizers only without console (we'd see some leaks on argtable when console exits)
13+
if(NOT CONFIG_TEST_CONSOLE AND CONFIG_IDF_TARGET_LINUX)
14+
idf_component_get_property(mdns mdns COMPONENT_LIB)
15+
target_link_options(${mdns} INTERFACE -fsanitize=address -fsanitize=undefined)
16+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
idf_component_register(SRCS "main.c" "esp_system_linux2.c"
2+
INCLUDE_DIRS
3+
"."
4+
REQUIRES mdns console nvs_flash)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
menu "Test Configuration"
2+
3+
config TEST_HOSTNAME
4+
string "mDNS Hostname"
5+
default "esp32-mdns"
6+
help
7+
mDNS Hostname for example to use
8+
9+
config TEST_NETIF_NAME
10+
string "Network interface name"
11+
default "eth2"
12+
help
13+
Name/ID if the network interface on which we run the mDNS host test
14+
15+
config TEST_CONSOLE
16+
bool "Start console"
17+
default n
18+
help
19+
Test uses esp_console for interactive testing.
20+
21+
endmenu

0 commit comments

Comments
 (0)