Home of the Squeezebox™ & Transporter® network music players.
Results 1 to 5 of 5
  1. #1
    Senior Member erland's Avatar
    Join Date
    Dec 2005
    Location
    Sweden
    Posts
    11,305

    Announce: Applet/Plugin for remote administration of SqueezePlay

    I've continued a bit on the plugin/applet combination I announced earlier for reading the SqueezeOS file system, the old thread was this one:
    http://forums.slimdevices.com/showthread.php?t=75919

    The name has now been changed to "SqueezePlay Admin" (applet) and "SqueezePlay Admin Client" (plugin) to better reflect their purpose. I've also generalized the solution a bit to make it easier to extend.

    It follows the same principles as the old one but the applet part is now a lot more extensible.

    I'm posting it here instead of in the 3rd party plugins section because it's mostly developer oriented at the moment. It needs some more user interfaces before it's ready to use by end users.

    The applet exposes a registration service "squeezePlayAdminDispatch" which other third party applets can use to register their own commands they want to expose remotely.

    A registration call looks like this:
    Code:
    appletManager:callService("squeezePlayAdminDispatch","myprefreadcommand","MyApplet","myCommandHandlerFunction")
    And inside the applet, you will need to implement the function that handles the command, for example like this:
    Code:
    function myCommandHandlerFunction(self,params)
            -- Read parameters from command
            local applet = params.applet
            local pref = params.pref
    
            -- Execute command
            local instance = appletManager:loadApplet(applet)
            local value = instance["getSettings"](instance)[pref]
    
            -- Package and return result
            local result = {
                    value = value
            }
            return result
    end
    The result is that this command will be available over CLI/JSON in all SBS instances on the network which have the "SqueezePlay Admin Client" plugin installed AND is currently connected to the player/controller. The CLI/JSON command looks like this in the above case:
    Code:
    squeezeplayadmin myprefreadcommand 00:01:02:03:04:05 applet:ScreenSavers pref:whenPlaying
    And the response might return:
    Code:
    value:AlbumFlow:openScreensaver2
    The current implementation implements a number of commands, but as mentioned above this can be extended by other third party applets, the currently implemented command are:

    List contents of directory /usr/share/jive/applets
    Code:
    squeezeplayadmin dir 00:01:02:03:04:05 dir:/usr/share/jive/applets
    Retrieve file /var/log/messages (base64 encoded)
    Code:
    squeezeplayadmin get 00:01:02:03:04:05 file:/var/log/messages
    Get value of preference "whenPlaying" in "ScreenSavers" applet
    Code:
    squeezeplayadmin getpref 00:01:02:03:04:05 applet:ScreenSavers pref:whenPlaying
    Get all preferences for "ScreenSavers" applet
    Code:
    squeezeplayadmin getprefs 00:01:02:03:04:05 applet:ScreenSavers
    Check if applet "PatchInstaller" is installed
    Code:
    squeezeplayadmin hasapplet 00:01:02:03:04:05 applet:PatchInstaller
    Get a list of installed applets
    Code:
    squeezeplayadmin applets 00:01:02:03:04:05
    If people find this useful, I have some ideas for other commands but here is where I'd like some input, some obvious are:
    - put: Write a file
    - setpref: Set a preference (this is actually implemented but I haven't exposed it because it doesn't work correctly for hierarchical preferences yet)
    - gettinyscpref: Get preference in TinySC
    - settinyscpref: Set preference in TinySC

    I'm not completely sure yet how to integrate the preferences in SBS web interface, currently the web interface only makes it possible to browse the file system and retrieve files (for example /var/log/messages)

    I wonder if it would be suitable to create player pages in the web UI to make it possible to read/write the applet preferences through SBS web interface player settings pages ?

    It would also be nice to have some kind of backup/restore option of the preferences to make it possible to restore preferences after a factory reset. Maybe through some integration with the SettingsManager plugin ?

    The security follows the principles we discussed in the old thread:
    - The applet register itself towards all SBS instances it connects to which have the "SqueezePlay Admin Client" plugin installed. It registers with a random number and later it will only accept commands with the same random number
    - If neither CSRF protection nor password is enabled in SBS it will show a warning in the web interface
    - The applet only sends responses to the server that's represented by the secret random number, so if someone sends a faked package the response will still go to the standard server.
    - To break the web interface through CSRF you need to know the MAC address of the player/controller, this should hopefully take care of any CSRF issues good enough.

    I'm not sure if it would be suitable to add some more security measures. It feels like you have bigger problems to worry about if someone have access to the local network, so the main hole (the web interface and CSRF) should be to covered good enough. However, if anyone have thoughts about this and have a solution which offers better security without making it too complex for the user I'm open for suggestions.
    Erland Isaksson (My homepage)
    Developer of many plugins/applets
    Starting with LMS 8.0 I no longer support my plugins/applets (see here for more information )

  2. #2
    Senior Member erland's Avatar
    Join Date
    Dec 2005
    Location
    Sweden
    Posts
    11,305
    Forgot to say that it's available in my testing repository, in case anyone want to try it out:
    Code:
    http://erlandplugins.googlecode.com/svn/repository/trunk/testing.xml
    Erland Isaksson (My homepage)
    Developer of many plugins/applets
    Starting with LMS 8.0 I no longer support my plugins/applets (see here for more information )

  3. #3
    First, this looks really cool. :-)

    From your examples, it looks like the SBS CLI command takes playerid as an explicit argument instead of using the normal $request->client mechanism. Why do you use
    Code:
    squeezeplayadmin dir 00:01:02:03:04:05 dir:/usr/share/jive/applets
    rather than
    Code:
    00:01:02:03:04:05 squeezeplayadmin dir dir:/usr/share/jive/applets
    ? I'm just curious. I haven't thought through all the implications -- it does seem like your approach may be more flexible, may allow for usages like
    Code:
    # run mycommand on all players
    squeezeplayadmin dir {ALL} mycommand
    # run mycommand on all Touch players
    squeezeplayadmin dir {fab4} mycommand
    # run mycommand on all upstairs players
    squeezeplayadmin dir "Upstairs*" mycommand
    but then you could also do something like that with a different usage convention, e.g.

    Code:
    squeezeplayadmin dir dir:/usr/share/jive/applets player:00:01:02:03:04:05
    squeezeplayadmin dir dir:/usr/share/jive/applets player:{ALL}
    might cause "dir" to run on all players where "dir" has been registered, and code on each dir-enabled player would look for a "player" param to decide whether to run.

    I'm thinking about this because I recently added "scope" capabilities to KidsPlay -- see the section "Running on certain Squeezeboxes" on http://www.tux.org/~peterw/slim/KidsPlay.html. It just looks a little clumsy now to me when I see CLI commands that must be executed N times for N players. :-)
    owner of the stuff at https://tuxreborn.netlify.app/
    (which used to reside at www. tux.org/~peterw/)
    Note: The best way to reach me is email or PM, as I don't spend much time on the forums.
    Free plugins: AllQuiet Auto Dim/AutoDisplay BlankSaver ContextMenu DenonSerial
    FuzzyTime KidsPlay KitchenTimer PlayLog PowerCenter/BottleRocket SaverSwitcher
    SettingsManager SleepFade StatusFirst SyncOptions VolumeLock

  4. #4
    Senior Member erland's Avatar
    Join Date
    Dec 2005
    Location
    Sweden
    Posts
    11,305
    Quote Originally Posted by peterw View Post
    First, this looks really cool. :-)

    From your examples, it looks like the SBS CLI command takes playerid as an explicit argument instead of using the normal $request->client mechanism. Why do you use
    Code:
    squeezeplayadmin dir 00:01:02:03:04:05 dir:/usr/share/jive/applets
    rather than
    Code:
    00:01:02:03:04:05 squeezeplayadmin dir dir:/usr/share/jive/applets
    ? I'm just curious. I haven't thought through all the implications
    The reason is that all SqueezePlay devices aren't players, for example a Controller or a Touch configured with no audio output. $client object only represent players, the controllers aren't represented on the server.

    Quote Originally Posted by peterw View Post
    -- it does seem like your approach may be more flexible, may allow for usages like
    Code:
    # run mycommand on all players
    squeezeplayadmin dir {ALL} mycommand
    # run mycommand on all Touch players
    squeezeplayadmin dir {fab4} mycommand
    # run mycommand on all upstairs players
    squeezeplayadmin dir "Upstairs*" mycommand
    I hadn't thought of that, might be useful.
    The only issue I can see is that the plugin would have to somehow synchronize and combine the responses for each player because the CLI command wants a single response.

    Quote Originally Posted by peterw View Post
    but then you could also do something like that with a different usage convention, e.g.

    Code:
    squeezeplayadmin dir dir:/usr/share/jive/applets player:00:01:02:03:04:05
    squeezeplayadmin dir dir:/usr/share/jive/applets player:{ALL}
    might cause "dir" to run on all players where "dir" has been registered, and code on each dir-enabled player would look for a "player" param to decide whether to run.
    The difference between this and the first approach is just the positioning of the "player" parameter, right ?
    Or are you saying that you want the player (and not the plugin) to be in control if it wants to execute a command or not ?

    What I described in the initial post was the external application/plugin -> SBS communication, the SBS -> Player communication actually add some more information:

    - A handle(unique request identity) which is used to correlate the response later on. The reason this is required is that this is all asynchronous communication where SBS actually sends the command to all players as a notification (notifyFromArray) and the applet will be triggered by the notification and it will check if the command belongs to it and execute it and at the end make a callback to a standard JSON command that's implemented by the plugin. In the callback I pass back the handle, so the plugin can synchronize it with the request that triggered it from the start. When the plugin get back the handle for a earlier sent notification, it will send the CLI response.

    - A secret random number which the plugin got from the player when it registered it self in the beginning. This is just used to make sure only server applications that SqueezePlay connects to is able to send the command to the applet. If the secret random number doesn't match, the applet ignores the notification. To be honest, I'm not really sure if this provides any extra security, so it might be removed in a future version. However, it's completely hidden from both the CLI user and the third party applet on the player side that implements a command.

    Due to the above mentioned correlation, I think the server must at least get an answer from each player if we want to allow a single CLI command to result in commands executed on multiple players. With a solution like that the plugin would just have to wait until it has got an answer from all players that implements the command, currently it generates the CLI response when it gets the first answer since it knows that only one player will answer.
    Erland Isaksson (My homepage)
    Developer of many plugins/applets
    Starting with LMS 8.0 I no longer support my plugins/applets (see here for more information )

  5. #5
    Senior Member
    Join Date
    Sep 2012
    Posts
    113
    Hi, very interesting applet

    I have an idea :

    On the Squeeezebox Radio this is not possible to switch to "line-in" remotely (by CLI, SSH or else).
    But an applet can make that : the native "LineInApplet.lua" and this one which call the native one by a button combination.

    I tried my own modification of the native applet but your solution is probably what I need. I will not refuse some help to be able to run the function appletManager:getAppletInstance("LineIn")


    The idea is to run something similar to this :

    Code:
    	local LineInAppletInstance = appletManager:getAppletInstance("LineIn")
    	
    	log:debug("Line-In activated.")
    	LineInAppletInstance:activateLineIn(true)
    (Or may be you have an easier way to just run a function from an applet ?)


    Thank you !


    EDIT : OK , it was not so difficult I have created my own function and it works on LMS 7.9 ! Now I'm trying to make it work on LMS 8.2 -> "Plugin failed to load"
    EDIT2: OK I had this error
    Code:
    Can't use an array as a reference at /var/lib/squeezeboxserver/cache/InstalledPlugins/Plugins/SqueezePlayAdminClient/Plugin.pm line 117.
    .
    As I'm not sure of the synthax that should be used for a perl array I've just commented it : quick and dirty but it works on 8.2 now
    Last edited by schmurtz; 2021-09-01 at 18:13.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •