aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs85
-rw-r--r--src/structs.rs3
2 files changed, 64 insertions, 24 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 271917971..6a1b7970c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -184,10 +184,14 @@ enum IoctlState {
184 kind: u32, 184 kind: u32,
185 cmd: u32, 185 cmd: u32,
186 iface: u32, 186 iface: u32,
187 buf: *const [u8], 187 buf: *mut [u8],
188 },
189 Sent {
190 buf: *mut [u8],
191 },
192 Done {
193 resp_len: usize,
188 }, 194 },
189 Sent,
190 Done,
191} 195}
192 196
193pub struct State { 197pub struct State {
@@ -237,9 +241,12 @@ impl<'a> Control<'a> {
237 buf[0..8].copy_from_slice(b"clmload\x00"); 241 buf[0..8].copy_from_slice(b"clmload\x00");
238 buf[8..20].copy_from_slice(&header.to_bytes()); 242 buf[8..20].copy_from_slice(&header.to_bytes());
239 buf[20..][..chunk.len()].copy_from_slice(&chunk); 243 buf[20..][..chunk.len()].copy_from_slice(&chunk);
240 self.ioctl(2, 263, 0, &buf[..8 + 12 + chunk.len()]).await; 244 self.ioctl(2, 263, 0, &mut buf[..8 + 12 + chunk.len()]).await;
241 } 245 }
242 246
247 // check clmload ok
248 assert_eq!(self.get_iovar_u32("clmload_status").await, 0);
249
243 info!("Configuring misc stuff..."); 250 info!("Configuring misc stuff...");
244 251
245 self.set_iovar_u32("bus:txglom", 0).await; 252 self.set_iovar_u32("bus:txglom", 0).await;
@@ -275,7 +282,7 @@ impl<'a> Control<'a> {
275 self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; 282 self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await;
276 283
277 // set wifi up 284 // set wifi up
278 self.ioctl(2, 2, 0, &[]).await; 285 self.ioctl(2, 2, 0, &mut []).await;
279 286
280 Timer::after(Duration::from_millis(100)).await; 287 Timer::after(Duration::from_millis(100)).await;
281 288
@@ -299,7 +306,7 @@ impl<'a> Control<'a> {
299 ssid: [0; 32], 306 ssid: [0; 32],
300 }; 307 };
301 i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes()); 308 i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes());
302 self.ioctl(2, 26, 0, &i.to_bytes()).await; // set_ssid 309 self.ioctl(2, 26, 0, &mut i.to_bytes()).await; // set_ssid
303 310
304 info!("JOINED"); 311 info!("JOINED");
305 } 312 }
@@ -310,10 +317,18 @@ impl<'a> Control<'a> {
310 buf[4..8].copy_from_slice(&val2.to_le_bytes()); 317 buf[4..8].copy_from_slice(&val2.to_le_bytes());
311 self.set_iovar(name, &buf).await 318 self.set_iovar(name, &buf).await
312 } 319 }
320
313 async fn set_iovar_u32(&mut self, name: &str, val: u32) { 321 async fn set_iovar_u32(&mut self, name: &str, val: u32) {
314 self.set_iovar(name, &val.to_le_bytes()).await 322 self.set_iovar(name, &val.to_le_bytes()).await
315 } 323 }
316 324
325 async fn get_iovar_u32(&mut self, name: &str) -> u32 {
326 let mut buf = [0; 4];
327 let len = self.get_iovar(name, &mut buf).await;
328 assert_eq!(len, 4);
329 u32::from_le_bytes(buf)
330 }
331
317 async fn set_iovar(&mut self, name: &str, val: &[u8]) { 332 async fn set_iovar(&mut self, name: &str, val: &[u8]) {
318 info!("set {} = {:02x}", name, val); 333 info!("set {} = {:02x}", name, val);
319 334
@@ -323,14 +338,28 @@ impl<'a> Control<'a> {
323 buf[name.len() + 1..][..val.len()].copy_from_slice(val); 338 buf[name.len() + 1..][..val.len()].copy_from_slice(val);
324 339
325 let total_len = name.len() + 1 + val.len(); 340 let total_len = name.len() + 1 + val.len();
326 self.ioctl(2, 263, 0, &buf[..total_len]).await; 341 self.ioctl(2, 263, 0, &mut buf).await;
342 }
343
344 async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize {
345 info!("get {}", name);
346
347 let mut buf = [0; 64];
348 buf[..name.len()].copy_from_slice(name.as_bytes());
349 buf[name.len()] = 0;
350
351 let total_len = name.len() + 1 + res.len();
352 let res_len = self.ioctl(2, 262, 0, &mut buf[..total_len]).await - name.len() - 1;
353 res[..res_len].copy_from_slice(&buf[name.len() + 1..][..res_len]);
354 res_len
327 } 355 }
328 356
329 async fn ioctl_set_u32(&mut self, cmd: u32, iface: u32, val: u32) { 357 async fn ioctl_set_u32(&mut self, cmd: u32, iface: u32, val: u32) {
330 self.ioctl(2, cmd, 0, &val.to_le_bytes()).await 358 let mut buf = val.to_le_bytes();
359 self.ioctl(2, cmd, 0, &mut buf).await;
331 } 360 }
332 361
333 async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &[u8]) { 362 async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &mut [u8]) -> usize {
334 // TODO cancel ioctl on future drop. 363 // TODO cancel ioctl on future drop.
335 364
336 while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) { 365 while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) {
@@ -343,11 +372,16 @@ impl<'a> Control<'a> {
343 .ioctl_state 372 .ioctl_state
344 .set(IoctlState::Pending { kind, cmd, iface, buf }); 373 .set(IoctlState::Pending { kind, cmd, iface, buf });
345 374
346 while !matches!(self.state.ioctl_state.get(), IoctlState::Done) { 375 let resp_len = loop {
376 if let IoctlState::Done { resp_len } = self.state.ioctl_state.get() {
377 break resp_len;
378 }
347 yield_now().await; 379 yield_now().await;
348 } 380 };
349 381
350 self.state.ioctl_state.set(IoctlState::Idle); 382 self.state.ioctl_state.set(IoctlState::Idle);
383
384 resp_len
351 } 385 }
352} 386}
353 387
@@ -519,7 +553,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
519 // Send stuff 553 // Send stuff
520 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { 554 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() {
521 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get()); 555 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get());
522 self.state.ioctl_state.set(IoctlState::Sent); 556 self.state.ioctl_state.set(IoctlState::Sent { buf });
523 } 557 }
524 558
525 // Receive stuff 559 // Receive stuff
@@ -546,7 +580,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
546 } 580 }
547 self.cs.set_high(); 581 self.cs.set_high();
548 582
549 //info!("rx {:02x}", &buf[..(len as usize).min(36)]); 583 trace!("rx {:02x}", &buf[..(len as usize).min(48)]);
550 584
551 self.rx(&buf[..len as usize]); 585 self.rx(&buf[..len as usize]);
552 } 586 }
@@ -564,7 +598,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
564 } 598 }
565 599
566 let sdpcm_header = SdpcmHeader::from_bytes(packet[..SdpcmHeader::SIZE].try_into().unwrap()); 600 let sdpcm_header = SdpcmHeader::from_bytes(packet[..SdpcmHeader::SIZE].try_into().unwrap());
567 601 trace!("rx {:?}", sdpcm_header);
568 if sdpcm_header.len != !sdpcm_header.len_inv { 602 if sdpcm_header.len != !sdpcm_header.len_inv {
569 warn!("len inv mismatch"); 603 warn!("len inv mismatch");
570 return; 604 return;
@@ -587,15 +621,21 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
587 } 621 }
588 622
589 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap()); 623 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap());
624 trace!(" {:?}", cdc_header);
590 625
591 if cdc_header.id == self.state.ioctl_id.get() { 626 if let IoctlState::Sent { buf } = self.state.ioctl_state.get() {
592 assert_eq!(cdc_header.status, 0); // todo propagate error 627 if cdc_header.id == self.state.ioctl_id.get() {
593 self.state.ioctl_state.set(IoctlState::Done); 628 assert_eq!(cdc_header.status, 0); // todo propagate error instead
629
630 let resp_len = cdc_header.len as usize;
631 (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]);
632 self.state.ioctl_state.set(IoctlState::Done { resp_len });
633 }
594 } 634 }
595 } 635 }
596 1 => { 636 1 => {
597 let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap()); 637 let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap());
598 //info!("{}", bcd_header); 638 trace!(" {:?}", bcd_header);
599 639
600 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize; 640 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize;
601 if packet_start > payload.len() { 641 if packet_start > payload.len() {
@@ -603,7 +643,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
603 return; 643 return;
604 } 644 }
605 let packet = &payload[packet_start..]; 645 let packet = &payload[packet_start..];
606 //info!("rx {:02x}", &packet[..(packet.len() as usize).min(36)]); 646 trace!(" {:02x}", &packet[..(packet.len() as usize).min(36)]);
607 647
608 let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap()); 648 let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap());
609 evt.byteswap(); 649 evt.byteswap();
@@ -642,12 +682,13 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
642 682
643 let cdc_header = CdcHeader { 683 let cdc_header = CdcHeader {
644 cmd: cmd, 684 cmd: cmd,
645 out_len: data.len() as _, 685 len: data.len() as _,
646 in_len: 0,
647 flags: kind as u16 | (iface as u16) << 12, 686 flags: kind as u16 | (iface as u16) << 12,
648 id, 687 id,
649 status: 0, 688 status: 0,
650 }; 689 };
690 trace!("tx {:?}", sdpcm_header);
691 trace!(" {:?}", cdc_header);
651 692
652 buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); 693 buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes());
653 buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); 694 buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes());
@@ -655,7 +696,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
655 696
656 let total_len = (total_len + 3) & !3; // round up to 4byte 697 let total_len = (total_len + 3) & !3; // round up to 4byte
657 698
658 //info!("tx {:02x}", &buf[..total_len.min(48)]); 699 trace!(" {:02x}", &buf[..total_len.min(48)]);
659 700
660 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); 701 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _);
661 self.cs.set_low(); 702 self.cs.set_low();
diff --git a/src/structs.rs b/src/structs.rs
index beda9f364..91df616ad 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -42,8 +42,7 @@ impl_bytes!(SdpcmHeader);
42#[repr(C)] 42#[repr(C)]
43pub struct CdcHeader { 43pub struct CdcHeader {
44 pub cmd: u32, 44 pub cmd: u32,
45 pub out_len: u16, 45 pub len: u32,
46 pub in_len: u16,
47 pub flags: u16, 46 pub flags: u16,
48 pub id: u16, 47 pub id: u16,
49 pub status: u32, 48 pub status: u32,