Skip to main content

j1939_async/name/
name_manager.rs

1use crate::can::CanInterface;
2use crate::can::Frame;
3use crate::can::FrameData;
4use crate::error::mkerr;
5use crate::pgn;
6type Error = crate::error::Error;
7const FILE_CODE: u8 = 0xFC;
8
9const BROADCAST_ADDRESS: u8 = 0xFF; // 255
10const NAME_TIMEOUT_RESOLUTION: u8 = 10;
11const NAME_TIMEOUT_RECALL: u8 = 1;
12const NAME_CLAIM_TIMEOUT: u8 = 250 / NAME_TIMEOUT_RESOLUTION;
13const CLAIM_PRIORITY: u8 = 5;
14use crate::name::name_table::NULL_ADDRESS;
15
16use crate::name::name_table::NameEntry;
17use crate::name::name_table::NameState;
18use crate::name::name_table::NameTable;
19
20#[derive(Debug, Copy, Clone, PartialEq, defmt::Format)]
21#[repr(u8)]
22enum NameManagerState {
23    Disabled,
24    Init,
25    WaitOtherNames,
26    //LocalClaimsWaiting,
27    Active,
28}
29
30impl NameManagerState {
31    fn running(&self) -> bool {
32        match self {
33            NameManagerState::Disabled => false,
34            NameManagerState::Init => false,
35            NameManagerState::WaitOtherNames => false,
36            //NameManagerState::LocalClaimsWaiting => true,
37            NameManagerState::Active => true,
38        }
39    }
40}
41
42pub struct NameManager {
43    table: NameTable,
44    next_timeout: Option<u8>,
45    time_delta_remander: usize,
46    manager_state: NameManagerState,
47    manager_state_timeout: u8,
48}
49
50impl NameManager {
51    pub fn new() -> NameManager {
52        NameManager {
53            table: NameTable::new(),
54            next_timeout: Some(0),
55            time_delta_remander: 0,
56            manager_state: NameManagerState::Init,
57            manager_state_timeout: 0,
58        }
59    }
60
61    pub fn disable(&mut self) {
62        self.to_state(NameManagerState::Disabled);
63        self.next_timeout = None;
64    }
65
66    pub fn enable(&mut self) {
67        if self.manager_state != NameManagerState::Disabled {
68            return;
69        }
70        self.to_state(NameManagerState::Init);
71    }
72
73    fn to_state(&mut self, state: NameManagerState) {
74        defmt::println!("NameManager state={:?} -> {:?}", self.manager_state, state);
75        match state {
76            NameManagerState::Disabled => {}
77            NameManagerState::Init => {
78                self.table.reset_state(line!());
79                self.next_timeout = Some(250 / NAME_TIMEOUT_RESOLUTION);
80            }
81            NameManagerState::WaitOtherNames => {}
82            NameManagerState::Active => {}
83        }
84        self.manager_state = state;
85    }
86
87    fn expect_enabled(&self) -> Result<(), Error> {
88        if self.manager_state == NameManagerState::Disabled {
89            return Err(mkerr(
90                FILE_CODE,
91                crate::error::ErrorCode::NotEnabled,
92                line!(),
93            ));
94        }
95        Ok(())
96    }
97
98    pub fn find_spare_address(&self, pref: u8) -> Option<u8> {
99        let mut cur = pref;
100        loop {
101            match self.table.index_at_address(cur) {
102                None => {
103                    return Some(cur);
104                }
105                Some(_) => {
106                    if cur >= NULL_ADDRESS - 1 {
107                        cur = 0
108                    } else {
109                        cur += 1
110                    }
111                    if cur == pref {
112                        return None;
113                    }
114                }
115            }
116        }
117    }
118    pub fn get_next_timeout_ms(&self) -> Option<u32> {
119        match self.next_timeout {
120            Some(x) => Some(x as u32 * NAME_TIMEOUT_RESOLUTION as u32),
121            None => None,
122        }
123    }
124
125    fn send_claim(
126        &mut self,
127        iface: &mut dyn CanInterface,
128        index: usize,
129        info: &NameEntry,
130        address: u8,
131        destination: u8,
132    ) -> Result<(), Error> {
133        let id = crate::can::new_id_unchecked(
134            pgn::ADDRESS_CLAIMED,
135            address,
136            destination,
137            CLAIM_PRIORITY,
138        );
139        /*defmt::println!(
140            "Send claim {} {} {} {:?} {:?}",
141            line!(),
142            index,
143            address,
144            destination,
145            info.state(),
146        );*/
147        if iface
148            .transmit(Frame::from_iter(
149                id.as_raw(),
150                self.table.name(index).bytes_iter(),
151            ))
152            .is_ok()
153        {
154            if info.address() == NULL_ADDRESS {
155                // Finally sent our death notice
156                self.table.set_state(index, NameState::DEAD, line!())?;
157                self.clear_timeout(index)?;
158
159            // If in active, just sending due to a request.
160            } else if info.state() != NameState::ACTTIVE {
161                // Sending our claim, now need to wait 250ms
162                self.table.set_state(index, NameState::CLAIMING, line!())?;
163                self.set_name_timeout(index, NAME_CLAIM_TIMEOUT)?;
164            }
165        } else {
166            // Queue full, recall in 10ms?
167            self.set_name_timeout(index, NAME_TIMEOUT_RECALL)?;
168        }
169        Ok(())
170    }
171    fn kill_claim(&mut self, iface: &mut dyn CanInterface, index: usize) -> Result<usize, Error> {
172        self.table.set_address(index, NULL_ADDRESS)?;
173
174        let info = self.table.info(index)?;
175        if info.local() {
176            self.send_claim(iface, index, &info, NULL_ADDRESS, BROADCAST_ADDRESS)?;
177        } else {
178            self.table.set_state(index, NameState::DEAD, line!())?;
179            self.table.clear_timeout(index)?;
180        }
181
182        Ok(index)
183    }
184
185    pub fn request_names(&mut self, iface: &mut dyn CanInterface, src: u8) -> Result<(), Error> {
186        self.expect_enabled()?;
187        let id = crate::can::new_id(pgn::REQUEST, src, 0xff, 5).unwrap();
188        #[cfg(feature = "defmt")]
189        defmt::println!("Request names");
190        match iface.transmit(crate::can::Frame::from_slice(
191            id.as_raw(),
192            &pgn::encode(pgn::ADDRESS_CLAIMED), //&data
193        )) {
194            Ok(_) => Ok(()),
195            Err(_) => Err(mkerr(FILE_CODE, crate::error::ErrorCode::NoSpace, line!())),
196        }
197    }
198
199    fn set_name_timeout(self: &mut Self, index: usize, timeout: u8) -> Result<usize, Error> {
200        self.next_timeout = match self.next_timeout {
201            None => Some(timeout),
202            Some(x) => Some(core::cmp::min(x, timeout)),
203        };
204        self.table.set_timeout(index, timeout)
205    }
206    fn set_manager_timeout(self: &mut Self, timeout: u8) {
207        self.next_timeout = match self.next_timeout {
208            None => Some(timeout),
209            Some(x) => Some(core::cmp::min(x, timeout)),
210        };
211        self.manager_state_timeout = timeout;
212    }
213    fn clear_timeout(self: &mut Self, index: usize) -> Result<usize, Error> {
214        self.table.clear_timeout(index)
215    }
216    fn accept_claim(
217        &mut self,
218        iface: &mut dyn CanInterface,
219        index: usize,
220        address: u8,
221    ) -> Result<usize, Error> {
222        self.table.set_address(index, address)?;
223        //print!("Claim Accept New {} {} {}\n", index, address, self.table.info(index).unwrap().address());
224
225        let info = self.table.info(index)?;
226        if info.local() {
227            match self.manager_state {
228                NameManagerState::Disabled => {
229                    return Err(mkerr(
230                        FILE_CODE,
231                        crate::error::ErrorCode::NotEnabled,
232                        line!(),
233                    ));
234                }
235                NameManagerState::Init => {
236                    self.table.set_state(index, NameState::INIT, line!())?;
237                    //self.set_name_timeout(index, NAME_CLAIM_TIMEOUT)?;
238                }
239                NameManagerState::WaitOtherNames => {
240                    self.table.set_state(index, NameState::INIT, line!())?;
241                    //self.set_name_timeout(index, self.manager_state_timeout)?;
242                }
243                NameManagerState::Active => {
244                    self.send_claim(iface, index, &info, address, BROADCAST_ADDRESS)?;
245                }
246            }
247        } else {
248            self.table.set_state(index, NameState::CLAIMING, line!())?;
249            self.set_name_timeout(index, NAME_CLAIM_TIMEOUT)?;
250        }
251
252        Ok(index)
253    }
254
255    // Sent at bootup after waiting for other names.
256    fn send_local_claims(
257        &mut self,
258        iface: &mut dyn CanInterface,
259        for_addr: u8,
260    ) -> Result<bool, Error> {
261        if for_addr == 255 {
262            for index in 0..self.table.size() {
263                let info = self.table.info(index).unwrap();
264                if !info.local() {
265                    continue;
266                }
267                defmt::println!(
268                    "Send local claim {} {} {:?}\n",
269                    line!(),
270                    index,
271                    info.address()
272                );
273                self.send_claim(iface, index, &info, info.address(), BROADCAST_ADDRESS)?;
274            }
275        } else {
276            match self.table.index_at_address(for_addr) {
277                Some(index) => {
278                    let info = self.table.info(index)?;
279                    if info.local() {
280                        self.send_claim(iface, index, &info, info.address(), BROADCAST_ADDRESS)?;
281                    }
282                }
283                None => {}
284            }
285        }
286        return Ok(true);
287    }
288
289    pub fn advance_time(
290        &mut self,
291        iface: &mut dyn CanInterface,
292        mut time_delta_ms: usize,
293    ) -> Result<bool, Error> {
294        time_delta_ms += self.time_delta_remander;
295        if time_delta_ms > 255 {
296            time_delta_ms = 250;
297        }
298
299        let time_delta = (time_delta_ms / (NAME_TIMEOUT_RESOLUTION as usize)) as u8;
300        self.time_delta_remander = time_delta_ms % (NAME_TIMEOUT_RESOLUTION as usize);
301        let cur_timeout = self.next_timeout;
302        self.next_timeout = None;
303
304        if self.manager_state == NameManagerState::Disabled {
305            return Ok(false);
306        }
307
308        match self.manager_state {
309            NameManagerState::Disabled => {
310                return Ok(false);
311            }
312            NameManagerState::Init => {
313                self.to_state(NameManagerState::WaitOtherNames);
314                self.set_manager_timeout(NAME_CLAIM_TIMEOUT); // FIXME
315                self.request_names(iface, NULL_ADDRESS)?;
316            }
317            NameManagerState::WaitOtherNames => {
318                if self.manager_state_timeout <= time_delta {
319                    self.manager_state_timeout = 0;
320                    self.to_state(NameManagerState::Active);
321                    self.send_local_claims(iface, BROADCAST_ADDRESS)?;
322                } else {
323                    self.set_manager_timeout(self.manager_state_timeout - time_delta);
324                }
325            }
326            //NameManagerState::LocalClaimsWaiting => {}
327            NameManagerState::Active => {
328                // Fixme: This can probably be after the match.
329                if cur_timeout.is_none() {
330                    return Ok(true);
331                }
332            }
333        }
334
335        for index in 0..self.table.size() {
336            let info = self.table.info(index).unwrap();
337            if 0 == info.timeout() {
338                continue;
339            } // No timeout
340            if info.timeout() > time_delta {
341                // Decrement timeout
342                self.set_name_timeout(index, info.timeout() - time_delta)?;
343                continue;
344            }
345
346            // Expired
347            self.clear_timeout(index)?;
348
349            if info.state() == NameState::CLAIMING {
350                // Promote to active state
351                self.table.set_state(index, NameState::ACTTIVE, line!())?;
352                //print!("CLAIM ACTIVE address={}\n", info.address());
353            } else if info.local() {
354                // Fixme; Needed? shouldn't set timeout until running.
355                if !self.manager_state.running() {
356                    self.set_name_timeout(index, 10)?;
357                    // Wait for state to change.
358                    continue;
359                }
360                self.send_claim(iface, index, &info, info.address(), BROADCAST_ADDRESS)?;
361            }
362        }
363        return Ok(true);
364    }
365
366    fn process_claim(
367        &mut self,
368        iface: &mut dyn CanInterface,
369        source: u8,
370        name: &crate::name::Name,
371        local: bool,
372    ) -> Result<bool, Error> {
373        let index = self.table.entry(name)?;
374        if local {
375            self.table.set_local(index, local)?;
376        }
377        let info = self.table.info(index)?; // Copy
378
379        // Dead NAME
380        if source == NULL_ADDRESS || source == BROADCAST_ADDRESS {
381            defmt::println!("Claim dead {} {}\n", line!(), source);
382            self.kill_claim(iface, index)?;
383            return Ok(true);
384        }
385
386        if info.state() == NameState::DEAD
387            || info.state() == NameState::INIT
388            || info.address() != source
389        {
390            let current_clam = self.table.index_at_address(source);
391            if current_clam.is_some() && current_clam.unwrap() != index {
392                // Existing entry, who wins?
393                let current_claim_index = current_clam.unwrap();
394                let current_claim_name = self.table.get_name(current_claim_index);
395                let current_claim_info = self.table.info(current_claim_index)?; // Copy
396                let local_not_started =
397                    current_claim_info.state() == NameState::INIT && current_claim_info.local();
398                if local_not_started
399                    || (current_claim_name.is_ok() && current_claim_name.unwrap() < *name)
400                {
401                    //print!("Claim New Win\n");
402                    // New Claim wins
403
404                    if current_claim_info.local() {
405                        // Local claim, try another address
406                        match self.find_spare_address(128) {
407                            Some(new_add) => {
408                                defmt::println!(
409                                    "Claim local move {} {}->{}\n",
410                                    line!(),
411                                    source,
412                                    new_add
413                                );
414                                self.accept_claim(iface, current_claim_index, new_add)?;
415                            }
416                            None => {
417                                //  Couldn't find one
418                                defmt::println!("Claim dead {} {}\n", line!(), source);
419                                self.kill_claim(iface, current_claim_index)?;
420                            }
421                        }
422                    } else {
423                        defmt::println!("Claim dead {} {}\n", line!(), source);
424                        self.kill_claim(iface, current_claim_index)?;
425                    }
426                    self.accept_claim(iface, index, source)?;
427                } else {
428                    //print!("Claim New Loose\n");
429                    // Existing claim wins
430                    if local {
431                        // Local claim, try another address
432                        match self.find_spare_address(128) {
433                            Some(new_add) => {
434                                defmt::println!(
435                                    "Claim local move {} {}->{}\n",
436                                    line!(),
437                                    source,
438                                    new_add
439                                );
440                                self.accept_claim(iface, index, new_add)?;
441                            }
442                            None => {
443                                //  Couldn't find one
444                                defmt::println!("Claim dead {} {}\n", line!(), source);
445                                self.kill_claim(iface, index)?;
446                            }
447                        }
448                    } else {
449                        defmt::println!("Claim dead {} {}->{}\n", line!(), info.address(), source);
450                        self.kill_claim(iface, index)?;
451                    }
452                }
453            } else {
454                //print!("Claim New {}\n", source);
455                self.accept_claim(iface, index, source)?;
456            }
457        }
458
459        // Nothing changed?
460
461        Ok(true)
462    }
463
464    pub fn resolve(&self, name: &crate::name::Name) -> Result<crate::can::Address, Error> {
465        self.expect_enabled()?;
466        let info = self.table.info_from_name(name)?;
467        if info.state() != NameState::ACTTIVE {
468            return Err(mkerr(
469                FILE_CODE,
470                crate::error::ErrorCode::NotResolved,
471                line!(),
472            ));
473        }
474
475        Ok(info.address())
476    }
477
478    pub fn resolve_local(&self, name: &crate::name::Name) -> Result<crate::can::Address, Error> {
479        self.expect_enabled()?;
480        let info = self.table.info_from_name(name)?;
481        if !info.local() {
482            return Err(mkerr(FILE_CODE, crate::error::ErrorCode::NotLocal, line!()));
483        }
484        if info.state() != NameState::ACTTIVE {
485            return Err(crate::error::mkerr_u32(
486                FILE_CODE,
487                crate::error::ErrorCode::NotResolved,
488                line!(),
489                info.state() as u32,
490            ));
491        }
492
493        Ok(info.address())
494    }
495
496    pub fn resolve_local_else_null(&self, name: &crate::name::Name) -> u8 {
497        match self.resolve_local(name) {
498            Ok(addr) => addr,
499            Err(_) => 254,
500        }
501    }
502
503    pub fn register_local_name(
504        &mut self,
505        iface: &mut dyn CanInterface,
506        address: u8,
507        name: &crate::name::Name,
508    ) -> Result<bool, Error> {
509        defmt::println!("Register local name {} {}\n", line!(), address);
510        self.process_claim(iface, address, name, true)
511    }
512
513    pub fn on_can_frame(
514        &mut self,
515        iface: &mut dyn CanInterface,
516        id: crate::can::ApiId,
517        data: &FrameData,
518    ) -> Result<bool, Error> {
519        if self.manager_state == NameManagerState::Disabled {
520            return Ok(false);
521        }
522        //print!("Name Got Frame pgn={}\n", id.pgn());
523        #[cfg(feature = "defmt")]
524        defmt::println!(
525            "Name Got Frame pgn={}/{} len={}\n",
526            id.pgn(),
527            pgn::REQUEST,
528            data.len()
529        );
530        use crate::can::Id;
531        return match id.pgn() {
532            pgn::ADDRESS_CLAIMED => match crate::name::Name::from_bytes(&data) {
533                Ok(name) => {
534                    defmt::println!("Remote claim {} {}\n", line!(), id.source());
535                    self.process_claim(iface, id.source(), &name, false)
536                }
537                Err(e) => Err(e),
538            },
539            pgn::REQUEST if data.len() >= 3 && data[0..3] == pgn::encode(pgn::ADDRESS_CLAIMED) => {
540                #[cfg(feature = "defmt")]
541                defmt::println!("PR @{}", line!());
542
543                self.send_local_claims(iface, id.destination())?;
544                Ok(true)
545            }
546            _ => Ok(false),
547        };
548    }
549}
550
551/*fn send_frames(iface : & mut dyn CanInterface, man: & mut NameManager) {
552    use crate::Id;
553    loop {
554        if let Some(pkt) = iface.get_packet() {
555            let id = Id::new(pkt.id());
556            match man.on_can_frame(iface, id, &pkt.data()) {
557                Ok(true)    => print!("Packet handled\n"),
558                Ok(false)   => print!("Packet NOT handled\n"),
559                Err(err)    => print!("Packet error: {}\n",err),
560            }
561        } else {
562            break;
563        }
564    }
565}*/
566
567/*fn j1939_frame(_pgn: u32, source: u8, destination:u8, priority:u8, data: &[u8]) -> Frame {
568    let id = crate::Id::new_with_fields(_pgn, source, destination, priority);
569    //print!("ID {:x} pgn={:x}->{:x}\n", id.as_raw(), _pgn, id.pgn());
570    Frame::from_iter(id.as_raw(), data)
571}*/
572
573#[cfg(test)]
574pub mod name_manager_tests {
575    use crate::can::CanInterface;
576    use crate::can::DummyCanInerface;
577    use crate::can::FrameData;
578    use crate::name::name_manager::NameManager;
579    use crate::name::Name;
580
581    #[test]
582    fn name_manager() {
583        let mut man = NameManager::new();
584        let mut can = DummyCanInerface::new();
585
586        assert_eq!(man.get_next_timeout_ms(), Some(0));
587        assert_eq!(0, can.tx_queue.len());
588        assert_eq!(Some(true), man.advance_time(&mut can, 0).ok());
589
590        // Should be a request all names message
591        assert_eq!(1, can.tx_queue.len());
592        let frame = can.tx_queue.dequeue().unwrap();
593        assert_eq!(frame.id().as_raw(), 0x14EAFFFE);
594        assert_eq!(frame.data().as_slice(), &[0u8, 0xEEu8, 0u8]);
595        assert_eq!(0, can.tx_queue.len());
596
597        // Name manager needs to wait 250ms to init
598        assert_eq!(man.get_next_timeout_ms(), Some(250));
599        assert_eq!(Some(true), man.advance_time(&mut can, 250).ok());
600        assert_eq!(0, can.tx_queue.len());
601
602        print!(
603            "Name SC {:x}\n",
604            Name::create(true, 0, 0, 0, 0, 0, 0, 0, 0).raw()
605        );
606        let local_name = Name(0);
607
608        print!("Register local name on 130\n");
609        assert_eq!(
610            Some(true),
611            man.register_local_name(&mut can, 0x82, &local_name).ok()
612        );
613        assert_eq!(0xFE, man.resolve_local_else_null(&local_name)); // Not resolved yet
614
615        // Expect address claim message
616        assert_eq!(1, can.tx_queue.len());
617        let frame = can.tx_queue.dequeue().unwrap();
618        print!(
619            "FRAME: {:x} {:?}\n",
620            frame.id().as_raw(),
621            frame.data().as_slice()
622        );
623        assert_eq!(frame.id().as_raw(), 0x14EEFF82);
624        assert_eq!(frame.data().as_slice(), &[0, 0, 0, 0, 0, 0, 0, 0,]);
625        assert_eq!(0, can.tx_queue.len());
626
627        print!("Advance time by 200\n");
628        assert_eq!(Some(true), man.advance_time(&mut can, 200).ok());
629        assert_eq!(0xFE, man.resolve_local_else_null(&local_name)); // Not resolved yet
630        print!("Advance time by 49\n");
631        assert_eq!(Some(true), man.advance_time(&mut can, 49).ok());
632        assert_eq!(0xFE, man.resolve_local_else_null(&local_name)); // Not resolved yet
633        print!("Advance time by 1\n");
634        assert_eq!(Some(true), man.advance_time(&mut can, 1).ok());
635        assert_eq!(0x82, man.resolve_local_else_null(&local_name)); // Resolved
636
637        assert_eq!(
638            Some(true),
639            man.on_can_frame(
640                &mut can,
641                crate::can::new_id(crate::pgn::ADDRESS_CLAIMED, 28, 255, 3).unwrap(),
642                &FrameData::from_iter(Name::create(true, 0, 0, 0, 0, 0, 0, 0, 123).bytes_iter())
643            )
644            .ok()
645        );
646        print!("Advance time by 249\n");
647        assert_eq!(Some(true), man.advance_time(&mut can, 249).ok());
648        print!("Advance time by 1\n");
649        assert_eq!(Some(true), man.advance_time(&mut can, 1).ok());
650        assert_eq!(0, can.tx_queue.len());
651    }
652
653    #[test]
654    fn conflict() {
655        let our_name = Name::create(true, 0, 0, 0, 0, 0, 0, 0, 123);
656        let them_name = Name::create(true, 0, 0, 0, 0, 0, 0, 0, 124);
657        let mut man = NameManager::new();
658        let mut can = DummyCanInerface::new();
659        print!("US   Name SC {:x}\n", our_name.raw());
660        print!("Then Name SC {:x}\n", them_name.raw());
661
662        assert_eq!(man.get_next_timeout_ms(), Some(0));
663        assert_eq!(0, can.tx_queue.len());
664        assert_eq!(Some(true), man.advance_time(&mut can, 0).ok());
665
666        // Should be a request all names message
667        assert_eq!(1, can.tx_queue.len());
668        let frame = can.tx_queue.dequeue().unwrap();
669        assert_eq!(frame.id().as_raw(), 0x14EAFFFE);
670        assert_eq!(frame.data().as_slice(), &[0u8, 0xEEu8, 0u8]);
671        assert_eq!(0, can.tx_queue.len());
672
673        // Name manager needs to wait 250ms to init
674        assert_eq!(man.get_next_timeout_ms(), Some(250));
675        assert_eq!(Some(true), man.advance_time(&mut can, 250).ok());
676        assert_eq!(0, can.tx_queue.len());
677
678        assert_eq!(
679            Some(true),
680            man.register_local_name(&mut can, 130, &our_name).ok()
681        );
682
683        // Expect address claim message
684        assert_eq!(1, can.tx_queue.len());
685        let frame = can.tx_queue.dequeue().unwrap();
686        print!(
687            "FRAME: {:x} {:?}\n",
688            frame.id().as_raw(),
689            frame.data().as_slice()
690        );
691        assert_eq!(frame.id().as_raw(), 0x14EEFF82);
692        assert_eq!(
693            frame.data().as_slice(),
694            &our_name.bytes_iter().collect::<Vec<u8>>()
695        );
696        assert_eq!(0, can.tx_queue.len());
697
698        print!(
699            "XXXXX Advance time by 200 {:?}\n",
700            man.get_next_timeout_ms()
701        );
702        assert_eq!(Some(true), man.advance_time(&mut can, 200).ok());
703        assert_eq!(0xFE, man.resolve_local_else_null(&our_name)); // Not resolved yet
704        print!("Advance time by 49\n");
705        assert_eq!(Some(true), man.advance_time(&mut can, 49).ok());
706        assert_eq!(0xFE, man.resolve_local_else_null(&our_name)); // Not resolved yet
707        print!("Advance time by 1\n");
708        assert_eq!(Some(true), man.advance_time(&mut can, 1).ok());
709        assert_eq!(0x82, man.resolve_local_else_null(&our_name)); // Not resolved yet
710
711        assert_eq!(
712            Some(true),
713            man.on_can_frame(
714                &mut can,
715                crate::can::new_id(crate::pgn::ADDRESS_CLAIMED, 130, 255, 3).unwrap(),
716                &FrameData::from_iter(them_name.bytes_iter())
717            )
718            .ok()
719        );
720        print!("Advance time by 249\n");
721        assert_eq!(Some(true), man.advance_time(&mut can, 249).ok());
722        print!("Advance time by 1\n");
723        assert_eq!(Some(true), man.advance_time(&mut can, 1).ok());
724        assert_eq!(0x82, man.resolve_local_else_null(&our_name)); // Not resolved yet
725        assert_eq!(0, can.tx_queue.len());
726    }
727
728    #[test]
729    fn name_manager_junk() {
730        use crate::can::Id;
731        let mut _man = NameManager::new();
732        let mut _can_dummy = DummyCanInerface::new();
733        let _can: &mut dyn CanInterface = &mut _can_dummy;
734        assert_eq!(
735            crate::pgn::ADDRESS_CLAIMED,
736            crate::can::new_id(crate::pgn::ADDRESS_CLAIMED, 1, 2, 3)
737                .unwrap()
738                .pgn()
739        );
740        //let name_1 = Name(0x1234_1234_1234_1234u64);
741
742        //can.transmit(j1939_frame( crate::pgn::ADDRESS_CLAIMED, 2, 3, 4, &[0, 1, 2, 3, 4, 5, 6, 7])).unwrap();
743        //send_frames(can, &mut man);
744        //use crate::name_manager::NameManager;
745        //let frame: Box<dyn embedded_hal::can::Frame> = Frame::new(0x123456, [0, 1, 2, 3, 4, 5, 6, 7]);
746        //let frame  = bxcan::Frame::new_data(bxcan::ExtendedId::new(0x123456).unwrap(), [0, 1, 2, 3, 4, 5, 6, 7]);
747
748        //let frame = bxcan::Frame::new(embedded_hal::can::ExtendedId::new(0).unwrap(), &[0, 1, 2, 3, 4, 5, 6, 7]);
749
750        //fn do_something(frame: Box<dyn embedded_hal::can::Frame>){
751        //
752        //}
753        //do_something(frame.unwrap());
754        //struct Frame {id: RawCanId, len: FrameDataLen, data: [u8; 8]};
755
756        //let mut sent_frames = Vec<Frame>::new();
757        /*let mut sent_frames = Vec::new();
758
759        let mut man = NameManager::new(
760            Box::new(|id, len, data| {
761                sent_frames.push(Frame{id, len, data});
762                true})
763        );
764        */
765    }
766} // mod name_manager_tests