1use tokio::net::UdpSocket;
2use tokio::time::{sleep, Duration};
3use tokio::sync::Mutex;
4
5use crate::errors::{Result, TelloError};
6use crate::wifi::wait_for_wifi;
7use crate::state::*;
8use crate::video::*;
9use crate::command::*;
10use crate::options::TelloOptions;
11
12const DEFAULT_DRONE_HOST:&str = "192.168.10.1";
13
14const CONTROL_UDP_PORT:i32 = 8889;
15
16#[derive(Debug)]
18pub struct NoWifi;
19
20#[derive(Debug)]
22pub struct Disconnected;
23
24#[derive(Debug)]
26pub struct Connected {
27 sock: UdpSocket,
28 state_listener: Option<StateListener>,
29 video_listener: Option<VideoListener>,
30 command_receiver: Option<Mutex<TelloCommandReceiver>>
31}
32
33#[derive(Debug)]
69pub struct Tello<S = NoWifi> {
70 inner: S
72}
73
74impl Tello<NoWifi> {
75 pub fn new() -> Self {
77 Self { inner: NoWifi }
78 }
79
80 pub async fn wait_for_wifi(&self) -> Result<Tello<Disconnected>> {
85 println!("[Tello] waiting for WiFi...");
86 wait_for_wifi("TELLO").await?;
87 Ok(Tello { inner: Disconnected })
88 }
89
90 pub async fn assume_wifi(&self) -> Result<Tello<Disconnected>> {
92 println!("[Tello] assuming WiFi has already been joined");
93 Ok(Tello { inner: Disconnected })
94 }
95}
96
97impl Tello<Disconnected> {
98 pub async fn connect(&self) -> Result<Tello<Connected>> {
104 self.connect_with(TelloOptions::default()).await
105 }
106
107 pub async fn connect_with(&self, options:TelloOptions) -> Result<Tello<Connected>> {
112 let local_address = format!("0.0.0.0:{CONTROL_UDP_PORT}");
113
114 let drone_host = DEFAULT_DRONE_HOST;
115 let drone_address = format!("{drone_host}:{CONTROL_UDP_PORT}");
116
117 println!("[Tello] CONNECT {local_address} → {drone_address}");
118
119 println!("[Tello] binding local {local_address}...");
121 let sock = UdpSocket::bind(&local_address).await?;
122
123 println!("[Tello] connecting to drone at {drone_address}...");
125 let mut i = 0;
126 loop {
127 i = i + 1;
128 match sock.connect(&drone_address).await {
129 Ok(_) => {
130 println!("[Tello] CONNECTED");
131 break;
132 }
133 Err(err) => {
134 println!("[Tello] connection attempt #{i} failed ({err}), retrying...");
135 sleep(Duration::from_millis(100)).await;
136 }
137 }
138 }
139
140 let mut drone = Tello { inner: Connected { sock, state_listener: None, video_listener: None, command_receiver: None } };
142
143 if let Some(state_tx) = &options.state_sender {
145 let state_listener = StateListener::start_listening(state_tx.clone()).await?;
146 drone.inner.state_listener = Some(state_listener);
147 }
148
149 if let Some(video_tx) = &options.video_sender {
151 let video_listener = VideoListener::start_listening(video_tx.clone()).await?;
152 drone.inner.video_listener = Some(video_listener);
153 }
154
155 if let Some(command_rx) = options.command_receiver {
157 drone.inner.command_receiver = Some(Mutex::new(command_rx));
158 }
159
160 println!("[Tello] putting drone in command mode...");
162 drone.send_expect_ok("command").await?;
163
164 let b = drone.battery().await?;
166 if b < 10 {
167 println!("[Tello] WARNING low battery: {b}%");
168 }
169 else {
170 println!("[Tello] battery: {b}%");
171 }
172
173 Ok(drone)
174 }
175}
176
177impl Tello<Connected> {
178 pub async fn disconnect(&self) -> Result<Tello<Disconnected>> {
180 println!("[Tello] DISCONNECT");
181
182 if let Some(state_listener) = &self.inner.state_listener {
183 state_listener.stop_listening().await?;
184 }
185
186 if let Some(video_listener) = &self.inner.video_listener {
187 video_listener.stop_listening().await?;
188 }
189
190 Ok(Tello { inner: Disconnected })
191 }
192
193 pub async fn send(&self, command: &str) -> Result<String> {
204 println!("[Tello] SEND {command}");
205
206 let s = &self.inner.sock;
207 s.send(command.as_bytes()).await?;
208
209 let response = self.recv().await?;
210
211 if response == "forced stop" {
214 self.on_forced_stop();
215
216 self.recv().await
218 }
219 else {
220 Ok(response)
221 }
222 }
223
224 async fn recv(&self) -> Result<String> {
225 let s = &self.inner.sock;
226 let mut buf = vec![0; 256];
227 let n = s.recv(&mut buf).await?;
228
229 buf.truncate(n);
230 let r = String::from_utf8(buf)?;
231 let response = r.trim().to_string();
232
233 println!("[Tello] RECEIVED {response}");
234
235 Ok(response)
236 }
237
238 fn on_forced_stop(&self) {
239 println!("[Tello] FORCED STOP");
240 }
241
242 pub async fn send_expect_ok(&self, command: &str) -> Result<()> {
247 match self.send(command).await {
248 Ok(response) => {
249 if response == "ok" {
250 Ok(())
251 }
252 else {
253 Err(TelloError::from_not_ok_response(response))
254 }
255 }
256 Err(err) => Err(err)
257 }
258 }
259
260 pub async fn send_value_expect_ok<T: std::fmt::Display>(&self, command: &str, value: T) -> Result<()> {
267 match self.send(&format!("{command} {value}")).await {
268 Ok(response) => {
269 if response == "ok" {
270 Ok(())
271 }
272 else {
273 Err(TelloError::from_not_ok_response(response))
274 }
275 }
276 Err(err) => Err(err)
277 }
278 }
279
280 pub async fn send_expect_nothing(&self, command: &str) -> Result<()> {
285 println!("[Tello] SEND {command}");
286
287 let s = &self.inner.sock;
288 s.send(command.as_bytes()).await?;
289
290 Ok(())
291 }
292
293 pub async fn send_expect<T: std::str::FromStr>(&self, command: &str) -> Result<T> {
298 let r = self.send(command).await?;
299 let v = r.parse::<T>().map_err(|_| TelloError::ParseError { msg: format!("unexpected response: \"{r}\"")})?;
300 Ok(v)
301 }
302
303 pub async fn serial_number(&self) -> Result<String> {
305 self.send("sn?").await
306 }
307
308 pub async fn sdk_version(&self) -> Result<String> {
310 self.send("sdk?").await
311 }
312
313 pub async fn battery(&self) -> Result<u8> {
315 self.send_expect::<u8>("battery?").await
316 }
317
318 pub async fn wifi_signal_to_noise_ratio(&self) -> Result<u8> {
320 self.send_expect::<u8>("wifi?").await
321 }
322
323 pub async fn flight_time(&self) -> Result<u16> {
325 self.send_expect::<u16>("time?").await
326 }
327
328 pub async fn emergency_stop(&self) -> Result<()> {
333 self.send_expect_nothing("emergency").await
334 }
335
336 pub async fn take_off(&self) -> Result<()> {
338 self.send_expect_ok("takeoff").await
339 }
340
341 pub async fn land(&self) -> Result<()> {
343 self.send_expect_ok("land").await
344 }
345
346 pub async fn speed(&self) -> Result<f32> {
348 self.send_expect::<f32>("speed?").await
349 }
350
351 pub async fn set_speed(&self, speed: u8) -> Result<()> {
356 self.send_value_expect_ok("speed", speed).await
357 }
358
359 pub async fn wait(&self, duration:Duration) -> Result<()> {
364 println!("[Tello] waiting for {duration:#?}");
365 sleep(duration).await;
366 Ok(())
367 }
368
369 pub async fn stop(&self) -> Result<()> {
371 self.send_expect_ok("stop").await
373 }
374
375 pub async fn turn_clockwise(&self, degrees: u16) -> Result<()> {
380 self.send_value_expect_ok("cw", degrees).await
381 }
382
383 pub async fn turn_counterclockwise(&self, degrees: u16) -> Result<()> {
387 self.send_value_expect_ok("ccw", degrees).await
388 }
389
390 pub async fn move_up(&self, distance: u16) -> Result<()> {
395 self.send_value_expect_ok("up", distance).await
396 }
397
398 pub async fn move_down(&self, distance: u16) -> Result<()> {
403 self.send_value_expect_ok("down", distance).await
404 }
405
406 pub async fn move_left(&self, distance: u16) -> Result<()> {
411 self.send_value_expect_ok("left", distance).await
412 }
413
414 pub async fn move_right(&self, distance: u16) -> Result<()> {
419 self.send_value_expect_ok("right", distance).await
420 }
421
422 pub async fn move_forward(&self, distance: u16) -> Result<()> {
427 self.send_value_expect_ok("forward", distance).await
428 }
429
430 pub async fn move_back(&self, distance: u16) -> Result<()> {
435 self.send_value_expect_ok("back", distance).await
436 }
437
438 pub async fn flip_left(&self) -> Result<()> {
443 self.send_expect_ok("flip l").await
444 }
445
446 pub async fn flip_right(&self) -> Result<()> {
451 self.send_expect_ok("flip r").await
452 }
453
454 pub async fn flip_forward(&self) -> Result<()> {
459 self.send_expect_ok("flip f").await
460 }
461
462 pub async fn flip_back(&self) -> Result<()> {
467 self.send_expect_ok("flip b").await
468 }
469
470 pub async fn start_video(&self) -> Result<()> {
479 self.send_expect_ok("streamon").await
480 }
481
482 pub async fn stop_video(&self) -> Result<()> {
484 self.send_expect_ok("streamoff").await
485 }
486
487 pub async fn remote_control(&self, left_right:i8, forwards_backwards:i8, up_down:i8, yaw:i8) -> Result<()> {
496 self.send_expect_nothing(&format!("rc {left_right} {forwards_backwards} {up_down} {yaw}")).await
497 }
498
499
500 pub async fn handle_commands(&self) -> Result<()> {
503 if let Some(command_receiver) = &self.inner.command_receiver {
504 let mut command_rx = command_receiver.lock().await;
505 while let Some(command) = command_rx.recv().await {
506 match command {
507 TelloCommand::TakeOff => self.take_off().await?,
508 TelloCommand::Land => self.land().await?,
509 TelloCommand::StopAndHover => self.stop().await?,
510 TelloCommand::EmergencyStop => self.emergency_stop().await?,
511 TelloCommand::RemoteControl { left_right, forwards_backwards, up_down, yaw } =>
512 self.remote_control(left_right, forwards_backwards, up_down, yaw).await?,
513 TelloCommand::FlipLeft => self.flip_left().await?,
514 TelloCommand::FlipRight => self.flip_right().await?,
515 TelloCommand::FlipForward => self.flip_forward().await?,
516 TelloCommand::FlipBack => self.flip_back().await?
517 }
518 }
519 }
520
521 Ok(())
522
523 }
524
525}