ng_gateway_connector/
lib.rs1pub mod modbus;
2
3use crate::modbus::ModbusDriver;
4use anyhow::anyhow;
5use async_trait::async_trait;
6use libloading::{Library, Symbol};
7use std::any::Any;
8use std::collections::HashMap;
9use std::path::Path;
10use std::sync::Arc;
11use tokio::sync::{Mutex, OnceCell};
12
13#[async_trait]
14pub trait NGDriver: Send + Sync + Any {
15 async fn init(&self) -> Result<(), anyhow::Error> {
16 self.initialize().await?;
17 self.run().await?;
18 Ok(())
19 }
20
21 async fn initialize(&self) -> Result<(), anyhow::Error>;
22
23 async fn run(&self) -> Result<(), anyhow::Error>;
24
25 async fn execute_command(
26 &self,
27 device_id: i32,
28 command: &str,
29 params: Box<dyn Any + Send>,
30 ) -> Result<Box<dyn Any + Send>, anyhow::Error>;
31
32 async fn shutdown(&self) -> Result<(), anyhow::Error>;
33
34 fn converter(&self) -> Box<dyn NGConverter>;
35
36 fn name(&self) -> &'static str;
37}
38
39pub trait NGConnector {
41 fn collect_data(&self) -> Result<Vec<u8>, anyhow::Error>;
42 fn send_data(&self, data: Vec<u8>) -> Result<(), anyhow::Error>;
43}
44
45pub trait NGConverter {
47 fn convert_in(&self, input: Box<dyn Any + Send>) -> Result<Box<dyn Any + Send>, anyhow::Error>;
48 fn convert_out(&self, input: Box<dyn Any + Send>)
49 -> Result<Box<dyn Any + Send>, anyhow::Error>;
50}
51
52pub struct DriverManager {
53 drivers: Arc<Mutex<HashMap<String, Arc<dyn NGDriver>>>>,
54}
55
56static INSTANCE: OnceCell<Arc<Mutex<DriverManager>>> = OnceCell::const_new();
57
58impl DriverManager {
59 pub fn instance() -> Result<Arc<Mutex<Self>>, anyhow::Error> {
60 INSTANCE
61 .get()
62 .ok_or_else(|| anyhow!("NGControlCenter is not initialized"))
63 .cloned()
64 }
65
66 pub async fn init(extension_paths: &[String]) -> Result<(), anyhow::Error> {
67 let mut dm = DriverManager {
68 drivers: Arc::new(Mutex::new(HashMap::new())),
69 };
70 dm.register_builtin_drivers().await?;
71 dm.load_custom_drivers(extension_paths).await?;
72 INSTANCE
73 .set(Arc::new(Mutex::new(dm)))
74 .map_err(|_| anyhow!("Failed to initialize driver manager"))
75 }
76
77 async fn register_builtin_drivers(&mut self) -> Result<(), anyhow::Error> {
79 self.register_driver("modbus", Arc::new(ModbusDriver::new()))
80 .await?;
81 Ok(())
82 }
83
84 pub async fn register_driver(&mut self, name: &str, driver: Arc<dyn NGDriver>) -> Result<(), anyhow::Error> {
86 let mut drivers = self.drivers.lock().await;
87
88 if drivers.contains_key(name) {
89 return Err(anyhow!(format!("Driver '{}' already exists", name)));
90 }
91 drivers.insert(name.to_string(), driver);
92 Ok(())
93 }
94
95 pub async fn get_driver(&self, name: &str) -> Option<Arc<dyn NGDriver>> {
96 let drivers = Arc::clone(&self.drivers);
97 let driver = drivers.lock().await.get(name).cloned();
98 driver
99 }
100
101 async fn load_custom_drivers(&mut self, paths: &[String]) -> Result<(), anyhow::Error> {
102 for path in paths {
103 if Path::new(path).is_dir() {
104 for entry in std::fs::read_dir(path)? {
105 let entry = entry?;
106 let path = entry.path();
107 if path.is_file() && path.extension().map_or(false, |ext| ext == "so") {
108 unsafe {
109 self.load_library(&path).await?;
110 }
111 }
112 }
113 } else if Path::new(path).is_file() {
114 unsafe {
115 self.load_library(Path::new(path)).await?;
116 }
117 }
118 }
119 Ok(())
120 }
121
122 async fn load_library(&mut self, path: &Path) -> Result<(), anyhow::Error> {
123 let library = unsafe { Library::new(path) }
124 .map_err(|err| anyhow!(format!("Failed to load library: {:?}", err)))?;
125 let symbol: Symbol<fn() -> Arc<dyn NGDriver>> = unsafe { library.get(b"create_driver") }
126 .map_err(|err| anyhow!(format!("Failed to load symbol: {:?}", err)))?;
127 let driver = symbol();
128 self.register_driver(driver.name(), driver).await?;
129 Ok(())
130 }
131}