Skip to content

Commit 19aa36a

Browse files
committed
introduce config.rs for config-related stuff
1 parent 569409e commit 19aa36a

File tree

5 files changed

+167
-164
lines changed

5 files changed

+167
-164
lines changed

src/config.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
use bluer::Address;
2+
use serde::de::{self, Deserializer, Error as DeError, Visitor};
3+
use serde::Deserialize;
4+
use std::fmt::{self, Display};
5+
use std::path::PathBuf;
6+
use std::str::FromStr;
7+
8+
#[derive(clap::ValueEnum, Default, Debug, PartialEq, PartialOrd, Clone, Copy, Deserialize)]
9+
pub enum HexdumpLevel {
10+
#[default]
11+
Disabled,
12+
DecryptedInput,
13+
RawInput,
14+
DecryptedOutput,
15+
RawOutput,
16+
All,
17+
}
18+
19+
#[derive(Debug, Clone)]
20+
pub struct UsbId {
21+
pub vid: u16,
22+
pub pid: u16,
23+
}
24+
25+
impl std::str::FromStr for UsbId {
26+
type Err = String;
27+
28+
fn from_str(s: &str) -> Result<Self, Self::Err> {
29+
let parts: Vec<&str> = s.split(':').collect();
30+
if parts.len() != 2 {
31+
return Err("Expected format VID:PID".to_string());
32+
}
33+
let vid = u16::from_str_radix(parts[0], 16).map_err(|e| e.to_string())?;
34+
let pid = u16::from_str_radix(parts[1], 16).map_err(|e| e.to_string())?;
35+
Ok(UsbId { vid, pid })
36+
}
37+
}
38+
39+
impl<'de> Deserialize<'de> for UsbId {
40+
fn deserialize<D>(deserializer: D) -> Result<UsbId, D::Error>
41+
where
42+
D: Deserializer<'de>,
43+
{
44+
struct UsbIdVisitor;
45+
46+
impl<'de> Visitor<'de> for UsbIdVisitor {
47+
type Value = UsbId;
48+
49+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
50+
formatter.write_str("a string in the format VID:PID")
51+
}
52+
53+
fn visit_str<E>(self, value: &str) -> Result<UsbId, E>
54+
where
55+
E: de::Error,
56+
{
57+
UsbId::from_str(value).map_err(de::Error::custom)
58+
}
59+
}
60+
61+
deserializer.deserialize_str(UsbIdVisitor)
62+
}
63+
}
64+
65+
pub fn empty_string_as_none<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
66+
where
67+
T: FromStr,
68+
T::Err: Display,
69+
D: Deserializer<'de>,
70+
{
71+
let s: String = Deserialize::deserialize(deserializer)?;
72+
if s.trim().is_empty() {
73+
Ok(None)
74+
} else {
75+
T::from_str(&s).map(Some).map_err(DeError::custom)
76+
}
77+
}
78+
79+
#[derive(Debug, Clone, Deserialize)]
80+
#[serde(default)]
81+
pub struct AppConfig {
82+
pub advertise: bool,
83+
pub debug: bool,
84+
pub hexdump_level: HexdumpLevel,
85+
pub disable_console_debug: bool,
86+
pub legacy: bool,
87+
#[serde(default, deserialize_with = "empty_string_as_none")]
88+
pub connect: Option<Address>,
89+
pub logfile: PathBuf,
90+
pub stats_interval: u16,
91+
#[serde(default, deserialize_with = "empty_string_as_none")]
92+
pub udc: Option<String>,
93+
pub iface: String,
94+
pub hostapd_conf: PathBuf,
95+
#[serde(default, deserialize_with = "empty_string_as_none")]
96+
pub btalias: Option<String>,
97+
pub keepalive: bool,
98+
pub timeout_secs: u16,
99+
pub bt_timeout_secs: u16,
100+
pub mitm: bool,
101+
pub dpi: u16,
102+
pub remove_tap_restriction: bool,
103+
pub video_in_motion: bool,
104+
pub disable_media_sink: bool,
105+
pub disable_tts_sink: bool,
106+
pub developer_mode: bool,
107+
#[serde(default, deserialize_with = "empty_string_as_none")]
108+
pub wired: Option<UsbId>,
109+
pub dhu: bool,
110+
pub ev: bool,
111+
#[serde(default, deserialize_with = "empty_string_as_none")]
112+
pub ev_battery_logger: Option<PathBuf>,
113+
pub ev_battery_capacity: u64,
114+
pub ev_factor: f32,
115+
}
116+
117+
impl Default for AppConfig {
118+
fn default() -> Self {
119+
Self {
120+
advertise: false,
121+
debug: false,
122+
hexdump_level: HexdumpLevel::Disabled,
123+
disable_console_debug: false,
124+
legacy: true,
125+
connect: None,
126+
logfile: "/var/log/aa-proxy-rs.log".into(),
127+
stats_interval: 0,
128+
udc: None,
129+
iface: "wlan0".to_string(),
130+
hostapd_conf: "/var/run/hostapd.conf".into(),
131+
btalias: None,
132+
keepalive: false,
133+
timeout_secs: 10,
134+
bt_timeout_secs: 120,
135+
mitm: false,
136+
dpi: 0,
137+
remove_tap_restriction: false,
138+
video_in_motion: false,
139+
disable_media_sink: false,
140+
disable_tts_sink: false,
141+
developer_mode: false,
142+
wired: None,
143+
dhu: false,
144+
ev: false,
145+
ev_battery_logger: None,
146+
ev_battery_capacity: 22000,
147+
ev_factor: 0.075,
148+
}
149+
}
150+
}
151+
152+
pub fn load_config(config_file: PathBuf) -> Result<AppConfig, Box<dyn std::error::Error>> {
153+
let file_config: AppConfig = config::Config::builder()
154+
.add_source(config::File::from(config_file).required(false))
155+
.build()?
156+
.try_deserialize()
157+
.unwrap_or_default();
158+
159+
Ok(file_config)
160+
}

src/io_uring.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ const USB_ACCESSORY_PATH: &str = "/dev/usb_accessory";
3333
pub const BUFFER_LEN: usize = 16 * 1024;
3434
const TCP_CLIENT_TIMEOUT: Duration = Duration::new(30, 0);
3535

36+
use crate::config::HexdumpLevel;
37+
use crate::config::UsbId;
3638
use crate::ev::{rest_server, RestContext};
3739
use crate::mitm::endpoint_reader;
3840
use crate::mitm::proxy;
3941
use crate::mitm::Packet;
4042
use crate::mitm::ProxyType;
4143
use crate::usb_stream;
4244
use crate::usb_stream::{UsbStreamRead, UsbStreamWrite};
43-
use crate::HexdumpLevel;
44-
use crate::UsbId;
4545
use crate::{TCP_DHU_PORT, TCP_SERVER_PORT};
4646

4747
// tokio_uring::fs::File and tokio_uring::net::TcpStream are using different

src/main.rs

Lines changed: 3 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
mod aoa;
22
mod bluetooth;
3+
mod config;
34
mod ev;
45
mod io_uring;
56
mod mitm;
67
mod usb_gadget;
78
mod usb_stream;
89

9-
use bluer::Address;
10+
use crate::config::AppConfig;
1011
use bluetooth::bluetooth_setup_connection;
1112
use bluetooth::bluetooth_stop;
1213
use clap::Parser;
@@ -17,12 +18,8 @@ use simplelog::*;
1718
use usb_gadget::uevent_listener;
1819
use usb_gadget::UsbGadgetState;
1920

20-
use serde::de::{self, Deserializer, Error as DeError, Visitor};
21-
use serde::Deserialize;
22-
use std::fmt::{self, Display};
2321
use std::fs::OpenOptions;
2422
use std::path::PathBuf;
25-
use std::str::FromStr;
2623
use std::sync::Arc;
2724
use std::time::Duration;
2825
use tokio::runtime::Builder;
@@ -36,63 +33,6 @@ const DEFAULT_WLAN_ADDR: &str = "10.0.0.1";
3633
const TCP_SERVER_PORT: i32 = 5288;
3734
const TCP_DHU_PORT: i32 = 5277;
3835

39-
#[derive(clap::ValueEnum, Default, Debug, PartialEq, PartialOrd, Clone, Copy, Deserialize)]
40-
pub enum HexdumpLevel {
41-
#[default]
42-
Disabled,
43-
DecryptedInput,
44-
RawInput,
45-
DecryptedOutput,
46-
RawOutput,
47-
All,
48-
}
49-
50-
#[derive(Debug, Clone)]
51-
struct UsbId {
52-
vid: u16,
53-
pid: u16,
54-
}
55-
56-
impl std::str::FromStr for UsbId {
57-
type Err = String;
58-
59-
fn from_str(s: &str) -> Result<Self, Self::Err> {
60-
let parts: Vec<&str> = s.split(':').collect();
61-
if parts.len() != 2 {
62-
return Err("Expected format VID:PID".to_string());
63-
}
64-
let vid = u16::from_str_radix(parts[0], 16).map_err(|e| e.to_string())?;
65-
let pid = u16::from_str_radix(parts[1], 16).map_err(|e| e.to_string())?;
66-
Ok(UsbId { vid, pid })
67-
}
68-
}
69-
70-
impl<'de> Deserialize<'de> for UsbId {
71-
fn deserialize<D>(deserializer: D) -> Result<UsbId, D::Error>
72-
where
73-
D: Deserializer<'de>,
74-
{
75-
struct UsbIdVisitor;
76-
77-
impl<'de> Visitor<'de> for UsbIdVisitor {
78-
type Value = UsbId;
79-
80-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
81-
formatter.write_str("a string in the format VID:PID")
82-
}
83-
84-
fn visit_str<E>(self, value: &str) -> Result<UsbId, E>
85-
where
86-
E: de::Error,
87-
{
88-
UsbId::from_str(value).map_err(de::Error::custom)
89-
}
90-
}
91-
92-
deserializer.deserialize_str(UsbIdVisitor)
93-
}
94-
}
95-
9636
/// AndroidAuto wired/wireless proxy
9737
#[derive(Parser, Debug)]
9838
#[clap(version, long_about = None, about = format!(
@@ -112,103 +52,6 @@ struct Args {
11252
config: PathBuf,
11353
}
11454

115-
pub fn empty_string_as_none<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
116-
where
117-
T: FromStr,
118-
T::Err: Display,
119-
D: Deserializer<'de>,
120-
{
121-
let s: String = Deserialize::deserialize(deserializer)?;
122-
if s.trim().is_empty() {
123-
Ok(None)
124-
} else {
125-
T::from_str(&s).map(Some).map_err(DeError::custom)
126-
}
127-
}
128-
129-
#[derive(Debug, Clone, Deserialize)]
130-
#[serde(default)]
131-
pub struct AppConfig {
132-
advertise: bool,
133-
debug: bool,
134-
hexdump_level: HexdumpLevel,
135-
disable_console_debug: bool,
136-
legacy: bool,
137-
#[serde(default, deserialize_with = "empty_string_as_none")]
138-
connect: Option<Address>,
139-
logfile: PathBuf,
140-
stats_interval: u16,
141-
#[serde(default, deserialize_with = "empty_string_as_none")]
142-
udc: Option<String>,
143-
iface: String,
144-
hostapd_conf: PathBuf,
145-
#[serde(default, deserialize_with = "empty_string_as_none")]
146-
btalias: Option<String>,
147-
keepalive: bool,
148-
timeout_secs: u16,
149-
bt_timeout_secs: u16,
150-
mitm: bool,
151-
dpi: u16,
152-
remove_tap_restriction: bool,
153-
video_in_motion: bool,
154-
disable_media_sink: bool,
155-
disable_tts_sink: bool,
156-
developer_mode: bool,
157-
#[serde(default, deserialize_with = "empty_string_as_none")]
158-
wired: Option<UsbId>,
159-
dhu: bool,
160-
ev: bool,
161-
#[serde(default, deserialize_with = "empty_string_as_none")]
162-
ev_battery_logger: Option<PathBuf>,
163-
ev_battery_capacity: u64,
164-
ev_factor: f32,
165-
}
166-
167-
impl Default for AppConfig {
168-
fn default() -> Self {
169-
Self {
170-
advertise: false,
171-
debug: false,
172-
hexdump_level: HexdumpLevel::Disabled,
173-
disable_console_debug: false,
174-
legacy: true,
175-
connect: None,
176-
logfile: "/var/log/aa-proxy-rs.log".into(),
177-
stats_interval: 0,
178-
udc: None,
179-
iface: "wlan0".to_string(),
180-
hostapd_conf: "/var/run/hostapd.conf".into(),
181-
btalias: None,
182-
keepalive: false,
183-
timeout_secs: 10,
184-
bt_timeout_secs: 120,
185-
mitm: false,
186-
dpi: 0,
187-
remove_tap_restriction: false,
188-
video_in_motion: false,
189-
disable_media_sink: false,
190-
disable_tts_sink: false,
191-
developer_mode: false,
192-
wired: None,
193-
dhu: false,
194-
ev: false,
195-
ev_battery_logger: None,
196-
ev_battery_capacity: 22000,
197-
ev_factor: 0.075,
198-
}
199-
}
200-
}
201-
202-
fn load_config(config_file: PathBuf) -> Result<AppConfig, Box<dyn std::error::Error>> {
203-
let file_config: AppConfig = config::Config::builder()
204-
.add_source(config::File::from(config_file).required(false))
205-
.build()?
206-
.try_deserialize()
207-
.unwrap_or_default();
208-
209-
Ok(file_config)
210-
}
211-
21255
#[derive(Clone)]
21356
struct WifiConfig {
21457
ip_addr: String,
@@ -392,7 +235,7 @@ fn main() {
392235
let args = Args::parse();
393236

394237
// parse config
395-
let config = load_config(args.config.clone()).unwrap();
238+
let config = config::load_config(args.config.clone()).unwrap();
396239

397240
logging_init(config.debug, config.disable_console_debug, &config.logfile);
398241
info!(

src/mitm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ use protobuf::text_format::print_to_string_pretty;
2727
use protobuf::{Enum, Message, MessageDyn};
2828
use protos::ControlMessageType::{self, *};
2929

30+
use crate::config::HexdumpLevel;
3031
use crate::ev::RestContext;
3132
use crate::io_uring::Endpoint;
3233
use crate::io_uring::IoDevice;
3334
use crate::io_uring::BUFFER_LEN;
34-
use crate::HexdumpLevel;
3535

3636
// module name for logging engine
3737
fn get_name(proxy_type: ProxyType) -> String {

0 commit comments

Comments
 (0)