Skip to content

Commit

Permalink
Changed CFs to be stored as Rc<RefCell<CF>>, more general network man…
Browse files Browse the repository at this point in the history
…ager additions

Changed CFs to be stored differently.
Added a function to send a CAN message.
Added a way to create an ICF.
Started adding receive message processing.
  • Loading branch information
ad3154 committed Sep 25, 2023
1 parent 6a720bc commit 44006ea
Show file tree
Hide file tree
Showing 4 changed files with 285 additions and 69 deletions.
2 changes: 1 addition & 1 deletion src/driver/can_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ mod tests {
Address(0x0F),
Priority::Six,
);
assert!(matches!(encode_result, Err(_)));
assert!(encode_result.is_err());

let error_contents: EncodingError = encode_result.unwrap_err();
assert_eq!(error_contents.priority, Priority::Six);
Expand Down
18 changes: 16 additions & 2 deletions src/network_management/can_message.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// Copyright 2023 Raven Industries inc.
#![allow(dead_code)]

use super::name::NAME;
use crate::driver::CanId;

Expand All @@ -20,4 +18,20 @@ impl CANMessage {
destination_name: NAME::default(),
}
}

pub fn get_data(&self) -> &[u8] {
self.data.as_slice()
}

pub fn get_identifier(&self) -> CanId {
self.identifier
}

pub fn get_source_name(&self) -> NAME {
self.source_name
}

pub fn get_destination_name(&self) -> NAME {
self.destination_name
}
}
87 changes: 55 additions & 32 deletions src/network_management/control_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
use crate::driver::Address;
use crate::network_management::name::NAME;
use rand::Rng;
use std::cell::RefCell;
use std::rc::Rc;
use std::time::{Duration, Instant};

use super::network_manager::{MessageQueuePriority, NetworkManager};
Expand Down Expand Up @@ -48,6 +50,28 @@ pub enum ControlFunction {
},
}

impl ControlFunction {
pub fn new_internal_control_function(
name: NAME,
preferred_address: Address,
enabled: bool,
network: &mut NetworkManager,
) -> Rc<RefCell<Self>> {
let cf = Rc::new(RefCell::new(ControlFunction::Internal {
address_claim_data: AddressClaimingData::new(name, preferred_address, enabled),
}));
network.on_new_internal_control_function(cf.clone());
cf
}

pub fn get_name(&self) -> NAME {
match self {
ControlFunction::Internal { address_claim_data } => address_claim_data.get_name(),
ControlFunction::External { name } => *name,
}
}
}

impl AddressClaimingState {
pub(super) fn new() -> Self {
Self::None
Expand Down Expand Up @@ -86,40 +110,39 @@ impl AddressClaimingState {
{
let is_device_at_our_address =
network.get_control_function_by_address(claim_to_process.get_preferred_address());
let default_external_cf = ControlFunction::External {
name: NAME::default(),
};
let device_at_our_address = match is_device_at_our_address {
Some(_) => is_device_at_our_address.as_ref().unwrap(),
None => &default_external_cf,
};

let preferred_address_name: u64 = match device_at_our_address {
ControlFunction::External { name } => (*name).into(),
ControlFunction::Internal {
address_claim_data: _,
} => claim_to_process.get_name().into(),
};

if (!claim_to_process.get_name().get_self_configurable_address()
&& preferred_address_name > claim_to_process.get_name().into())
|| <NAME as Into<u64>>::into(NAME::default()) == preferred_address_name
{
// Either our preferred address is free, this is the best case, or:
// Our address is not free, but we cannot be at an arbitrary address, and the address can be stolen by us
AddressClaimingState::SendPreferredAddressClaim
} else if !claim_to_process.get_name().get_self_configurable_address() {
// We cannot claim because we cannot tolerate an arbitrary address, and the CF at that spot wins due to its lower NAME
AddressClaimingState::UnableToClaim
} else {
// We will move to another address if whoever is in our spot has a lower NAME
if preferred_address_name < claim_to_process.get_name().into() {
// We must scan the address space and move to a free address
AddressClaimingState::SendArbitraryAddressClaim
} else {
// Our address claim wins because it's lower than the device that's in our preferred spot
let is_valid_device: bool = is_device_at_our_address.is_some();

if is_valid_device {
let preferred_address_name: u64 =
match *is_device_at_our_address.as_ref().unwrap().clone().borrow() {
ControlFunction::External { name } => name.into(),
ControlFunction::Internal {
address_claim_data: _,
} => claim_to_process.get_name().into(),
};

if (!claim_to_process.get_name().get_self_configurable_address()
&& preferred_address_name > claim_to_process.get_name().into())
|| <NAME as Into<u64>>::into(NAME::default()) == preferred_address_name
{
// Either our preferred address is free, this is the best case, or:
// Our address is not free, but we cannot be at an arbitrary address, and the address can be stolen by us
AddressClaimingState::SendPreferredAddressClaim
} else if !claim_to_process.get_name().get_self_configurable_address() {
// We cannot claim because we cannot tolerate an arbitrary address, and the CF at that spot wins due to its lower ISONAME
AddressClaimingState::UnableToClaim
} else {
// We will move to another address if whoever is in our spot has a lower NAME
if preferred_address_name < claim_to_process.get_name().into() {
// We must scan the address space and move to a free address
AddressClaimingState::SendArbitraryAddressClaim
} else {
// Our address claim wins because it's lower than the device that's in our preferred spot
AddressClaimingState::SendPreferredAddressClaim
}
}
} else {
AddressClaimingState::SendPreferredAddressClaim
}
} else {
AddressClaimingState::WaitForRequestContentionPeriod
Expand Down
Loading

0 comments on commit 44006ea

Please sign in to comment.