1use crate::transport::Transport;
2use log::*;
3use serde_derive::Deserialize;
4use serde_xml_rs::from_str;
5use std::io;
6
7pub mod transport;
8pub mod vendor;
9
10#[derive(Debug, Deserialize)]
11struct Hello {
12 pub capabilities: Capabilities,
13}
14
15#[derive(Debug, Deserialize)]
16struct Capabilities {
17 pub capability: Vec<String>,
18}
19
20pub struct Connection {
22 pub(crate) transport: Box<dyn Transport + Send + 'static>,
23}
24
25impl Connection {
26 pub fn new(transport: impl Transport + 'static) -> io::Result<Connection> {
27 let mut res = Connection {
28 transport: Box::from(transport),
29 };
30 res.hello()?;
31 Ok(res)
32 }
33
34 fn hello(&mut self) -> io::Result<()> {
35 debug!("Get capabilities of NetConf server");
36 self.transport.write_xml(
37 r#"
38<?xml version="1.0" encoding="UTF-8"?>
39<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
40 <capabilities>
41 <capability>
42 urn:ietf:params:netconf:base:1.0
43 </capability>
44 </capabilities>
45</hello>
46]]>]]>
47 "#,
48 )?;
49 let resp = self.transport.read_xml()?;
50 let hello: Hello = from_str(&resp.trim()).unwrap();
51 debug!("{:#?}", hello);
52 Ok(())
53 }
54
55 pub fn get_config(&mut self) -> io::Result<String> {
56 self.transport.write_xml(
57 r#"
58<?xml version="1.0" encoding="UTF-8"?>
59<rpc message-id="100"
60 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
61 <get-config>
62 <source>
63 <running/>
64 </source>
65 </get-config>
66</rpc>
67 "#,
68 )?;
69 let resp = self.transport.read_xml()?;
70 Ok(resp)
71 }
72}