add logging in sql db
This commit is contained in:
parent
268020b28a
commit
ac9300a048
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
/data
|
||||
|
86
Cargo.lock
generated
86
Cargo.lock
generated
@ -17,6 +17,18 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
@ -142,6 +154,18 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
@ -165,6 +189,24 @@ version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.61"
|
||||
@ -210,6 +252,17 @@ version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
@ -242,6 +295,7 @@ dependencies = [
|
||||
"encoding_rs",
|
||||
"lazy_static",
|
||||
"rand",
|
||||
"rusqlite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@ -318,6 +372,12 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
@ -390,6 +450,20 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
"libsqlite3-sys",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
@ -505,6 +579,18 @@ version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
@ -10,4 +10,5 @@ chrono = { version = "0.4" }
|
||||
encoding_rs = { version = "0.8" }
|
||||
lazy_static = { version = "1.5" }
|
||||
rand = { version = "0.8" }
|
||||
rusqlite = { version = "0.32.0", features = ["bundled"] }
|
||||
tokio = { version = "1.42", features = ["full", "sync"] }
|
||||
|
42
src/db.rs
Normal file
42
src/db.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use rusqlite::*;
|
||||
|
||||
const DBPATH: &'static str = "data/tracker.db";
|
||||
const STATEMENTS: [&str; 2] = [
|
||||
"CREATE TABLE log (id integer primary key autoincrement, time text, latitude float, longitude float);",
|
||||
"CREATE INDEX idx_time on log (time);",];
|
||||
const QUERY_INSERT: &'static str =
|
||||
"INSERT INTO log (time, latitude, longitude) values (:time, :latitude, :longitude)";
|
||||
|
||||
pub fn connectdb() -> Result<Connection> {
|
||||
let conn = Connection::open(DBPATH)?;
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
pub fn initdb(conn: &Connection) -> Result<()> {
|
||||
create_tables(&conn)?;
|
||||
set_pragmas(&conn)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_tables(conn: &Connection) -> Result<()> {
|
||||
for s in STATEMENTS {
|
||||
match conn.execute(s, params![]) {
|
||||
Ok(_) => {}
|
||||
Err(err) => println!("update failed: {}", err),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_pragmas(conn: &Connection) -> Result<()> {
|
||||
conn.pragma_update(Some(DatabaseName::Main), "journal_mode", "WAL")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert(conn: &Connection, time: &String, latitude: &f64, longitude: &f64) -> Result<()> {
|
||||
match conn.execute(QUERY_INSERT, params![time, latitude, longitude]) {
|
||||
Ok(inserted) => println!("{} rows were inserted", inserted),
|
||||
Err(err) => println!("insert failed: {}", err),
|
||||
}
|
||||
Ok(())
|
||||
}
|
14
src/main.rs
14
src/main.rs
@ -1,5 +1,7 @@
|
||||
mod db;
|
||||
mod parser;
|
||||
|
||||
use crate::db::*;
|
||||
use crate::parser::*;
|
||||
|
||||
use std::io;
|
||||
@ -11,9 +13,21 @@ const BUFSIZE: usize = 1024;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
//test();
|
||||
let conn = connectdb().unwrap();
|
||||
initdb(&conn).unwrap();
|
||||
apiserver().await.unwrap();
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn test() {
|
||||
use bcd_convert::BcdNumber;
|
||||
let data: Vec<u8> = vec![0x36, 0x31, 0x33, 0x32, 0x31, 0x31, 0x38];
|
||||
let code = BcdNumber::try_from(&data as &[u8]).unwrap();
|
||||
println!("{code}");
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
async fn apiserver() -> io::Result<()> {
|
||||
let listener = match TcpListener::bind(ADDR).await {
|
||||
Ok(o) => o,
|
||||
|
@ -4,7 +4,6 @@ use chrono::prelude::*;
|
||||
use encoding_rs::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
||||
pub trait BodyMessage {
|
||||
fn build(&self) {}
|
||||
|
||||
@ -23,6 +22,7 @@ pub trait BodyMessage {
|
||||
fn parse(&mut self, rawbody: &Vec<u8>) {}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct TerminalUniversalResponse {
|
||||
pub answer_serial_no: u16,
|
||||
@ -30,12 +30,14 @@ pub struct TerminalUniversalResponse {
|
||||
pub result: u8,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl TerminalUniversalResponse {
|
||||
pub const ID: u16 = 0x0001;
|
||||
|
||||
pub fn debug() {}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl BodyMessage for TerminalUniversalResponse {
|
||||
fn parse(&mut self, rawbody: &Vec<u8>) {}
|
||||
}
|
||||
@ -44,7 +46,7 @@ impl BodyMessage for TerminalUniversalResponse {
|
||||
pub struct PlatformUniversalResponse {
|
||||
pub answer_serial_no: u16,
|
||||
pub answer_id: u16,
|
||||
pub result: u8,
|
||||
pub result: PlatformUniversalResponseResult,
|
||||
}
|
||||
|
||||
impl PlatformUniversalResponse {
|
||||
@ -62,11 +64,27 @@ impl BodyMessage for PlatformUniversalResponse {
|
||||
for b in self.answer_id.to_be_bytes() {
|
||||
res.push(b);
|
||||
}
|
||||
res.push(self.result);
|
||||
res.push(self.result.clone() as u8);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PlatformUniversalResponseResult {
|
||||
Success = 0x00,
|
||||
Failed,
|
||||
MessageError,
|
||||
NotSupported,
|
||||
AlertProcessingConfirm,
|
||||
}
|
||||
|
||||
impl Default for PlatformUniversalResponseResult {
|
||||
fn default() -> Self {
|
||||
PlatformUniversalResponseResult::Success
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct TerminalHeartbeat {}
|
||||
|
||||
@ -79,7 +97,7 @@ impl TerminalHeartbeat {
|
||||
let mut res = PlatformUniversalResponse::default();
|
||||
res.answer_serial_no = serial;
|
||||
res.answer_id = answer_id;
|
||||
res.result = TerminalRegistrationResult::Success as u8;
|
||||
res.result = PlatformUniversalResponseResult::Success;
|
||||
res
|
||||
}
|
||||
}
|
||||
@ -108,9 +126,7 @@ impl TerminalRegistration {
|
||||
let mut res = TerminalRegistrationReply::default();
|
||||
res.answer_serial_no = serial;
|
||||
res.result = TerminalRegistrationResult::Success as u8;
|
||||
//res.authentication_code = String::from_utf8(terminal_id).unwrap();
|
||||
println!("{:?}", terminal_id);
|
||||
res.authentication_code = vec![0x36, 0x31, 0x33, 0x32, 0x31, 0x31, 0x38];
|
||||
res.authentication_code = self.terminal_id.into();
|
||||
res
|
||||
}
|
||||
}
|
||||
@ -166,7 +182,7 @@ impl std::fmt::Display for TerminalRegistration {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
enum TerminalRegistrationResult {
|
||||
pub enum TerminalRegistrationResult {
|
||||
Success = 0x00,
|
||||
VehicleRegistered,
|
||||
VehicleNotInDatabase,
|
||||
@ -212,7 +228,7 @@ impl TerminalLogout {
|
||||
let mut res = PlatformUniversalResponse::default();
|
||||
res.answer_serial_no = serial;
|
||||
res.answer_id = answer_id;
|
||||
res.result = TerminalRegistrationResult::Success as u8;
|
||||
res.result = PlatformUniversalResponseResult::Success;
|
||||
res
|
||||
}
|
||||
}
|
||||
@ -239,7 +255,7 @@ impl TerminalAuthentication {
|
||||
let mut res = PlatformUniversalResponse::default();
|
||||
res.answer_serial_no = serial;
|
||||
res.answer_id = answer_id;
|
||||
res.result = TerminalRegistrationResult::Success as u8;
|
||||
res.result = PlatformUniversalResponseResult::Success;
|
||||
res
|
||||
}
|
||||
}
|
||||
@ -263,6 +279,7 @@ impl std::fmt::Display for TerminalAuthentication {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct TerminalParameterSetting {
|
||||
pub total_parameters: u8,
|
||||
@ -277,6 +294,7 @@ impl BodyMessage for TerminalParameterSetting {
|
||||
fn parse(&mut self, rawbody: &Vec<u8>) {}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct TerminalParameterData {
|
||||
pub parameter_id: u32,
|
||||
@ -300,6 +318,7 @@ impl BodyMessage for QueryTerminalParameter {
|
||||
fn parse(&mut self, rawbody: &Vec<u8>) {}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct QueryTerminalParameterResponse {
|
||||
pub response_serial_no: u16,
|
||||
@ -315,6 +334,7 @@ impl BodyMessage for QueryTerminalParameterResponse {
|
||||
fn parse(&mut self, rawbody: &Vec<u8>) {}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct TerminalControl {
|
||||
pub command_word: u8,
|
||||
@ -343,15 +363,29 @@ pub struct LocationInformationReport {
|
||||
|
||||
impl LocationInformationReport {
|
||||
pub const ID: u16 = 0x0200;
|
||||
pub const TABLE: &'static str = "LocationInformationReport";
|
||||
|
||||
pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
|
||||
let mut res = PlatformUniversalResponse::default();
|
||||
res.answer_serial_no = serial;
|
||||
res.answer_id = answer_id;
|
||||
res.result = TerminalRegistrationResult::Success as u8;
|
||||
res.result = PlatformUniversalResponseResult::Success;
|
||||
res
|
||||
}
|
||||
|
||||
fn parse_time(&mut self, timeslice: [u8; 6]) {
|
||||
let code = BcdNumber::try_from(×lice as &[u8]).unwrap();
|
||||
let time = format!("{}", code.to_u64().unwrap());
|
||||
match NaiveDateTime::parse_from_str(time.as_str(), "%y%m%d%H%M%S") {
|
||||
Ok(o) => {
|
||||
self.time = o;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("{timeslice:?} {code} {time} {e}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_latitude(&self, latitude: u32) -> f64 {
|
||||
let mut res = latitude as f64 / 1_000_000.;
|
||||
if self.status.south {
|
||||
@ -434,16 +468,7 @@ impl BodyMessage for LocationInformationReport {
|
||||
for i in 0..tmptime.len() {
|
||||
tmptime[i] = *bd.next().unwrap();
|
||||
}
|
||||
let code = BcdNumber::try_from(&tmptime as &[u8]).unwrap();
|
||||
let time = format!("{}", code.to_u64().unwrap());
|
||||
match NaiveDateTime::parse_from_str(time.as_str(), "%y%m%d%H%M%S") {
|
||||
Ok(o) => {
|
||||
self.time = o;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("{tmptime:?} {code} {time} {e}");
|
||||
}
|
||||
};
|
||||
self.parse_time(tmptime);
|
||||
res = true;
|
||||
()
|
||||
}
|
||||
|
@ -67,20 +67,20 @@ impl MessageHeader {
|
||||
}
|
||||
|
||||
pub fn to_raw(&self) -> Vec<u8> {
|
||||
let mut r: Vec<u8> = vec![];
|
||||
let mut raw: Vec<u8> = vec![];
|
||||
for b in self.id.to_be_bytes() {
|
||||
r.push(b);
|
||||
raw.push(b);
|
||||
}
|
||||
for b in self.properties.to_be_bytes() {
|
||||
r.push(b);
|
||||
raw.push(b);
|
||||
}
|
||||
for b in self.raw_terminal_id.into_iter() {
|
||||
r.push(b);
|
||||
raw.push(b);
|
||||
}
|
||||
for b in self.serial_number.to_be_bytes() {
|
||||
r.push(b);
|
||||
raw.push(b);
|
||||
}
|
||||
r
|
||||
raw
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ impl std::fmt::Display for MessageHeader {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"message header: id: {:X?}, length: {}, terminal id: {}, serial: {:X?}",
|
||||
"id: {:X?}, length: {}, terminal id: {}, serial: {:X?}",
|
||||
self.id, self.bodylength, self.terminal_id, self.serial_number
|
||||
)
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ use body::*;
|
||||
use error::*;
|
||||
use header::*;
|
||||
|
||||
use crate::db::*;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
const FLAG_DELIMITER: u8 = 0x7E;
|
||||
@ -65,20 +67,23 @@ impl Iterator for InboundDataWrapper {
|
||||
match self.data.pop_front() {
|
||||
Some(o) => {
|
||||
if self.started {
|
||||
if o == FLAG_DELIMITER {
|
||||
match self.data.pop_front() {
|
||||
match o {
|
||||
FLAG_DELIMITER_ESCAPE => match self.data.pop_front() {
|
||||
Some(o) => match o {
|
||||
0x02 => res = Some(FLAG_DELIMITER),
|
||||
0x01 => res = Some(FLAG_DELIMITER_ESCAPE),
|
||||
_ => {
|
||||
self.escaped = Some(o);
|
||||
self.ended = true;
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
None => res = None,
|
||||
},
|
||||
FLAG_DELIMITER => {
|
||||
res = None;
|
||||
}
|
||||
_ => {
|
||||
res = Some(o);
|
||||
}
|
||||
} else {
|
||||
res = Some(o);
|
||||
}
|
||||
}
|
||||
if o == FLAG_DELIMITER && self.index == 0 {
|
||||
@ -105,6 +110,7 @@ pub struct Message {
|
||||
pub body: Vec<u8>,
|
||||
pub checksum: u8,
|
||||
valid: bool,
|
||||
pub status: bool,
|
||||
}
|
||||
|
||||
impl Message {
|
||||
@ -299,6 +305,32 @@ impl Message {
|
||||
pub fn store(inmsg: &Message) {
|
||||
match inmsg.content {
|
||||
MessageType::LocationInformationReport(ref t) => {
|
||||
/*{
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::prelude::*;
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.append(true)
|
||||
.open("data/log.txt")
|
||||
.unwrap();
|
||||
|
||||
//if let Err(e) = writeln!(file, ) {
|
||||
// eprintln!("Couldn't write to file: {}", e);
|
||||
//}
|
||||
file.write(format!("{},{},{}\n", t.time, t.latitude, t.longitude).as_bytes())
|
||||
.unwrap();
|
||||
}*/
|
||||
|
||||
let conn = connectdb().unwrap();
|
||||
insert(
|
||||
&conn,
|
||||
&t.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||
&t.latitude,
|
||||
&t.longitude,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
println!("{:?}", t);
|
||||
}
|
||||
_ => {}
|
||||
|
Loading…
Reference in New Issue
Block a user