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
// Copyright (c) 2021 Open Community Project Association https://ocpa.ch
// This software is published under the AGPLv3 license.

//! # Process SYS Messages
//! 
//! The SYS messages are defined in the protobuf format.
//! They are used to send between libqaul and the host OS.
//! 
//! They are used for the following modules:
//! 
//! * BLE module

use crossbeam_channel::{unbounded, Sender, Receiver, TryRecvError};
use state::Storage;

use crate::connections::{
    lan::Lan,
    internet::Internet,
};
use crate::connections::ble::Ble;


/// receiving end of the mpsc channel
static EXTERN_RECEIVE: Storage<Receiver<Vec<u8>>> = Storage::new();
/// sending end of the mpsc channel
static EXTERN_SEND: Storage<Sender<Vec<u8>>> = Storage::new();
/// sending end of th mpsc channel for libqaul to send
static LIBQAUL_SEND: Storage<Sender<Vec<u8>>> = Storage::new();


/// Handling of SYS messages of libqaul
pub struct Sys {

}


impl Sys {
    /// Initialize SYS module 
    /// Create the sending and receiving channels and put them to state.
    /// Return the receiving channel for libqaul.
    pub fn init() -> Receiver<Vec<u8>> {
        // create channels
        let (libqaul_send, extern_receive) = unbounded();
        let (extern_send, libqaul_receive) = unbounded();

        // save to state
        EXTERN_RECEIVE.set(extern_receive);
        EXTERN_SEND.set(extern_send);
        LIBQAUL_SEND.set(libqaul_send.clone());

        // return libqaul receiving channel
        libqaul_receive
    }

    /// send sys message from the outside to the inside 
    /// of the worker thread of libqaul.
    pub fn send_to_libqaul(binary_message: Vec<u8>) {
        let sender = EXTERN_SEND.get().clone();
        match sender.send(binary_message) {
            Ok(()) => {},
            Err(err) => {
                // log error message
                log::error!("{:?}", err);
            },
        }
    }

    /// check the receiving sys channel if there
    /// are new messages from inside libqaul for 
    /// the outside.
    pub fn receive_from_libqaul() -> Result<Vec<u8>, TryRecvError> {
        let receiver = EXTERN_RECEIVE.get().clone();
        receiver.try_recv()
    }

    /// send an rpc message from inside libqaul thread
    /// to the extern.
    pub fn send_to_extern(message: Vec<u8>) {
        let sender = LIBQAUL_SEND.get().clone();
        match sender.send(message) {
            Ok(()) => {},
            Err(err) => {
                // log error message
                log::error!("{:?}", err);
            },
        }
    }

    /// Process received binary protobuf encoded SYS message
    /// 
    /// This function will decode the message from the binary
    /// protobuf format to rust structures and send it to 
    /// the module responsible.
    pub fn process_received_message( data: Vec<u8>, _lan: Option<&mut Lan>, _internet: Option<&mut Internet> ) {
        // as there is only BLE module just forward the data
        Ble::sys_received(data);
    }

    /// sends a SYS message to the outside
    pub fn send_message(data: Vec<u8>) {
        // send the message
        Self::send_to_extern(data);
    }
}