Makefile changes.

pull/26/head
Christopher Young 2015-08-31 12:18:44 -04:00
commit 02494192ef
9 zmienionych plików z 390 dodań i 185 usunięć

Wyświetl plik

@ -4,7 +4,7 @@ GOARM ?= 7
all: all:
GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) go get -t -d -v ./... GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) go get -t -d -v ./...
GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) go build main/gen_gdl90.go main/traffic.go main/ry835ai.go main/network.go GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) go build main/gen_gdl90.go main/traffic.go main/ry835ai.go main/network.go managementinterface.go
test: test:
sh -c true sh -c true

Wyświetl plik

@ -5,7 +5,6 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"log" "log"
"net"
"os" "os"
"runtime" "runtime"
"strings" "strings"
@ -17,7 +16,7 @@ import (
const ( const (
stratuxVersion = "v0.2" stratuxVersion = "v0.2"
configLocation = "/etc/stratux.conf" configLocation = "/etc/stratux.conf"
managementAddr = "127.0.0.1:9110" managementAddr = ":9110"
maxDatagramSize = 8192 maxDatagramSize = 8192
UPLINK_BLOCK_DATA_BITS = 576 UPLINK_BLOCK_DATA_BITS = 576
UPLINK_BLOCK_BITS = (UPLINK_BLOCK_DATA_BITS + 160) UPLINK_BLOCK_BITS = (UPLINK_BLOCK_DATA_BITS + 160)
@ -390,55 +389,6 @@ type status struct {
var globalSettings settings var globalSettings settings
var globalStatus status var globalStatus status
func handleManagementConnection(conn net.Conn) {
defer conn.Close()
rw := bufio.NewReader(conn)
for {
s, err := rw.ReadString('\n')
if err != nil {
break
}
s = strings.Trim(s, "\r\n")
if s == "STATUS" {
resp, _ := json.Marshal(&globalStatus)
conn.Write(resp)
} else if s == "SETTINGS" {
resp, _ := json.Marshal(&globalSettings)
conn.Write(resp)
} else if s == "QUIT" {
break
} else {
// Assume settings.
//TODO: Make this so that there is some positive way of doing this versus assuming that everything other than commands above are settings.
var newSettings settings
err := json.Unmarshal([]byte(s), &newSettings)
if err != nil {
log.Printf("%s - error: %s\n", s, err.Error())
} else {
log.Printf("new settings: %s\n", s)
globalSettings = newSettings
saveSettings()
}
}
}
}
func managementInterface() {
ln, err := net.Listen("tcp", managementAddr)
if err != nil { //TODO
log.Printf("couldn't open management port: %s\n", err.Error())
return
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil { //TODO
continue
}
go handleManagementConnection(conn)
}
}
func defaultSettings() { func defaultSettings() {
globalSettings.UAT_Enabled = true //TODO globalSettings.UAT_Enabled = true //TODO
globalSettings.ES_Enabled = false //TODO globalSettings.ES_Enabled = false //TODO
@ -480,8 +430,6 @@ func saveSettings() {
log.Printf("can't save settings %s: %s\n", configLocation, err.Error()) log.Printf("can't save settings %s: %s\n", configLocation, err.Error())
return return
} }
jsonSettings, _ := json.Marshal(&globalSettings)
fd.Write(jsonSettings)
log.Printf("wrote settings.\n") log.Printf("wrote settings.\n")
} }

Wyświetl plik

@ -0,0 +1,77 @@
package main
import (
"encoding/json"
"log"
"time"
"golang.org/x/net/websocket"
"io"
"net/http"
)
type SettingMessage struct {
Setting string `json:"setting"`
Value bool `json:"state"`
}
func statusSender(conn *websocket.Conn) {
timer := time.NewTicker(1 * time.Second)
for {
<-timer.C
statResp, _ := json.Marshal(&globalStatus)
conn.Write(statResp)
settingResp, _ := json.Marshal(&globalSettings)
_, err := conn.Write(settingResp)
if err != nil {
log.Printf("Web client disconnected.\n")
break
}
}
}
func handleManagementConnection(conn *websocket.Conn) {
go statusSender(conn)
for {
var msg SettingMessage
err := websocket.JSON.Receive(conn, &msg)
if err == io.EOF {
break
} else if err != nil {
log.Printf("handleManagementConnection: %s\n", err.Error())
} else {
if msg.Setting == "UAT_Enabled" {
globalSettings.UAT_Enabled = msg.Value
}
if msg.Setting == "ES_Enabled" {
globalSettings.ES_Enabled = msg.Value
}
if msg.Setting == "GPS_Enabled" {
globalSettings.GPS_Enabled = msg.Value
}
if msg.Setting == "AHRS_Enabled" {
globalSettings.AHRS_Enabled = msg.Value
}
saveSettings()
}
}
}
func managementInterface() {
http.HandleFunc("/",
func (w http.ResponseWriter, req *http.Request) {
s := websocket.Server{
Handler: websocket.Handler(handleManagementConnection)}
s.ServeHTTP(w, req)
});
err := http.ListenAndServe(managementAddr, nil)
if err != nil {
log.Printf("managementInterface ListenAndServe: %s\n", err.Error())
}
}

Wyświetl plik

@ -1,64 +0,0 @@
<?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";
?>

5
web/css/bootstrap.min.css vendored 100644

File diff suppressed because one or more lines are too long

45
web/css/onoff.css 100644
Wyświetl plik

@ -0,0 +1,45 @@
.onoffswitch {
position: relative; width: 68px;
-webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
display: none;
}
.onoffswitch-label {
display: block; overflow: hidden; cursor: pointer;
border: 2px solid #ddd; border-radius: 20px;
}
.onoffswitch-inner {
display: block; width: 200%; margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
box-sizing: border-box;
}
.onoffswitch-inner:before {
content: "ON";
padding-left: 10px;
background-color: #337AB7; color: #FFFFFF;
}
.onoffswitch-inner:after {
content: "OFF";
padding-right: 10px;
background-color: #F5F5F5; color: #DDDDDD;
text-align: right;
}
.onoffswitch-switch {
display: block; width: 18px; margin: 6px;
background: #FFFFFF;
position: absolute; top: 0; bottom: 0;
right: 34px;
border: 2px solid #ddd; border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
right: 0px;
}

Wyświetl plik

@ -0,0 +1,46 @@
@import url(bootstrap.min.css);
@import url(onoff.css);
body
{
background-color: #ddd;
}
#stratux-main
{
margin-right: 0;
margin-left: 0;
background-color: #fff;
border-color: #ddd;
border-width: 1px;
border-radius: 4px 4px 0 0;
box-shadow: none;
margin: auto;
max-width: 400px;
}
#RY835AI_connected-container
{
display: table-cell;
vertical-align: middle;
}
.led-red
{
display: inline-block;
width: 12px;
height: 12px;
background-color: #940;
border-radius: 50%;
box-shadow: #000 0 -1px 7px 1px, inset #600 0 -1px 9px, #F00 0 2px 12px;
}
.led-green
{
display: inline-block;
width: 12px;
height: 12px;
background-color: #00FF00;
border-radius: 50%;
box-shadow: #000 0 -1px 7px 1px, inset #460 0 -1px 9px, #7D0 0 2px 12px;
}

Wyświetl plik

@ -1,70 +1,120 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html> <html>
<head> <head>
<title> <title>
Stratux Stratux
</title> </title>
<script src="js/jquery-2.1.4.min.js" type="text/javascript"></script> <script src="js/jquery-2.1.4.min.js" type="text/javascript"></script>
<script src="js/jquery.form.min.js" type="text/javascript"></script> <script src="js/jquery.form.min.js" type="text/javascript"></script>
</head> <script src="js/stratux.js" type="text/javascript"></script>
<body> <link href="css/stratux.css" rel="stylesheet" media="screen">
<script type="text/javascript"> </head>
$(document).ready(function() { <body>
$('input[name=UAT_Enabled]').change(function(){ <div id="stratux-main" class="well well-large">
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'}) <h1>Stratux</h1>
});
$('input[name=ES_Enabled]').change(function(){ <div class="panel panel-default">
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'}) <div class="panel-heading">Status <span id="connectedLabel" class="label label-warning">Disconnected</span></div>
}); <div class="panel-body">
$('input[name=GPS_Enabled]').change(function(){ <div class="form-horizontal">
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'}) <div class="row">
}); <label class="col-sm-6">RTL-SDR devices:</label>
$('input[name=AHRS_Enabled]').change(function(){ <span id="Devices" class="col-sm-2">--</span>
$('#settings').ajaxSubmit({url: 'control.php', type: 'post'}) </div>
}); <div class="row">
}); <label class="col-sm-6">Clients connected:</label>
(function worker() { <span id="Connected_Users" class="col-sm-5">--</span>
$.ajax({ </div>
url: 'control.php', <div class="row">
success: function(data) { <label class="col-sm-6">Current firmware:</label>
obj = $.parseJSON(data); <span id="Version" class="col-sm-6">--</span>
$.each(obj, function(k, v) { </div>
// Radio values. <div class="row">
if ((k == "UAT_Enabled") || (k == "ES_Enabled") || (k == "GPS_Enabled") || (k == "AHRS_Enabled")) { <label class="col-sm-6">UAT msgs:</label>
$('[name=' + k + ']').val([v.toString()]); <div class="col-sm-6">
} <span id="UAT_messages_last_minute">--</span>
$('#' + k).text(v); /
}); <span id="UAT_messages_max">--</span>
</div>
}, </div>
complete: function() { <div class="row">
// Schedule the next request when the current one is complete. <label class="col-sm-6">1090ES msgs:</label>
setTimeout(worker, 1000); <div class="col-sm-6">
} <span id="ES_messages_last_minute">--</span>
}); /
})(); <span id="ES_messages_max">--</span>
</div>
</script> </div>
Status:<br> <div class="row">
RTL-SDR devices: <span id="Devices">1</span><br> <label class="col-sm-6">GPS satellites:</label>
Clients connected: <span id="Connected_Users">2</span><br> <span id="GPS_satellites_locked" class="col-sm-6">--</span>
Current firmware: <span id="Version">v0.1</span><br> </div>
UAT msgs: <span id="UAT_messages_last_minute"></span> / <span id="UAT_messages_max"></span><br> <div class="row">
1090ES msgs: <span id="ES_messages_last_minute"></span> / <span id="ES_messages_max"></span><br> <label class="col-sm-6">AHRS:</label>
GPS satellites: <span id="GPS_satellites_locked"></span><br> <div id="RY835AI_connected-container" class="col-sm-6">
AHRS: <span id="RY835AI_connected"></span><br> <div id="RY835AI_connected" class="led-red"></div>
Uptime: <span id="Uptime"></span><br> </div>
<br> </div>
<form id="settings"> <div class="row">
Set:<br> <label class="col-sm-6">Uptime:</label>
978MHz <input type="radio" name="UAT_Enabled" value="true">On <span id="Uptime" class="col-sm-6">--</span>
<input type="radio" name="UAT_Enabled" value="false">Off<br> </div>
1090MHz <input type="radio" name="ES_Enabled" value="true">On </div>
<input type="radio" name="ES_Enabled" value="false">Off<br> </div>
GPS <input type="radio" name="GPS_Enabled" value="true">On </div>
<input type="radio" name="GPS_Enabled" value="false">Off<br> <div class="panel panel-default">
AHRS <input type="radio" name="AHRS_Enabled" value="true">On <div class="panel-heading">Settings</div>
<input type="radio" name="AHRS_Enabled" value="false">Off<br> <div class="panel-body form-horizontal">
</form> <div class="form-group">
</body> <label class="control-label col-sm-4">978MHz</label>
<div class="col-sm-1">
<div class="onoffswitch">
<input type="checkbox" name="UAT_Enabled" class="onoffswitch-checkbox" id="uat-onoffswitch" checked>
<label class="onoffswitch-label" for="uat-onoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-4">1090MHz</label>
<div class="col-sm-1">
<div class="onoffswitch">
<input type="checkbox" name="ES_Enabled" class="onoffswitch-checkbox" id="es-onoffswitch" checked>
<label class="onoffswitch-label" for="es-onoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-4">GPS</label>
<div class="col-sm-1">
<div class="onoffswitch">
<input type="checkbox" name="GPS_Enabled" class="onoffswitch-checkbox" id="gps-onoffswitch" checked>
<label class="onoffswitch-label" for="gps-onoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-4">AHRS</label>
<div class="col-sm-1">
<div class="onoffswitch">
<input type="checkbox" name="AHRS_Enabled" class="onoffswitch-checkbox" id="ahrs-onoffswitch" checked>
<label class="onoffswitch-label" for="ahrs-onoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html> </html>

98
web/js/stratux.js 100644
Wyświetl plik

@ -0,0 +1,98 @@
var socket;
function setLEDstatus (ledElement, status) {
if(status) {
ledElement.removeClass('led-red');
ledElement.addClass('led-green');
}
else {
ledElement.removeClass('led-green');
ledElement.addClass('led-red');
}
}
function setConnectedClass (cssClass) {
$('#connectedLabel').removeClass('label-success');
$('#connectedLabel').removeClass('label-warning');
$('#connectedLabel').removeClass('label-danger');
$('#connectedLabel').addClass( cssClass );
if(cssClass == 'label-success')
$('#connectedLabel').text('Connected');
else
$('#connectedLabel').text('Disconnected');
}
function connect() {
socket = new WebSocket('ws://' + window.location.hostname + ':9110/');
socket.onopen = function(msg) {
setConnectedClass('label-success');
};
socket.onclose = function(msg) {
setConnectedClass('label-danger');
setTimeout(connect,1000);
};
socket.onerror = function(msg) {
setConnectedClass('label-danger');
};
socket.onmessage = function(msg) {
console.log('Received status update.')
var status = JSON.parse(msg.data)
// Update Status
$('#Version').text(status.Version);
$('#Devices').text(status.Devices);
$('#Connected_Users').text(status.Connected_Users);
$('#UAT_messages_last_minute').text(status.UAT_messages_last_minute);
$('#UAT_messages_max').text(status.UAT_messages_max);
$('#ES_messages_last_minute').text(status.ES_messages_last_minute);
$('#ES_messages_max').text(status.ES_messages_max);
$('#GPS_satellites_locked').text(status.GPS_satellites_locked);
setLEDstatus($('#RY835AI_connected'), status.RY835AI_connected);
$('#Uptime').text(status.Uptime);
// Update Settings
$('input[name=UAT_Enabled]').prop('checked', status.UAT_Enabled);
$('input[name=ES_Enabled]').prop('checked', status.ES_Enabled);
$('input[name=GPS_Enabled]').prop('checked', status.GPS_Enabled);
$('input[name=AHRS_Enabled]').prop('checked', status.AHRS_Enabled);
};
}
$(document).ready(function() {
connect();
$('input[name=UAT_Enabled]').click(function () {
console.log('UAT_Enabled clicked');
msg = {setting: 'UAT_Enabled', state: $('input[name=UAT_Enabled]').prop('checked') };
socket.send(JSON.stringify(msg));
});
$('input[name=ES_Enabled]').click(function () {
console.log('ES_Enabled clicked');
msg = {setting: 'ES_Enabled', state: $('input[name=ES_Enabled]').prop('checked') };
socket.send(JSON.stringify(msg));
});
$('input[name=GPS_Enabled]').click(function () {
console.log('GPS_Enabled clicked');
msg = {setting: 'GPS_Enabled', state: $('input[name=GPS_Enabled]').prop('checked') };
socket.send(JSON.stringify(msg));
});
$('input[name=AHRS_Enabled]').click(function () {
console.log('AHRS_Enabled clicked');
msg = {setting: 'AHRS_Enabled', state: $('input[name=AHRS_Enabled]').prop('checked') };
socket.send(JSON.stringify(msg));
});
});