| 97 | } |
| 98 | |
| 99 | pub async fn encode( |
| 100 | f_port: u8, |
| 101 | variables: &HashMap<String, String>, |
| 102 | encode_config: &str, |
| 103 | s: &prost_types::Struct, |
| 104 | ) -> Result<(u8, Vec<u8>)> { |
| 105 | let conf = config::get(); |
| 106 | let max_run_ts = SystemTime::now() + conf.codec.js.max_execution_time; |
| 107 | |
| 108 | let resolver = rquickjs::loader::BuiltinResolver::default() |
| 109 | .with_module("base64-js") |
| 110 | .with_module("ieee754") |
| 111 | .with_module("buffer"); |
| 112 | let loader = rquickjs::loader::BuiltinLoader::default() |
| 113 | .with_module("base64-js", vendor_base64_js::SCRIPT) |
| 114 | .with_module("ieee754", vendor_ieee754::SCRIPT) |
| 115 | .with_module("buffer", vendor_buffer::SCRIPT); |
| 116 | |
| 117 | let rt = rquickjs::Runtime::new()?; |
| 118 | rt.set_interrupt_handler(Some(Box::new(move || SystemTime::now() > max_run_ts))); |
| 119 | rt.set_loader(resolver, loader); |
| 120 | |
| 121 | let ctx = rquickjs::Context::full(&rt)?; |
| 122 | |
| 123 | let script = format!( |
| 124 | r#" |
| 125 | import {{ Buffer }} from "buffer"; |
| 126 | |
| 127 | {} |
| 128 | |
| 129 | export default encodeDownlink(chirpstack_input); |
| 130 | "#, |
| 131 | encode_config, |
| 132 | ); |
| 133 | |
| 134 | ctx.with(|ctx| { |
| 135 | let input = rquickjs::Object::new(ctx.clone())?; |
| 136 | input.set("variables", variables.into_js(&ctx)?)?; |
| 137 | input.set("data", convert::struct_to_rquickjs(&ctx, s))?; |
| 138 | ctx.globals().set("chirpstack_input", input)?; |
| 139 | |
| 140 | let module = rquickjs::Module::declare(ctx.clone(), "main", script) |
| 141 | .catch(&ctx) |
| 142 | .map_err(|e| anyhow!("JS error: {}", e))?; |
| 143 | |
| 144 | let (module, promise) = module |
| 145 | .eval() |
| 146 | .catch(&ctx) |
| 147 | .map_err(|e| anyhow!("JS error: {}", e))?; |
| 148 | () = promise |
| 149 | .finish() |
| 150 | .catch(&ctx) |
| 151 | .map_err(|e| anyhow!("JS error: {}", e))?; |
| 152 | |
| 153 | let res: rquickjs::Object = module |
| 154 | .get("default") |
| 155 | .catch(&ctx) |
| 156 | .map_err(|e| anyhow!("JS error: {}", e))?; |