Author: bklaas
Date: Thu Jan 8 12:03:41 2009
New Revision: 3740
URL: http://svn.slimdevices.com?rev=3740&root=Jive&view=rev
Log:
Bug: 10526
Description: refactor Wireless class
jive.net.Wireless becomes jive.net.Networking and the constructor is slightly
different
local wirelessInterface = Networking:wirelessInterface()
local wireless = Networking(jnt, wirelessInterface)
Added:
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
Removed:
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Wireless.lua
Modified:
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
7.4/trunk/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
Modified:
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
Thu Jan 8 12:03:41 2009
@@ -36,7 +36,7 @@
local Surface = require("jive.ui.Surface")
local LocalPlayer = require("jive.slim.LocalPlayer")
-local hasWireless, Wireless = pcall(require, "jive.net.Wireless")
+local hasNetworking, Networking = pcall(require, "jive.net.Networking")
local log = require("jive.utils.log").logger("applets.setup")
local debug = require("jive.utils.debug")
@@ -61,8 +61,11 @@
self.serverItem = {}
self.scanResults = {}
- if hasWireless then
- self.wireless = Wireless(jnt, "eth0")
+ if hasNetworking then
+ local wirelessInterface = Networking:wirelessInterface()
+ if wirelessInterface then
+ self.wireless = Networking(jnt, wirelessInterface)
+ end
end
jnt:subscribe(self)
Modified:
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
Thu Jan 8 12:03:41 2009
@@ -27,7 +27,7 @@
local Player = require("jive.slim.Player")
local Udap = require("jive.net.Udap")
-local hasWireless, Wireless = pcall(require, "jive.net.Wireless")
+local hasNetworking, Networking = pcall(require, "jive.net.Networking")
local log =
require("jive.utils.log").logger("applets.setup")
@@ -108,8 +108,11 @@
error("No player discovery")
end
- if hasWireless then
- self.wireless = Wireless(jnt, "eth0")
+ if hasNetworking then
+ local wirelessInterface = Networking:wirelessInterface()
+ if wirelessInterface then
+ self.wireless = Networking(jnt, wirelessInterface)
+ end
end
-- socket for udap discovery
@@ -143,7 +146,7 @@
-- note we keep old entries so this list the window is not empty
-- during initial setup. if this becomes a problem a "finding
-- squeezeboxen" screen will need to be added.
- if hasWireless then
+ if self.wireless then
self:_scanComplete(self.wireless:scanResults(), keepOldEntries)
end
@@ -203,7 +206,7 @@
function _scan(self)
- if hasWireless then
+ if self.wireless then
self.wireless:scan(function(scanTable)
_scanComplete(self, scanTable)
end)
Modified:
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
Thu Jan 8 12:03:41 2009
@@ -37,7 +37,7 @@
local SocketUdp = require("jive.net.SocketUdp")
local Udap = require("jive.net.Udap")
-local hasWireless, Wireless = pcall(require, "jive.net.Wireless")
+local hasNetworking, Networking = pcall(require, "jive.net.Networking")
local Player = require("jive.slim.Player")
local SlimServer = require("jive.slim.SlimServer")
@@ -217,8 +217,11 @@
end)
-- wireless discovery
- if hasWireless then
- obj.wireless = Wireless(jnt, "eth0")
+ if hasNetworking then
+ local wirelessInterface = Networking:wirelessInterface()
+ if wirelessInterface then
+ obj.wireless = Networking(jnt, wirelessInterface)
+ end
end
-- discovery timer
@@ -253,7 +256,7 @@
self.udap:send(function() return packet end, "255.255.255.255")
-- Wireless discovery, only in probing state
- if self.state == 'probing' and hasWireless then
+ if self.state == 'probing' and self.wireless then
self.wireless:scan(
function(scanTable)
_scanComplete(self, scanTable)
Modified:
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
Thu Jan 8 12:03:41 2009
@@ -32,7 +32,7 @@
local Textarea = require("jive.ui.Textarea")
local Window = require("jive.ui.Window")
-local Wireless = require("jive.net.Wireless")
+local Networking = require("jive.net.Networking")
local log = require("jive.utils.log").logger("applets.setup")
local locale = require("jive.utils.locale")
@@ -141,7 +141,7 @@
log:info("step5")
-- wireless connection, using squeezebox?
- local scanResults = Wireless.scanResults()
+ local scanResults = Networking.scanResults()
for ssid,_ in pairs(scanResults) do
log:warn("checking ssid ", ssid)
@@ -174,7 +174,7 @@
log:info("step6")
-- wireless connection, using squeezebox?
- local scanResults = Wireless.scanResults()
+ local scanResults = Networking.scanResults()
for ssid,_ in pairs(scanResults) do
log:warn("checking ssid ", ssid)
Modified:
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
Thu Jan 8 12:03:41 2009
@@ -10,7 +10,7 @@
local jiveBSP = require("jiveBSP")
local Watchdog = require("jiveWatchdog")
-local Wireless = require("jive.net.Wireless")
+local Networking = require("jive.net.Networking")
local LocalPlayer = require("jive.slim.LocalPlayer")
local Applet = require("jive.Applet")
@@ -146,7 +146,8 @@
end)
-- wireless
- self.wireless = Wireless(jnt, "eth0")
+ local wireless = Networking:wirelessInterface()
+ self.wireless = Networking(jnt, wireless)
-- register network active function
jnt:registerNetworkActive(function(active)
Modified:
7.4/trunk/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
Thu Jan 8 12:03:41 2009
@@ -10,7 +10,7 @@
local jiveBSP = require("jiveBSP")
local Watchdog = require("jiveWatchdog")
-local Wireless = require("jive.net.Wireless")
+local Networking = require("jive.net.Networking")
local Applet = require("jive.Applet")
local Audio = require("jive.ui.Audio")
@@ -143,7 +143,8 @@
end)
-- wireless
- self.wireless = Wireless(jnt, "eth0")
+ local wireless = Networking:wirelessInterface()
+ self.wireless = Networking(jnt, wireless)
-- register network active function
jnt:registerNetworkActive(function(active)
@@ -1012,6 +1013,7 @@
function _wlanPowerSave(self, active)
+
if active ~= nil then
-- update the network active state
self.networkActive = active
Modified:
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua?rev=3740&root=Jive&r1=3739&r2=3740&view=diff
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
(original)
+++
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
Thu Jan 8 12:03:41 2009
@@ -32,7 +32,7 @@
local Window = require("jive.ui.Window")
local Popup = require("jive.ui.Popup")
-local Wireless = require("jive.net.Wireless")
+local Networking = require("jive.net.Networking")
local log =
require("jive.utils.log").logger("applets.setup")
@@ -59,7 +59,10 @@
function init(self)
- self.t_ctrl = Wireless(jnt, "eth0")
+
+ local wirelessInterface = Networking:wirelessInterface()
+ self.t_ctrl = Networking(jnt, wirelessInterface)
+
end
@@ -702,7 +705,7 @@
-- FIXME this function and associated attach/detach functions should
--- be refactored into Wireless.lua with callbacks on approriate events.
+-- be refactored into Networking.lua with callbacks on approriate events.
function _eventSink(self, chunk)
log:warn("wpa-cli event: ", chunk)
Added:
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
URL:
http://svn.slimdevices.com/7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua?rev=3740&root=Jive&view=auto
==============================================================================
---
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
(added)
+++
7.4/trunk/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
Thu Jan 8 12:03:41 2009
@@ -1,0 +1,1095 @@
+--[[
+=head1 NAME
+
+jive.net.Networking
+
+=head1 DESCRIPTION
+
+This class implements methods for administering network interfaces.
+
+Much of the methods in this class need to be done through Task. These methods
are by convention prefixed with t_
+
+=head1 SYNOPSIS
+
+pull in networking object to manipulate wireless interface
+
+ local wirelessInterface = Networking:wirelessInterface()
+ local wireless = Networking(jnt, wirelessInterface)
+
+=head1 FUNCTIONS
+
+=cut
+--]]
+
+local assert, ipairs, pairs, pcall, tonumber, tostring, type = assert, ipairs,
pairs, pcall, tonumber, tostring, type
+
+local oo = require("loop.simple")
+
+local io = require("io")
+local os = require("os")
+local string = require("string")
+local table = require("jive.utils.table")
+local ltn12 = require("ltn12")
+
+local debug = require("jive.utils.debug")
+local log = require("jive.utils.log").logger("net.socket")
+
+local Framework = require("jive.ui.Framework")
+local Socket = require("jive.net.Socket")
+local Task = require("jive.ui.Task")
+local wireless = require("jiveWireless")
+
+
+module("jive.net.Networking")
+oo.class(_M, Socket)
+
+
+local SSID_TIMEOUT = 20000
+
+-- wpa scan results signal level -> quality
+-- FIXME tune with production boards
+local WIRELESS_LEVEL = {
+ 0,
+ 175,
+ 180,
+ 190,
+}
+
+-- iwpriv snr -> quality
+-- FIXME tune with production boards
+local WIRELESS_SNR = {
+ 0,
+ 10,
+ 18,
+ 25,
+}
+
+-- FIXME check this region mapping is correct for Marvell and Atheros
+local REGION_CODE_MAPPING = {
+ -- name, marvell code, atheros code
+ [ "US" ] = { 0x10, 4 }, -- ch 1-11
+ [ "CA" ] = { 0x20, 6 }, -- ch 1-11
+ [ "EU" ] = { 0x30, 14 }, -- ch 1-13
+ [ "FR" ] = { 0x30, 13 }, -- ch 1-13
+ [ "CH" ] = { 0x30, 23 }, -- ch 1-13
+ [ "TW" ] = { 0x30, 21 }, -- ch 1-13
+ [ "AU" ] = { 0x10, 7 }, -- ch 1-11
+ [ "JP" ] = { 0x41, 16 }, -- ch 1-13
+}
+
+
+-- global for storing data on available network interfaces
+local interfaceTable = {}
+
+-- global wireless network scan results
+local _scanResults = {}
+
+-- singleton wireless instance per interface
+local _instance = {}
+
+--[[
+
+=head2 jive.net.Networking(jnt, interface, name)
+
+Constructs an object for administration of a network interface
+
+=cut
+--]]
+
+function __init(self, jnt, interface, name)
+
+ if _instance[interface] then
+ return _instance[interface]
+ end
+
+ local obj = oo.rawnew(self, Socket(jnt, name))
+
+ obj.interface = interface
+ obj.isWireless = ( interfaceTable[interface] and
interfaceTable[interface].isWireless )
+ or obj:isWireless(interface)
+ log:debug('Interface : ', obj.interface)
+ log:debug('isWireless: ', obj.isWireless)
+ obj.responseQueue = {}
+
+ obj:open()
+
+ _instance[interface] = obj
+ return obj
+end
+
+--[[
+
+=head2 jive.net.Networking:interfaces()
+
+returns a table of existing interfaces on a device
+
+=cut
+--]]
+
+
+function interfaces(self)
+
+ log:debug('scanning /proc/net/dev for interfaces...')
+
+ for i, v in ipairs(interfaceTable) do
+ if i then
+ return interfaceTable
+ end
+ end
+
+ local interfaces = {}
+
+ local f = io.popen("cat /proc/net/dev")
+ if f == nil then
+ return interfaces
+ end
+
+ while true do
+ local line = f:read("*l")
+ if line == nil then
+ break
+ end
+ local interface = string.match(line, "^%s*(%w+):")
+ if interface ~= nil and interface ~= 'lo' then
+ table.insert(interfaces, interface)
+ end
+ end
+
+ for _, interface in ipairs(interfaces) do
+ if not interfaceTable[interface] then
+ interfaceTable[interface] = {}
+ end
+ self:isWireless(interface)
+ end
+
+ f:close()
+ return interfaces
+
+end
+
+--[[
+
+=head2 jive.net.Networking:wirelessInterface()
+
+returns the first interface (if any) from the interface table capable of
wireless
+
+=cut
+--]]
+
+
+function wirelessInterface(self)
+
+ self:interfaces()
+
+ for _, v in ipairs(interfaceTable) do
+ if self:isWireless(v) then
+ log:debug('Wireless interface found: ', v)
+ return v
+ end
+ end
+
+ log:error('Error: interfaceTable shows no wireless interface. returning
eth0, the default wireless on SBC')
+ return 'eth0'
+
+end
+
+
+--[[
+
+=head2 jive.net.Networking:wiredInterface()
+
+returns the first available interface (if any) from the interface table that
does not do wireless
+
+=cut
+--]]
+
+
+function wiredInterface(self)
+
+ self:interfaces()
+
+ for _, v in ipairs(interfaceTable) do
+ if not self:isWireless(v) then
+ return v
+ end
+ end
+ return false
+end
+
+--[[
+
+=head2 jive.net.Networking:isWireless(interface)
+
+returns true if the named I<interface> is wireless
+
+=cut
+--]]
+
+function isWireless(self, interface)
+
+ if not interface then
+ return false
+ end
+
+ -- look to see if we've cached this already
+ if interfaceTable[interface] and interfaceTable[interface].isWireless
then
+ return true
+ end
+
+ local f = io.popen("/sbin/iwconfig " .. interface .. " 2>/dev/null")
+ if f == nil then
+ return false
+ end
+
+ while true do
+ local line = f:read("*l")
+ if line == nil then
+ break
+ end
+ local doesWireless = string.match(line, "^(%w+)%s+")
+ if interface == doesWireless then
+ interfaceTable[interface]['isWireless'] = true
+ f:close()
+ return true
+ end
+ end
+
+ f:close()
+
+ return false
+
+end
+
+--[[
+
+=head2 jive.net.Networking:getRegionNames()
+
+returns the available wireless region names
+
+=cut
+--]]
+
+function getRegionNames(self)
+ return pairs(REGION_CODE_MAPPING)
+end
+
+--[[
+
+=head2 jive.net.Networking:getRegion()
+
+returns the current region
+
+=cut
+--]]
+
+
+function getRegion(self)
+ -- check config file
+ local fh = io.open("/etc/network/config")
+ if fh then
+ local file = fh:read("*a")
+ fh:close()
+
+ local region = string.match(file, "REGION=([^%s]+)")
+ if region then
+ return region
+ end
+ end
+
+ -- check marvell region
+ local fh = assert(io.popen("/sbin/iwpriv " .. self.interface .. "
getregioncode"))
+ local line = fh:read("*a")
+ fh:close()
+
+ local code = tonumber(string.match(line, "getregioncode:(%d+)"))
+
+ for name,mapping in pairs(REGION_CODE_MAPPING) do
+ log:info("code=", code, " mapping[1]=", mapping[1])
+ if mapping[1] == code then
+ log:info("returning=", name)
+ return name
+ end
+ end
+ return nil
+end
+
+--[[
+
+=head2 jive.net.Networking:setRegion(region)
+
+sets the current region
+
+=cut
+--]]
+
+function setRegion(self, region)
+ if type(self.interface) ~= "string" then
+ return
+ end
+ local mapping = REGION_CODE_MAPPING[region]
+ if not mapping then
+ return
+ end
+
+ -- save config file
+ local fh = assert(io.open("/etc/network/config", "w"))
+ fh:write("REGION=" .. region .. "\n")
+ fh:write("REGIONCODE=" .. mapping[1] .. "\n")
+ fh:close()
+
+ -- set new region
+ local cmd = "/sbin/iwpriv " .. self.interface .. " setregioncode " ..
mapping[1]
+ log:info("setRegion: ", cmd)
+ os.execute(cmd)
+end
+
+
+--[[
+
+=head2 jive.net.Networking:getMarvellRegionCode()
+
+returns the region code for Marvell on Jive
+
+=cut
+--]]
+
+function getMarvellRegionCode(self)
+ local mapping = REGION_CODE_MAPPING[region or self:getRegion()]
+ return mapping and mapping[1] or 0
+end
+
+--[[
+
+=head2 jive.net.Networking:getAtherosRegionCode()
+
+returns the region code for Atheros on Squeezebox
+
+=cut
+--]]
+
+
+function getAtherosRegionCode(self)
+ local mapping = REGION_CODE_MAPPING[region or self:getRegion()]
+ return mapping and mapping[2] or 0
+end
+
+--[[
+
+=head2 jive.net.Networking:scan(callback)
+
+start a wireless network scan in a new task
+
+=cut
+--]]
+
+function scan(self, callback)
+ Task("networkScan", self,
+ function()
+ t_scan(self, callback)
+ end):addTask()
+end
+
+--[[
+
+=head2 jive.net.Networking:scanResults()
+
+returns wireless scan results, or nil if a network scan has not been performed.
+
+=cut
+--]]
+
+function scanResults(self)
+ return _scanResults
+end
+
+--[[
+
+=head2 jive.net.Networking:t_scan(callback)
+
+network scanning. this can take a little time so we do this in
+the network thread so the ui is not blocked.
+
+=cut
+--]]
+
+
+function t_scan(self, callback)
+ assert(Task:running(), "Networking:scan must be called in a Task")
+
+ local status, err = self:request("SCAN")
+ if err then
+ return
+ end
+
+ local status, err = self:request("STATUS")
+ if err then
+ return
+ end
+
+ local associated = string.match(status, "\nssid=([^\n]+)")
+
+ local scanResults, err = self:request("SCAN_RESULTS")
+ if err then
+ return
+ end
+
+ _scanResults = _scanResults or {}
+
+ local now = Framework:getTicks()
+
+ for bssid, level, flags, ssid in string.gmatch(scanResults,
"([%x:]+)\t%d+\t(%d+)\t(%S*)\t([^\n]+)\n") do
+
+ local quality = 1
+ level = tonumber(level)
+ for i, l in ipairs(WIRELESS_LEVEL) do
+ if level < l then
+ break
+ end
+ quality = i
+ end
+
+ _scanResults[ssid] = {
+ bssid = string.lower(bssid),
+ flags = flags,
+ level = level,
+ quality = quality,
+ associated = (ssid == associated),
+ lastScan = now
+ }
+ end
+
+ for ssid, entry in pairs(_scanResults) do
+ if now - entry.lastScan > SSID_TIMEOUT then
+ _scanResults[ssid] = nil
+ end
+ end
+
+ -- Bug #5227 if we are associated use the same quality indicator
+ -- as the icon bar
+ if associated and _scanResults[associated] then
+ _scanResults[associated].quality = self:getLinkQuality()
+ end
+
+ if callback then
+ callback(_scanResults)
+ end
+
+ self.scanTask = nil
+end
+
+--[[
+
+=head2 jive.net.Networking:t_wpaStatus()
+
+parse and return wpa status
+
+=cut
+--]]
+
+function t_wpaStatus(self)
+ assert(Task:running(), "Networking:wpaStatus must be called in a Task")
+
+ local statusStr = self:request("STATUS")
+
+ local status = {}
+ for k,v in string.gmatch(statusStr, "([^=]+)=([^\n]+)\n") do
+ status[k] = v
+ end
+
+ return status
+end
+
+--[[
+
+=head2 jive.net.Networking:t_addNetwork(ssid, option)
+
+adds a network to the list of discovered networks
+
+=cut
+--]]
+
+
+function t_addNetwork(self, ssid, option)
+ assert(Task:running(), "Networking:addNetwork must be called in a Task")
+
+ local request, response
+
+ -- make sure this ssid is not in any configuration
+ self:t_removeNetwork(ssid)
+
+ log:info("Connect to ", ssid)
+ local flags = (_scanResults[ssid] and _scanResults[ssid].flags) or ""
+
+ -- Set to use dhcp by default
+ self:_editNetworkInterfaces(ssid, "dhcp", "script
/etc/network/udhcpc_action")
+
+ response = self:request("ADD_NETWORK")
+ local id = string.match(response, "%d+")
+ assert(id, "wpa_cli failed: to add network")
+
+ request = 'SET_NETWORK ' .. id .. ' ssid "' .. ssid .. '"'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ if string.find(flags, "IBSS") or option.ibss then
+ request = 'SET_NETWORK ' .. id .. ' mode 1 '
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+ end
+
+ if option.encryption == "wpa" then
+ log:info("encryption WPA")
+
+ request = 'SET_NETWORK ' .. id .. ' key_mgmt WPA-PSK'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+
+ request = 'SET_NETWORK ' .. id .. ' proto WPA'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+
+ -- Setting the PSK can timeout
+ pcall(function()
+ request = 'SET_NETWORK ' .. id .. ' psk "' ..
option.psk .. '"'
+ assert(self:request(request) == "OK\n", "wpa_cli
failed:" .. request)
+ end)
+ elseif option.encryption == "wpa2" then
+ log:info("encryption WPA2")
+
+ request = 'SET_NETWORK ' .. id .. ' key_mgmt WPA-PSK'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+
+ request = 'SET_NETWORK ' .. id .. ' proto WPA2'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+
+ -- Setting the PSK can timeout
+ pcall(function()
+ request = 'SET_NETWORK ' .. id .. ' psk "' ..
option.psk .. '"'
+ assert(self:request(request) == "OK\n", "wpa_cli
failed:" .. request)
+ end)
+ else
+ request = 'SET_NETWORK ' .. id .. ' key_mgmt NONE'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+ end
+
+ if option.encryption == "wep40" or option.encryption == "wep104" then
+ log:info("encryption WEP")
+
+ request = 'SET_NETWORK ' .. id .. ' wep_key0 ' .. option.key
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+ end
+
+ -- If we have not scanned the ssid then enable scanning with ssid
+ -- specific probe requests. This allows us to find APs with hidden
+ -- SSIDS
+ if not _scanResults[ssid] then
+ request = 'SET_NETWORK ' .. id .. ' scan_ssid 1'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+ end
+
+ -- Disconnect from existing network
+ self:t_disconnectNetwork()
+
+ -- Use select network to disable all other networks
+ request = 'SELECT_NETWORK ' .. id
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ -- Allow association
+ request = 'REASSOCIATE'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ -- Save config, it will be removed later if it fails
+ request = 'SAVE_CONFIG'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ return id
+end
+
+--[[
+
+=head2 jive.net.Networking:t_removeNetwork(ssid)
+
+forgets a previously discovered network
+
+=cut
+--]]
+
+function t_removeNetwork(self, ssid)
+ assert(Task:running(), "Networking:removeNetwork must be called in a
Task")
+
+ local networkResults = self:request("LIST_NETWORKS")
+
+ local id = false
+ for nid, nssid in string.gmatch(networkResults,
"([%d]+)\t([^\t]*).-\n") do
+ if nssid == ssid then
+ id = nid
+ break
+ end
+ end
+
+ -- Remove ssid from wpa supplicant
+ if id then
+ local request = 'REMOVE_NETWORK ' .. id
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+
+ request = 'SAVE_CONFIG'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" ..
request)
+ end
+
+ -- Remove dhcp/static ip configuration for network
+ self:_editNetworkInterfaces(ssid)
+end
+
+--[[
+
+=head2 jive.net.Networking:t_disconnectNetwork()
+
+brings down a network interface. If wireless, then force the wireless
disconnect as well
+
+=cut
+--]]
+
+function t_disconnectNetwork(self)
+
+ assert(type(self.interface) == 'string')
+ assert(Task:running(), "Networking:disconnectNetwork must be called in
a Task")
+
+ -- Force disconnect from existing network
+ local request = 'DISCONNECT'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ -- Force the interface down
+ local ifDown = "/sbin/ifdown -f " .. self.interface
+ os.execute(ifDown)
+end
+
+--[[
+
+=head2 jive.net.Networking:t_selectNetwork(ssid)
+
+selects a network to connect to. wireless only
+
+=cut
+--]]
+
+
+function t_selectNetwork(self, ssid)
+
+ assert(Task:running(), "Networking:selectNetwork must be called in a
Task")
+
+ local networkResults = self:request("LIST_NETWORKS")
+ log:info("list results ", networkResults)
+
+ local id = false
+ for nid, nssid in string.gmatch(networkResults,
"([%d]+)\t([^\t]*).-\n") do
+ log:info("id=", nid, " ssid=", nssid)
+ if nssid == ssid then
+ id = nid
+ break
+ end
+ end
+
+ -- Select network
+ if not id then
+ log:warn("can't find network ", ssid)
+ return
+ end
+
+ -- Disconnect from existing network
+ self:t_disconnectNetwork()
+
+ local request = 'SELECT_NETWORK ' .. id
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ -- Allow association
+ request = 'REASSOCIATE'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+
+ -- Save configuration
+ request = 'SAVE_CONFIG'
+ assert(self:request(request) == "OK\n", "wpa_cli failed:" .. request)
+end
+
+
+--[[
+
+=head2 jive.net.Networking:t_setStaticIp(ssid, ipAddress, ipSubnet, ipGateway,
ipDNS)
+
+apply IP address and associated configuration parameters to a network interface
+
+=cut
+--]]
+
+
+function t_setStaticIP(self, ssid, ipAddress, ipSubnet, ipGateway, ipDNS)
+ assert(type(self.interface) == 'string')
+ -- Reset the network
+ local killCommand = "kill -TERM `cat /var/run/udhcpc." ..
self.interface .. "pid`"
+ local configCommand = "/sbin/ifconfig " .. self.interface .. " 0.0.0.0"
+
+ os.execute(killCommand)
+ os.execute(configCommand)
+
+ -- Set static ip configuration for network
+ self:_editNetworkInterfaces(ssid, "static",
+ "address " .. ipAddress,
+ "netmask " .. ipSubnet,
+ "gateway " .. ipGateway,
+ "dns " .. ipDNS,
+ "up echo 'nameserver " .. ipDNS .. "' >
/etc/resolv.conf"
+ )
+
+ -- Bring up the network
+ local ifUp = "/sbin/ifup " .. interface
+ local status = os.execute(ifUp)
+ log:info("ifup status=", status)
+end
+
+
+function _editNetworkInterfaces(self, ssid, method, ...)
+ -- the interfaces file uses " \t" as word breaks so munge the ssid
+ -- FIXME ssid's with \n are not supported
+ assert(ssid, debug.traceback())
+ ssid = string.gsub(ssid, "[ \t]", "_")
+ log:info("munged ssid=", ssid)
+
+ local fi = assert(io.open("/etc/network/interfaces", "r+"))
+ local fo = assert(io.open("/etc/network/interfaces.tmp", "w"))
+
+ local network = ""
+ for line in fi:lines() do
+ if string.match(line, "^mapping%s") or string.match(line,
"^auto%s") then
+ network = ""
+ elseif string.match(line, "^iface%s") then
+ network = string.match(line, "^iface%s([^%s]+)%s")
+ end
+
+ if network ~= ssid then
+ fo:write(line .. "\n")
+ end
+ end
+
+ if method then
+ fo:write("iface " .. ssid .. " inet " .. method .. "\n")
+ for _,v in ipairs{...} do
+ fo:write("\t" .. v .. "\n")
+ end
+ end
+
+ fi:close()
+ fo:close()
+
+ os.execute("/bin/mv /etc/network/interfaces.tmp
/etc/network/interfaces")
+end
+
+--[[
+
+=head2 jive.net.Networking:getLinkQuality()
+
+returns "quality" of wireless interface
+used for dividing SNR values into categorical levels of signal quality
+
+ quality of 1 indicates SNR of 0
+ quality of 2 indicates SNR <= 10
+ quality of 3 indicates SNR <= 18
+ quality of 4 indicates SNR <= 25
+
+=cut
+--]]
+
+function getLinkQuality(self)
+
+ local snr = self:getSNR()
+
+ if snr == nil or snr == 0 then
+ return nil
+ end
+
+ local quality = 1
+ for i, l in ipairs(WIRELESS_SNR) do
+ if snr <= l then
+ break
+ end
+ quality = i
+ end
+
+ return quality
+end
+
+--[[
+
+=head2 jive.net.Networking:getSNR()
+
+returns signal to noise ratio of wireless link
+
+=cut
+--]]
+
+
+function getSNR(self)
+ if type(self.interface) ~= 'string' then
+ return 0
+ end
+ local f = io.popen("/sbin/iwpriv " .. self.interface .. " getSNR 1")
+ if f == nil then
+ return 0
+ end
+
+ local t = f:read("*all")
+ f:close()
+
+ return tonumber(string.match(t, ":(%d+)"))
+end
+
+--[[
+
+=head2 jive.net.Networking:getRSSI()
+
+returns Received Signal Strength Indication (signal power) of a wireless
interface
+=cut
+--]]
+
+function getRSSI(self)
+ if type(self.interface) ~= 'string' then
+ return 0
+ end
+ local f = io.popen("/sbin/iwpriv " .. self.interface .. " getRSSI 1")
+ if f == nil then
+ return 0
+ end
+
+ local t = f:read("*all")
+ f:close()
+
+ return tonumber(string.match(t, ":(%-?%d+)"))
+end
+
+--[[
+
+=head2 jive.net.Networking:getNF()
+
+returns NF (?) of a wireless interface
+
+=cut
+--]]
+
+
+function getNF(self)
+ if type(self.interface) ~= 'string' then
+ return 0
+ end
+ local f = io.popen("/sbin/iwpriv " .. self.interface .. " getNF 1")
+ if f == nil then
+ return 0
+ end
+
+ local t = f:read("*all")
+ f:close()
+
+ return tonumber(string.match(t, ":(%-?%d+)"))
+end
+
+--[[
+
+=head2 jive.net.Networking:getTxBitRate()
+
+returns bitrate of a wireless interface
+
+=cut
+--]]
+
+function getTxBitRate(self)
+ if type(self.interface) ~= 'string' then
+ return "0"
+ end
+ local f = io.popen("/sbin/iwconfig " .. self.interface)
+ if f == nil then
+ return "0"
+ end
+
+ local t = f:read("*all")
+ f:close()
+
+ return string.match(t, "Bit Rate:(%d+%s[^%s]+)")
+end
+
+--[[
+
+=head2 jive.net.Networking:powerSave(enable)
+
+sets wireless power save state
+
+=cut
+--]]
+
+
+function powerSave(self, enable)
+ if self._powerSaveState == enable then
+ return
+ end
+
+ if not self.t_sock then
+ return
+ end
+
+ self._powerSaveState = enable
+ if enable then
+ log:info("iwconfig power on")
+ self.t_sock:setPower(true)
+ else
+ log:info("iwconfig power off")
+ self.t_sock:setPower(false)
+ end
+end
+
+--[[
+
+=head2 jive.net.Networking:open()
+
+opens a socket to pick up network events
+
+=cut
+--]]
+
+
+
+function open(self)
+ if self.t_sock then
+ log:error("Socket already open")
+ return
+ end
+
+ local err
+
+ if self.isWireless then
+ log:debug('Open wireless socket')
+ self.t_sock, err = wireless:open(self.interface)
+ if err then
+ log:warn(err)
+
+ self:close()
+ return false
+ end
+
+ local source = function()
+ return self.t_sock:receive()
+ end
+
+ local sink = function(chunk, err)
+ if chunk and string.sub(chunk, 1, 1) ==
"<" then
+ -- wpa event message
+ if self.eventSink then
+ Task("wirelessEvent", nil,
+ function()
+
self.eventSink(chunk, err)
+ end):addTask()
+ end
+ else
+ -- request response
+ local task =
table.remove(self.responseQueue, 1)
+ if task then
+ task:addTask(chunk, err)
+ end
+ end
+ end
+
+ self:t_addRead(function()
+ -- XXXX handle timeout
+ local status, err =
ltn12.pump.step(source, sink)
+ if err then
+ log:warn(err)
+ self:close()
+ end
+ end,
+ 0) -- no timeout
+ end
+
+ return true
+end
+
+--[[
+
+=head2 jive.net.Networking:close()
+
+closes existing socket
+
+=cut
+--]]
+
+
+function close(self)
+ -- cancel queued requests
+ for i, task in ipairs(self.responseQueue) do
+ task:addTask(nil, "closed")
+ end
+ self.responseQueue = {}
+
+ Socket.close(self)
+end
+
+--[[
+
+=head2 jive.net.Networking:request()
+
+pushes request to open socket
+
+=cut
+--]]
+
+
+function request(self, ...)
+ local task = Task:running()
+ assert(task, "Networking:request must be called in a Task")
+
+ log:info("REQUEST: ", ...)
+
+ -- open the socket if it is closed
+ if not self.t_sock and not self:open() then
+ -- XXXX callers expect a string
+ return "", "closed"
+ end
+
+ local status, err = self.t_sock:request(...)
+
+ if err then
+ log:warn(err)
+ self:close()
+
+ -- XXXX callers expect a string
+ return "", err
+ end
+
+ -- yield task
+ table.insert(self.responseQueue, task)
+ local _, reply, err = Task:yield(false)
+
+ if not reply or err then
+ log:warn(err)
+ self:close()
+
+ -- XXXX callers expect a string
+ return "", err
+ end
+
+ log:info("REPLY:", reply)
+ return reply
+end
+
+
+function attach(self, sink)
+ -- XXXX allow multiple sinks
+ self.eventSink = sink
+end
+
+
+function detach(self)
+ self.eventSink = nil
+end
+
+
+--[[
+
+=head1 LICENSE
+
+Copyright 2009 Logitech. All Rights Reserved.
+
+This file is subject to the Logitech Public Source License Version 1.0. Please
see the LICENCE file for details.
+
+=cut
+--]]
_______________________________________________
Jive-checkins mailing list
[email protected]
http://lists.slimdevices.com/cgi-bin/mailman/listinfo/jive-checkins