1use hex_literal::hex;
5use iso7816::command::writer::IntoWriter;
6use iso7816::command::Writer;
7
8pub type Crc = crc16::State<crc16::X_25>;
9
10use core::fmt::{self, Debug};
11use core::ops::Not;
12
13use crate::embedded_hal::{
14 i2c::{Read, Write, WriteRead},
15 Delay,
16};
17use crate::macros::enum_u8;
18
19mod i2cimpl;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct Atr<'a> {
23 pub pver: u8,
25 pub vid: &'a [u8; 5],
27 pub bwt: u16,
29 pub ifsc: u16,
31 pub plid: u8,
33 pub mcf: u16,
35 pub config: u8,
36 pub mpot: u8,
38 pub segt: u16,
40 pub wut: u16,
42 pub historical_bytes: &'a [u8],
43}
44
45impl Default for Atr<'_> {
46 fn default() -> Self {
47 Self {
48 pver: 1,
49 vid: &hex!("FFFFFFFFFF"),
50 bwt: 0,
51 ifsc: MAX_FRAME_DATA_LEN as _,
52 plid: 0,
53 mcf: 0,
54 config: 0,
55 mpot: 1,
56 segt: SEGT_US as _,
57 wut: 0,
58 historical_bytes: &[],
59 }
60 }
61}
62
63impl<'a> Atr<'a> {
64 pub fn parse(data: &'a [u8]) -> Result<Self, Error> {
66 debug!("Parsing atr: {data:02x?}");
68 if data.len() < 7 {
69 error!("ATR Error 1");
70 return Err(Error::Line(line!()));
71 }
72 let pver = data[0];
73 let vid: &[u8; 5] = (&data[1..][..5]).try_into().unwrap();
74 let dllp_len = data[6];
75
76 let rem = &data[7..];
77
78 if rem.len() < dllp_len as usize || dllp_len < 2 {
79 error!("ATR Error 2");
80 return Err(Error::Line(line!()));
81 }
82 let (dllp, rem) = rem.split_at(dllp_len as usize);
83
84 let [bwt1, bwt2, ifsc1, ifsc2, ..] = dllp else {
85 error!("ATR Error 3");
86 return Err(Error::Line(line!()));
87 };
88 let bwt = u16::from_be_bytes([*bwt1, *bwt2]);
89 let ifsc = u16::from_be_bytes([*ifsc1, *ifsc2]);
90
91 if rem.len() < 2 {
92 error!("ATR Error 4");
93 return Err(Error::Line(line!()));
94 }
95
96 let plid = rem[0];
97 let plp_len = rem[1];
98 let rem = &rem[2..];
99 if rem.len() < plp_len as usize {
100 error!("ATR Error 6");
101 return Err(Error::Line(line!()));
102 }
103 let (plp, rem) = rem.split_at(plp_len as usize);
104 let [mcf1, mcf2, config, mpot, _rfu1, _rfu2, _rfu3, segt1, segt2, wut1, wut2, ..] = plp
105 else {
106 error!("ATR Error 7");
107 return Err(Error::Line(line!()));
108 };
109 let mcf = u16::from_be_bytes([*mcf1, *mcf2]);
110 let segt = u16::from_be_bytes([*segt1, *segt2]);
111 let wut = u16::from_be_bytes([*wut1, *wut2]);
112
113 if rem.is_empty() {
114 error!("ATR Error 8");
115 return Err(Error::Line(line!()));
116 }
117 let hb_len = rem[0];
118 let rem = &rem[1..];
119 if rem.len() < hb_len as usize {
120 error!("ATR Error 9");
121 return Err(Error::Line(line!()));
122 }
123
124 let historical_bytes = &rem[..hb_len as usize];
125
126 Ok(Self {
127 pver,
128 vid,
129 bwt,
130 ifsc,
131 plid,
132 mcf,
133 config: *config,
134 mpot: *mpot,
135 segt,
136 wut,
137 historical_bytes,
138 })
139 }
140}
141
142#[derive(PartialEq, Eq, Clone, Copy, Debug)]
143pub struct Seq(bool);
144
145impl Seq {
146 pub const ZERO: Self = Seq(false);
147 pub const ONE: Self = Seq(true);
148}
149
150impl Not for Seq {
151 type Output = Self;
152 fn not(self) -> Self::Output {
153 Seq(!self.0)
154 }
155}
156
157#[derive(PartialEq, Eq, Clone, Copy, Debug)]
158pub enum Pcb {
159 I(Seq, bool), S(SBlock), R(Seq, RBlockError), }
163
164enum_u8!(
165 #[rustfmt::skip]
166 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
167 pub enum SBlock {
168 ResyncRequest = 0b11000000,
169 ResyncResponse = 0b11100000,
170 IfsRequest = 0b11000001,
171 IfsResponse = 0b11100001,
172 AbortRequest = 0b11000010,
173 AbortResponse = 0b11100010,
174 WtxRequest = 0b11000011,
175 WtxResponse = 0b11100011,
176 InterfaceSoftResetRequest = 0b11001111,
177 InterfaceSoftResetResponse = 0b11101111,
178 EndOfApduSessionRequest = 0b11000101,
179 EndOfApduSessionResponse = 0b11100101,
180 SeChipResetRequest = 0b11000110,
181 SeChipResetResponse = 0b11100110,
182 GetAtrRequest = 0b11000111,
183 GetAtrResponse = 0b11100111,
184 }
185);
186
187enum_u8!(
188 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
189 pub enum RBlockError {
190 #![mask(0b11)]
191 NoError = 0b00,
192 CrcError = 0b01,
193 OtherError = 0b10,
194 }
195);
196
197const I_BLOCK_PCB_MASK: u8 = 0b10011111;
199const I_BLOCK_PCB: u8 = 0b00000000;
201const I_BLOCK_SEQ: u8 = 0b01000000;
203const I_BLOCK_MOR: u8 = 0b00100000;
205
206const R_BLOCK_PCB: u8 = 0b10000000;
208const R_BLOCK_PCB_MASK: u8 = 0b11101100;
210const R_BLOCK_SEQ: u8 = 0b00010000;
212const R_BLOCK_ERROR_MASK: u8 = 0b00000011;
214
215impl Pcb {
216 pub fn to_byte(self) -> u8 {
217 match self {
218 Self::I(seq, multi) => Self::i_pcb(seq, multi),
219 Self::S(block) => Self::s_pcb(block),
220 Self::R(seq, err) => Self::r_pcb(seq, err),
221 }
222 }
223
224 pub fn i_pcb(seq: Seq, multi: bool) -> u8 {
225 let mut pcb = I_BLOCK_PCB;
226 if multi {
227 pcb |= I_BLOCK_MOR;
228 }
229
230 if seq == Seq::ONE {
231 pcb |= I_BLOCK_SEQ;
232 }
233 pcb
234 }
235 pub fn s_pcb(block: SBlock) -> u8 {
236 block.into()
237 }
238 pub fn r_pcb(seq: Seq, error: RBlockError) -> u8 {
239 let mut pcb = R_BLOCK_PCB;
240 if seq == Seq::ONE {
241 pcb |= R_BLOCK_SEQ;
242 }
243
244 pcb |= error as u8;
245 pcb
246 }
247
248 pub fn parse(value: u8) -> Result<Self, Error> {
249 if value & I_BLOCK_PCB_MASK == I_BLOCK_PCB {
250 let seq = if value & I_BLOCK_SEQ == 0 {
251 Seq::ZERO
252 } else {
253 Seq::ONE
254 };
255
256 let more = (value & I_BLOCK_MOR) != 0;
257 return Ok(Self::I(seq, more));
258 }
259
260 if value & R_BLOCK_PCB_MASK == R_BLOCK_PCB {
261 let seq = if value & R_BLOCK_SEQ == 0 {
262 Seq::ZERO
263 } else {
264 Seq::ONE
265 };
266 let error = (value & R_BLOCK_ERROR_MASK)
267 .try_into()
268 .map_err(|_| Error::BadPcb)?;
269 return Ok(Self::R(seq, error));
270 }
271
272 if let Ok(sblock) = value.try_into() {
273 return Ok(Self::S(sblock));
274 }
275
276 Err(Error::BadPcb)
277 }
278}
279
280pub trait I2CErrorNack: Debug {
281 fn is_address_nack(&self) -> bool;
282 fn is_data_nack(&self) -> bool;
283}
284pub trait I2CForT1:
285 Read<u8, Error = <Self as I2CForT1>::Error>
286 + Write<u8, Error = <Self as I2CForT1>::Error>
287 + WriteRead<u8, Error = <Self as I2CForT1>::Error>
288{
289 type Error: I2CErrorNack;
290}
291
292impl<T> I2CForT1 for T
293where
294 T: Read<u8>
295 + Write<u8, Error = <T as Read<u8>>::Error>
296 + WriteRead<u8, Error = <T as Read<u8>>::Error>,
297 <T as Read<u8>>::Error: I2CErrorNack,
298{
299 type Error = <T as Read<u8>>::Error;
300}
301
302#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303pub enum Error {
304 Unknown,
305 AddressNack,
306 DataNack,
307 BadCrc,
308 BadPcb,
309 BadAddress,
310 ReceptionBuffer,
311 Line(u32),
312 Timeout,
313}
314
315impl fmt::Display for Error {
316 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317 match self {
318 Self::Unknown => f.write_str("Unknown T=1 error"),
319 Self::AddressNack => f.write_str("NACK on from the device address"),
320 Self::DataNack => f.write_str("Nack for data write"),
321 Self::BadCrc => f.write_str("CRC error"),
322 Self::BadPcb => f.write_str("Received invalid PCB"),
323 Self::BadAddress => f.write_str("Bad address"),
324 Self::ReceptionBuffer => f.write_str("Reception buffer is too small"),
325 Self::Timeout => f.write_str("Read timed out"),
326 Self::Line(l) => write!(f, "Error comming from line: {l}"),
327 }
328 }
329}
330
331impl iso7816::command::writer::Error for Error {
332 fn failed_serialization(_cause: &'static str) -> Self {
333 error!("Failed serializaiton: {}", _cause);
334 Self::Line(line!())
335 }
336}
337
338pub struct T1oI2C<Twi, D> {
339 twi: Twi,
340 se_address: u8,
341 nad_hd2se: u8,
342 nad_se2hd: u8,
343 iseq_snd: Seq,
344 iseq_rcv: Seq,
345 mpot: u32,
349 pub retry_count: u32,
351 delay: D,
352 segt: u32,
353 bwt: u32,
358}
359
360const SEGT_US: u32 = 10;
366const BWT_US: u32 = 100_000;
367
368const NAD_HD_TO_SE: u8 = 0x5A;
370const NAD_SE_TO_HD: u8 = 0xA5;
372
373#[derive(Debug, Clone, Copy, PartialEq, Eq)]
374pub enum DataReceived {
375 IBlocks(usize),
379 SBlock {
380 block: SBlock,
381 i_data: usize,
383 s_data: usize,
384 },
385}
386
387const DEFAULT_RETRY_COUNT: u32 = 1024;
388
389#[cfg(feature = "embedded-hal-v0.2.7")]
390impl<M, N, E> T1oI2C<crate::embedded_hal::Hal027<M>, crate::embedded_hal::Hal027<N>>
391where
392 N: embedded_hal_v0_2_7::blocking::delay::DelayUs<u32>,
393 M: embedded_hal_v0_2_7::blocking::i2c::Write<Error = E>
394 + embedded_hal_v0_2_7::blocking::i2c::Read<Error = E>
395 + embedded_hal_v0_2_7::blocking::i2c::WriteRead<Error = E>,
396 E: I2CErrorNack,
397{
398 pub fn new_hal_027(twi: M, se_address: u8, delay: N) -> Self {
399 Self::new(
400 crate::embedded_hal::Hal027(twi),
401 se_address,
402 crate::embedded_hal::Hal027(delay),
403 )
404 }
405}
406
407#[cfg(feature = "embedded-hal-v1.0")]
408impl<M, N, E> T1oI2C<crate::embedded_hal::Hal10<M>, crate::embedded_hal::Hal10<N>>
409where
410 N: embedded_hal_v1_0::delay::DelayNs,
411 M: embedded_hal_v1_0::i2c::I2c<Error = E>,
412 E: I2CErrorNack,
413{
414 pub fn new_hal_10(twi: M, se_address: u8, delay: N) -> Self {
415 Self::new(
416 crate::embedded_hal::Hal10(twi),
417 se_address,
418 crate::embedded_hal::Hal10(delay),
419 )
420 }
421}
422
423impl<Twi: I2CForT1, D: Delay> T1oI2C<Twi, D> {
424 pub fn new(twi: Twi, se_address: u8, delay: D) -> Self {
425 const DMPOT_MS: u32 = 1;
428 Self {
429 twi,
430 se_address,
431 nad_hd2se: NAD_HD_TO_SE,
433 nad_se2hd: NAD_SE_TO_HD,
434 iseq_snd: Seq::ZERO,
435 iseq_rcv: Seq::ZERO,
436 mpot: DMPOT_MS * 1000,
437 segt: SEGT_US as _,
438 retry_count: DEFAULT_RETRY_COUNT,
439 bwt: BWT_US,
440 delay,
441 }
442 }
443
444 pub fn write(&mut self, data: &[u8]) -> Result<(), Error> {
445 trace!("Writing");
446 match self.twi.write(self.se_address, data) {
447 Ok(_) => Ok(()),
448 Err(err) if err.is_address_nack() => Err(Error::AddressNack),
449 Err(err) if err.is_data_nack() => Err(Error::DataNack),
450 Err(_err) => {
451 warn!("Got error: {:?}", _err);
452 Err(Error::Line(line!()))
453 }
454 }
455 }
456
457 pub fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
458 match self.twi.read(self.se_address, buffer) {
459 Ok(_) => Ok(()),
460 Err(err) if err.is_address_nack() => Err(Error::AddressNack),
461 Err(err) if err.is_data_nack() => Err(Error::DataNack),
462 Err(_err) => {
463 warn!("Got error: {:?}", _err);
464 Err(Error::Line(line!()))
465 }
466 }
467 }
468
469 pub fn write_read(&mut self, data: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
471 match self.twi.write_read(self.se_address, data, buffer) {
472 Ok(_) => Ok(()),
473 Err(err) if err.is_address_nack() => Err(Error::AddressNack),
474 Err(err) if err.is_data_nack() => Err(Error::DataNack),
475 Err(_err) => {
476 warn!("Unknown error when writing & reading: {:?}", _err);
477 Err(Error::Line(line!()))
478 }
479 }
480 }
481
482 pub fn receive_data(&mut self, buffer: &mut [u8]) -> Result<DataReceived, Error> {
483 let mut written = 0;
484 let mut retry_count = self.bwt / self.mpot + 1;
485 let mut i = 0;
486 loop {
487 let mut header_buffer = [0; HEADER_LEN];
488 let mut crc_buf = [0; TRAILER_LEN];
489 i += 1;
490 if i == retry_count {
491 break;
492 }
493
494 let read = self.read(&mut header_buffer);
495 match read {
496 Ok(()) => {}
497 Err(Error::AddressNack) => {
498 self.wait_mpot();
499 continue;
500 }
501 Err(err) => {
502 return Err(err);
503 }
504 }
505
506 let [nad, pcb, len] = header_buffer;
507 debug!("Received header: {:02x?}", header_buffer);
508
509 if buffer.len() < written + len as usize {
510 error!("Buffer too small");
511 return Err(Error::ReceptionBuffer);
512 }
513
514 if len as usize > MAX_FRAME_DATA_LEN {
515 error!("Frame too large");
516 return Err(Error::ReceptionBuffer);
517 }
518
519 let mut data_buf = [0; MAX_FRAME_DATA_LEN];
520 let current_buf = &mut buffer[written..][..len as usize];
521 let data_buf = &mut data_buf[..len as _];
522
523 if nad != self.nad_se2hd {
524 error!("Received bad nad: {:02x}", nad);
525 return Err(Error::BadAddress);
526 }
527
528 if len != 0 {
529 self.read(data_buf)?;
530 }
531 self.read(&mut crc_buf)?;
532
533 let pcb = Pcb::parse(pcb).map_err(|_| Error::BadPcb)?;
534
535 let mut crc = Crc::new();
536 crc.update(&header_buffer);
537 crc.update(data_buf);
538 let crc = crc.get().to_le_bytes();
539 if crc_buf != crc {
540 error!("Got bad crc: {:02x?} expected {:02x?}", &data_buf[..2], crc);
541 return Err(Error::BadCrc);
543 }
544
545 let (seq, more) = match pcb {
546 Pcb::S(SBlock::WtxRequest) => {
547 if len != 1 {
548 return Err(Error::Line(line!()));
549 }
550 let mult = data_buf[0];
551 debug!("Got WtxRequest, {mult}");
552 let frame = [
553 self.nad_hd2se,
554 Pcb::S(SBlock::WtxResponse).to_byte(),
555 1,
556 mult,
557 ];
558 let [crc1, crc2] = Crc::calculate(&frame).to_le_bytes();
559 self.write(&[frame[0], frame[1], frame[2], frame[3], crc1, crc2])?;
560
561 retry_count = (self.bwt * mult as u32) / self.mpot + 1;
562 i = 0;
563 self.delay.delay_us(100_000);
564 continue;
565 }
566 Pcb::S(block) => {
567 current_buf.copy_from_slice(data_buf);
568 return Ok(DataReceived::SBlock {
569 block,
570 i_data: written,
571 s_data: len as usize,
572 });
573 }
574 Pcb::R(_, _) => {
575 error!("Got unexpected R-Block in receive");
576 return Err(Error::Line(line!()));
577 }
578 Pcb::I(seq, more) => (seq, more),
579 };
580 current_buf.copy_from_slice(data_buf);
581 written += len as usize;
582
583 if seq != self.iseq_rcv {
584 warn!("Got bad seq");
585 }
586 self.iseq_rcv = !seq;
587
588 if !more {
589 return Ok(DataReceived::IBlocks(written));
590 }
591 let frame = [
592 self.nad_hd2se,
593 Pcb::R(!seq, RBlockError::NoError).to_byte(),
594 0,
595 ];
596 let [crc1, crc2] = Crc::calculate(&frame).to_le_bytes();
597 self.write(&[frame[0], frame[1], frame[2], crc1, crc2])?;
598 }
599 error!("Waited for btw");
600 Err(Error::Timeout)
601 }
602
603 pub fn resync(&mut self) -> Result<(), Error> {
604 trace!("Resync");
605 let header = [self.nad_hd2se, Pcb::S(SBlock::ResyncRequest).to_byte(), 0];
606 let [crc1, crc2] = Crc::calculate(&header).to_le_bytes();
607 let frame = [header[0], header[1], header[2], crc1, crc2];
608 debug!("Sending: {frame:02x?}");
609 self.write(&frame)?;
610 self.wait_segt();
611 let data = self.receive_data(&mut [])?;
612 if !matches!(
613 data,
614 DataReceived::SBlock {
615 block: SBlock::ResyncResponse,
616 i_data: 0,
617 s_data: 0
618 }
619 ) {
620 error!("Got unexpected error: {data:?}");
621 return Err(Error::BadPcb);
622 }
623 self.iseq_snd = Seq::ZERO;
624 self.iseq_rcv = Seq::ZERO;
625 Ok(())
626 }
627
628 pub fn interface_soft_reset<'buf>(
630 &mut self,
631 buffer: &'buf mut [u8; 64],
632 ) -> Result<Atr<'buf>, Error> {
633 trace!("Interface Soft Reset");
634 let header = [
635 self.nad_hd2se,
636 Pcb::S(SBlock::InterfaceSoftResetRequest).to_byte(),
637 0,
638 ];
639 let [crc1, crc2] = Crc::calculate(&header).to_le_bytes();
640 self.write(&[header[0], header[1], header[2], crc1, crc2])?;
641 self.wait_segt();
642 let data = self.receive_data(buffer)?;
643 let received = if let DataReceived::SBlock {
644 block: SBlock::InterfaceSoftResetResponse,
645 i_data: 0,
646 s_data,
647 } = data
648 {
649 s_data
650 } else {
651 error!("Got unexpected error: {data:?}");
652 return Err(Error::BadPcb);
653 };
654 let atr = Atr::parse(&buffer[..received]);
655 if let Ok(atr) = &atr {
656 let mpot: u32 = atr.mpot.into();
657 self.mpot = 1000 * mpot;
658 self.segt = atr.segt.into();
659 self.bwt = (atr.bwt as u32) * 1000;
660 };
661 self.iseq_snd = Seq::ZERO;
662 self.iseq_rcv = Seq::ZERO;
663 debug_now!("Got atr: {atr:?}");
664 Ok(atr.unwrap_or_default())
665 }
666
667 pub fn wait_segt(&mut self) {
668 self.delay.delay_us(self.segt)
669 }
670
671 pub fn wait_mpot(&mut self) {
672 self.delay.delay_us(self.mpot)
673 }
674}
675
676const MAX_FRAME_DATA_LEN: usize = 0xFE;
678const HEADER_LEN: usize = 3;
679const TRAILER_LEN: usize = 2;
680const MAX_FRAME_LEN: usize = MAX_FRAME_DATA_LEN + HEADER_LEN + TRAILER_LEN;
681
682pub struct FrameSender<'writer, Twi, D> {
683 writer: &'writer mut T1oI2C<Twi, D>,
684 data: usize,
686 written: usize,
688 sent: usize,
689 current_frame_buffer: [u8; MAX_FRAME_LEN],
690}
691
692impl<'writer, Twi: I2CForT1, D: Delay> FrameSender<'writer, Twi, D> {
693 fn current_offset(&self) -> usize {
694 debug_assert!(self.written - self.sent <= MAX_FRAME_LEN);
695 self.written - self.sent
696 }
697
698 pub fn new(writer: &'writer mut T1oI2C<Twi, D>, data: usize) -> Self {
699 Self {
700 writer,
701 data,
702 written: 0,
703 sent: 0,
704 current_frame_buffer: [0; MAX_FRAME_LEN],
705 }
706 }
707
708 pub fn write_data(&mut self, data: &[u8]) -> Result<usize, Error> {
709 #[allow(clippy::if_same_then_else)]
711 if data.len() < 10 {
712 debug!("Writing data: {:02x?}", data);
713 } else {
714 debug!("Writing {} bytes", data.len());
715 }
716
717 if data.is_empty() {
718 return Ok(0);
719 }
720 if data.len() + self.written > self.data {
721 error!("Writing more data than expected");
722 return Err(Error::Line(line!()));
723 }
724
725 let current_offset = self.current_offset();
726 let available_in_frame = MAX_FRAME_DATA_LEN - current_offset;
727 let chunk_len = available_in_frame.min(data.len());
728 let chunk = &data[..chunk_len];
729 self.written += chunk_len;
730 self.current_frame_buffer[HEADER_LEN + current_offset..][..chunk_len]
731 .copy_from_slice(chunk);
732
733 let full_frame = chunk_len == available_in_frame;
735 let final_data = self.written == self.data;
737
738 if full_frame || final_data {
739 self.send_current_frame()?;
740 }
741
742 Ok(chunk_len)
743 }
744
745 pub fn send_current_frame(&mut self) -> Result<(), Error> {
746 let data_len = self.current_offset();
747 let is_last = self.written == self.data;
748 let pcb = Pcb::I(self.writer.iseq_snd, !is_last).to_byte();
749
750 self.writer.iseq_snd = !self.writer.iseq_snd;
751
752 let header = [self.writer.nad_hd2se, pcb, data_len as u8];
753 self.current_frame_buffer[0..HEADER_LEN].copy_from_slice(&header);
754 let trailer =
755 Crc::calculate(&self.current_frame_buffer[..HEADER_LEN + data_len]).to_le_bytes();
756 self.current_frame_buffer[HEADER_LEN + data_len..][..TRAILER_LEN].copy_from_slice(&trailer);
757 trace!(
758 "Sending:\n\tHeader: {:02x?}\n\tData: {:02x?}\n\tTrailer: {:02x?}",
759 &self.current_frame_buffer[..HEADER_LEN],
760 &self.current_frame_buffer[HEADER_LEN..][..data_len],
761 &self.current_frame_buffer[HEADER_LEN + data_len..][..TRAILER_LEN],
762 );
763
764 let mut wrote_success = false;
765 for _ in 0..self.writer.retry_count {
766 match self
767 .writer
768 .write(&self.current_frame_buffer[..data_len + HEADER_LEN + TRAILER_LEN])
769 {
770 Ok(()) => {
771 wrote_success = true;
772 break;
773 }
774 Err(Error::AddressNack) => {
779 self.writer.wait_segt();
780 continue;
781 }
782 Err(e) => return Err(e),
783 }
784 }
785
786 if !wrote_success {
787 debug_now!(
788 "Failed to send data after {} tries",
789 self.writer.retry_count
790 );
791 return Err(Error::Timeout);
792 }
793
794 self.sent += data_len;
795
796 if is_last {
797 return Ok(());
799 }
800
801 let mut resp_buf = [0u8; 5];
802 self.writer.wait_segt();
803 self.writer.read(&mut resp_buf)?;
804 debug!("Got R-Block: {:02x?}", resp_buf);
805 let [nad, pcb, len, crc1, crc2] = resp_buf;
806
807 if nad != self.writer.nad_se2hd {
808 error!("Received bad nad: {:02x}", nad);
809 return Err(Error::BadAddress);
810 }
811
812 let pcb = Pcb::parse(pcb);
813
814 match pcb {
815 Ok(Pcb::R(seq, RBlockError::NoError)) if seq == self.writer.iseq_snd => {}
816 Ok(Pcb::R(_, RBlockError::NoError)) => {
817 warn!("Got incorrect expected sequence");
818 }
819 Ok(Pcb::R(_, RBlockError::CrcError)) => {
820 error!("Got CrcError");
821 return Err(Error::BadCrc);
822 }
823 _ => {
824 error!("Got bad PCB: {pcb:?}");
825 return Err(Error::BadPcb);
826 }
827 }
828
829 if len != 0 {
830 error!("Received R-block with bad len: {}", len);
831 return Err(Error::BadAddress);
832 }
833
834 let crc = Crc::calculate(&resp_buf[0..HEADER_LEN]).to_le_bytes();
835 if [crc1, crc2] != crc {
836 error!(
837 "Got bad crc. Got {:02x?}, expected {:02x?}",
838 [crc1, crc2],
839 crc
840 );
841 return Err(Error::BadCrc);
842 }
843
844 Ok(())
845 }
846}
847
848impl<Twi: I2CForT1, D: Delay> Writer for FrameSender<'_, Twi, D> {
849 type Error = Error;
850 fn write(&mut self, data: &[u8]) -> Result<usize, Self::Error> {
851 self.write_data(data)
852 }
853}
854
855impl<'writer, Twi: I2CForT1, D: Delay> IntoWriter for &'writer mut T1oI2C<Twi, D> {
856 type Writer = FrameSender<'writer, Twi, D>;
857 fn into_writer(self, to_write: usize) -> Result<Self::Writer, <Self::Writer as Writer>::Error> {
858 Ok(FrameSender::new(self, to_write))
859 }
860}
861
862#[cfg(test)]
863mod tests {
864 use super::*;
865
866 fn assert_round_trip(value: u8, pcb: Pcb) {
867 assert_eq!(
868 value,
869 pcb.to_byte(),
870 "Expected 0b{value:08b}, got 0b{:08b}",
871 pcb.to_byte()
872 );
873 assert_eq!(pcb, Pcb::parse(value).unwrap());
874 }
875
876 #[test]
877 fn i_pcb() {
878 assert_round_trip(0b01100000, Pcb::I(Seq::ONE, true));
879 assert_round_trip(0b01000000, Pcb::I(Seq::ONE, false));
880 assert_round_trip(0b00100000, Pcb::I(Seq::ZERO, true));
881 assert_round_trip(0b00000000, Pcb::I(Seq::ZERO, false));
882 }
883
884 #[test]
885 fn r_pcb() {
886 assert_round_trip(0b10010000, Pcb::R(Seq::ONE, RBlockError::NoError));
887 assert_round_trip(0b10000000, Pcb::R(Seq::ZERO, RBlockError::NoError));
888
889 assert_round_trip(0b10010001, Pcb::R(Seq::ONE, RBlockError::CrcError));
890 assert_round_trip(0b10000001, Pcb::R(Seq::ZERO, RBlockError::CrcError));
891
892 assert_round_trip(0b10010010, Pcb::R(Seq::ONE, RBlockError::OtherError));
893 assert_round_trip(0b10000010, Pcb::R(Seq::ZERO, RBlockError::OtherError));
894 }
895
896 #[test]
897 fn atr() {
898 let atr: [u8; 0x23] = hex!(
899 "00" "a000000396" "04" "03e8" "00fe" "02" "0b""03e8" "08" "01" "000000" "0064" "0000" "0a" "4a434f5034204154504f"
914 );
915 assert_eq!(
916 Atr::parse(&atr).unwrap(),
917 Atr {
918 pver: 0,
919 vid: &hex!("a000000396"),
920 bwt: 1000,
921 ifsc: 0xFE,
922 plid: 2,
923 mcf: 1000,
924 config: 0x08,
925 mpot: 1,
926 segt: 100,
927 wut: 0,
928 historical_bytes: &hex!("4a434f5034204154504f")
929 }
930 );
931 }
932}