Merge pull request #3 from cyoung/master

Merge upstream
pull/25/head
Brant K. Kyser 2015-08-25 19:11:18 -05:00
commit 3f6828a600
10 zmienionych plików z 249 dodań i 28 usunięć

6
.gitignore vendored
Wyświetl plik

@ -3,3 +3,9 @@ dump978/uat2esnt
dump978/uat2json
dump978/uat2text
gen_gdl90
*.mp4
*.img
*.zip

Wyświetl plik

@ -10,8 +10,15 @@ Supported WiFi adapters:
* TP-LINK TL-WN725N
Tested RTL-SDR:
*NooElec NESDR Mini 2
* NooElec NESDR Mini 2
* Generic R820T (degraded performance)
Tested weather/traffic displays:
* ForeFlight 7.2 (Jul 13, 2015) - weather, traffic, AHRS.
* Naviator - weather, traffic, AHRS.
* WingX - weather & traffic.
* Avare
* iFly 740 - weather & traffic.
https://www.reddit.com/r/stratux

Wyświetl plik

@ -15,7 +15,7 @@ import (
// http://www.faa.gov/nextgen/programs/adsb/wsa/media/GDL90_Public_ICD_RevA.PDF
const (
stratuxVersion = "v0.1"
stratuxVersion = "v0.2"
configLocation = "/etc/stratux.conf"
managementAddr = "127.0.0.1:9110"
maxDatagramSize = 8192
@ -56,6 +56,7 @@ type msg struct {
}
var MsgLog []msg
var timeStarted time.Time
// Construct the CRC table. Adapted from FAA ref above.
func crcInit() {
@ -299,9 +300,20 @@ func updateStatus() {
globalStatus.UAT_messages_last_minute = UAT_messages_last_minute
globalStatus.ES_messages_last_minute = ES_messages_last_minute
// Update "max messages/min" counters.
if globalStatus.UAT_messages_max < UAT_messages_last_minute {
globalStatus.UAT_messages_max = UAT_messages_last_minute
}
if globalStatus.ES_messages_max < ES_messages_last_minute {
globalStatus.ES_messages_max = ES_messages_last_minute
}
if isGPSValid() {
globalStatus.GPS_satellites_locked = mySituation.satellites
}
// Update Uptime.
globalStatus.Uptime = time.Since(timeStarted).String()
}
func parseInput(buf string) ([]byte, uint16) {
@ -372,6 +384,7 @@ type status struct {
GPS_satellites_locked uint16
GPS_connected bool
RY835AI_connected bool
Uptime string
}
var globalSettings settings
@ -427,11 +440,11 @@ func managementInterface() {
}
func defaultSettings() {
globalSettings.UAT_Enabled = true //TODO
globalSettings.ES_Enabled = true //TODO
globalSettings.GPS_Enabled = true //TODO
globalSettings.NetworkOutputs = []networkConnection{{nil, "", 4000, NETWORK_GDL90}, {nil, "", 43211, NETWORK_GDL90}, {nil, "", 49002, NETWORK_AHRS}}
globalSettings.AHRS_Enabled = true
globalSettings.UAT_Enabled = true //TODO
globalSettings.ES_Enabled = false //TODO
globalSettings.GPS_Enabled = false //TODO
globalSettings.NetworkOutputs = []networkConnection{{nil, "", 4000, NETWORK_GDL90_STANDARD}, {nil, "", 43211, NETWORK_GDL90_STANDARD | NETWORK_AHRS_GDL90}, {nil, "", 49002, NETWORK_AHRS_FFSIM}}
globalSettings.AHRS_Enabled = false
}
func readSettings() {
@ -473,6 +486,7 @@ func saveSettings() {
}
func main() {
timeStarted = time.Now()
runtime.GOMAXPROCS(runtime.NumCPU()) // redundant with Go v1.5+ compiler
MsgLog = make([]msg, 0)
@ -480,9 +494,7 @@ func main() {
initTraffic()
globalStatus.Version = stratuxVersion
globalStatus.Devices = 123 //TODO
globalStatus.UAT_messages_last_minute = 567 //TODO
globalStatus.ES_messages_last_minute = 981 //TODO
globalStatus.Devices = 0 //TODO
readSettings()

Wyświetl plik

@ -1,7 +1,6 @@
package main
import (
"golang.org/x/exp/inotify"
"io/ioutil"
"log"
"net"
@ -29,8 +28,9 @@ var dhcpLeases map[string]string
var netMutex *sync.Mutex
const (
NETWORK_GDL90 = 1
NETWORK_AHRS = 2
NETWORK_GDL90_STANDARD = 1
NETWORK_AHRS_FFSIM = 2
NETWORK_AHRS_GDL90 = 4
dhcp_lease_file = "/var/lib/dhcp/dhcpd.leases"
)
@ -134,25 +134,16 @@ func sendMsg(msg []byte, msgType uint8) {
}
func sendGDL90(msg []byte) {
sendMsg(msg, NETWORK_GDL90)
sendMsg(msg, NETWORK_GDL90_STANDARD)
}
func monitorDHCPLeases() {
watcher, err := inotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
err = watcher.AddWatch(dhcp_lease_file, inotify.IN_CLOSE_WRITE)
if err != nil {
log.Fatal(err)
}
//TODO: inotify or dhcp event hook.
timer := time.NewTicker(30 * time.Second)
for {
select {
case <-watcher.Event:
log.Println("file modified, attempting to refresh DHCP")
case <-timer.C:
refreshConnectedClients()
case err := <-watcher.Error:
log.Println("error with DHCP file system watcher:", err)
}
}
}

Wyświetl plik

@ -259,6 +259,53 @@ func tempAndPressureReader() {
globalStatus.RY835AI_connected = false
}
func makeFFAHRSSimReport() {
s := fmt.Sprintf("XATTStratux,%f,%f,%f", mySituation.gyro_heading, mySituation.pitch, mySituation.roll)
sendMsg([]byte(s), NETWORK_AHRS_FFSIM)
}
func makeAHRSGDL90Report() {
msg := make([]byte, 16)
msg[0] = 0x4c
msg[1] = 0x45
msg[2] = 0x01
msg[3] = 0x00
pitch := int16(float64(mySituation.pitch) * float64(10.0))
roll := int16(float64(mySituation.roll) * float64(10.0))
hdg := uint16(float64(mySituation.gyro_heading) * float64(10.0)) //TODO.
slip_skid := int16(float64(0) * float64(10.0)) //TODO.
yaw_rate := int16(float64(0) * float64(10.0)) //TODO.
g := int16(float64(1.0) * float64(10.0)) //TODO.
// Roll.
msg[4] = byte((roll >> 8) & 0xFF)
msg[5] = byte(roll & 0xFF)
// Pitch.
msg[6] = byte((pitch >> 8) & 0xFF)
msg[7] = byte(pitch & 0xFF)
// Heading.
msg[8] = byte((hdg >> 8) & 0xFF)
msg[9] = byte(hdg & 0xFF)
// Slip/skid.
msg[10] = byte((slip_skid >> 8) & 0xFF)
msg[11] = byte(slip_skid & 0xFF)
// Yaw rate.
msg[12] = byte((yaw_rate >> 8) & 0xFF)
msg[13] = byte(yaw_rate & 0xFF)
// "G".
msg[14] = byte((g >> 8) & 0xFF)
msg[15] = byte(g & 0xFF)
sendMsg(prepareMessage(msg), NETWORK_AHRS_GDL90)
}
func attitudeReaderSender() {
timer := time.NewTicker(100 * time.Millisecond) // ~10Hz update.
for globalStatus.RY835AI_connected && globalSettings.AHRS_Enabled {
@ -281,9 +328,9 @@ func attitudeReaderSender() {
// Send, if valid.
// if isGPSGroundTrackValid(), etc.
s := fmt.Sprintf("XATTStratux,%f,%f,%f", mySituation.gyro_heading, mySituation.pitch, mySituation.roll)
sendMsg([]byte(s), NETWORK_AHRS)
makeFFAHRSSimReport()
makeAHRSGDL90Report()
mySituation.mu_Attitude.Unlock()
}

Wyświetl plik

@ -360,6 +360,15 @@ func esListen() {
if err != nil {
continue
}
// Log the message after we've determined that it at least meets some requirements on the fields.
var thisMsg msg
thisMsg.MessageClass = MSGCLASS_ES
thisMsg.TimeReceived = time.Now()
thisMsg.Data = []byte(buf)
MsgLog = append(MsgLog, thisMsg)
// Begin to parse the message.
icaoDec := uint32(icaoDecf)
trafficMutex.Lock()
// Retrieve previous information on this ICAO code.

64
web/control.php 100644
Wyświetl plik

@ -0,0 +1,64 @@
<?php
function _str_send($sock, $str) {
return socket_send($sock, $str, strlen($str), 0);
}
function get_json($tp) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_connect($sock, '127.0.0.1', '9110')) {
throw new Exception("couldn't connect");
}
_str_send($sock, $tp);
$buf = "";
socket_recv($sock, $buf, 1024, 0);
$x = json_decode($buf, true);
socket_close($sock);
return $x;
}
function get_settings() {
return get_json("SETTINGS\n");
}
function get_status() {
return get_json("STATUS\n");
}
function set_settings($to_set) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_connect($sock, '127.0.0.1', '9110')) {
print "couldn't connect\n";
exit;
}
$buf = json_encode($to_set);
_str_send($sock, $buf . "\n");
_str_send($sock, "QUIT\n");
}
$current_settings = get_settings();
// Copy over old settings to the new ones, such that if there is a field that doesn't change it gets sent over again.
if (isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'POST')) {
$new_settings = $current_settings;
foreach ($_POST as $k => $v) {
if ($v === "true") $v = true;
else if ($v === "false") $v = false;
$new_settings[$k] = $v; //FIXME.
}
set_settings($new_settings);
$current_settings = get_settings();
}
$current_status = get_status();
$p = array_merge($current_settings, $current_status);
print json_encode($p) . "\n";
?>

70
web/index.html 100644
Wyświetl plik

@ -0,0 +1,70 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>
Stratux
</title>
<script src="js/jquery-2.1.4.min.js" type="text/javascript"></script>
<script src="js/jquery.form.min.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
$('input[name=UAT_Enabled]').change(function(){
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'})
});
$('input[name=ES_Enabled]').change(function(){
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'})
});
$('input[name=GPS_Enabled]').change(function(){
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'})
});
$('input[name=AHRS_Enabled]').change(function(){
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'})
});
});
(function worker() {
$.ajax({
url: 'control.php',
success: function(data) {
obj = $.parseJSON(data);
$.each(obj, function(k, v) {
// Radio values.
if ((k == "UAT_Enabled") || (k == "ES_Enabled") || (k == "GPS_Enabled") || (k == "AHRS_Enabled")) {
$('[name=' + k + ']').val([v.toString()]);
}
$('#' + k).text(v);
});
},
complete: function() {
// Schedule the next request when the current one is complete.
setTimeout(worker, 1000);
}
});
})();
</script>
Status:<br>
RTL-SDR devices: <span id="Devices">1</span><br>
Clients connected: <span id="Connected_Users">2</span><br>
Current firmware: <span id="Version">v0.1</span><br>
UAT msgs: <span id="UAT_messages_last_minute"></span> / <span id="UAT_messages_max"></span><br>
1090ES msgs: <span id="ES_messages_last_minute"></span> / <span id="ES_messages_max"></span><br>
GPS satellites: <span id="GPS_satellites_locked"></span><br>
AHRS: <span id="RY835AI_connected"></span><br>
Uptime: <span id="Uptime"></span><br>
<br>
<form id="settings">
Set:<br>
978MHz <input type="radio" name="UAT_Enabled" value="true">On
<input type="radio" name="UAT_Enabled" value="false">Off<br>
1090MHz <input type="radio" name="ES_Enabled" value="true">On
<input type="radio" name="ES_Enabled" value="false">Off<br>
GPS <input type="radio" name="GPS_Enabled" value="true">On
<input type="radio" name="GPS_Enabled" value="false">Off<br>
AHRS <input type="radio" name="AHRS_Enabled" value="true">On
<input type="radio" name="AHRS_Enabled" value="false">Off<br>
</form>
</body>
</html>

4
web/js/jquery-2.1.4.min.js vendored 100644

File diff suppressed because one or more lines are too long

11
web/js/jquery.form.min.js vendored 100644

File diff suppressed because one or more lines are too long