1use core::cell::Cell;
37use kernel::hil::flash::{self, Flash};
38use kernel::hil::hasher::{self, Hasher};
39use kernel::utilities::cells::{MapCell, OptionalCell, TakeCell};
40use kernel::utilities::leasable_buffer::{SubSlice, SubSliceMut};
41use kernel::ErrorCode;
42use tickv::AsyncTicKV;
43
44pub trait KeyType: Eq + Copy + Clone + Sized + AsRef<[u8]> + AsMut<[u8]> {}
47
48impl KeyType for [u8; 8] {}
49
50pub trait KVSystemClient<K: KeyType> {
52    fn generate_key_complete(
58        &self,
59        result: Result<(), ErrorCode>,
60        unhashed_key: SubSliceMut<'static, u8>,
61        key_buf: &'static mut K,
62    );
63
64    fn append_key_complete(
70        &self,
71        result: Result<(), ErrorCode>,
72        key: &'static mut K,
73        value: SubSliceMut<'static, u8>,
74    );
75
76    fn get_value_complete(
82        &self,
83        result: Result<(), ErrorCode>,
84        key: &'static mut K,
85        ret_buf: SubSliceMut<'static, u8>,
86    );
87
88    fn invalidate_key_complete(&self, result: Result<(), ErrorCode>, key: &'static mut K);
93
94    fn garbage_collect_complete(&self, result: Result<(), ErrorCode>);
98}
99
100pub trait KVSystem<'a> {
101    type K: KeyType;
103
104    fn set_client(&self, client: &'a dyn KVSystemClient<Self::K>);
106
107    fn generate_key(
115        &self,
116        unhashed_key: SubSliceMut<'static, u8>,
117        key_buf: &'static mut Self::K,
118    ) -> Result<(), (SubSliceMut<'static, u8>, &'static mut Self::K, ErrorCode)>;
119
120    fn append_key(
140        &self,
141        key: &'static mut Self::K,
142        value: SubSliceMut<'static, u8>,
143    ) -> Result<(), (&'static mut Self::K, SubSliceMut<'static, u8>, ErrorCode)>;
144
145    fn get_value(
160        &self,
161        key: &'static mut Self::K,
162        ret_buf: SubSliceMut<'static, u8>,
163    ) -> Result<(), (&'static mut Self::K, SubSliceMut<'static, u8>, ErrorCode)>;
164
165    fn invalidate_key(
178        &self,
179        key: &'static mut Self::K,
180    ) -> Result<(), (&'static mut Self::K, ErrorCode)>;
181
182    fn garbage_collect(&self) -> Result<(), ErrorCode>;
196}
197
198#[derive(Clone, Copy, PartialEq, Debug)]
199enum Operation {
200    None,
201    Init,
202    GetKey,
203    AppendKey,
204    InvalidateKey,
205    GarbageCollect,
206}
207
208pub struct TickFSFlashCtrl<'a, F: Flash + 'static> {
219    flash: &'a F,
220    flash_read_buffer: TakeCell<'static, F::Page>,
221    region_offset: usize,
222}
223
224impl<'a, F: Flash> TickFSFlashCtrl<'a, F> {
225    pub fn new(
226        flash: &'a F,
227        flash_read_buffer: &'static mut F::Page,
228        region_offset: usize,
229    ) -> TickFSFlashCtrl<'a, F> {
230        Self {
231            flash,
232            flash_read_buffer: TakeCell::new(flash_read_buffer),
233            region_offset,
234        }
235    }
236}
237
238impl<F: Flash, const PAGE_SIZE: usize> tickv::flash_controller::FlashController<PAGE_SIZE>
239    for TickFSFlashCtrl<'_, F>
240{
241    fn read_region(
242        &self,
243        region_number: usize,
244        _buf: &mut [u8; PAGE_SIZE],
245    ) -> Result<(), tickv::error_codes::ErrorCode> {
246        if self
247            .flash
248            .read_page(
249                self.region_offset + region_number,
250                self.flash_read_buffer.take().unwrap(),
251            )
252            .is_err()
253        {
254            Err(tickv::error_codes::ErrorCode::ReadFail)
255        } else {
256            Err(tickv::error_codes::ErrorCode::ReadNotReady(region_number))
257        }
258    }
259
260    fn write(&self, address: usize, buf: &[u8]) -> Result<(), tickv::error_codes::ErrorCode> {
261        let data_buf = self.flash_read_buffer.take().unwrap();
262
263        for (i, d) in buf.iter().enumerate() {
264            data_buf.as_mut()[i + (address % PAGE_SIZE)] = *d;
265        }
266
267        if self
268            .flash
269            .write_page(self.region_offset + (address / PAGE_SIZE), data_buf)
270            .is_err()
271        {
272            return Err(tickv::error_codes::ErrorCode::WriteFail);
273        }
274
275        Err(tickv::error_codes::ErrorCode::WriteNotReady(address))
276    }
277
278    fn erase_region(&self, region_number: usize) -> Result<(), tickv::error_codes::ErrorCode> {
279        let _ = self.flash.erase_page(self.region_offset + region_number);
280
281        Err(tickv::error_codes::ErrorCode::EraseNotReady(region_number))
282    }
283}
284
285pub type TicKVKeyType = [u8; 8];
286
287pub struct TicKVSystem<'a, F: Flash + 'static, H: Hasher<'a, 8>, const PAGE_SIZE: usize> {
289    tickv: AsyncTicKV<'a, TickFSFlashCtrl<'a, F>, PAGE_SIZE>,
291    hasher: &'a H,
293    operation: Cell<Operation>,
295    next_operation: Cell<Operation>,
297    unhashed_key_buffer: MapCell<SubSliceMut<'static, u8>>,
300    key_buffer: TakeCell<'static, [u8; 8]>,
302    value_buffer: MapCell<SubSliceMut<'static, u8>>,
305    client: OptionalCell<&'a dyn KVSystemClient<TicKVKeyType>>,
307}
308
309impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> TicKVSystem<'a, F, H, PAGE_SIZE> {
310    pub fn new(
311        flash: &'a F,
312        hasher: &'a H,
313        tickfs_read_buf: &'static mut [u8; PAGE_SIZE],
314        flash_read_buffer: &'static mut F::Page,
315        region_offset: usize,
316        flash_size: usize,
317    ) -> TicKVSystem<'a, F, H, PAGE_SIZE> {
318        let tickv = AsyncTicKV::<TickFSFlashCtrl<F>, PAGE_SIZE>::new(
319            TickFSFlashCtrl::new(flash, flash_read_buffer, region_offset),
320            tickfs_read_buf,
321            flash_size,
322        );
323
324        Self {
325            tickv,
326            hasher,
327            operation: Cell::new(Operation::None),
328            next_operation: Cell::new(Operation::None),
329            unhashed_key_buffer: MapCell::empty(),
330            key_buffer: TakeCell::empty(),
331            value_buffer: MapCell::empty(),
332            client: OptionalCell::empty(),
333        }
334    }
335
336    pub fn initialise(&self) {
337        let _ret = self.tickv.initialise(0x7bc9f7ff4f76f244);
338        self.operation.set(Operation::Init);
339    }
340
341    fn complete_init(&self) {
342        self.operation.set(Operation::None);
343        match self.next_operation.get() {
344            Operation::None | Operation::Init => {}
345            Operation::GetKey => {
346                if let Err((key, value, error)) = self.get_value(
347                    self.key_buffer.take().unwrap(),
348                    self.value_buffer.take().unwrap(),
349                ) {
350                    self.client.map(move |cb| {
351                        cb.get_value_complete(Err(error), key, value);
352                    });
353                }
354            }
355            Operation::AppendKey => {
356                if let Err((key, value, error)) = self.append_key(
357                    self.key_buffer.take().unwrap(),
358                    self.value_buffer.take().unwrap(),
359                ) {
360                    self.client.map(move |cb| {
361                        cb.append_key_complete(Err(error), key, value);
362                    });
363                }
364            }
365            Operation::InvalidateKey => {
366                if let Err((key, error)) = self.invalidate_key(self.key_buffer.take().unwrap()) {
367                    self.client.map(move |cb| {
368                        cb.invalidate_key_complete(Err(error), key);
369                    });
370                }
371            }
372            Operation::GarbageCollect => {
373                if let Err(error) = self.garbage_collect() {
374                    self.client.map(move |cb| {
375                        cb.garbage_collect_complete(Err(error));
376                    });
377                }
378            }
379        }
380        self.next_operation.set(Operation::None);
381    }
382}
383
384impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> hasher::Client<8>
385    for TicKVSystem<'a, F, H, PAGE_SIZE>
386{
387    fn add_mut_data_done(&self, _result: Result<(), ErrorCode>, data: SubSliceMut<'static, u8>) {
388        self.unhashed_key_buffer.replace(data);
389        self.hasher.run(self.key_buffer.take().unwrap()).unwrap();
390    }
391
392    fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: SubSlice<'static, u8>) {}
393
394    fn hash_done(&self, _result: Result<(), ErrorCode>, digest: &'static mut [u8; 8]) {
395        self.client.map(move |cb| {
396            cb.generate_key_complete(Ok(()), self.unhashed_key_buffer.take().unwrap(), digest);
397        });
398
399        self.hasher.clear_data();
400    }
401}
402
403impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> flash::Client<F>
404    for TicKVSystem<'a, F, H, PAGE_SIZE>
405{
406    fn read_complete(&self, pagebuffer: &'static mut F::Page, _result: Result<(), flash::Error>) {
407        self.tickv.set_read_buffer(pagebuffer.as_mut());
408        self.tickv
409            .tickv
410            .controller
411            .flash_read_buffer
412            .replace(pagebuffer);
413        let (ret, tickv_buf, tickv_buf_len) = self.tickv.continue_operation();
414
415        tickv_buf.map(|buf| {
417            let mut val_buf = SubSliceMut::new(buf);
418            if tickv_buf_len > 0 {
419                val_buf.slice(0..tickv_buf_len);
422            }
423            self.value_buffer.replace(val_buf);
424        });
425
426        match self.operation.get() {
427            Operation::Init => match ret {
428                Ok(tickv::success_codes::SuccessCode::Complete)
429                | Ok(tickv::success_codes::SuccessCode::Written) => {
430                    self.complete_init();
431                }
432                _ => {}
433            },
434            Operation::GetKey => {
435                match ret {
436                    Ok(tickv::success_codes::SuccessCode::Complete)
437                    | Ok(tickv::success_codes::SuccessCode::Written) => {
438                        self.operation.set(Operation::None);
441                        self.client.map(|cb| {
442                            cb.get_value_complete(
443                                Ok(()),
444                                self.key_buffer.take().unwrap(),
445                                self.value_buffer.take().unwrap(),
446                            );
447                        });
448                    }
449                    Err(tickv::error_codes::ErrorCode::BufferTooSmall(_)) => {
450                        self.operation.set(Operation::None);
456                        self.client.map(|cb| {
457                            cb.get_value_complete(
458                                Err(ErrorCode::SIZE),
459                                self.key_buffer.take().unwrap(),
460                                self.value_buffer.take().unwrap(),
461                            );
462                        });
463                    }
464                    Err(tickv::error_codes::ErrorCode::ReadNotReady(_)) => {
465                        }
470                    Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) | Ok(_) => {}
471                    Err(e) => {
472                        let get_tock_err = match e {
473                            tickv::error_codes::ErrorCode::KeyNotFound => ErrorCode::NOSUPPORT,
474                            _ => ErrorCode::FAIL,
475                        };
476                        self.operation.set(Operation::None);
477                        self.client.map(|cb| {
478                            cb.get_value_complete(
479                                Err(get_tock_err),
480                                self.key_buffer.take().unwrap(),
481                                self.value_buffer.take().unwrap(),
482                            );
483                        });
484                    }
485                }
486            }
487            Operation::AppendKey => {
488                match ret {
489                    Ok(tickv::success_codes::SuccessCode::Complete)
490                    | Ok(tickv::success_codes::SuccessCode::Written) => {
491                        self.operation.set(Operation::None);
494                    }
495                    Ok(tickv::success_codes::SuccessCode::Queued) => {}
496                    Err(tickv::error_codes::ErrorCode::ReadNotReady(_))
497                    | Err(tickv::error_codes::ErrorCode::WriteNotReady(_))
498                    | Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) => {
499                        }
501                    Err(e) => {
502                        self.operation.set(Operation::None);
503
504                        let tock_hil_error = match e {
505                            tickv::error_codes::ErrorCode::KeyAlreadyExists => ErrorCode::NOSUPPORT,
506                            tickv::error_codes::ErrorCode::RegionFull => ErrorCode::NOMEM,
507                            tickv::error_codes::ErrorCode::FlashFull => ErrorCode::NOMEM,
508                            _ => ErrorCode::FAIL,
509                        };
510                        self.client.map(|cb| {
511                            cb.append_key_complete(
512                                Err(tock_hil_error),
513                                self.key_buffer.take().unwrap(),
514                                self.value_buffer.take().unwrap(),
515                            );
516                        });
517                    }
518                }
519            }
520            Operation::InvalidateKey => match ret {
521                Ok(tickv::success_codes::SuccessCode::Complete)
522                | Ok(tickv::success_codes::SuccessCode::Written) => {
523                    self.operation.set(Operation::None);
525                }
526                Ok(tickv::success_codes::SuccessCode::Queued) => {}
527                Err(tickv::error_codes::ErrorCode::ReadNotReady(_))
528                | Err(tickv::error_codes::ErrorCode::WriteNotReady(_))
529                | Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) => {
530                    }
532                Err(e) => {
533                    self.operation.set(Operation::None);
534
535                    let tock_hil_error = match e {
536                        tickv::error_codes::ErrorCode::KeyNotFound => ErrorCode::NOSUPPORT,
537                        _ => ErrorCode::FAIL,
538                    };
539                    self.client.map(|cb| {
540                        cb.invalidate_key_complete(
541                            Err(tock_hil_error),
542                            self.key_buffer.take().unwrap(),
543                        );
544                    });
545                }
546            },
547            Operation::GarbageCollect => match ret {
548                Ok(tickv::success_codes::SuccessCode::Complete)
549                | Ok(tickv::success_codes::SuccessCode::Written) => {
550                    self.operation.set(Operation::None);
551                    self.client.map(|cb| {
552                        cb.garbage_collect_complete(Ok(()));
553                    });
554                }
555                _ => {}
556            },
557            _ => unreachable!(),
558        }
559    }
560
561    fn write_complete(&self, pagebuffer: &'static mut F::Page, _result: Result<(), flash::Error>) {
562        self.tickv
563            .tickv
564            .controller
565            .flash_read_buffer
566            .replace(pagebuffer);
567
568        match self.operation.get() {
569            Operation::Init => {
570                self.complete_init();
571            }
572            Operation::AppendKey => {
573                self.operation.set(Operation::None);
574                self.client.map(|cb| {
575                    cb.append_key_complete(
576                        Ok(()),
577                        self.key_buffer.take().unwrap(),
578                        self.value_buffer.take().unwrap(),
579                    );
580                });
581            }
582            Operation::InvalidateKey => {
583                self.operation.set(Operation::None);
584                self.client.map(|cb| {
585                    cb.invalidate_key_complete(Ok(()), self.key_buffer.take().unwrap());
586                });
587            }
588            _ => unreachable!(),
589        }
590    }
591
592    fn erase_complete(&self, _result: Result<(), flash::Error>) {
593        let (ret, tickv_buf, tickv_buf_len) = self.tickv.continue_operation();
594
595        tickv_buf.map(|buf| {
597            let mut val_buf = SubSliceMut::new(buf);
598            if tickv_buf_len > 0 {
599                val_buf.slice(0..tickv_buf_len);
602            }
603            self.value_buffer.replace(val_buf);
604        });
605
606        match self.operation.get() {
607            Operation::Init => match ret {
608                Ok(tickv::success_codes::SuccessCode::Complete)
609                | Ok(tickv::success_codes::SuccessCode::Written) => {
610                    self.complete_init();
611                }
612                _ => {}
613            },
614            Operation::GarbageCollect => match ret {
615                Ok(tickv::success_codes::SuccessCode::Complete)
616                | Ok(tickv::success_codes::SuccessCode::Written) => {
617                    self.operation.set(Operation::None);
618                    self.client.map(|cb| {
619                        cb.garbage_collect_complete(Ok(()));
620                    });
621                }
622                _ => {}
623            },
624            _ => unreachable!(),
625        }
626    }
627}
628
629impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> KVSystem<'a>
630    for TicKVSystem<'a, F, H, PAGE_SIZE>
631{
632    type K = TicKVKeyType;
633
634    fn set_client(&self, client: &'a dyn KVSystemClient<Self::K>) {
635        self.client.set(client);
636    }
637
638    fn generate_key(
639        &self,
640        unhashed_key: SubSliceMut<'static, u8>,
641        key: &'static mut Self::K,
642    ) -> Result<(), (SubSliceMut<'static, u8>, &'static mut Self::K, ErrorCode)> {
643        match self.hasher.add_mut_data(unhashed_key) {
644            Ok(_) => {
645                self.key_buffer.replace(key);
646                Ok(())
647            }
648            Err((e, buf)) => Err((buf, key, e)),
649        }
650    }
651
652    fn append_key(
653        &self,
654        key: &'static mut Self::K,
655        value: SubSliceMut<'static, u8>,
656    ) -> Result<(), (&'static mut [u8; 8], SubSliceMut<'static, u8>, ErrorCode)> {
657        match self.operation.get() {
658            Operation::None => {
659                self.operation.set(Operation::AppendKey);
660
661                let length = value.len();
662                match self
663                    .tickv
664                    .append_key(u64::from_be_bytes(*key), value.take(), length)
665                {
666                    Ok(_ret) => {
667                        self.key_buffer.replace(key);
668                        Ok(())
669                    }
670                    Err((buf, e)) => {
671                        let tock_error = match e {
672                            tickv::error_codes::ErrorCode::ObjectTooLarge => ErrorCode::SIZE,
673                            _ => ErrorCode::FAIL,
674                        };
675                        Err((key, SubSliceMut::new(buf), tock_error))
676                    }
677                }
678            }
679            Operation::Init => {
680                self.next_operation.set(Operation::AppendKey);
683                self.key_buffer.replace(key);
684                self.value_buffer.replace(value);
685                Ok(())
686            }
687            _ => {
688                Err((key, value, ErrorCode::BUSY))
690            }
691        }
692    }
693
694    fn get_value(
695        &self,
696        key: &'static mut Self::K,
697        value: SubSliceMut<'static, u8>,
698    ) -> Result<(), (&'static mut [u8; 8], SubSliceMut<'static, u8>, ErrorCode)> {
699        if value.is_sliced() {
700            return Err((key, value, ErrorCode::SIZE));
701        }
702        match self.operation.get() {
703            Operation::None => {
704                self.operation.set(Operation::GetKey);
705
706                match self.tickv.get_key(u64::from_be_bytes(*key), value.take()) {
707                    Ok(_ret) => {
708                        self.key_buffer.replace(key);
709                        Ok(())
710                    }
711                    Err((buf, _e)) => Err((key, SubSliceMut::new(buf), ErrorCode::FAIL)),
712                }
713            }
714            Operation::Init => {
715                self.next_operation.set(Operation::GetKey);
718                self.key_buffer.replace(key);
719                self.value_buffer.replace(value);
720                Ok(())
721            }
722            _ => {
723                Err((key, value, ErrorCode::BUSY))
725            }
726        }
727    }
728
729    fn invalidate_key(
730        &self,
731        key: &'static mut Self::K,
732    ) -> Result<(), (&'static mut Self::K, ErrorCode)> {
733        match self.operation.get() {
734            Operation::None => {
735                self.operation.set(Operation::InvalidateKey);
736
737                match self.tickv.invalidate_key(u64::from_be_bytes(*key)) {
738                    Ok(_ret) => {
739                        self.key_buffer.replace(key);
740                        Ok(())
741                    }
742                    Err(_e) => Err((key, ErrorCode::FAIL)),
743                }
744            }
745            Operation::Init => {
746                self.next_operation.set(Operation::InvalidateKey);
749                self.key_buffer.replace(key);
750                Ok(())
751            }
752            _ => {
753                Err((key, ErrorCode::BUSY))
755            }
756        }
757    }
758
759    fn garbage_collect(&self) -> Result<(), ErrorCode> {
760        match self.operation.get() {
761            Operation::None => {
762                self.operation.set(Operation::GarbageCollect);
763                self.tickv
764                    .garbage_collect()
765                    .and(Ok(()))
766                    .or(Err(ErrorCode::FAIL))
767            }
768            Operation::Init => {
769                self.next_operation.set(Operation::GarbageCollect);
772                Ok(())
773            }
774            _ => {
775                Err(ErrorCode::BUSY)
777            }
778        }
779    }
780}