Author: titmuss
Date: Thu Jan 17 04:54:29 2008
New Revision: 1478

URL: http://svn.slimdevices.com?rev=1478&root=Jive&view=rev
Log:
Bug: N/A
Description:
Move udap class into main jive application.

Detect squeezeboxen in setup mode in Choose Players, at the moment this goes 
nowhere.


Added:
    trunk/jive/src/pkg/jive/share/jive/net/Udap.lua
Removed:
    
trunk/jive/src/pkg/jive_squeezeboxjive/share/applets/SetupSqueezebox/udap.lua
Modified:
    trunk/jive/src/pkg/jive/share/applets/SelectPlayer/SelectPlayerApplet.lua
    trunk/jive/src/pkg/jive/share/applets/SelectPlayer/strings.txt

Modified: 
trunk/jive/src/pkg/jive/share/applets/SelectPlayer/SelectPlayerApplet.lua
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/applets/SelectPlayer/SelectPlayerApplet.lua?rev=1478&root=Jive&r1=1477&r2=1478&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/share/applets/SelectPlayer/SelectPlayerApplet.lua 
(original)
+++ trunk/jive/src/pkg/jive/share/applets/SelectPlayer/SelectPlayerApplet.lua 
Thu Jan 17 04:54:29 2008
@@ -17,9 +17,11 @@
 
 
 -- stuff we use
-local pairs, ipairs, tostring      = pairs, ipairs, tostring
+local assert, pairs, ipairs, tostring = assert, pairs, ipairs, tostring
 
 local oo                 = require("loop.simple")
+local os                 = require("os")
+local string             = require("string")
 
 local Applet             = require("jive.Applet")
 local AppletManager      = require("jive.AppletManager")
@@ -32,6 +34,9 @@
 local Label              = require("jive.ui.Label")
 local Framework          = require("jive.ui.Framework")
 
+local SocketUdp          = require("jive.net.SocketUdp")
+local udap               = require("jive.net.Udap")
+
 local log                = require("jive.utils.log").logger("applets.setup")
 local debug              = require("jive.utils.debug")
 
@@ -39,6 +44,8 @@
 local jnt                = jnt
 
 local EVENT_WINDOW_POP = jive.ui.EVENT_WINDOW_POP
+local EVENT_WINDOW_ACTIVE = jive.ui.EVENT_WINDOW_ACTIVE
+local EVENT_WINDOW_INACTIVE = jive.ui.EVENT_WINDOW_INACTIVE
 
 -- load SetupWallpaper for use in previewing Wallpapers
 local SetupWallpaper = AppletManager:loadApplet("SetupWallpaper")
@@ -49,23 +56,26 @@
 
 function init(self, ...)
        self.playerItem = {}
+       self.scanResults = {}
+
        jnt:subscribe(self)
-
        self:manageSelectPlayerMenu()
 end
 
+
 function notify_playerDelete(self, playerObj)
-       local playerMac = playerObj.id
+       local mac = playerObj.id
        manageSelectPlayerMenu(self)
-       if self.playerMenu and self.playerItem[playerMac] then
-               self.playerMenu:removeItem(self.playerItem[playerMac])
-               self.playerItem[playerMac] = nil
-       end
-end
+       if self.playerMenu and self.playerItem[mac] then
+               self.playerMenu:removeItem(self.playerItem[mac])
+               self.playerItem[mac] = nil
+       end
+end
+
 
 function notify_playerNew(self, playerObj)
        -- get number of players. if number of players is > 1, add menu item
-       local playerMac = playerObj.id
+       local mac = playerObj.id
 
        manageSelectPlayerMenu(self)
        if self.playerMenu then
@@ -73,10 +83,12 @@
        end
 end
 
+
 function notify_playerCurrent(self, playerObj)
        self.selectedPlayer = playerObj
        self:manageSelectPlayerMenu()
 end
+
 
 function manageSelectPlayerMenu(self)
         local sdApplet = AppletManager:getAppletInstance("SlimDiscovery")
@@ -106,12 +118,18 @@
        end
 end
 
+
+function _unifyMac(mac)
+       return string.upper(string.gsub(mac, "[^%x]", ""))
+end
+
+
 function _addPlayerItem(self, player)
-       local playerMac = player.id
+       local mac = player.id
        local playerName = player.name
 
-       log:warn("_addPlayerItem")
        local item = {
+               id = _unifyMac(mac),
                text = playerName,
                sound = "WINDOWSHOW",
                callback = function()
@@ -119,22 +137,44 @@
                                   self.setupNext()
                           end,
                focusGained = function(event)
-                       self:_showWallpaper(playerMac)
+                       self:_showWallpaper(mac)
                end,
                weight =  1
        }
        self.playerMenu:addItem(item)
-       self.playerItem[playerMac] = item
+       self.playerItem[mac] = item
        
        if self.selectedPlayer == player then
                self.playerMenu:setSelectedItem(item)
        end
 end
 
+
+-- add a squeezebox discovered using udap or an adhoc network
+function _addSqueezeboxItem(self, mac, name, adhoc)
+       local item = {
+               id = _unifyMac(mac),
+               text = name or self:string("SQUEEZEBOX_NAME", string.sub(mac, 
7)),
+               sound = "WINDOWSHOW",
+               callback = function()
+                                  log:error("SETUP SQUEEZEBOX")
+                                  --self.setupNext()
+                          end,
+               focusGained = function(event)
+                       self:_showWallpaper(nil)
+               end,
+               weight =  1
+       }
+       self.playerMenu:addItem(item)
+       self.playerItem[mac] = item
+end
+
+
 function _showWallpaper(self, playerId)
        log:info("previewing background wallpaper for ", playerId)
        SetupWallpaper:_setBackground(nil, playerId)
 end
+
 
 function setupShow(self, setupNext)
        -- get list of slimservers
@@ -150,13 +190,13 @@
                        window:hide(Window.transitionPushLeft)
                end
 
-        local sdApplet = AppletManager:getAppletInstance("SlimDiscovery")
-        if not sdApplet then
+        self.discovery = AppletManager:getAppletInstance("SlimDiscovery")
+        if not self.discovery then
                return
        end
 
-       self.selectedPlayer = sdApplet:getCurrentPlayer()
-       for playerMac, playerObj in sdApplet:allPlayers() do
+       self.selectedPlayer = self.discovery:getCurrentPlayer()
+       for mac, playerObj in self.discovery:allPlayers() do
                _addPlayerItem(self, playerObj)
        end
 
@@ -173,30 +213,92 @@
                                })
        end
 
-       --[[
-       -- no player for debugging
-       self.playerMenu:addItem({
-                                       text = "NO PLAYER (DEBUG)",
-                                       sound = "WINDOWSHOW",
-                                       callback = function()
-                                                          
self:selectPlayer(nil)
-                                                          self.setupNext()
-                                                  end,
-                                       weight =  9
-                               })
-       --]]
-
        window:addWidget(menu)
 
-       sdApplet:discover()
-       window:addTimer(1000, function() sdApplet:discover() end)
+       window:addTimer(1000, function() self:_scan() end)
+
+
+       window:addListener(EVENT_WINDOW_ACTIVE,
+                          function()
+                                  self:_scanActive()
+                                  self:_scan()
+                          end)
+
+       window:addListener(EVENT_WINDOW_INACTIVE,
+                          function()
+                                  self:_scanInactive()
+                          end)
 
        self:tieAndShowWindow(window)
        return window
 end
 
+
+function _scanActive(self)
+       -- socket for udap discovery
+       if not self.socket then
+               self.socket = assert(SocketUdp(jnt, function(chunk, err)
+                                                           
self:_udapSink(chunk, err)
+                                                   end))
+       end
+end
+
+
+function _scanInactive(self)
+       self.socket:close()
+       self.socket = nil
+end
+
+
+function _udapSink(self, chunk, err)
+       if chunk == nil then
+               return -- ignore errors
+       end
+
+       local pkt = udap.parseUdap(chunk.data)
+
+       if pkt.uapMethod ~= "adv_discover"
+               or pkt.ucp.device_status ~= "wait_slimserver"
+               or pkt.ucp.type ~= "squeezebox" then
+               -- we are only looking for squeezeboxen trying to connect to SC
+               return
+       end
+
+       local mac = pkt.source
+       local name = pkt.ucp.name
+       if not self.scanResults[mac] then
+               self.scanResults[mac] = {
+                       lastScan = os.time(),
+                       udap = true,
+               }
+
+               self:_addSqueezeboxItem(mac, name, nil)
+       end
+end
+
+
+function _scan(self)
+       -- SqueezeCenter and player discovery
+       self.discovery:discover()
+
+       -- udap discovery
+       local packet = udap.createAdvancedDiscover(nil, 1)
+       self.socket:send(function() return packet end, "255.255.255.255", 
udap.port)
+
+       -- remove squeezeboxen not seen for 10 seconds
+       local now = os.time()
+       for mac, entry in pairs(self.scanResults) do
+               if os.difftime(now, entry.lastScan) > 10 then
+                       self.playerMenu:removeItem(self.playerItem[mac])
+                       self.playerItem[mac] = nil
+                       self.scanResults[mac] = nil
+               end
+       end
+end
+
+
 function selectPlayer(self, player)
-       log:warn("Selected player is now ", player)
+       log:info("Selected player=", player)
 
        local manager = AppletManager:getAppletInstance("SlimDiscovery")
        if manager then
@@ -205,6 +307,7 @@
 
        return true
 end
+
 
 function free(self)
 

Modified: trunk/jive/src/pkg/jive/share/applets/SelectPlayer/strings.txt
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/applets/SelectPlayer/strings.txt?rev=1478&root=Jive&r1=1477&r2=1478&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/share/applets/SelectPlayer/strings.txt (original)
+++ trunk/jive/src/pkg/jive/share/applets/SelectPlayer/strings.txt Thu Jan 17 
04:54:29 2008
@@ -16,4 +16,11 @@
        IT      Configura Squeezebox
        NL      Squeezebox instellen
 
+SQUEEZEBOX_NAME
+       DE      Squeezebox %s
+       EN      Squeezebox %s
+       ES      Squeezebox %s
+       FR      Squeezebox %s
+       IT      Squeezebox %s
+       NL      Squeezebox %s
 

Added: trunk/jive/src/pkg/jive/share/jive/net/Udap.lua
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/jive/net/Udap.lua?rev=1478&root=Jive&view=auto
==============================================================================
--- trunk/jive/src/pkg/jive/share/jive/net/Udap.lua (added)
+++ trunk/jive/src/pkg/jive/share/jive/net/Udap.lua Thu Jan 17 04:54:29 2008
@@ -1,0 +1,374 @@
+
+local pairs, ipairs, print, tonumber, unpack = pairs, ipairs, print, tonumber, 
unpack
+
+local oo          = require("loop.base")
+
+local socket      = require("socket")
+local string      = require("string")
+local table       = require("table")
+
+
+module(..., oo.class)
+
+
+port = 0x4578
+
+
+-- Squeezebox nvram settings
+local configSettings = {
+       [ "lan_ip_mode" ] = { 4, 1 },
+       [ "lan_network_address" ] = { 5, 4 },
+       [ "lan_subnet_mask" ] = { 9, 4 },
+       [ "lan_gateway" ] = { 13, 4 },
+       [ "hostname" ] = { 17, 33 },
+       [ "bridging" ] = { 50, 1 },
+       [ "interface" ] = { 52, 1 },
+       [ "primary_dns" ] = { 59, 4 },
+       [ "secondary_dns" ] = { 67, 4 },
+       [ "server_address" ] = { 71, 4 },
+       [ "slimserver_address" ] = { 79, 4 },
+       [ "wireless_mode" ] = { 173, 1 },
+       [ "SSID" ] = { 183, 33 },
+       [ "channel" ] = { 216, 1 },
+       [ "region_id" ] = { 218, 1 },
+       [ "keylen" ] = { 220, 1 },
+       [ "wep_key" ] = { 222, 13 },
+       [ "wepon" ] = { 274, 1 },
+       [ "wpa_cipher" ] = { 275, 1 },
+       [ "wpa_enabled" ] = { 277, 1 },
+       [ "wpa_mode" ] = { 276, 1 },
+       [ "wpa_psk" ] = { 278, 64 }
+}
+
+
+-- ucp methods
+local ucpMethods = {
+       "discover",
+       "get_ip",
+       "set_ip",
+       "reset",
+       "get_data",
+       "set_data",
+       "error",
+       "credentials_error",
+       "adv_discover",
+       nil,
+       "get_uuid"
+}
+
+
+-- ucp discovery codes
+local ucpCodes = {
+       nil,
+       "name",
+       "type",
+       "use_dhcp",
+       "ip_addr",
+       "subnet_mask",
+       "gateway_addr",
+       nil,
+       "firmware_rev",
+       "hardware_rev",
+       "device_id",
+       "device_status",
+       "uuid"
+}
+
+
+function packNumber(v, len)
+       local t = {}
+
+       for i = 1,len do
+               t[#t + 1] = string.char(v & 0xFF)
+               v = v >> 8
+       end
+
+       return string.reverse(table.concat(t))
+end
+
+
+function unpackString(str, pos, len)
+       local v = ""
+       for i = pos, pos+len-1 do
+               v = string.format("%s%02x", v, string.byte(string.sub(str, i, 
i+1)))
+       end
+
+       return v, pos + len
+end
+
+
+function unpackNumber(str, pos, len)
+       local v, offset = unpackString(str, pos, len)
+       return tonumber(v, 16), offset
+end
+
+
+function parseDiscover(pkt, recv, offset)
+       pkt.ucp = {}
+       while offset < #recv do
+               local ucp_code, ucp_len, ucp_pkt
+               
+               ucp_code, offset = unpackNumber(recv, offset, 1)
+               ucp_len, offset = unpackNumber(recv, offset, 1)
+               ucp_data = string.sub(recv, offset, offset + ucp_len - 1)
+               offset = offset + ucp_len
+
+               pkt.ucp[ucpCodes[ucp_code]] = ucp_data
+       end
+end
+
+
+function parseGetData(pkt, recv, offset)
+       local num, off, len, data
+
+       pkt.data = {}
+
+       num, offset = unpackNumber(recv, offset, 2)
+       for i = 1,num do
+               off, offset = unpackNumber(recv, offset, 2)
+               len, offset = unpackNumber(recv, offset, 2)
+               data = string.sub(recv, offset, offset + len - 1)
+               offset = offset + len
+
+               for k,v in pairs(configSettings) do
+                       if v[1] == off and v[2] == len then
+                               pkt.data[k] = data
+                               break
+                       end
+               end
+       end
+end
+
+
+function parseGetUUID(pkt, recv, offset)
+       local num, off, len, data
+
+       pkt.data = {}
+
+       len, offset = unpackNumber(recv, offset, 2)
+       local n = { string.byte(string.sub(recv, offset, offset + len - 1), 1, 
len) }
+
+       pkt.uuid = {}
+       for k,v in ipairs(n) do
+               pkt.uuid[#pkt.uuid + 1] = string.format("%02x", v)
+       end
+       pkt.uuid = table.concat(pkt.uuid)
+end
+
+
+local ucpMethodHandlers = {
+       [ "discover" ] = parseDiscover,
+       [ "get_ip" ] = parseDiscover,
+       [ "set_ip" ] = nil,
+       [ "reset" ] = nil,
+       [ "get_data" ] = parseGetData,
+       [ "set_data" ] = nil,
+       [ "error" ] = nil,
+       [ "credentials_error" ] = nil,
+       [ "adv_discover" ] = parseDiscover,
+       [ "get_uuid" ] = parseGetUUID,
+}
+
+
+function parseUdap(recv)
+       local offset = 1
+       local pkt = {}
+
+       pkt.destType, offset = unpackNumber(recv, offset, 2)
+       if pkt.destType == 1 then
+               -- mac address
+               pkt.dest, offset = unpackString(recv, offset, 6)
+       elseif pkt.destType == 2 then
+               -- ip address
+               pkt.dest, offset = unpackString(recv, offset, 6)
+       else
+               error("uknown address type " .. pkt.destType)
+       end
+
+       pkt.sourceType, offset = unpackNumber(recv, offset, 2)
+       if pkt.sourceType == 1 then
+               -- mac address
+               pkt.source, offset = unpackString(recv, offset, 6)
+       elseif pkt.sourceType == 2 then
+               -- ip address
+               pkt.source, offset = unpackString(recv, offset, 6)
+       else
+               error("uknown address type " .. pkt.sourceType)
+       end
+
+       pkt.seqno, offset = unpackNumber(recv, offset, 2)
+       pkt.udapType, offset = unpackNumber(recv, offset, 2)
+       pkt.udapFlag, offset = unpackNumber(recv, offset, 1)
+       pkt.uapClass, offset = unpackString(recv, offset, 4)
+       pkt.uapMethodId, offset = unpackNumber(recv, offset, 2)
+       
+       pkt.uapMethod = ucpMethods[pkt.uapMethodId]
+       
+       if ucpMethodHandlers[pkt.uapMethod] then
+               ucpMethodHandlers[pkt.uapMethod](pkt, recv, offset)
+       end
+
+       return pkt
+end
+
+
+function createUdap(mac, seq, ...)
+       local macstr = {}
+       local bcast = 0
+
+       if mac == nil then
+               bcast = 1
+               mac = "000000000000"
+       end
+
+       for i=1,12,2 do
+               macstr[#macstr + 1] = string.char(tonumber(string.sub(mac, i, 
i+1), 16))
+       end
+
+       return table.concat {
+               packNumber(bcast, 1),         -- broadcast
+               packNumber(0x01, 1),          -- ethernet
+               table.concat(macstr),         -- destination mac
+               packNumber(0x0002, 2),        -- source type udp
+               packNumber(0x00000000, 4),    -- source ip
+               packNumber(0x0000, 2),        -- source port
+               packNumber(seq, 2),           -- seqno number
+               packNumber(0xC001, 2),        -- udap_type_ucp
+               packNumber(0x01, 1),          -- flags
+               packNumber(0x00001, 2),       -- uap_class_ucp
+               packNumber(0x00001, 2),
+               table.concat({...})
+       }
+end
+
+
+function createDiscover(mac, seq)
+       return createUdap(mac,
+                         seq,
+                         packNumber(0x0001, 2) -- discover
+                  )
+end
+
+
+function createAdvancedDiscover(mac, seq)
+       return createUdap(mac,
+                         seq,
+                         packNumber(0x0009, 2) -- discover
+                  )
+end
+
+
+function createReset(mac, seq)
+       return createUdap(mac,
+                         seq,
+                         packNumber(0x0004, 2) -- reset
+                  )
+end
+
+
+function createGetIPAddr(mac, seq)
+       return createUdap(mac,
+                         seq,
+                         packNumber(0x0002, 2) -- get ip
+                  )
+end
+
+
+function createGetUUID(mac, seq)
+       return createUdap(mac,
+                         seq,
+                         packNumber(0x000b, 2) -- get uuid
+                  )
+end
+
+
+function createGetData(mac, seq, args)
+       local req = {
+               packNumber(0x0005, 2),    -- get data
+               string.rep("\0", 16),      -- username
+               string.rep("\0", 16),      -- password
+               packNumber(#args, 2),     -- num of items
+       }
+       
+       for i,k in ipairs(args) do
+               local p = configSettings[k]
+               if p ~= nil then
+                       req[ #req + 1 ] = packNumber(p[1], 2)  -- offset
+                       req[ #req + 1 ] = packNumber(p[2], 2)  -- length
+               end
+       end
+
+       return createUdap(mac,
+                         seq,
+                         unpack(req))
+end
+
+
+function createSetData(mac, seq, args)
+       local num = 0
+       for k,v in pairs(args) do
+               num = num + 1
+       end
+
+       local req = {
+               packNumber(0x0006, 2),    -- set data
+               string.rep("\0", 16),      -- username
+               string.rep("\0", 16),      -- password
+               packNumber(num, 2),       -- num of items
+       }
+       
+       for k,v in pairs(args) do
+               local p = configSettings[k]
+               if p ~= nil then
+                       req[ #req + 1 ] = packNumber(p[1], 2)  -- offset
+                       req[ #req + 1 ] = packNumber(p[2], 2)  -- length
+                       req[ #req + 1 ] = v .. string.rep("\0", p[2] - #v)
+               end
+       end
+
+       return createUdap(mac,
+                         seq,
+                         unpack(req))
+end
+
+
+function tostringUdap(pkt)
+       local t = {
+               "source:\t\t" .. pkt.source,
+               "dest:\t\t" .. pkt.dest,
+               "seq:\t\t" .. pkt.seqno,
+               "udap type:\t" .. string.format("%04x", pkt.udapType),
+               "udap flag:\t" .. string.format("%02x", pkt.udapFlag),
+               "uap class:\t" .. pkt.uapClass,
+               "uap method:\t" .. pkt.uapMethod,
+       }
+       if pkt.ucp then
+               for k,v in pairs(pkt.ucp) do
+                       t[#t + 1] = k .. ":\t" .. v
+               end
+       end
+       if pkt.data then
+               for k,v in pairs(pkt.data) do
+                       local hex = ""
+                       for i = 1,#v do
+                               hex = hex .. string.format("%02x", 
string.byte(string.sub(v, i, i)))
+                       end
+
+                       t[#t + 1] = k .. " (#" .. #v .. "):\t" .. hex
+               end
+       end
+
+       return table.concat(t, "\n")
+end
+
+
+--[[
+
+=head1 LICENSE
+
+Copyright 2007 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