Author: titmuss
Date: Fri Jan  9 01:26:13 2009
New Revision: 3744

URL: http://svn.slimdevices.com?rev=3744&root=Jive&view=rev
Log:
 r3...@harrypotter (orig r3737):  richard | 2009-01-08 16:17:34 +0000
 Bug: 10296
 Description:
 Revert change to watchdog timer on 7.4.
 
 
 r3...@harrypotter (orig r3739):  tom | 2009-01-08 17:18:12 +0000
 Bug: N/A
 Description: Initial event model rework
 r3...@harrypotter (orig r3740):  bklaas | 2009-01-08 20:03:41 +0000
 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/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
Removed:
    
7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Wireless.lua
Modified:
    7.4/branches/pango/   (props changed)
    
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
    
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
    
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
    7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/JiveMain.lua
    7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Event.lua
    7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Framework.lua
    7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive.h
    7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_event.c
    7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_framework.c
    7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/lua_jiveui.c
    
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
    
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
    
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
    
7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua

Propchange: 7.4/branches/pango/
------------------------------------------------------------------------------
--- svk:merge (original)
+++ svk:merge Fri Jan  9 01:26:13 2009
@@ -4,7 +4,7 @@
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/7.2/trunk:2921
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/7.3/private-branches/jive-refresh:3653
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/7.3/trunk:3729
-bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/7.4/trunk:3733
+bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/7.4/trunk:3740
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/7.0:2013
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/SN:1083
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/scrolling:1378

Modified: 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SelectPlayer/SelectPlayerApplet.lua
 Fri Jan  9 01:26:13 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/branches/pango/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SetupSqueezebox/SetupSqueezeboxApplet.lua
 Fri Jan  9 01:26:13 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/branches/pango/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/applets/SlimDiscovery/SlimDiscoveryApplet.lua
 Fri Jan  9 01:26:13 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/branches/pango/squeezeplay/src/squeezeplay/share/jive/JiveMain.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/JiveMain.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/JiveMain.lua 
(original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/JiveMain.lua Fri 
Jan  9 01:26:13 2009
@@ -65,6 +65,7 @@
 --require("profiler")
 
 local EVENT_KEY_ALL        = jive.ui.EVENT_KEY_ALL
+local ACTION               = jive.ui.ACTION
 local EVENT_KEY_PRESS      = jive.ui.EVENT_KEY_PRESS
 local EVENT_CHAR_PRESS      = jive.ui.EVENT_CHAR_PRESS
 local EVENT_KEY_HOLD       = jive.ui.EVENT_KEY_HOLD
@@ -102,6 +103,7 @@
        ["i"]  = { keyCode = KEY_UP,   event = EVENT_KEY_PRESS },
        ["k"]  = { keyCode = KEY_DOWN, event = EVENT_KEY_PRESS },
        ["j"]  = { keyCode = KEY_LEFT, event = EVENT_KEY_PRESS },
+       ["J"]  = { keyCode = KEY_LEFT, event = EVENT_KEY_HOLD },
        ["l"]  = { keyCode = KEY_RIGHT, event = EVENT_KEY_PRESS },
        ["h"]  = { keyCode = KEY_HOME, event = EVENT_KEY_PRESS },
        ["p"]  = { keyCode = KEY_PLAY, event = EVENT_KEY_PRESS },
@@ -124,8 +126,35 @@
        ["\27"]  = { keyCode = KEY_BACK, event = EVENT_KEY_PRESS } -- ESC
 }
 
+local keyActionMappingsPress = {
+    [KEY_LEFT] = "arrow_left.press"  -- using button naming convention from SC 
default.map, though these are action events
+}
+
+
+local keyActionMappingsHold = {
+    [KEY_LEFT] = "arrow_left.hold",
+    [KEY_REW | KEY_PAUSE] = "take_screenshot"  -- a stab at how to handle 
multi-press
+}
+
 local _defaultSkin
 local _fullscreen
+
+local function _goHome() 
+               local windowStack = Framework.windowStack
+
+               if #windowStack > 1 then
+                       Framework:playSound("JUMP")
+                       jiveMain:closeToHome(true)
+               else
+                       Framework:playSound("BUMP")
+                       windowStack[1]:bumpLeft()
+               end
+end
+
+local function _disconnectPlayer(self, event) --self, event not used in our 
case, could be left out
+    appletManager:callService("setCurrentPlayer", nil)
+    _goHome()
+end
 
 -- bring us to the home menu
 local function _homeHandler(event)
@@ -143,23 +172,10 @@
                
                return EVENT_CONSUME
 
-       elseif (( type == EVENT_KEY_PRESS and event:getKeycode() == KEY_HOME) or
-           ( type == EVENT_KEY_HOLD and event:getKeycode() == KEY_BACK)) then
-
-               -- disconnect from player on press and hold left
-               if type == EVENT_KEY_HOLD then
-                       appletManager:callService("setCurrentPlayer", nil)
-               end
-
-               local windowStack = Framework.windowStack
-
-               if #windowStack > 1 then
-                       Framework:playSound("JUMP")
-                       jiveMain:closeToHome(true)
-               else
-                       Framework:playSound("BUMP")
-                       windowStack[1]:bumpLeft()
-               end
+       elseif ( type == EVENT_KEY_PRESS and event:getKeycode() == KEY_HOME) 
then
+
+        _goHome()
+        
                return EVENT_CONSUME
       end
       return EVENT_UNUSED
@@ -170,6 +186,34 @@
     package.path = package.path .. System.getUserDir() .. dirSeparator 
.."?.lua;"
     package.path = package.path .. System.getUserDir() .. dirSeparator .. "?" 
.. dirSeparator .. "?.lua;"
 end
+
+-- transform user input events (key, etc) to a matching action name
+local function getAction(event)
+    --naive implementation for demonstration - will be more involved later
+
+    local eventType = event:getType()
+    local action = nil
+    
+    if eventType == EVENT_KEY_PRESS then
+        action = keyActionMappingsPress[event:getKeycode()]
+    elseif eventType == EVENT_KEY_HOLD then
+        action = keyActionMappingsHold[event:getKeycode()]
+    end
+    
+    return action
+    
+end
+
+function registerDefaultActions()
+    for key, action in pairs(keyActionMappingsPress) do 
+        Framework:registerAction(action)
+    end
+    for key, action in pairs(keyActionMappingsHold) do 
+        Framework:registerAction(action)
+    end
+
+end
+
 
 -- __init
 -- creates our JiveMain main object
@@ -222,6 +266,33 @@
                end,
                10)
 
+    registerDefaultActions()
+
+       -- action mapping listener, should be last listener in chain to allow 
for direct access to keys/other input types if needed.
+       --todo add other input types
+       Framework:addListener(EVENT_KEY_ALL,
+               function(event)
+                   local action = getAction(event)
+                   if not action then
+                       return EVENT_UNUSED
+                   end
+                   
+                   local actionEvent = Framework:newActionEvent(action)
+                   if not actionEvent then
+                       log:error("Odd, newActionEvent returned nil, but should 
always return a result when match was found for action: ", action)
+                       return EVENT_UNUSED
+                   end
+                   
+                   log:debug("Pushing action event (", action, ") - 
event:getAction: " , actionEvent:getAction())
+               Framework:pushEvent(actionEvent)
+                       return EVENT_CONSUMED
+               end,
+               9999)
+               
+       
+    -- disconnect from player on press and hold left
+    Framework:addActionListener("arrow_left.hold", self, _disconnectPlayer)
+       
        -- show our window!
        jiveMain.window:show()
 

Modified: 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Event.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Event.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Event.lua 
(original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Event.lua Fri 
Jan  9 01:26:13 2009
@@ -44,6 +44,14 @@
 
 Returns the mouse x,y position for EVENT_MOUSE_* events.
 
+=head2 jive.ui.Event:getAction()
+
+Returns the action name for ACTION events.
+
+=head2 jive.ui.Event:getActionInternal()
+
+Returns the internal representation of the action name for ACTION events. Used 
by getAction(), should not be needed for general use.
+
 =back
 
 
@@ -189,13 +197,23 @@
 =cut
 --]]
 
+local require = require
 
 local oo        = require("loop.base")
 
 module(..., oo.class)
 
-
--- C implementation
+local Framework                = require("jive.ui.Framework")
+
+
+
+function getAction(self)
+    local actionIndex = self:getActionInternal()
+    return Framework:getActionEventNameByIndex(actionIndex)
+end
+
+-- the rest is C implementation
+
 --[[
 
 =head1 LICENSE

Modified: 
7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Framework.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Framework.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Framework.lua 
(original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/share/jive/ui/Framework.lua 
Fri Jan  9 01:26:13 2009
@@ -39,6 +39,7 @@
 local EVENT_HIDE    = jive.ui.EVENT_HIDE
 local EVENT_CONSUME = jive.ui.EVENT_CONSUME
 local EVENT_UNUSED  = jive.ui.EVENT_UNUSED
+local ACTION        = jive.ui.ACTION
 
 local FRAME_RATE    = jive.ui.FRAME_RATE
 
@@ -97,6 +98,9 @@
 screen = {}
 screen.bounds = { 0, 0, 240, 320 }
 screen.bpp = 16
+
+actionsByName = {}
+actionsByIndex = {}
 
 -- Put default global settings here
 default_global_settings = {
@@ -537,6 +541,100 @@
        table.delete(self.unusedListeners, handle)
 end
 
+function dumpActions(self)
+    local result = "Available Actions: " 
+    for action in table.pairsByKeys(self.actionsByName) do
+        result = result .. " " .. action
+    end
+    return result
+end
+
+function _getActionEventIndexByName(self, name)
+    if (self.actionsByName[name] == nil) then
+        return nil   
+    end
+    
+    return self.actionsByName[name].index
+end
+
+function getActionEventNameByIndex(self, index)
+    if (index > #self.actionsByIndex) then
+        log:error("action event index out of bounds: " , index)
+        return nil   
+    end
+    
+    return self.actionsByIndex[index].name
+end
+
+--[[
+
+=head2 jive.ui.Framework:newActionEvent(action)
+
+Returns a new ACTION event or nil if no matching action has been registered.
+
+=cut
+--]]
+function newActionEvent(self, action)
+    local actionIndex = self:_getActionEventIndexByName(action)
+    if not actionIndex then
+        log:error("action name not registered: (" , action, "). Available 
actions: ", self:dumpActions() )
+        return nil
+    end
+    
+    return Event:new(ACTION, actionIndex)
+    
+end
+
+--[[
+
+=head2 jive.ui.Framework:registerAction(action)
+
+Register an action. action is a unique string that represents an action.
+Each action must be registered before listeners using it can be created (for 
typo prevention, and other future uses). 
+
+=cut
+--]]
+function registerAction(self, actionName)
+    if (self.actionsByName[actionName]) then
+        log:error("Action already registered, doing nothing")
+        return
+    end
+    
+    local actionEventDefinition = { name = actionName, index = 
#self.actionsByIndex + 1 }
+
+    log:debug("Registering action: ", actionEventDefinition.name, " with 
index: ", actionEventDefinition.index)
+    self.actionsByName[actionName] = actionEventDefinition
+    table.insert(self.actionsByIndex, actionEventDefinition)
+    
+end
+
+
+--example: addActionListener("play", self, playAction)
+function addActionListener(self, action, obj, listener)
+       _assert(type(listener) == "function")
+
+
+    if not self:_getActionEventIndexByName(action) then
+        log:error("action name not registered:(" , action, "). Available 
actions: ", self:dumpActions() )
+        return 
+    end
+
+    log:debug("Creating action listener for action: (" , action, ") from 
source: todo would be nice to be able to display the source of the listener in 
a meaningful way for debugging")
+    
+       self:addListener(ACTION,
+               function(event)
+                   local eventAction = event:getAction()
+                   if eventAction != action then
+                       return EVENT_UNUSED
+                   end
+
+            local listenerResult = listener(obj, event)
+            --default to consume unless the listener specifically wants to set 
a specific event return
+            return listenerResult and listenerResult or EVENT_CONSUME
+               end
+       )
+    
+end
 
 --[[
 

Modified: 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive.h
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive.h?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive.h (original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive.h Fri Jan  9 
01:26:13 2009
@@ -107,6 +107,7 @@
        JIVE_EVENT_MOTION               = 0x00800000,
 
        JIVE_EVENT_CHAR_PRESS   = 0x02000000,
+       JIVE_ACTION                 = 0x04000000,
        
        JIVE_EVENT_CHAR_ALL     = ( JIVE_EVENT_CHAR_PRESS),
        JIVE_EVENT_KEY_ALL              = ( JIVE_EVENT_KEY_DOWN | 
JIVE_EVENT_KEY_UP | JIVE_EVENT_KEY_PRESS | JIVE_EVENT_KEY_HOLD ),
@@ -196,6 +197,10 @@
        int rel;
 };
 
+struct jive_action_event {
+       int index;
+};
+
 struct jive_key_event {
        JiveKey code;
 };
@@ -226,6 +231,7 @@
 
        union {
                struct jive_scroll_event scroll;
+               struct jive_action_event action;
                struct jive_key_event key;
                struct jive_char_event text;
                struct jive_mouse_event mouse;
@@ -417,6 +423,7 @@
 int jiveL_event_get_keycode(lua_State *L);
 int jiveL_event_get_unicode(lua_State *L);
 int jiveL_event_get_mouse(lua_State *L);
+int jiveL_event_get_action_internal(lua_State *L);
 int jiveL_event_get_motion(lua_State *L);
 int jiveL_event_get_switch(lua_State *L);
 

Modified: 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_event.c
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_event.c?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_event.c 
(original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_event.c Fri Jan  
9 01:26:13 2009
@@ -47,6 +47,10 @@
                switch (event->type) {
                case JIVE_EVENT_SCROLL:
                        event->u.scroll.rel = lua_tointeger(L, 3);
+                       break;
+               
+               case JIVE_ACTION:
+                       event->u.action.index = lua_tointeger(L, 3);
                        break;
                
                case JIVE_EVENT_KEY_DOWN:
@@ -177,6 +181,23 @@
        return 0;
 }
 
+int jiveL_event_get_action_internal(lua_State *L) {
+       JiveEvent* event = (JiveEvent*)lua_touserdata(L, 1);
+       if (event == NULL) {
+               luaL_error(L, "invalid Event");
+       }
+
+       switch (event->type) {
+       case JIVE_ACTION:
+               lua_pushinteger(L, event->u.action.index);
+               return 1;
+
+       default:
+               luaL_error(L, "Not an action event");
+       }
+       return 0;
+}
+
 
 int jiveL_event_get_motion(lua_State *L) {
         JiveEvent* event = (JiveEvent*)lua_touserdata(L, 1);
@@ -254,6 +275,11 @@
        case JIVE_EVENT_KEY_HOLD:
                lua_pushfstring(L, "KEY_HOLD code=%d", event->u.key.code);
                break;
+
+       case JIVE_ACTION:
+           //todo: also show actionEventName - convert index to 
actionEventName by calling Framework:getActionEventNameByIndex
+               lua_pushfstring(L, "ACTION actionIndex=%d", 
event->u.action.index);
+               break;
                
        case JIVE_EVENT_MOUSE_DOWN:
                lua_pushfstring(L, "MOUSE_DOWN x=%d,y=%d", event->u.mouse.x, 
event->u.mouse.y);

Modified: 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_framework.c
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_framework.c?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_framework.c 
(original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/jive_framework.c Fri 
Jan  9 01:26:13 2009
@@ -1333,6 +1333,7 @@
        { "getKeycode", jiveL_event_get_keycode },
        { "getUnicode", jiveL_event_get_unicode },
        { "getMouse", jiveL_event_get_mouse },
+       { "getActionInternal", jiveL_event_get_action_internal },
        { "getMotion", jiveL_event_get_motion },
        { "getSwitch", jiveL_event_get_switch },
        { "tostring", jiveL_event_tostring },

Modified: 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/lua_jiveui.c
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/lua_jiveui.c?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/lua_jiveui.c 
(original)
+++ 7.4/branches/pango/squeezeplay/src/squeezeplay/src/ui/lua_jiveui.c Fri Jan  
9 01:26:13 2009
@@ -2203,6 +2203,7 @@
    tolua_constant(tolua_S,"EVENT_SWITCH",JIVE_EVENT_SWITCH);
    tolua_constant(tolua_S,"EVENT_MOTION",JIVE_EVENT_MOTION);
    tolua_constant(tolua_S,"EVENT_KEY_ALL",JIVE_EVENT_KEY_ALL);
+   tolua_constant(tolua_S,"ACTION",JIVE_ACTION);
    tolua_constant(tolua_S,"EVENT_MOUSE_ALL",JIVE_EVENT_MOUSE_ALL);
    tolua_constant(tolua_S,"EVENT_ALL_INPUT",JIVE_EVENT_ALL_INPUT);
    tolua_constant(tolua_S,"EVENT_VISIBLE_ALL",JIVE_EVENT_VISIBLE_ALL);

Modified: 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SetupWelcome/SetupWelcomeApplet.lua
 Fri Jan  9 01:26:13 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/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/share/applets/SqueezeboxJive/SqueezeboxJiveApplet.lua
 Fri Jan  9 01:26:13 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")
@@ -118,10 +118,10 @@
                local timer = Timer(2000, -- 2 seconds
                        function()
                                -- 10 second when running
-                               --if not self.watchdogRunning then
-                               --      self.watchdog:setTimeout(10)
-                               --      self.watchdogRunning = true
-                               --end
+                               if not self.watchdogRunning then
+                                       self.watchdog:setTimeout(10)
+                                       self.watchdogRunning = true
+                               end
                                self.watchdog:keepAlive()
                        end)
                timer:start()
@@ -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/branches/pango/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay_jive/specialProjects/sbcPosSlideshow/SqueezeboxJiveApplet.lua
 Fri Jan  9 01:26:13 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/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua?rev=3744&root=Jive&r1=3743&r2=3744&view=diff
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
 (original)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/applets/SetupWireless/SetupWirelessApplet.lua
 Fri Jan  9 01:26:13 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/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
URL: 
http://svn.slimdevices.com/7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua?rev=3744&root=Jive&view=auto
==============================================================================
--- 
7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
 (added)
+++ 
7.4/branches/pango/squeezeplay/src/squeezeplay_squeezeos/share/jive/net/Networking.lua
 Fri Jan  9 01:26:13 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

Reply via email to