2019-06-28 17:50:02 +00:00
|
|
|
local Config = require('opus.config')
|
|
|
|
local Event = require('opus.event')
|
|
|
|
local Socket = require('opus.socket')
|
|
|
|
local UI = require('opus.ui')
|
|
|
|
local Util = require('opus.util')
|
2016-12-11 19:24:52 +00:00
|
|
|
|
2017-10-08 21:45:01 +00:00
|
|
|
local colors = _G.colors
|
|
|
|
local device = _G.device
|
|
|
|
local network = _G.network
|
2017-10-11 20:31:48 +00:00
|
|
|
local os = _G.os
|
2017-10-08 21:45:01 +00:00
|
|
|
local shell = _ENV.shell
|
|
|
|
|
2016-12-11 19:24:52 +00:00
|
|
|
UI:configure('Network', ...)
|
|
|
|
|
|
|
|
local gridColumns = {
|
2018-01-24 22:39:38 +00:00
|
|
|
{ heading = 'Label', key = 'label' },
|
2019-03-07 18:14:16 +00:00
|
|
|
{ heading = 'Dist', key = 'distance', align = 'right' },
|
2018-01-24 22:39:38 +00:00
|
|
|
{ heading = 'Status', key = 'status' },
|
2016-12-11 19:24:52 +00:00
|
|
|
}
|
|
|
|
|
2018-12-05 02:16:48 +00:00
|
|
|
local config = Config.load('network', { })
|
|
|
|
|
2016-12-11 19:24:52 +00:00
|
|
|
if UI.term.width >= 30 then
|
2019-03-07 18:14:16 +00:00
|
|
|
table.insert(gridColumns, { heading = 'Fuel', key = 'fuel', width = 5, align = 'right' })
|
2019-02-22 08:52:47 +00:00
|
|
|
end
|
|
|
|
if UI.term.width >= 40 then
|
2019-03-07 18:14:16 +00:00
|
|
|
table.insert(gridColumns, { heading = 'Uptime', key = 'uptime', align = 'right' })
|
2016-12-11 19:24:52 +00:00
|
|
|
end
|
|
|
|
|
2016-12-27 21:01:06 +00:00
|
|
|
local page = UI.Page {
|
2018-01-24 22:39:38 +00:00
|
|
|
menuBar = UI.MenuBar {
|
|
|
|
buttons = {
|
|
|
|
{ text = 'Connect', dropdown = {
|
|
|
|
{ text = 'Telnet t', event = 'telnet' },
|
|
|
|
{ text = 'VNC v', event = 'vnc' },
|
2019-03-31 19:16:45 +00:00
|
|
|
{ spacer = true },
|
2018-01-24 22:39:38 +00:00
|
|
|
{ text = 'Reboot r', event = 'reboot' },
|
|
|
|
} },
|
|
|
|
{ text = 'Trust', dropdown = {
|
|
|
|
{ text = 'Establish', event = 'trust' },
|
|
|
|
} },
|
2018-12-05 02:16:48 +00:00
|
|
|
{
|
2019-01-05 15:35:25 +00:00
|
|
|
text = '\187',
|
2018-12-05 02:16:48 +00:00
|
|
|
x = -3,
|
|
|
|
dropdown = {
|
2019-01-28 22:54:00 +00:00
|
|
|
{ text = 'Port Status', event = 'ports', modem = true },
|
2019-07-05 01:33:47 +00:00
|
|
|
{ spacer = true },
|
2019-01-28 22:54:00 +00:00
|
|
|
{ text = 'Help', event = 'help', noCheck = true },
|
2018-12-05 02:16:48 +00:00
|
|
|
},
|
|
|
|
},
|
2018-01-24 22:39:38 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
grid = UI.ScrollingGrid {
|
|
|
|
y = 2,
|
|
|
|
values = network,
|
|
|
|
columns = gridColumns,
|
|
|
|
sortColumn = 'label',
|
|
|
|
autospace = true,
|
|
|
|
},
|
2019-01-27 05:26:41 +00:00
|
|
|
ports = UI.SlideOut {
|
|
|
|
titleBar = UI.TitleBar {
|
|
|
|
title = 'Ports',
|
|
|
|
event = 'ports_hide',
|
|
|
|
},
|
|
|
|
grid = UI.ScrollingGrid {
|
|
|
|
y = 2,
|
|
|
|
columns = {
|
|
|
|
{ heading = 'Port', key = 'port' },
|
|
|
|
{ heading = 'State', key = 'state' },
|
|
|
|
{ heading = 'Connection', key = 'connection' },
|
|
|
|
},
|
|
|
|
sortColumn = 'port',
|
|
|
|
autospace = true,
|
|
|
|
},
|
|
|
|
},
|
2019-01-30 20:11:41 +00:00
|
|
|
help = UI.SlideOut {
|
|
|
|
backgroundColor = colors.cyan,
|
|
|
|
x = 5, ex = -5, height = 8, y = -8,
|
|
|
|
titleBar = UI.TitleBar {
|
|
|
|
title = 'Network Help',
|
|
|
|
event = 'slide_hide',
|
|
|
|
},
|
|
|
|
text = UI.TextArea {
|
|
|
|
x = 2, y = 2,
|
|
|
|
backgroundColor = colors.cyan,
|
|
|
|
value = [[
|
|
|
|
|
|
|
|
In order to connect to another computer:
|
|
|
|
|
|
|
|
1. The target computer must have a password set (run 'password' from the shell prompt).
|
|
|
|
|
|
|
|
2. From this computer, click trust and enter the password for that computer.
|
|
|
|
|
|
|
|
This only needs to be done once.
|
|
|
|
]],
|
|
|
|
},
|
|
|
|
accelerators = {
|
|
|
|
q = 'slide_hide',
|
|
|
|
}
|
|
|
|
},
|
2018-01-24 22:39:38 +00:00
|
|
|
notification = UI.Notification { },
|
|
|
|
accelerators = {
|
|
|
|
t = 'telnet',
|
|
|
|
v = 'vnc',
|
|
|
|
r = 'reboot',
|
2019-07-02 18:11:33 +00:00
|
|
|
[ 'control-q' ] = 'quit',
|
2018-01-24 22:39:38 +00:00
|
|
|
c = 'clear',
|
|
|
|
},
|
2016-12-27 21:01:06 +00:00
|
|
|
}
|
2016-12-11 19:24:52 +00:00
|
|
|
|
2017-05-14 01:05:05 +00:00
|
|
|
local function sendCommand(host, command)
|
2018-01-24 22:39:38 +00:00
|
|
|
if not device.wireless_modem then
|
|
|
|
page.notification:error('Wireless modem not present')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
page.notification:info('Connecting')
|
|
|
|
page:sync()
|
|
|
|
|
|
|
|
local socket = Socket.connect(host, 161)
|
|
|
|
if socket then
|
|
|
|
socket:write({ type = command })
|
|
|
|
socket:close()
|
|
|
|
page.notification:success('Command sent')
|
|
|
|
else
|
|
|
|
page.notification:error('Failed to connect')
|
|
|
|
end
|
2016-12-11 19:24:52 +00:00
|
|
|
end
|
|
|
|
|
2019-02-23 23:36:17 +00:00
|
|
|
function page.ports:eventHandler(event)
|
|
|
|
if event.type == 'grid_select' then
|
2019-07-05 01:46:09 +00:00
|
|
|
shell.openForegroundTab('Sniff ' .. event.selected.port)
|
2019-02-23 23:36:17 +00:00
|
|
|
end
|
|
|
|
return UI.SlideOut.eventHandler(self, event)
|
|
|
|
end
|
|
|
|
|
2019-01-27 05:26:41 +00:00
|
|
|
function page.ports.grid:update()
|
2019-06-29 20:35:33 +00:00
|
|
|
local transport = network:getTransport()
|
|
|
|
|
2019-01-27 05:26:41 +00:00
|
|
|
local function findConnection(port)
|
2019-06-29 20:35:33 +00:00
|
|
|
if transport then
|
|
|
|
for _,socket in pairs(transport.sockets) do
|
|
|
|
if socket.sport == port then
|
|
|
|
return socket
|
|
|
|
end
|
2019-01-27 05:26:41 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local connections = { }
|
|
|
|
|
2019-01-28 22:54:00 +00:00
|
|
|
pcall(function() -- guard against modem removal
|
|
|
|
if device.wireless_modem then
|
|
|
|
for i = 0, 65535 do
|
|
|
|
if device.wireless_modem.isOpen(i) then
|
|
|
|
local conn = {
|
|
|
|
port = i
|
|
|
|
}
|
|
|
|
local socket = findConnection(i)
|
|
|
|
if socket then
|
|
|
|
conn.state = 'CONNECTED'
|
|
|
|
local host = socket.dhost
|
|
|
|
if network[host] then
|
|
|
|
host = network[host].label
|
|
|
|
end
|
|
|
|
conn.connection = host .. ':' .. socket.dport
|
|
|
|
else
|
|
|
|
conn.state = 'LISTEN'
|
|
|
|
end
|
|
|
|
table.insert(connections, conn)
|
2019-01-27 05:26:41 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-01-28 22:54:00 +00:00
|
|
|
end)
|
|
|
|
|
2019-01-27 05:26:41 +00:00
|
|
|
self.values = connections
|
|
|
|
UI.Grid.update(self)
|
|
|
|
end
|
|
|
|
|
2016-12-11 19:24:52 +00:00
|
|
|
function page:eventHandler(event)
|
2018-01-24 22:39:38 +00:00
|
|
|
local t = self.grid:getSelected()
|
|
|
|
if t then
|
|
|
|
if event.type == 'telnet' then
|
2019-03-08 21:47:39 +00:00
|
|
|
shell.openForegroundTab('telnet ' .. t.id)
|
|
|
|
|
2018-01-24 22:39:38 +00:00
|
|
|
elseif event.type == 'vnc' then
|
2019-03-08 21:47:39 +00:00
|
|
|
shell.openForegroundTab('vnc.lua ' .. t.id)
|
2018-12-10 15:33:56 +00:00
|
|
|
os.queueEvent('overview_shortcut', {
|
|
|
|
title = t.label,
|
|
|
|
category = "VNC",
|
2019-07-17 02:29:47 +00:00
|
|
|
icon = "\010\030 \009\009\031e\\\031 \031e/\031dn\010\030 \009\009 \031e\\/\031 \031bc",
|
2018-12-10 15:33:56 +00:00
|
|
|
run = "vnc.lua " .. t.id,
|
|
|
|
})
|
2019-03-08 21:47:39 +00:00
|
|
|
|
2018-01-24 22:39:38 +00:00
|
|
|
elseif event.type == 'clear' then
|
|
|
|
Util.clear(network)
|
|
|
|
page.grid:update()
|
|
|
|
page.grid:draw()
|
|
|
|
|
|
|
|
elseif event.type == 'trust' then
|
|
|
|
shell.openForegroundTab('trust ' .. t.id)
|
|
|
|
|
|
|
|
elseif event.type == 'reboot' then
|
|
|
|
sendCommand(t.id, 'reboot')
|
|
|
|
|
|
|
|
elseif event.type == 'shutdown' then
|
|
|
|
sendCommand(t.id, 'shutdown')
|
|
|
|
end
|
|
|
|
end
|
2017-10-09 17:08:38 +00:00
|
|
|
|
2019-01-30 20:11:41 +00:00
|
|
|
if event.type == 'help' then
|
|
|
|
self.help:show()
|
2018-12-05 02:16:48 +00:00
|
|
|
|
2019-01-27 05:26:41 +00:00
|
|
|
elseif event.type == 'ports' then
|
|
|
|
self.ports.grid:update()
|
|
|
|
self.ports:show()
|
|
|
|
|
|
|
|
self.portsHandler = Event.onInterval(3, function()
|
|
|
|
self.ports.grid:update()
|
|
|
|
self.ports.grid:draw()
|
|
|
|
self:sync()
|
|
|
|
end)
|
|
|
|
|
|
|
|
elseif event.type == 'ports_hide' then
|
|
|
|
Event.off(self.portsHandler)
|
|
|
|
self.ports:hide()
|
|
|
|
|
2018-12-05 02:16:48 +00:00
|
|
|
elseif event.type == 'show_trusted' then
|
|
|
|
config.showTrusted = true
|
|
|
|
Config.update('network', config)
|
|
|
|
|
2018-01-24 22:39:38 +00:00
|
|
|
elseif event.type == 'quit' then
|
|
|
|
Event.exitPullEvents()
|
|
|
|
end
|
|
|
|
UI.Page.eventHandler(self, event)
|
2016-12-11 19:24:52 +00:00
|
|
|
end
|
|
|
|
|
2017-10-09 17:08:38 +00:00
|
|
|
function page.menuBar:getActive(menuItem)
|
2018-01-24 22:39:38 +00:00
|
|
|
local t = page.grid:getSelected()
|
2019-01-28 22:54:00 +00:00
|
|
|
if menuItem.modem then
|
|
|
|
return not not device.wireless_modem
|
2018-01-24 22:39:38 +00:00
|
|
|
end
|
2018-12-06 02:21:30 +00:00
|
|
|
return menuItem.noCheck or not not t
|
2017-10-09 17:08:38 +00:00
|
|
|
end
|
|
|
|
|
2016-12-11 19:24:52 +00:00
|
|
|
function page.grid:getRowTextColor(row, selected)
|
2018-01-24 22:39:38 +00:00
|
|
|
if not row.active then
|
2019-01-28 22:54:00 +00:00
|
|
|
return colors.lightGray
|
2018-01-24 22:39:38 +00:00
|
|
|
end
|
|
|
|
return UI.Grid.getRowTextColor(self, row, selected)
|
2016-12-11 19:24:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function page.grid:getDisplayValues(row)
|
2018-01-24 22:39:38 +00:00
|
|
|
row = Util.shallowCopy(row)
|
|
|
|
if row.uptime then
|
|
|
|
if row.uptime < 60 then
|
|
|
|
row.uptime = string.format("%ds", math.floor(row.uptime))
|
2019-03-07 18:14:16 +00:00
|
|
|
elseif row.uptime < 3600 then
|
|
|
|
row.uptime = string.format("%sm", math.floor(row.uptime / 60))
|
2018-01-24 22:39:38 +00:00
|
|
|
else
|
2019-03-07 18:14:16 +00:00
|
|
|
row.uptime = string.format("%sh", math.floor(row.uptime / 3600))
|
2018-01-24 22:39:38 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
if row.fuel then
|
2018-12-21 00:28:26 +00:00
|
|
|
row.fuel = row.fuel > 0 and Util.toBytes(row.fuel) or ''
|
2018-01-24 22:39:38 +00:00
|
|
|
end
|
|
|
|
if row.distance then
|
2019-03-10 23:36:56 +00:00
|
|
|
row.distance = Util.toBytes(Util.round(row.distance, 1))
|
2018-01-24 22:39:38 +00:00
|
|
|
end
|
|
|
|
return row
|
2016-12-11 19:24:52 +00:00
|
|
|
end
|
|
|
|
|
2017-07-24 02:37:07 +00:00
|
|
|
Event.onInterval(1, function()
|
2019-01-28 22:54:00 +00:00
|
|
|
page.grid:update()
|
2018-01-24 22:39:38 +00:00
|
|
|
page.grid:draw()
|
|
|
|
page:sync()
|
2016-12-27 03:26:43 +00:00
|
|
|
end)
|
2016-12-11 19:24:52 +00:00
|
|
|
|
2017-10-08 21:45:01 +00:00
|
|
|
Event.on('device_attach', function(_, deviceName)
|
2018-01-24 22:39:38 +00:00
|
|
|
if deviceName == 'wireless_modem' then
|
|
|
|
page.notification:success('Modem connected')
|
|
|
|
page:sync()
|
|
|
|
end
|
2016-12-11 19:24:52 +00:00
|
|
|
end)
|
|
|
|
|
2017-10-08 21:45:01 +00:00
|
|
|
Event.on('device_detach', function(_, deviceName)
|
2018-01-24 22:39:38 +00:00
|
|
|
if deviceName == 'wireless_modem' then
|
|
|
|
page.notification:error('Wireless modem not attached')
|
|
|
|
page:sync()
|
|
|
|
end
|
2016-12-11 19:24:52 +00:00
|
|
|
end)
|
|
|
|
|
|
|
|
if not device.wireless_modem then
|
2018-01-24 22:39:38 +00:00
|
|
|
page.notification:error('Wireless modem not attached')
|
2016-12-11 19:24:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
UI:setPage(page)
|
2017-07-28 23:01:59 +00:00
|
|
|
UI:pullEvents()
|