Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
frafra committed May 25, 2019
0 parents commit cfb5e33
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
**/*.rs.bk
106 changes: 106 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "frakegps"
version = "0.1.0"
authors = ["Francesco Frassinelli <fraph24@gmail.com>"]
edition = "2018"

[dependencies]
time = "0.1"
web-view = "0.4.1"
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Description

FrakeGPS simulates a simple GPS receiver which emits NMEA codes. The location is selected clicking on a map, using [web-view](https://github.com/Boscop/web-view) and [Leaflet](http://leafletjs.com/).

![frakegps-gpsmon](https://user-images.githubusercontent.com/4068/58375414-ba3b3900-7f52-11e9-88bb-c6db1299eff0.png)

# Build

## Dependencies

- cargo
- gpsd
- webkit2gtk (devel)

### Fedora

```
dnf install cargo gpsd webkit2gtk3-devel
```

## Compile

```
cargo build
```

# Usage

## Usage with gpsd

```
./target/debug/frakegps |& gpsd -n -N /dev/stdin
```

## Usage with geoclue

```
./target/debug/frakegps |& nc -kl 10110
avahi-publish -s "FrakeGPS for $(hostname)" _nmea-0183._tcp 10110 "FrakeGPS service"
```

Note: Unreliable results with avahi.
10 changes: 10 additions & 0 deletions src/dist/map.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
body {
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
#map {
flex-grow: 1;
width: 100%;
}
17 changes: 17 additions & 0 deletions src/dist/map.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>FrakeGPS</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script>
{styles}
</head>
<body>
<div id="map"></div>
{scripts}
</body>
</html>

15 changes: 15 additions & 0 deletions src/dist/map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var map = L.map('map').setView([63.42682, 10.40163], 13);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',
id: 'osm.standard'
}).addTo(map);

var maker = L.marker();
map.on('click', function(event) {
maker.remove()
maker = L.marker(event.latlng);
maker.addTo(map);
external.invoke([event.latlng.lat, event.latlng.lng]);
});
35 changes: 35 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
mod nmea;

extern crate web_view;
use web_view::*;

fn main() -> WVResult {
let html = format!(include_str!("dist/map.html"),
styles = inline_style(include_str!("dist/map.css")),
scripts = inline_script(include_str!("dist/map.js")),
);
let webview = web_view::builder()
.title("FrakeGPS")
.content(Content::Html(html))
.size(800, 600)
.resizable(true)
.debug(true)
.user_data(())
.invoke_handler(|_webview, arg| {
let latlon: Vec<&str> = arg.split(",").collect();
let lat: f64 = latlon[0].parse().unwrap();
let lon: f64 = latlon[1].parse().unwrap();
println!("{}", nmea::rmc(lat, lon));
Ok(())
})
.build()?;
webview.run()
}

fn inline_style(s: &str) -> String {
format!(r#"<style type="text/css">{}</style>"#, s)
}

fn inline_script(s: &str) -> String {
format!(r#"<script type="text/javascript">{}</script>"#, s)
}
41 changes: 41 additions & 0 deletions src/nmea.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
extern crate time;

fn dec_to_dm(dec: f64) -> f64 {
let deg = dec.abs().floor();
let min = (dec-deg)*60.0/100.0;
deg+min
}

fn checksum(message: &String) -> String {
let mut checksum = 0;
for character in message.bytes() {
checksum ^= character;
}
format!("{:02X}", checksum)
}

pub fn rmc(lat: f64, lon: f64) -> String {
let lat_nmea = format!("{:08.3}", dec_to_dm(lat)*100.0);
let lon_nmea = format!("{:09.3}", dec_to_dm(lon)*100.0);
let ns = if lat.is_sign_negative() { 'S' } else { 'N' };
let ew = if lon.is_sign_negative() { 'W' } else { 'E' };
let now = time::now_utc();
let date = now.strftime("%d%m%y").unwrap();
let timestamp = now.strftime("%H%M%S").unwrap();
let message = [
"GPRMC",
&timestamp.to_string(),
"A", // A: valid, V: invalid
&lat_nmea,
&ns.to_string(),
&lon_nmea,
&ew.to_string(),
"0", // speed over ground (knots)
"0", // course over ground (degrees)
&date.to_string(),
"", // magnetic variation (degrees)
"", // E/W (east/west)
].join(",");
let checksum = checksum(&message);
format!("${}*{}", message, checksum)
}

0 comments on commit cfb5e33

Please sign in to comment.