Skip to main content

esp_idf/
event.rs

1use crate::*;
2use core::convert::{self};
3
4pub fn loop_create_default() -> Result<(), error::Error> {
5    unsafe {
6        let retval = esp_event_loop_create_default();
7        esp_int_into_result(retval)
8    }
9}
10
11#[derive(Clone, Copy, Debug, PartialEq)]
12pub enum Event {
13    Ip(IpEvent),
14    Wifi(WifiEvent),
15}
16
17#[derive(Clone, Copy, Debug, PartialEq)]
18pub enum EventBase {
19    Ip,
20    Wifi,
21}
22
23#[repr(i32)]
24#[derive(Clone, Copy, Debug, PartialEq)]
25pub enum IpEvent {
26    StaGotIp = ip_event_t_IP_EVENT_STA_GOT_IP as i32,
27}
28
29#[repr(i32)]
30#[derive(Clone, Copy, Debug, PartialEq)]
31pub enum WifiEvent {
32    StaStart = wifi_event_t_WIFI_EVENT_STA_START as i32,
33    StaDisconnected = wifi_event_t_WIFI_EVENT_STA_DISCONNECTED as i32,
34    Any = ESP_EVENT_ANY_ID,
35}
36
37impl Event {
38    // TODO: We implement TryFrom so we should automatically get TryInto,
39    // but there's some compiler error.  Look into it later.
40    fn try_into(&self) -> Result<(esp_event_base_t, i32), error::Error> {
41        unsafe {
42            match self {
43                Self::Ip(event_id) => Ok((IP_EVENT, *event_id as i32)),
44                Self::Wifi(event_id) => Ok((WIFI_EVENT, *event_id as i32)),
45            }
46        }
47    }
48}
49
50impl convert::TryFrom<(esp_event_base_t, i32)> for Event {
51    type Error = error::Error;
52
53    fn try_from(value: (esp_event_base_t, i32)) -> Result<Self, Self::Error> {
54        use Event::*;
55        match EventBase::try_from(value.0) {
56            Ok(EventBase::Ip) => Ok(Ip(IpEvent::try_from(value.1)?)),
57            Ok(EventBase::Wifi) => Ok(Wifi(WifiEvent::try_from(value.1)?)),
58            Err(_) => Err(error::Error::UnknownEventBase),
59        }
60    }
61}
62
63impl convert::TryFrom<esp_event_base_t> for EventBase {
64    type Error = error::Error;
65
66    fn try_from(value: esp_event_base_t) -> Result<Self, Self::Error> {
67        unsafe {
68            use EventBase::*;
69            if value == IP_EVENT {
70                Ok(Ip)
71            } else if value == WIFI_EVENT {
72                Ok(Wifi)
73            } else {
74                Err(error::Error::UnknownEventBase)
75            }
76        }
77    }
78}
79
80impl convert::TryFrom<i32> for IpEvent {
81    type Error = error::Error;
82
83    fn try_from(value: i32) -> Result<Self, Self::Error> {
84        #[allow(non_upper_case_globals)]
85        match value as u32 {
86            ip_event_t_IP_EVENT_STA_GOT_IP => Ok(IpEvent::StaGotIp),
87            _ => Err(Error::UnknownEventBase),
88        }
89    }
90}
91
92impl convert::TryFrom<i32> for WifiEvent {
93    type Error = error::Error;
94
95    fn try_from(value: i32) -> Result<Self, Self::Error> {
96        #[allow(non_upper_case_globals)]
97        match value as u32 {
98            wifi_event_t_WIFI_EVENT_STA_START => Ok(WifiEvent::StaStart),
99            wifi_event_t_WIFI_EVENT_STA_DISCONNECTED => Ok(WifiEvent::StaDisconnected),
100            _ => Err(Error::UnknownEventBase),
101        }
102    }
103}
104
105pub mod events {
106    use super::*;
107    pub mod ip {
108        use super::*;
109        pub const StaGotIp: Event = Event::Ip(IpEvent::StaGotIp);
110    }
111    pub mod wifi {
112        use super::*;
113        pub const Any: Event = Event::Wifi(WifiEvent::Any);
114    }
115}
116
117pub type EventHandler = unsafe extern "C" fn(
118    event_handler_arg: *mut ::core::ffi::c_void,
119    event_base: esp_event_base_t,
120    event_id: i32,
121    event_data: *mut ::core::ffi::c_void,
122);
123
124pub fn handler_register(event: Event, event_handler: EventHandler) -> Result<(), error::Error> {
125    let (event_base, event_id) = event.try_into()?;
126    let retval = unsafe {
127        esp_event_handler_register(
128            event_base,
129            event_id,
130            Some(event_handler),
131            core::ptr::null_mut(),
132        )
133    };
134    esp_int_into_result(retval)
135}