aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 134ee111b5474deb4eef4ac11c86b1a00dde35e2 (plain)
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
// Copyright 2018 Matthias P. Braendli
// SPDX-License-Identifier: GPL-2.0-only
extern crate libc;

extern crate raspi_rfm95_kiss;
use raspi_rfm95_kiss::rfm95::{RF95, Bandwidth, CodingRate, SpreadingFactor};
use std::fs::{OpenOptions, File};
use std::ffi::{CStr, CString};
use std::os::unix::io::AsRawFd;

const MAX_MTU: usize = 251;

extern {
    fn kissattach(
        callsign: * const libc::c_char,
        speed: libc::int32_t,
        mtu: libc::int32_t,
        kttyname: * const libc::c_char,
        allow_broadcast: libc::int32_t) -> libc::int32_t;
}

fn create_pts_pair() -> std::io::Result<File> {
    let master_file = OpenOptions::new()
        .read(true)
        .write(true)
        .open("/dev/ptmx")?;

    unsafe {
        let master_fd = master_file.as_raw_fd();
        if libc::grantpt(master_fd) == -1 {
            return Err(std::io::Error::last_os_error());
        }
        if libc::unlockpt(master_fd) == -1 {
            return Err(std::io::Error::last_os_error());
        }
    }

    Ok(master_file)
}

fn main() {
    eprintln!("Creating PTY pair");

    let master_file = match create_pts_pair() {
        Ok(fd) => fd,
        Err(e) => panic!("create_pts_pair failed: {}", e)
    };

    eprintln!("PTS master: {:?}", master_file);

    let slavename;
    unsafe {
        slavename = libc::ptsname(master_file.as_raw_fd());
    }

    if slavename.is_null() {
        panic!("Cannot get PTS slave name");
    }
    unsafe {
        let slice = CStr::from_ptr(slavename);
        eprintln!("PTS slave: {:?}", slice);
    }

    match RF95::new(Bandwidth::Bw250, CodingRate::Cr8, SpreadingFactor::Sf10) {
        Ok(mut radio) => {
            radio.reset().expect("radio reset");

            if let Ok(ver) = radio.get_version() {
                println!("Device version: {:02x}", ver);
            }
            else {
                eprintln!("Cannot read device version");
            }
        },
        Err(e) => panic!("Cannot create lora radio object, {}", e)
    };

    let callsign = CString::new("HB9EGM-1").expect("Failed to convert callsign to CString");
    let speed : i32 = 9600;
    let mtu : i32 = 251;
    let allow_broadcast : i32 = 1;

    let success = unsafe {
        kissattach(
            callsign.as_ptr(),
            speed,
            mtu,
            slavename,
            allow_broadcast)
    };

    if success == 0 {
        panic!("kissattach failed");
    }

    let todo = "Read/Write from/to TTY and RFM95";

    /*
    let master_tty = Box::new(master_file);

    let writer = thread::spawn(|| {
        loop {
            let mut buffer = [0; MAX_MTU];
            match *master_tty.read(&mut buffer[..]) {
                Ok(n) => radio.write_buffer(buffer),
                Err(e) => panic!("TTY Read error {}", e);
            }
        }
    });

    writer.join().unwrap();
    */
}