Skip to content

Commit 2730547

Browse files
committed
mitm: add video in motion feature
Credits and testing: @Ioniq3
1 parent 23f8be2 commit 2730547

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Currently it is intended to run as a more-or-less drop-in replacement of the `aa
1515
- Remove tap restriction
1616
- Disable media sink
1717
- Disable TTS sink
18+
- Video in motion
1819
- Developer mode
1920

2021
## Current project status
@@ -204,6 +205,9 @@ OPTIONS:
204205
205206
-V, --version
206207
Print version information
208+
209+
--video-in-motion
210+
MITM: video in motion
207211
```
208212
Most options are self explanatory, but these needs some more attention:<br>
209213
- `-l, --legacy`<br>

src/io_uring.rs

+3
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ pub async fn io_loop(
270270
disable_media_sink: bool,
271271
disable_tts_sink: bool,
272272
remove_tap_restriction: bool,
273+
video_in_motion: bool,
273274
) -> Result<()> {
274275
info!("{} 🛰️ Starting TCP server...", NAME);
275276
let bind_addr = format!("0.0.0.0:{}", TCP_SERVER_PORT).parse().unwrap();
@@ -355,6 +356,7 @@ pub async fn io_loop(
355356
disable_media_sink,
356357
disable_tts_sink,
357358
remove_tap_restriction,
359+
video_in_motion,
358360
));
359361
from_stream = tokio_uring::spawn(proxy(
360362
ProxyType::MobileDevice,
@@ -368,6 +370,7 @@ pub async fn io_loop(
368370
disable_media_sink,
369371
disable_tts_sink,
370372
remove_tap_restriction,
373+
video_in_motion,
371374
));
372375
} else {
373376
// We need to copy in both directions...

src/main.rs

+6
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ struct Args {
102102
#[clap(long, requires("mitm"))]
103103
remove_tap_restriction: bool,
104104

105+
/// MITM: video in motion
106+
#[clap(long, requires("mitm"))]
107+
video_in_motion: bool,
108+
105109
/// MITM: Disable media sink
106110
#[clap(long, requires("mitm"))]
107111
disable_media_sink: bool,
@@ -314,6 +318,7 @@ fn main() {
314318
let disable_media_sink = args.disable_media_sink;
315319
let disable_tts_sink = args.disable_tts_sink;
316320
let remove_tap_restriction = args.remove_tap_restriction;
321+
let video_in_motion = args.video_in_motion;
317322

318323
// build and spawn main tokio runtime
319324
let runtime = Builder::new_multi_thread().enable_all().build().unwrap();
@@ -332,6 +337,7 @@ fn main() {
332337
disable_media_sink,
333338
disable_tts_sink,
334339
remove_tap_restriction,
340+
video_in_motion,
335341
));
336342

337343
info!(

src/mitm.rs

+58-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use tokio_uring::buf::BoundedBuf;
1717
include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
1818
use crate::mitm::protos::*;
1919
use crate::mitm::AudioStreamType::*;
20+
use crate::mitm::SensorMessageId::*;
2021
use crate::mitm::SensorType::*;
2122
use protobuf::text_format::print_to_string_pretty;
2223
use protobuf::{Enum, Message, MessageDyn};
@@ -49,6 +50,10 @@ pub const ENCRYPTED: u8 = 1 << 3;
4950
// location for hu_/md_ private keys and certificates:
5051
const KEYS_PATH: &str = "/etc/aa-proxy-rs";
5152

53+
pub struct ModifyContext {
54+
sensor_channel: Option<u8>,
55+
}
56+
5257
#[derive(PartialEq, Copy, Clone)]
5358
pub enum ProxyType {
5459
HeadUnit,
@@ -246,20 +251,44 @@ pub async fn pkt_modify_hook(
246251
disable_media_sink: bool,
247252
disable_tts_sink: bool,
248253
remove_tap_restriction: bool,
254+
video_in_motion: bool,
255+
ctx: &mut ModifyContext,
249256
) -> Result<()> {
250-
if pkt.channel != 0 {
251-
return Ok(());
252-
}
253-
254257
// message_id is the first 2 bytes of payload
255258
let message_id: i32 = u16::from_be_bytes(pkt.payload[0..=1].try_into()?).into();
259+
let data = &pkt.payload[2..]; // start of message data
260+
261+
// handling driving_status_data change
262+
if let Some(ch) = ctx.sensor_channel {
263+
if ch == pkt.channel {
264+
match protos::SensorMessageId::from_i32(message_id).unwrap_or(SENSOR_MESSAGE_ERROR) {
265+
SENSOR_MESSAGE_BATCH => {
266+
if let Ok(mut msg) = SensorBatch::parse_from_bytes(data) {
267+
if !msg.driving_status_data.is_empty() {
268+
// forcing status to 0 value
269+
msg.driving_status_data[0].set_status(0);
270+
// regenerating payload data
271+
pkt.payload = msg.write_to_bytes()?;
272+
pkt.payload.insert(0, (message_id >> 8) as u8);
273+
pkt.payload.insert(1, (message_id & 0xff) as u8);
274+
}
275+
}
276+
}
277+
_ => (),
278+
}
279+
}
280+
// end sensors processing
281+
return Ok(());
282+
}
256283

284+
if pkt.channel != 0 {
285+
return Ok(());
286+
}
257287
// trying to obtain an Enum from message_id
258288
let control = protos::ControlMessageType::from_i32(message_id);
259289
debug!("message_id = {:04X}, {:?}", message_id, control);
260290

261291
// parsing data
262-
let data = &pkt.payload[2..]; // start of message data
263292
match control.unwrap_or(MESSAGE_UNEXPECTED_MESSAGE) {
264293
MESSAGE_SERVICE_DISCOVERY_RESPONSE => {
265294
let mut msg = ServiceDiscoveryResponse::parse_from_bytes(data)?;
@@ -313,6 +342,24 @@ pub async fn pkt_modify_hook(
313342
);
314343
}
315344

345+
// obtain SENSOR_DRIVING_STATUS_DATA sensor channel
346+
if video_in_motion {
347+
if let Some(svc) = msg
348+
.services
349+
.iter()
350+
.find(|svc| !svc.sensor_source_service.sensors.is_empty())
351+
{
352+
if let Some(_) = svc
353+
.sensor_source_service
354+
.sensors
355+
.iter()
356+
.find(|s| s.sensor_type() == SENSOR_DRIVING_STATUS_DATA)
357+
{
358+
ctx.sensor_channel = Some(svc.id() as u8);
359+
}
360+
}
361+
}
362+
316363
// remove tap restriction by removing SENSOR_SPEED
317364
if remove_tap_restriction {
318365
if let Some(svc) = msg
@@ -483,6 +530,7 @@ pub async fn proxy<A: Endpoint<A> + 'static>(
483530
disable_media_sink: bool,
484531
disable_tts_sink: bool,
485532
remove_tap_restriction: bool,
533+
video_in_motion: bool,
486534
) -> Result<()> {
487535
let ssl = ssl_builder(proxy_type).await?;
488536

@@ -553,6 +601,9 @@ pub async fn proxy<A: Endpoint<A> + 'static>(
553601
}
554602

555603
// main data processing/transfer loop
604+
let mut ctx = ModifyContext {
605+
sensor_channel: None,
606+
};
556607
loop {
557608
// handling data from opposite device's thread, which needs to be transmitted
558609
if let Ok(mut pkt) = rx.try_recv() {
@@ -564,6 +615,8 @@ pub async fn proxy<A: Endpoint<A> + 'static>(
564615
disable_media_sink,
565616
disable_tts_sink,
566617
remove_tap_restriction,
618+
video_in_motion,
619+
&mut ctx,
567620
)
568621
.await?;
569622
pkt.encrypt_payload(&mut mem_buf, &mut server).await?;

0 commit comments

Comments
 (0)