2017-05-07 03:37:30 +02:00
package runtime
import (
"bytes"
"fmt"
"net"
2017-07-06 18:20:12 +02:00
"github.com/genofire/golang-lib/log"
2017-05-07 03:37:30 +02:00
"github.com/FreifunkBremen/yanic/data"
2017-05-12 21:32:10 +02:00
"github.com/FreifunkBremen/yanic/jsontime"
2017-05-07 03:37:30 +02:00
yanicRuntime "github.com/FreifunkBremen/yanic/runtime"
2017-05-29 22:55:38 +02:00
"github.com/FreifunkBremen/freifunkmanager/ssh"
2017-05-07 03:37:30 +02:00
)
const (
2017-07-06 18:20:12 +02:00
SSHUpdateHostname = "uci set system.@system[0].hostname='%s'; uci set wireless.priv_radio0.ssid=\"offline-$(uci get system.@system[0].hostname)\"; uci set wireless.priv_radio1.ssid=\"offline-$(uci get system.@system[0].hostname)\"; uci commit; echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname; wifi"
SSHUpdateOwner = "uci set gluon-node-info.@owner[0].contact='%s';uci commit gluon-node-info;"
SSHUpdateLocation = "uci set gluon-node-info.@location[0].latitude='%f';uci set gluon-node-info.@location[0].longitude='%f';uci set gluon-node-info.@location[0].share_location=1;uci commit gluon-node-info;"
SSHUpdateWifiFreq24 = "if [ \"$(uci get wireless.radio0.hwmode | grep -c g)\" -ne 0 ]; then uci set wireless.radio0.channel='%d'; uci set wireless.radio0.txpower='%d'; elif [ \"$(uci get wireless.radio1.hwmode | grep -c g)\" -ne 0 ]; then uci set wireless.radio1.channel='%d'; uci set wireless.radio1.txpower='%d'; fi;"
SSHUpdateWifiFreq5 = "if [ \"$(uci get wireless.radio0.hwmode | grep -c a)\" -ne 0 ]; then uci set wireless.radio0.channel='%d'; uci set wireless.radio0.txpower='%d'; elif [ \"$(uci get wireless.radio1.hwmode | grep -c a)\" -ne 0 ]; then uci set wireless.radio1.channel='%d'; uci set wireless.radio1.txpower='%d'; fi;"
2017-05-07 03:37:30 +02:00
)
type Node struct {
2017-05-12 21:32:10 +02:00
Lastseen jsontime . Time ` json:"lastseen" `
2017-05-07 03:37:30 +02:00
NodeID string ` json:"node_id" `
Hostname string ` json:"hostname" `
Location data . Location ` json:"location" `
Wireless data . Wireless ` json:"wireless" `
Owner string ` json:"owner" `
2017-05-30 02:16:46 +02:00
Address net . IP ` json:"-" `
2017-05-08 19:49:18 +02:00
Stats struct {
Wireless data . WirelessStatistics ` json:"wireless" `
Clients data . Clients ` json:"clients" `
} ` json:"statistics" `
2017-05-07 03:37:30 +02:00
}
2017-05-08 19:49:18 +02:00
func NewNode ( nodeOrigin * yanicRuntime . Node ) * Node {
if nodeinfo := nodeOrigin . Nodeinfo ; nodeinfo != nil {
2017-05-07 03:37:30 +02:00
node := & Node {
Hostname : nodeinfo . Hostname ,
NodeID : nodeinfo . NodeID ,
2017-05-08 19:49:18 +02:00
Address : nodeOrigin . Address ,
2017-05-07 03:37:30 +02:00
}
if owner := nodeinfo . Owner ; owner != nil {
node . Owner = owner . Contact
}
if location := nodeinfo . Location ; location != nil {
node . Location = * location
}
if wireless := nodeinfo . Wireless ; wireless != nil {
node . Wireless = * wireless
}
2017-05-08 19:49:18 +02:00
if stats := nodeOrigin . Statistics ; stats != nil {
node . Stats . Clients = stats . Clients
node . Stats . Wireless = stats . Wireless
}
2017-05-07 03:37:30 +02:00
return node
}
return nil
}
func ( n * Node ) SSHUpdate ( ssh * ssh . Manager , iface string , oldnode * Node ) {
addr := n . GetAddress ( iface )
2017-07-07 08:12:25 +02:00
2017-07-06 08:03:37 +02:00
if oldnode == nil || n . Hostname != oldnode . Hostname {
2017-05-07 03:37:30 +02:00
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateHostname , n . Hostname ) )
}
2017-07-06 08:03:37 +02:00
if oldnode == nil || n . Owner != oldnode . Owner {
2017-05-07 03:37:30 +02:00
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateOwner , n . Owner ) )
}
2017-07-07 08:12:25 +02:00
if oldnode == nil || ! locationEqual ( n . Location , oldnode . Location ) {
2017-05-07 03:37:30 +02:00
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateLocation , n . Location . Latitude , n . Location . Longtitude ) )
}
2017-07-07 08:12:25 +02:00
if oldnode == nil || ! wirelessEqual ( n . Wireless , oldnode . Wireless ) {
2017-07-06 18:20:12 +02:00
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateWifiFreq24 , n . Wireless . Channel24 , n . Wireless . TxPower24 , n . Wireless . Channel24 , n . Wireless . TxPower24 ) )
ssh . ExecuteOn ( addr , fmt . Sprintf ( SSHUpdateWifiFreq5 , n . Wireless . Channel5 , n . Wireless . TxPower5 , n . Wireless . Channel5 , n . Wireless . TxPower5 ) )
ssh . ExecuteOn ( addr , "wifi" )
2017-07-07 08:12:25 +02:00
// send warning for running wifi, because it kicks clients from node
log . Log . Warn ( "[cmd] wifi " , n . NodeID )
2017-07-06 18:20:12 +02:00
}
2017-07-07 08:12:25 +02:00
oldnode = n
2017-05-07 03:37:30 +02:00
}
func ( n * Node ) GetAddress ( iface string ) net . TCPAddr {
return net . TCPAddr { IP : n . Address , Port : 22 , Zone : iface }
}
func ( n * Node ) Update ( node * yanicRuntime . Node ) {
if nodeinfo := node . Nodeinfo ; nodeinfo != nil {
n . Hostname = nodeinfo . Hostname
n . NodeID = nodeinfo . NodeID
n . Address = node . Address
if owner := nodeinfo . Owner ; owner != nil {
n . Owner = owner . Contact
}
if location := nodeinfo . Location ; location != nil {
n . Location = * location
}
if wireless := nodeinfo . Wireless ; wireless != nil {
n . Wireless = * wireless
}
}
}
func ( n * Node ) IsEqual ( node * Node ) bool {
if n . NodeID != node . NodeID {
return false
}
if ! bytes . Equal ( n . Address , node . Address ) {
return false
}
if n . Hostname != node . Hostname {
return false
}
if n . Owner != node . Owner {
return false
}
2017-07-07 08:12:25 +02:00
if ! locationEqual ( n . Location , node . Location ) {
2017-05-07 03:37:30 +02:00
return false
}
2017-07-07 08:12:25 +02:00
if ! wirelessEqual ( n . Wireless , node . Wireless ) {
2017-05-07 03:37:30 +02:00
return false
}
return true
}
2017-07-07 08:12:25 +02:00
func locationEqual ( a , b data . Location ) bool {
2017-05-07 03:37:30 +02:00
if a . Latitude != b . Latitude {
return false
}
if a . Longtitude != b . Longtitude {
return false
}
if a . Altitude != b . Altitude {
return false
}
return true
}
2017-07-07 08:12:25 +02:00
func wirelessEqual ( a , b data . Wireless ) bool {
2017-05-07 03:37:30 +02:00
if a . Channel24 != b . Channel24 {
return false
}
if a . Channel5 != b . Channel5 {
return false
}
if a . TxPower24 != b . TxPower24 {
return false
}
if a . TxPower5 != b . TxPower5 {
return false
}
return true
}