Skip to content
Snippets Groups Projects
Commit 625f9e6f authored by Stephen D's avatar Stephen D
Browse files

wip

parent 745da231
No related branches found
No related tags found
1 merge request!2Storage
......@@ -65,11 +65,16 @@ impl View {
pub fn from_contact_options_id(
id: usize,
contact_id: usize,
mut contacts: ContactIter,
storage: &Storage,
) -> Option<Self> {
let mut contacts = storage.contacts();
match id {
0 => {
let contact = contacts.nth(contact_id).unwrap_or(Contact::empty()).clone();
let contact = contacts
.nth(contact_id)
.unwrap_or_else(|| storage.new_contact())
.clone();
Some(View::ContactView(
ContactView::new(contact, false),
contact_id,
......@@ -77,7 +82,10 @@ impl View {
}
1 => {
let contact = contacts.nth(contact_id).unwrap_or(Contact::empty()).clone();
let contact = contacts
.nth(contact_id)
.unwrap_or_else(|| storage.new_contact())
.clone();
Some(View::ContactView(
ContactView::new(contact, true),
contact_id,
......@@ -183,24 +191,18 @@ impl Element for Controller {
(View::Contacts(c), KeyCode::Touchpad) => {
if c.selected() == self.storage.contacts_len() {
// TODO flash
// self.contacts.contacts.push(Contact::default()).unwrap();
// Go direct to edit page
self.cur_view =
View::from_contact_options_id(1, c.selected(), self.storage.contacts())
.unwrap();
View::from_contact_options_id(1, c.selected(), &self.storage).unwrap();
} else {
self.cur_view = View::new_contact_options(c.selected());
}
}
(View::ContactOptions(c, contact_id), KeyCode::Touchpad) => {
if let Some(new_view) = View::from_contact_options_id(
c.selected(),
*contact_id,
self.storage.contacts(),
) {
if let Some(new_view) =
View::from_contact_options_id(c.selected(), *contact_id, &self.storage)
{
self.cur_view = new_view;
}
}
......@@ -216,8 +218,8 @@ impl Element for Controller {
}
(View::ContactView(cv, contact_id), KeyCode::Back) => {
// TODO save contact
// self.storage.contacts().contacts[*contact_id] = cv.contact();
self.storage.save_contact(cv.contact());
self.cur_view = View::new_contact_options(*contact_id)
}
......
......@@ -77,24 +77,22 @@ impl ContactView {
}
}
pub fn contact(&self) -> Contact {
pub fn contact(&mut self) -> Contact {
if self.editable {
Contact {
callsign: self
.callsign
.get_text()
.try_into()
.unwrap_or_else(|_| self.contact.callsign.clone()),
ssid: self.ssid.get_text().parse().unwrap_or(self.contact.ssid),
name: self
.name
.get_text()
.try_into()
.unwrap_or_else(|_| self.contact.name.clone()),
if let Ok(callsign) = self.callsign.get_text().try_into() {
self.contact.callsign = callsign;
}
if let Ok(ssid) = self.ssid.get_text().parse() {
self.contact.ssid = ssid;
}
if let Ok(name) = self.name.get_text().try_into() {
self.contact.name = name;
}
} else {
self.contact.clone()
}
self.contact.clone()
}
}
......
......@@ -29,6 +29,19 @@ impl Storage {
}
}
pub fn save_contact(&mut self, contact: Contact) {
let len = self.contact_header.num_contacts;
// if id isn't less than the len, we're inserting a new contact
if contact.id >= usize::from(len) {
assert!(usize::from(len) < MAX_CONTACTS);
self.contact_header.num_contacts += 1;
self.contact_header.write(&self);
}
contact.write(&self);
}
pub fn contacts(&self) -> ContactIter {
ContactIter::new(self.contact_header.num_contacts.into())
}
......@@ -36,6 +49,22 @@ impl Storage {
pub fn contacts_len(&self) -> usize {
self.contact_header.num_contacts.into()
}
// Note - calling this twice without saving one
// will cause a duplicate ID
// We don't increment the len until the contact is actually saved
pub fn new_contact(&self) -> Contact {
Contact {
callsign: String::new(),
ssid: 0,
name: String::new(),
id: usize::from(self.contact_header.num_contacts),
}
}
fn write_data(&self, start_addr: usize, buf: &[u8]) {
todo!()
}
}
// Up to 100 contacts
......@@ -46,7 +75,7 @@ struct ContactHeader {
impl ContactHeader {
fn read() -> Self {
let bytes = unsafe { from_raw_parts(CONTACT_HEADER_START as *mut u8, CONTACT_LENGTH) };
let bytes = unsafe { from_raw_parts(CONTACT_HEADER_START as *mut u8, CONTACT_HEADER_SIZE) };
let num_contacts = bytes[0];
let checksum_expected = u16::from_le_bytes([bytes[1], bytes[2]]);
// CRC checksum is very overkill right now
......@@ -59,6 +88,15 @@ impl ContactHeader {
Self { num_contacts: 0 }
}
}
fn write(&self, storage: &Storage) {
let mut buf = [0; CONTACT_HEADER_SIZE];
buf[0] = self.num_contacts;
let checksum = X25.checksum(&[self.num_contacts]);
buf[1..].copy_from_slice(&checksum.to_le_bytes());
storage.write_data(CONTACT_HEADER_START, &buf);
}
}
#[derive(Clone)]
......@@ -66,6 +104,7 @@ pub struct Contact {
pub callsign: String<MAX_CONTACT_CALLSIGN_LENGTH>,
pub ssid: u8,
pub name: String<MAX_CONTACT_NAME_LENGTH>,
id: usize,
}
impl Contact {
......@@ -101,15 +140,27 @@ impl Contact {
callsign,
ssid,
name,
id: idx,
})
}
pub fn empty() -> Self {
Self {
callsign: String::new(),
ssid: 0,
name: String::new(),
}
fn write(&self, storage: &Storage) {
let start_addr = CONTACT_HEADER_START + CONTACT_HEADER_SIZE + self.id * CONTACT_LENGTH;
let mut buf = [0; CONTACT_LENGTH];
buf[0] = self.callsign.len().try_into().unwrap();
buf[1] = self.name.len().try_into().unwrap();
buf[2] = self.ssid;
let callsign_bytes = self.callsign.as_bytes();
let name_bytes = self.name.as_bytes();
buf[3..(3 + callsign_bytes.len())].copy_from_slice(&callsign_bytes);
buf[(3 + MAX_CONTACT_NAME_LENGTH)..(3 + MAX_CONTACT_NAME_LENGTH + name_bytes.len())]
.copy_from_slice(name_bytes);
let checksum = X25.checksum(&buf[..(CONTACT_LENGTH - 2)]);
buf[(CONTACT_LENGTH - 2)..].copy_from_slice(&checksum.to_le_bytes());
storage.write_data(start_addr, &buf);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment