From 5e73e7a370e9b3053659b000b8ddfdccffb02398 Mon Sep 17 00:00:00 2001
From: able <abl3theabove@gmail.com>
Date: Fri, 22 Mar 2024 05:13:17 -0500
Subject: [PATCH] begin work on ipc protocols

---
 .../service_definition_service.rs             | 64 ++++++++++++++++---
 kernel/src/ipc/buffer.rs                      | 21 +-----
 kernel/src/ipc/mod.rs                         |  1 +
 kernel/src/ipc/protocol.rs                    | 40 ++++++++++++
 sysdata/test-programs/sds_test.rhai           | 13 ++--
 5 files changed, 106 insertions(+), 33 deletions(-)
 create mode 100644 kernel/src/ipc/protocol.rs

diff --git a/kernel/src/holeybytes/kernel_services/service_definition_service.rs b/kernel/src/holeybytes/kernel_services/service_definition_service.rs
index 0866c39..7a79bee 100644
--- a/kernel/src/holeybytes/kernel_services/service_definition_service.rs
+++ b/kernel/src/holeybytes/kernel_services/service_definition_service.rs
@@ -1,30 +1,74 @@
 use {
     crate::{
         alloc::string::ToString,
+        arch::hardware_random_u64,
         holeybytes::{ecah::LogError, kernel_services::block_read, Vm},
+        ipc::{protocol, protocol::Protocol},
     },
     alloc::string::String,
     hashbrown::HashMap,
     log::info,
     spin::{lazy::Lazy, Mutex},
 };
-
-pub struct Services(HashMap<u64, String>);
-
+pub struct Services(HashMap<u64, Protocol>);
 pub static SERVICES: Lazy<Mutex<Services>> = Lazy::new(|| {
     let mut dt = Services(HashMap::new());
-    dt.0.insert(0, "SDS".to_string());
-    info!("test");
+    dt.0.insert(0, Protocol::void());
     Mutex::new(dt)
 });
 
 pub fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
     let mut msg_vec = block_read(mem_addr, length);
-    let buffer_id_raw = &msg_vec[0..8];
-    let mut arr = [0u8; 8];
-    arr.copy_from_slice(&buffer_id_raw);
-    let buffer_id = u64::from_le_bytes(arr);
-    info!("BufferID({:x?})", buffer_id);
+    let sds_event_type: ServiceEventType = msg_vec[0].into();
+    msg_vec.remove(0);
+
+    use ServiceEventType::*;
+    match sds_event_type {
+        CreateService => {
+            let string = String::from_utf8(msg_vec).expect("Our bytes should be valid utf8");
+            sds_create_service(string);
+        }
+        DeleteService => todo!(),
+        SearchServices => todo!(),
+    }
+    // let buffer_id_raw = &msg_vec[0..8];
+    // let mut arr = [0u8; 8];
+    // arr.copy_from_slice(&buffer_id_raw);
+    // let buffer_id = u64::from_le_bytes(arr);
+    // info!("BufferID({:x?})", buffer_id);
+
+    // let mut services = SERVICES.lock();
+    // let string = String::from_utf8(msg_vec).expect("Our bytes should be valid utf8");
+    // use core::borrow::BorrowMut;
+    // services.borrow_mut().0.insert(buffer_id, string);
 
     Ok(())
 }
+
+enum ServiceEventType {
+    CreateService = 0,
+    // UpdateService = 1,
+    DeleteService = 2,
+    SearchServices = 3,
+}
+impl From<u8> for ServiceEventType {
+    fn from(value: u8) -> Self {
+        use self::*;
+        match value {
+            0 => Self::CreateService,
+            // 1 =>
+            2 => Self::DeleteService,
+            3 => Self::SearchServices,
+            1_u8 | 4_u8..=u8::MAX => todo!(),
+        }
+    }
+}
+
+fn sds_create_service(protocol: String) -> u64 {
+    let buff_id = hardware_random_u64();
+    let mut services = SERVICES.lock();
+    services.0.insert(buff_id, protocol.clone().into());
+    info!("BufferID({}) => {}", buff_id, protocol);
+    let a: protocol::Protocol = protocol.into();
+    buff_id
+}
diff --git a/kernel/src/ipc/buffer.rs b/kernel/src/ipc/buffer.rs
index 1823413..596a0c6 100644
--- a/kernel/src/ipc/buffer.rs
+++ b/kernel/src/ipc/buffer.rs
@@ -1,10 +1,9 @@
 //!
 
 use {
-    super::message::Message,
+    super::{message::Message, protocol::Protocol},
     crossbeam_queue::{ArrayQueue, SegQueue},
 };
-
 pub enum BufferTypes {
     Unbound(SegQueue<Message>),
     Bound(ArrayQueue<Message>),
@@ -30,14 +29,14 @@ impl IpcBuffer {
                 let buftype = BufferTypes::Unbound(SegQueue::new());
 
                 Self {
-                    protocol: Protocol {},
+                    protocol: Protocol::void(),
                     buffer:   buftype,
                 }
             }
             (true, length) => {
                 let buftype = BufferTypes::Bound(ArrayQueue::new(length as usize));
                 Self {
-                    protocol: Protocol {},
+                    protocol: Protocol::void(),
                     buffer:   buftype,
                 }
             }
@@ -72,17 +71,3 @@ pub enum IpcError {
     /// An invalid message error returned to the sender
     InvalidMessage,
 }
-
-/// TODO: define this, possibly as the binary form of the IDL
-/// DEPEND: This depends on an IDL
-pub struct Protocol {
-    // TODO: add in settings
-    // like `invalid_message_handler` with some options similar to
-    //          `Deny` Drops the message
-    //          `Allow` Allows invalid messages (This disables validators IPC side and relies on programs to handle invalid messages)
-    //          `CustomFunct` a callback
-    // and `report_invalid_messages_to_sender`
-    //          `True`
-    //          `False`
-    // settings: PSettings,
-}
diff --git a/kernel/src/ipc/mod.rs b/kernel/src/ipc/mod.rs
index 47dec6b..f9c96a1 100644
--- a/kernel/src/ipc/mod.rs
+++ b/kernel/src/ipc/mod.rs
@@ -1,3 +1,4 @@
 //! Interprocess communication
 pub mod buffer;
 pub mod message;
+pub mod protocol;
diff --git a/kernel/src/ipc/protocol.rs b/kernel/src/ipc/protocol.rs
new file mode 100644
index 0000000..bd1c3e0
--- /dev/null
+++ b/kernel/src/ipc/protocol.rs
@@ -0,0 +1,40 @@
+use {
+    alloc::{string::String, vec::Vec},
+    hashbrown::HashMap,
+    log::info,
+};
+
+pub struct Type {}
+pub struct Funct {
+    takes: Vec<String>,
+    gives: Vec<String>,
+}
+
+pub struct Protocol {
+    types: HashMap<String, Type>,
+    fns:   HashMap<String, Funct>,
+}
+impl Protocol {
+    pub fn void() -> Self {
+        Self {
+            types: HashMap::new(),
+            fns:   HashMap::new(),
+        }
+    }
+    // Check if a protocol defines all types it needs too
+    fn validate_protocol() -> bool {
+        false
+    }
+}
+
+impl From<String> for Protocol {
+    fn from(value: alloc::string::String) -> Self {
+        if value.starts_with("protocol") {
+            info!("ABC");
+        }
+        Self {
+            types: HashMap::new(),
+            fns:   HashMap::new(),
+        }
+    }
+}
diff --git a/sysdata/test-programs/sds_test.rhai b/sysdata/test-programs/sds_test.rhai
index 8889eab..4a47709 100644
--- a/sysdata/test-programs/sds_test.rhai
+++ b/sysdata/test-programs/sds_test.rhai
@@ -1,7 +1,7 @@
-fn set_buffer_protocol(buffer_id, string) {
-    let str = data::str("01234567" + string);
-    li64(r10, buffer_id);
-    str(r10, r0, str, 8);
+fn create_buffer_protocol(string) {
+    let str = data::str("0" + string);
+    li8(r10, 0);
+    str(r10, r0, str, 1);
 
     li64(r1, 3);
     li64(r2, 0);
@@ -11,6 +11,9 @@ fn set_buffer_protocol(buffer_id, string) {
 }
 
 
-set_buffer_protocol(1, "string");
+create_buffer_protocol("protocol Math {\n\r"+
+"\tfn add(i64, i64) -> i64;\n\r"+
+"\tfn div(i64, i64) -> i64;\n\r"+
+"}");
 
 tx();
\ No newline at end of file