1use defmt::{Format, println};
4use heapless::Vec;
5use num_enum::TryFromPrimitive;
6
7use crate::{
8 EspError,
9 WireType::{Len, Varint},
10 proto_data::{RpcId, RpcReqWifiInit, RpcReqWifiScanStart},
11 rpc::{Rpc, WireType, decode_tag, decode_varint, setup_rpc, write_rpc},
12 util::write_empty_msg,
13};
14const MAX_AP_RECORDS: usize = 30; pub fn parse_ap_records(data: &[u8]) -> Result<Vec<WifiApRecord, MAX_AP_RECORDS>, EspError> {
29 let mut result = Vec::new();
30
31 let mut i = 1; if data.len() == 0 {
33 println!("Empty data on parsing AP records.");
34 return Err(EspError::InvalidData);
35 }
36
37 let (num_records, nr_len) = decode_varint(&data[i..])?;
38 i += nr_len;
39
40 for _ in 0..num_records {
41 i += 1; if i >= data.len() {
44 return Err(EspError::InvalidData);
45 }
46
47 let (record_len, record_len_len) = decode_varint(&data[i..])?;
48 i += record_len_len;
49
50 let (record, _record_size) = WifiApRecord::from_bytes(&data[i..i + record_len as usize])?;
52 i += record_len as usize;
53
54 result.push(record).map_err(|_| EspError::Capacity)?;
55 }
56
57 Ok(result)
58}
59
60#[derive(Clone, Format)]
61pub struct InitConfig {
62 pub static_rx_buf_num: i32,
63 pub dynamic_rx_buf_num: i32,
64 pub tx_buf_type: i32,
65 pub static_tx_buf_num: i32,
66 pub dynamic_tx_buf_num: i32,
67 pub cache_tx_buf_num: i32,
68 pub csi_enable: i32,
70 pub ampdu_rx_enable: i32,
71 pub ampdu_tx_enable: i32,
72 pub amsdu_tx_enable: i32,
73 pub nvs_enable: i32,
75 pub nano_enable: i32,
76 pub rx_ba_win: i32,
77 pub wifi_task_core_id: i32,
79 pub beacon_max_len: i32,
80 pub mgmt_sbuf_num: i32,
81 pub feature_caps: u64,
82 pub sta_disconnected_pm: bool,
83 pub espnow_max_encrypt_num: i32,
84 pub magic: i32,
85}
86
87impl Default for InitConfig {
88 fn default() -> Self {
90 Self {
91 static_rx_buf_num: 10,
92 dynamic_rx_buf_num: 32,
93 tx_buf_type: 3, static_tx_buf_num: 0,
95 dynamic_tx_buf_num: 32,
96 cache_tx_buf_num: 32,
97 csi_enable: 0,
99 ampdu_rx_enable: 1,
100 ampdu_tx_enable: 1,
101 amsdu_tx_enable: 1,
102 nvs_enable: 1, nano_enable: 0,
105 rx_ba_win: 6, wifi_task_core_id: 0,
108 beacon_max_len: 752, mgmt_sbuf_num: 32,
110 feature_caps: 0,
111 sta_disconnected_pm: false,
112 espnow_max_encrypt_num: 7,
113 magic: 0x1F2F3F4F, }
115 }
116}
117
118impl InitConfig {
119 pub fn new_promiscuous() -> Self {
121 Self {
122 static_rx_buf_num: 10,
123 dynamic_rx_buf_num: 64,
124 tx_buf_type: 1,
125 static_tx_buf_num: 0,
126 dynamic_tx_buf_num: 32, cache_tx_buf_num: 0,
128 csi_enable: 0,
130 ampdu_rx_enable: 0,
131 ampdu_tx_enable: 0,
132 amsdu_tx_enable: 0,
133 nvs_enable: 0, nano_enable: 0,
136 rx_ba_win: 6, wifi_task_core_id: 0,
139 beacon_max_len: 752, mgmt_sbuf_num: 32,
141 feature_caps: 0,
142 sta_disconnected_pm: false,
143 espnow_max_encrypt_num: 0,
144 magic: 0x1F2F3F4F, }
146 }
147
148 pub fn to_bytes(&self, buf: &mut [u8]) -> usize {
149 let c = &self;
150 let v = WireType::Varint;
151
152 let mut i = 0;
153
154 write_rpc(buf, 1, v, c.static_rx_buf_num as u64, &mut i);
155 write_rpc(buf, 2, v, c.dynamic_rx_buf_num as u64, &mut i);
156 write_rpc(buf, 3, v, c.tx_buf_type as u64, &mut i);
157 write_rpc(buf, 4, v, c.static_tx_buf_num as u64, &mut i);
158 write_rpc(buf, 5, v, c.dynamic_tx_buf_num as u64, &mut i);
159 write_rpc(buf, 6, v, c.cache_tx_buf_num as u64, &mut i);
160 write_rpc(buf, 7, v, c.csi_enable as u64, &mut i);
161 write_rpc(buf, 8, v, c.ampdu_rx_enable as u64, &mut i);
162 write_rpc(buf, 9, v, c.ampdu_tx_enable as u64, &mut i);
163 write_rpc(buf, 10, v, c.amsdu_tx_enable as u64, &mut i);
164 write_rpc(buf, 11, v, c.nvs_enable as u64, &mut i);
165 write_rpc(buf, 12, v, c.nano_enable as u64, &mut i);
166 write_rpc(buf, 13, v, c.rx_ba_win as u64, &mut i);
167 write_rpc(buf, 14, v, c.wifi_task_core_id as u64, &mut i);
168 write_rpc(buf, 15, v, c.beacon_max_len as u64, &mut i);
169 write_rpc(buf, 16, v, c.mgmt_sbuf_num as u64, &mut i);
170 write_rpc(buf, 17, v, c.feature_caps, &mut i);
171 write_rpc(buf, 18, v, c.sta_disconnected_pm as u64, &mut i);
172 write_rpc(buf, 19, v, c.espnow_max_encrypt_num as u64, &mut i);
173 write_rpc(buf, 20, v, c.magic as u64, &mut i);
174
175 i
176 }
177}
178
179#[derive(Clone, Default, Format)]
180pub struct ActiveScanTime {
183 pub min: u32,
185 pub max: u32,
188}
189
190impl ActiveScanTime {
191 pub fn to_bytes(&self, buf: &mut [u8]) -> usize {
192 let mut i = 0;
193
194 write_rpc(buf, 1, Varint, self.min as u64, &mut i);
195 write_rpc(buf, 2, Varint, self.max as u64, &mut i);
196
197 i
198 }
199}
200
201#[derive(Clone, Default)]
204pub struct ScanTime {
205 pub active: ActiveScanTime,
206 pub passive: u32,
209}
210
211impl ScanTime {
212 pub fn to_bytes(&self, buf: &mut [u8]) -> usize {
213 let mut i = 0;
214
215 let mut scan_time_buf = [0; 8]; let active_size = self.active.to_bytes(&mut scan_time_buf);
218
219 write_rpc(buf, 1, Len, active_size as u64, &mut i);
220 buf[i..i + active_size].copy_from_slice(&scan_time_buf[..active_size]);
221 i += active_size;
222
223 write_rpc(buf, 2, Varint, self.passive as u64, &mut i);
224
225 i
226 }
227}
228
229#[derive(Clone, Copy, PartialEq, Default, TryFromPrimitive, Format)]
230#[repr(u8)]
231pub enum ScanType {
232 #[default]
233 Active = 0,
234 Passive = 1,
235}
236
237#[derive(Default)]
241pub struct ScanConfig {
242 pub ssid: Vec<u8, 33>,
244 pub bssid: Vec<u8, 6>,
245 pub channel: u8,
247 pub show_hidden: bool,
249 pub scan_type: ScanType,
251 pub scan_time: ScanTime,
252 pub home_chan_dwell_time: u8,
253}
254
255impl ScanConfig {
256 pub fn to_bytes(&self, buf: &mut [u8]) -> usize {
257 let mut i = 0;
258
259 write_rpc(buf, 1, Len, self.ssid.len() as u64, &mut i);
260 buf[i..i + self.ssid.len()].copy_from_slice(&self.ssid);
261 i += self.ssid.len();
262
263 write_rpc(buf, 2, Len, self.bssid.len() as u64, &mut i);
264 buf[i..i + self.bssid.len()].copy_from_slice(&self.bssid);
265 i += self.bssid.len();
266
267 write_rpc(buf, 3, Varint, self.channel as u64, &mut i);
268 write_rpc(buf, 4, Varint, self.show_hidden as u64, &mut i);
269 write_rpc(buf, 5, Varint, self.scan_type as u64, &mut i);
270
271 let mut scan_time_buf = [0; 14]; let scan_time_size = self.scan_time.to_bytes(&mut scan_time_buf);
274
275 write_rpc(buf, 6, Len, scan_time_size as u64, &mut i);
276 buf[i..i + scan_time_size].copy_from_slice(&scan_time_buf[..scan_time_size]);
277 i += scan_time_size;
278
279 write_rpc(buf, 7, Varint, self.home_chan_dwell_time as u64, &mut i);
280
281 i
282 }
283}
284
285#[derive(Clone, Copy, PartialEq, Default, Format, TryFromPrimitive)]
287#[repr(u8)]
288pub enum WifiSecondChan {
289 #[default]
290 None = 0,
291 Above = 1,
292 Below = 2,
293}
294
295#[derive(Clone, Copy, PartialEq, Default, Format, TryFromPrimitive)]
300#[repr(u8)]
301pub enum WifiAuthMode {
302 #[default]
303 Open = 0,
304 WEP = 1,
305 WPA_PSK = 2,
306 WPA2_PSK = 3,
307 WPA_WPA2_PSK = 4,
308 ENTERPRISE = 5,
309 WPA2_ENTERPRISE = 6,
310 WPA3_PSK = 7,
311 }
313
314#[derive(Clone, Copy, PartialEq, Default, Format, TryFromPrimitive)]
316#[repr(u8)]
317pub enum WifiCipher {
318 #[default]
319 None = 0,
320 WEP40 = 1,
321 WEP104 = 2,
322 TKIP = 3,
323 CCMP = 4,
324 TKIP_CCMP = 5,
325 AES_CMAC128 = 6,
326 SMS4 = 7,
327 GCMP = 8,
328 GCMP256 = 9,
329 AES_GMAC128 = 10,
330 AES_GMAC256 = 11,
331 UNKNOWN = 12, }
333
334#[derive(Clone, Copy, PartialEq, Default, Format, TryFromPrimitive)]
336#[repr(u8)]
337pub enum WifiAnt {
338 #[default]
339 Ant0 = 0,
340 Ant1 = 1,
341 Max = 2,
343}
344
345#[derive(Default, Format)]
348pub struct WifiCountry {
349 pub cc: [u8; 3],
351 pub schan: u8,
353 pub nchan: u8,
355 pub max_tx_power: i8,
356 pub policy: u8,
358}
359
360#[derive(Clone, Copy, PartialEq, Default, Format, TryFromPrimitive)]
362#[repr(u8)]
363pub enum WifiBandwidth {
364 #[default]
365 HT20 = 0,
366 BW20 = 1,
368 BW_HT40 = 2,
369 BW40 = 3,
371 BW80 = 4,
372 BW160 = 5,
373 BW80_BW80 = 6,
375}
376
377#[derive(Default, Format)]
379pub struct WifiHeApInfo {
381 pub bitmask: u32,
382 pub bssid_index: u32,
383}
384
385#[derive(Default)]
389pub struct WifiApRecord {
390 pub bssid: [u8; 6],
391 pub ssid: Vec<u8, 33>,
392 pub primary: u8,
394 pub second: WifiSecondChan,
395 pub rssi: i8,
396 pub authmode: WifiAuthMode,
397 pub pairwise_cipher: WifiCipher,
398 pub group_cipher: WifiCipher,
399 pub ant: WifiAnt,
401 pub bitmask: u32,
403 pub country: WifiCountry,
404 pub he_ap: WifiHeApInfo,
405 pub bandwidth: WifiBandwidth,
409 pub vht_ch_freq1: u8,
413 pub vht_ch_freq2: u8,
416}
417
418impl WifiApRecord {
419 pub fn from_bytes(buf: &[u8]) -> Result<(Self, usize), EspError> {
420 let mut i = 0;
421 let mut result = Self::default();
422
423 loop {
424 if i >= buf.len() {
425 break;
426 }
427 let (tag, tag_len) = decode_varint(&buf[i..])?;
428 i += tag_len;
429
430 let (field, _wire_type) = decode_tag(tag as u16);
431
432 match field {
433 1 => {
434 let (field_len, field_len_len) = decode_varint(&buf[i..])?;
435 i += field_len_len;
436 if i + field_len as usize >= buf.len() {
439 return Err(EspError::Capacity);
440 }
441
442 result
443 .bssid
444 .copy_from_slice(&buf[i..i + field_len as usize]);
445 i += field_len as usize;
446 }
447 2 => {
448 let (field_len, field_len_len) = decode_varint(&buf[i..])?;
449 i += field_len_len;
450 if i + field_len as usize >= buf.len() {
453 return Err(EspError::Capacity);
454 }
455
456 result.ssid = Vec::<_, 33>::from_slice(&buf[i..i + field_len as usize])
457 .map_err(|_| EspError::InvalidData)?;
458 i += field_len as usize;
459 }
460 3 => {
461 result.primary = buf[i];
462 i += 1;
463 }
464 4 => {
465 result.second = buf[i].try_into().unwrap_or_default();
466 i += 1;
467 }
468 5 => {
469 result.rssi = buf[i] as i8;
470 i += 10; }
472 6 => {
473 result.authmode = buf[i].try_into().unwrap_or_default();
474 i += 1;
475 }
476 7 => {
477 result.pairwise_cipher = buf[i].try_into().unwrap_or_default();
478 i += 1;
479 }
480 8 => {
481 result.group_cipher = buf[i].try_into().unwrap_or_default();
482 i += 1;
483 }
484 9 => {
485 result.ant = buf[i].try_into().unwrap_or_default();
486 i += 1;
487 }
488 10 => {
489 let (val, len) = decode_varint(&buf[i..])?;
490 result.bitmask = val as u32;
491 i += len;
492 }
493 11 => {
494 let (country_len, country_len_len) = decode_varint(&buf[i..])?;
495 i += country_len_len;
496 i += country_len as usize;
498 }
499 12 => {
500 let (he_ap_len, he_ap_len_len) = decode_varint(&buf[i..])?;
501 i += he_ap_len_len;
502 i += he_ap_len as usize;
504 }
505 13 => {
506 result.bandwidth = buf[i].try_into().unwrap_or_default();
507 i += 1;
508 }
509 14 => {
510 result.vht_ch_freq1 = buf[i];
511 i += 1;
512 }
513 15 => {
514 result.vht_ch_freq2 = buf[i];
515 i += 1;
516 }
517 _ => {
518 println!("Unparsed field: {:?}", field);
519 }
520 }
521 }
522
523 Ok((result, i))
524 }
525}
526
527#[derive(Clone, Copy, Format)]
529#[repr(u8)]
530pub enum InterfaceType {
531 Station = 0,
532 Ap = 1,
533}
534
535#[derive(Clone, Copy, Format)]
537#[repr(u8)]
538pub enum WifiMode {
539 Null = 0,
540 Station = 1,
542 SoftAp = 2,
544 ApStation = 3,
546}
547
548pub fn start<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
553where
554 W: FnMut(&[u8]) -> Result<(), EspError>,
555{
556 write_empty_msg(buf, write, uid, RpcId::ReqWifiStart)
557}
558
559pub fn stop<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
564where
565 W: FnMut(&[u8]) -> Result<(), EspError>,
566{
567 write_empty_msg(buf, write, uid, RpcId::ReqWifiStop)
568}
569
570pub fn scan_get_ap_num<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
573where
574 W: FnMut(&[u8]) -> Result<(), EspError>,
575{
576 write_empty_msg(buf, write, uid, RpcId::ReqWifiScanGetApNum)
577}
578
579pub fn scan_get_ap_record<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
582where
583 W: FnMut(&[u8]) -> Result<(), EspError>,
584{
585 write_empty_msg(buf, write, uid, RpcId::ReqWifiScanGetApRecord)
586}
587
588pub fn clear_ap_list<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
593where
594 W: FnMut(&[u8]) -> Result<(), EspError>,
595{
596 write_empty_msg(buf, write, uid, RpcId::ReqWifiClearApList)
597}
598
599pub fn scan_get_ap_records<W>(
602 buf: &mut [u8],
603 mut write: W,
604 uid: u32,
605 max_number: u8,
606) -> Result<(), EspError>
607where
608 W: FnMut(&[u8]) -> Result<(), EspError>,
609{
610 let rpc = Rpc::new_req(RpcId::ReqWifiScanGetApRecords, uid);
611
612 let mut data = [0; 2];
613
614 let mut i = 0;
615 write_rpc(&mut data, 1, WireType::Varint, max_number as u64, &mut i);
616
617 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
618 write(&buf[..frame_len])?;
619
620 Ok(())
621}
622
623pub fn ap_get_sta_list<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
624where
625 W: FnMut(&[u8]) -> Result<(), EspError>,
626{
627 write_empty_msg(buf, write, uid, RpcId::ReqWifiApGetStaList)
628}
629
630pub fn get_mode<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
631where
632 W: FnMut(&[u8]) -> Result<(), EspError>,
633{
634 write_empty_msg(buf, write, uid, RpcId::ReqGetWifiMode)
635}
636
637pub fn set_mode<W>(buf: &mut [u8], mut write: W, uid: u32, mode: WifiMode) -> Result<(), EspError>
644where
645 W: FnMut(&[u8]) -> Result<(), EspError>,
646{
647 let rpc = Rpc::new_req(RpcId::ReqSetWifiMode, uid);
648
649 let mut data = [0; 2];
650
651 let mut i = 0;
652 write_rpc(&mut data, 1, WireType::Varint, mode as u64, &mut i);
653
654 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
655 write(&buf[..frame_len])?;
656
657 Ok(())
658}
659
660pub fn init<W>(buf: &mut [u8], mut write: W, uid: u32, cfg: &InitConfig) -> Result<(), EspError>
664where
665 W: FnMut(&[u8]) -> Result<(), EspError>,
666{
667 let rpc = Rpc::new_req(RpcId::ReqWifiInit, uid);
668
669 let mut data = [0; 85]; let pl = RpcReqWifiInit {
673 cfg: cfg.clone(), };
675
676 let data_len = pl.to_bytes(&mut data);
677
678 let frame_len = setup_rpc(buf, &rpc, &data[..data_len]);
679 write(&buf[..frame_len])?;
680
681 Ok(())
682}
683
684pub fn deinit<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
687where
688 W: FnMut(&[u8]) -> Result<(), EspError>,
689{
690 write_empty_msg(buf, write, uid, RpcId::ReqWifiDeinit)
691}
692
693#[derive(Clone, Copy, PartialEq, Format)]
698#[repr(u8)]
699pub enum PromiscuousPktType {
700 Mgmt = 0,
702 Ctrl = 1,
704 Data = 2,
706 Misc = 3,
708}
709
710#[derive(Format, Default)]
711pub struct PromiscuousFilter {
713 pub mgmt: bool,
714 pub ctrl: bool,
715 pub data: bool,
716 pub misc: bool,
717 pub data_mpdu: bool,
718 pub data_ampdu: bool,
719 pub fcsfail: bool,
720}
721
722impl PromiscuousFilter {
723 pub fn val(&self) -> u32 {
724 let mut result = 0;
725 if self.mgmt {
726 result |= 1 << 0;
727 }
728 if self.ctrl {
729 result |= 1 << 1;
730 }
731 if self.data {
732 result |= 1 << 2;
733 }
734 if self.misc {
735 result |= 1 << 3;
736 }
737 if self.data_mpdu {
738 result |= 1 << 4;
739 }
740 if self.data_ampdu {
741 result |= 1 << 5;
742 }
743 if self.fcsfail {
744 result |= 1 << 6;
745 }
746 result
747 }
748}
749
750#[derive(Format, Default)]
751pub struct PromiscuousCtrlFilter {
753 pub wrapper: bool,
754 pub bar: bool,
755 pub ba: bool,
756 pub pspoll: bool,
757 pub rts: bool,
758 pub cts: bool,
759 pub ack: bool,
760 pub cfend: bool,
761 pub cfendack: bool,
762}
763
764impl PromiscuousCtrlFilter {
765 pub fn val(&self) -> u32 {
766 let mut result = 0;
767 if self.wrapper {
768 result |= 1 << 0;
769 }
770 if self.bar {
771 result |= 1 << 1;
772 }
773 if self.ba {
774 result |= 1 << 2;
775 }
776 if self.pspoll {
777 result |= 1 << 3;
778 }
779 if self.rts {
780 result |= 1 << 4;
781 }
782 if self.cts {
783 result |= 1 << 5;
784 }
785 if self.ack {
786 result |= 1 << 6;
787 }
788 if self.cfend {
789 result |= 1 << 7;
790 }
791 if self.cfendack {
792 result |= 1 << 8;
793 }
794 result
795 }
796}
797
798pub fn set_promiscuous<W>(
801 buf: &mut [u8],
802 mut write: W,
803 uid: u32,
804 enabled: bool,
805 filter: &PromiscuousFilter,
806 ctrl_filter: Option<&PromiscuousCtrlFilter>,
807) -> Result<(), EspError>
808where
809 W: FnMut(&[u8]) -> Result<(), EspError>,
810{
811 let rpc = Rpc::new_req(RpcId::ReqWifiSetPromiscuous, uid);
815
816 let mut data = [0; 6];
817
818 let mut i = 0;
819 write_rpc(&mut data, 1, WireType::Varint, enabled as u64, &mut i);
820
821 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
822 write(&buf[..frame_len])?;
823
824 let rpc = Rpc::new_req(RpcId::ReqWifiSetPromiscuousFilter, uid);
826
827 let mut i = 0;
828 write_rpc(&mut data, 1, WireType::Len, 1, &mut i);
832 write_rpc(&mut data, 1, WireType::Varint, 1, &mut i); write_rpc(&mut data, 1, WireType::Varint, filter.val() as u64, &mut i);
835
836 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
837 write(&buf[..frame_len])?;
838
839 if let Some(f) = ctrl_filter {
841 let rpc = Rpc::new_req(RpcId::ReqWifiSetPromiscuousCtrlFilter, uid);
842
843 let mut i = 0;
844
845 write_rpc(&mut data, 1, WireType::Len, 1, &mut i);
846 write_rpc(&mut data, 1, WireType::Varint, 1, &mut i); write_rpc(&mut data, 1, WireType::Varint, f.val() as u64, &mut i);
849
850 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
851 write(&buf[..frame_len])?;
852 }
853
854 Ok(())
855}
856
857pub fn get_promiscuous<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
860where
861 W: FnMut(&[u8]) -> Result<(), EspError>,
862{
863 write_empty_msg(buf, write, uid, RpcId::ReqWifiGetPromiscuous)
864}
865
866pub fn get_promiscuous_filter<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
869where
870 W: FnMut(&[u8]) -> Result<(), EspError>,
871{
872 write_empty_msg(buf, write, uid, RpcId::ReqWifiGetPromiscuousFilter)
873}
874
875pub fn get_promiscuous_ctrl_filter<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
878where
879 W: FnMut(&[u8]) -> Result<(), EspError>,
880{
881 write_empty_msg(buf, write, uid, RpcId::ReqWifiGetPromiscuousCtrlFilter)
882}
883
884pub fn scan_start<W>(
887 buf: &mut [u8],
888 mut write: W,
889 uid: u32,
890 scan_start: &RpcReqWifiScanStart,
891) -> Result<(), EspError>
892where
893 W: FnMut(&[u8]) -> Result<(), EspError>,
894{
895 let rpc = Rpc::new_req(RpcId::ReqWifiScanStart, uid);
896
897 let mut data = [0; 100];
898 let data_size = scan_start.to_bytes(&mut data);
899
900 let frame_len = setup_rpc(buf, &rpc, &data[..data_size]);
901 write(&buf[..frame_len])?;
902
903 Ok(())
904}
905
906pub fn scan_stop<W>(buf: &mut [u8], write: W, uid: u32) -> Result<(), EspError>
909where
910 W: FnMut(&[u8]) -> Result<(), EspError>,
911{
912 write_empty_msg(buf, write, uid, RpcId::ReqWifiScanStop)
913}
914
915#[derive(Format)]
916pub struct Protocols {
917 pub p_11b: bool,
919 pub p_11g: bool,
921 pub p_11n: bool,
923 pub p_lr: bool,
925 pub p_11ax: bool,
927 pub wps: bool,
929 pub p_11a: bool,
931 pub p_11ac: bool,
932}
933
934impl Default for Protocols {
935 fn default() -> Self {
937 Self {
938 p_11b: true,
939 p_11g: true,
940 p_11n: true,
941 p_lr: false,
942 p_11ax: false,
943 wps: false,
944 p_11a: false,
945 p_11ac: false,
946 }
948 }
949}
950
951impl Protocols {
952 pub fn to_byte(&self) -> u8 {
953 (self.p_11b as u8)
954 | ((self.p_11g as u8) << 1)
955 | ((self.p_11n as u8) << 2)
956 | ((self.p_lr as u8) << 3)
957 | ((self.p_11ac as u8) << 5)
958 | ((self.p_11ax as u8) << 6)
959 }
960
961 pub fn from_byte(b: u8) -> Self {
962 Self {
963 p_11b: b & 1 != 0,
964 p_11g: (b >> 1) & 1 != 0,
965 p_11n: (b >> 2) & 1 != 0,
966 p_lr: (b >> 3) & 1 != 0,
967 p_11ax: (b >> 4) & 1 != 0,
968 wps: (b >> 5) & 1 != 0,
969 p_11a: false,
970 p_11ac: false,
971 }
975 }
976}
977
978pub fn set_protocol<W>(
984 buf: &mut [u8],
985 mut write: W,
986 uid: u32,
987 ifx: InterfaceType,
988 protocols: &Protocols,
989) -> Result<(), EspError>
990where
991 W: FnMut(&[u8]) -> Result<(), EspError>,
992{
993 let rpc = Rpc::new_req(RpcId::ReqWifiSetProtocol, uid);
994
995 let mut data = [0; 4];
996 let mut i = 0;
997
998 write_rpc(&mut data, 1, WireType::Varint, ifx as u64, &mut i);
999 write_rpc(
1000 &mut data,
1001 2,
1002 WireType::Varint,
1003 protocols.to_byte() as u64,
1004 &mut i,
1005 );
1006
1007 let frame_len = setup_rpc(buf, &rpc, &data[0..i]);
1008 write(&buf[..frame_len])?;
1009
1010 Ok(())
1011}
1012
1013pub fn get_protocol<W>(buf: &mut [u8], mut write: W, uid: u32) -> Result<(), EspError>
1016where
1017 W: FnMut(&[u8]) -> Result<(), EspError>,
1018{
1019 let rpc = Rpc::new_req(RpcId::ReqWifiGetProtocol, uid);
1020
1021 let mut data = [0; 4];
1022 let mut i = 0;
1023
1024 let interface_num = 0; write_rpc(&mut data, 1, WireType::Varint, interface_num, &mut i);
1026
1027 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
1028 write(&buf[..frame_len])?;
1029
1030 Ok(())
1031}
1032
1033pub fn set_ps<W>(buf: &mut [u8], mut write: W, uid: u32) -> Result<(), EspError>
1036where
1037 W: FnMut(&[u8]) -> Result<(), EspError>,
1038{
1039 let rpc = Rpc::new_req(RpcId::ReqWifiGetProtocol, uid);
1040
1041 let mut data = [0; 4];
1042 let mut i = 0;
1043
1044 let interface_num = 0; write_rpc(&mut data, 1, WireType::Varint, interface_num, &mut i);
1046
1047 let frame_len = setup_rpc(buf, &rpc, &data[..i]);
1048 write(&buf[..frame_len])?;
1049
1050 Ok(())
1051}