1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
/// Common Models Module
use std::collections::HashMap;
use std::convert::{TryFrom};

pub trait Service {
    fn operate(&mut self, operation: u8, env: Envelope);
}

#[derive(Debug, Copy, Clone)]
pub enum ServiceStatus {
    Unregistered        = 0, // Unknown/not registered yet
    // Service Starting Up
    NotInitialized      = 1, // Initial state
    Initializing        = 2, // Initializing service configuration
    Waiting             = 3, // Waiting on a dependent Service status to go to RUNNING
    Starting            = 4, // Starting Service
    Running             = 5, // Service is running normally
    Verified            = 6, // Service has been verified operating normally by receiving a message from it
    PartiallyRunning    = 7, // Service is running normally although not everything is running but it's expected to be normal
    DegradedRunning     = 8, // Service is running but in a degraded manner; likely no need for action, will hopefully come back to Running
    Blocked             = 9, // Service is being blocked from usage
    Unstable            = 10, // Service is running but there could be issues; likely need to restart

    // Service Pausing (Not Yet Supported In Any Service)
    Pausing             = 11, // Service will begin queueing all new requests while in-process requests will be completed
    Paused              = 12, // Service is queueing new requests and pre-pausing requests have completed
    Unpausing           = 13, // Service has stopped queueing new requests and is starting to resume normal operations

    // Service Shutdown
    ShuttingDown            = 14, // Service teardown imminent - not clean, process likely getting killed - perform the minimum ASAP
    GracefullyShuttingDown  = 15, // Ideal clean teardown
    Shutdown                = 16, // Was teardown forcefully - expect potential file / state corruption
    GracefullyShutdown      = 17, // Shutdown was graceful - safe to assume no file / state corruption

    // Restarting
    Restarting          = 18, // Short for GracefullyShuttingDown followed by Initializing on up

    // Unavailable
    Unavailable         = 19, // No Network available but not through blocking, more likely either not installed or not turned on

    // Service Error
    GenError            = 20 // Likely need of Service restart
}

impl ServiceStatus {
    fn as_str(&self) -> &'static str {
        match *self { // *self has type Direction
            ServiceStatus::Unregistered => "Unregistered",
            ServiceStatus::NotInitialized => "NotInitialized",
            ServiceStatus::Initializing => "Initializing",
            ServiceStatus::Waiting => "Waiting",
            ServiceStatus::Starting => "Starting",
            ServiceStatus::Running => "Running",
            ServiceStatus::Verified => "Verified",
            ServiceStatus::PartiallyRunning => "PartiallyRunning",
            ServiceStatus::DegradedRunning => "DegradedRunning",
            ServiceStatus::Blocked => "Blocked",
            ServiceStatus::Unstable => "Unstable",
            ServiceStatus::Pausing => "Pausing",
            ServiceStatus::Paused => "Paused",
            ServiceStatus::Unpausing => "Unpausing",
            ServiceStatus::ShuttingDown => "ShuttingDown",
            ServiceStatus::GracefullyShuttingDown => "GracefullyShuttingDown",
            ServiceStatus::Shutdown => "Shutdown",
            ServiceStatus::GracefullyShutdown => "GracefullyShutdown",
            ServiceStatus::Restarting => "Restarting",
            ServiceStatus::Unavailable => "Unavailable",
            ServiceStatus::GenError => "GenError"
        }
    }
}

impl TryFrom<u8> for ServiceStatus {
    type Error = ();
    fn try_from(original: u8) -> Result<Self, Self::Error> {
        match original {
            0 => Ok(ServiceStatus::Unregistered),
            1 => Ok(ServiceStatus::NotInitialized),
            2 => Ok(ServiceStatus::Initializing),
            3 => Ok(ServiceStatus::Waiting),
            4 => Ok(ServiceStatus::Starting),
            5 => Ok(ServiceStatus::Running),
            6 => Ok(ServiceStatus::Verified),
            7 => Ok(ServiceStatus::PartiallyRunning),
            8 => Ok(ServiceStatus::DegradedRunning),
            9 => Ok(ServiceStatus::Blocked),
            10 => Ok(ServiceStatus::Unstable),
            11 => Ok(ServiceStatus::Pausing),
            12 => Ok(ServiceStatus::Paused),
            13 => Ok(ServiceStatus::Unpausing),
            14 => Ok(ServiceStatus::ShuttingDown),
            15 => Ok(ServiceStatus::GracefullyShuttingDown),
            16 => Ok(ServiceStatus::Shutdown),
            17 => Ok(ServiceStatus::GracefullyShutdown),
            18 => Ok(ServiceStatus::Restarting),
            19 => Ok(ServiceStatus::Unavailable),
            20 => Ok(ServiceStatus::GenError),
            n => Err(())
        }
    }
}

pub trait Producer {
    fn send(&mut self, env: Envelope);
}

pub trait Consumer {
    fn receive(&mut self) -> Envelope;
}

#[derive(Debug, Copy, Clone)]
pub enum Action {
    POST    = 0,
    PUT     = 1,
    DELETE  = 2,
    GET     = 3
}

#[derive(Debug, Copy, Clone)]
pub enum NetworkId {
    IMS        = 0,
    LiFi       = 1,
    Bluetooth  = 2,
    WiFiDirect = 3,
    HTTPS      = 4,
    VPN        = 5,
    TOR        = 6,
    I2P        = 7,
    Satellite  = 8,
    FSRadio    = 9
}

impl TryFrom<u8> for NetworkId {
    type Error = ();
    fn try_from(original: u8) -> Result<Self, Self::Error> {
        match original {
            0 => Ok(NetworkId::IMS),
            1 => Ok(NetworkId::LiFi),
            2 => Ok(NetworkId::Bluetooth),
            3 => Ok(NetworkId::WiFiDirect),
            4 => Ok(NetworkId::HTTPS),
            5 => Ok(NetworkId::VPN),
            6 => Ok(NetworkId::TOR),
            7 => Ok(NetworkId::I2P),
            8 => Ok(NetworkId::Satellite),
            9 => Ok(NetworkId::FSRadio),
            _ => Err(())
        }
    }
}

#[derive(Debug, Copy, Clone)]
pub enum NetworkStatus {
    Unregistered           = 0, // Unknown/not registered yet

    // Network Client Starting Up
    NotInitialized         = 1, // Initial state - Registered
    Initializing           = 2, // Initializing Network Client's environment including configuration of Networking component
    Starting               = 3, // Starting of Networking component
    Waiting                = 4,  // Means this Network Client is waiting on a dependent Network Client's status to change to Starting, e.g. Bote waiting on I2P to begin starting up.
    // Network Networking
    NetworkWarmup          = 5, // Means this Network Client is waiting for a dependent Network Client's status to change to NetworkConnected, e.g. Bote waiting on I2P to actually connect.
    NetworkPortConflict    = 6, // Means this Network Client was unable to open the supplied port - likely being blocked; recommend changing ports
    NetworkConnecting      = 7, // Attempting to connect with network
    NetworkConnected       = 8, // Network successfully connected and ready to handle requests
    NetworkVerified        = 9, // Network has claimed to be connected (NetworkConnected) and we have received a message from the network verifying it is
    NetworkStopping        = 10, // Network connection is hanging, e.g. unacceptable response times, begin looking at alternatives
    NetworkStopped         = 11, // Network connection failed, try another or recommend alternative
    NetworkBlocked         = 12, // Network connection being blocked.
    NetworkUnavailable     = 13, // Network is not available; either not installed in machine or not started
    NetworkError           = 14, // Error in Network; handle within Network Client if possible yet make Network Client Service aware of likely service degradation.
    // Network Client Pausing (Not Yet Supported In Any Network)
    Pausing                = 15, // Queueing up requests both inbound and outbound waiting for pre-pausing requests to complete.
    Paused                 = 16, // All pre-pausing requests completed.
    Unpausing              = 17, // Unblocking queued requests to allow them to continue on and not queueing further requests.
    // Network Client Shutdown
    ShuttingDown           = 18, // Shutdown imminent - not clean, process likely getting killed - perform the minimum ASAP
    GracefullyShuttingDown = 19, // Ideal clean teardown
    Shutdown               = 20, // Was teardown forcefully - expect potential file / state corruption
    GracefullyShutdown     = 21, // Shutdown was graceful - safe to assume no file / state corruption
    // Network Client Restarting
    Restarting             = 22, // Short for GracefullyShuttingDown then STARTING back up.
    // Network Client Error
    GenError               = 23 // Likely need of Network Client restart
}

impl TryFrom<u8> for NetworkStatus {
    type Error = ();
    fn try_from(original: u8) -> Result<Self, Self::Error> {
        match original {
            0 => Ok(NetworkStatus::Unregistered),
            1 => Ok(NetworkStatus::NotInitialized),
            2 => Ok(NetworkStatus::Initializing),
            3 => Ok(NetworkStatus::Starting),
            4 => Ok(NetworkStatus::Waiting),
            5 => Ok(NetworkStatus::NetworkWarmup),
            6 => Ok(NetworkStatus::NetworkPortConflict),
            7 => Ok(NetworkStatus::NetworkConnecting),
            8 => Ok(NetworkStatus::NetworkConnected),
            9 => Ok(NetworkStatus::NetworkVerified),
            9 => Ok(NetworkStatus::NetworkStopping),
            9 => Ok(NetworkStatus::NetworkStopped),
            9 => Ok(NetworkStatus::NetworkBlocked),
            9 => Ok(NetworkStatus::NetworkUnavailable),
            9 => Ok(NetworkStatus::NetworkError),
            9 => Ok(NetworkStatus::Pausing),
            9 => Ok(NetworkStatus::Paused),
            9 => Ok(NetworkStatus::Unpausing),
            9 => Ok(NetworkStatus::ShuttingDown),
            9 => Ok(NetworkStatus::GracefullyShuttingDown),
            9 => Ok(NetworkStatus::Shutdown),
            9 => Ok(NetworkStatus::GracefullyShutdown),
            9 => Ok(NetworkStatus::Restarting),
            9 => Ok(NetworkStatus::GenError),
            _ => Err(())
        }
    }
}

#[derive(Debug, Copy, Clone)]
pub enum PacketType {
    Data  = 0, // packet carries a data payload
    Fin   = 1, // signals the end of a connection
    Ack   = 2, // signals acknowledgment of a packet
    Reset = 3, // forcibly terminates a connection
    Syn   = 4, // initiates a new connection with a peer
}

impl TryFrom<u8> for PacketType {
    type Error = ();
    fn try_from(original: u8) -> Result<Self, Self::Error> {
        match original {
            0 => Ok(PacketType::Data),
            1 => Ok(PacketType::Fin),
            2 => Ok(PacketType::Ack),
            3 => Ok(PacketType::Reset),
            4 => Ok(PacketType::Syn),
            n => Err(())
        }
    }
}

#[derive(Debug, Clone)]
// #[derive(Serialize,Deserialize)]
pub struct Packet {
    pub packet_type: u8,
    // Temporary identification of this packet between from and to address.
    // Normally used for Claim Checks and/or to ensure packet was received then discarded.
    pub id: u8,
    // Network this packet was sent over
    pub network_id: u8,
    // Sender node's address
    pub from_addr: String,
    // Destination node's address
    pub to_addr: String,
    // Delay for this many seconds as a minimum
    pub min_delay: u16,
    // Delay for this many seconds as a maximum
    pub max_delay: u16,
    // Data being sent
    pub envelope: Option<Envelope>
}

impl Packet {
    pub fn new(id: u8, packet_type: u8, network_id: u8, from_addr: String, to_addr: String, envelope: Option<Envelope>) -> Packet {
        Packet { id, packet_type, network_id, from_addr, to_addr, min_delay: 0, max_delay: 0, envelope }
    }
}

pub struct Node {
    pub local_peers: HashMap<NetworkId, Peer>
}

#[derive(Debug)]
pub struct Peer {
    pub network_id: NetworkId,
    pub did: DID
}

#[derive(Debug)]
pub struct DID {
    pub username: String,
    pub passphrase: String,
    pub passphrase2: String,
    pub address: String,
    pub algorithm: String
}

#[derive(Debug, Clone)]
/// An Envelope is a wrapper of data with some meta-data for internal routing.
pub struct Envelope {
    pub from: u8,
    pub to: u8,
    pub msg: Vec<u8>,
    /// A stack-based routing slip that can
    /// be added to at any time prior to
    /// completion.
    pub slip: Slip
}

impl Envelope {
    pub fn new(from: u8, to: u8, msg: Vec<u8>) -> Envelope {
        Envelope { from, to, msg, slip: Slip::new()}
    }
    pub fn new_msg_only(msg: Vec<u8>) -> Envelope {
        Envelope {from: 0, to: 0, msg, slip: Slip::new()}
    }
}

#[derive(Debug, Copy, Clone)]
pub struct Route {
    pub service: u8,
    pub op: u8,
}

impl Route {
    pub fn new(service: u8, op: u8) -> Route {
        Route { service, op }
    }
}

/// Provides a vector of Route implemented as a Stack.
/// Supports adding to the stack at any point.
#[derive(Debug, Clone)]
pub struct Slip {
    routes: Vec<Route>,
    in_progress: bool
}

impl Slip {
    fn new() -> Slip {
        Slip {
            routes: Vec::with_capacity(2),
            in_progress: false
        }
    }
    pub fn add_route(&mut self, r: Route) {
        self.routes.push(r);
    }
    pub fn current_route(&self) -> Option<&Route> {
        self.routes.last()
    }
    pub fn end_route(&mut self) -> Option<Route> {
        self.routes.pop()
    }
    pub fn number_remaining_routes(&self) -> usize {
        self.routes.len()
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}