Luup and UPnP actions: Another bug

It seems MCV has done a lot of effort implementing UPnP into Vera but unfortunately stopped before completing the last mile :frowning:

After @Ap15e 's workaround ([url=http://forum.micasaverde.com/index.php/topic,10220.0.html]http://forum.micasaverde.com/index.php/topic,10220.0.html[/url]) for bug #1473 ([url=http://bugs.micasaverde.com/view.php?id=1473]http://bugs.micasaverde.com/view.php?id=1473[/url]), here’s another bug to be fixed:

When calling a UPnP action for a UPnP device imported into Vera, it’s supposed to send a SOAP Message to the device as per the xml service file provided. Some devices (like a UPnP Media Server) expect the SOAP message to be properly formatted (ie the argument tags ordered as per the xml service file).

When using the luup.call_action function with an argument list, Vera will sort the tags in the SOAP Message as per their order in the arguments parameter (table) provided, but Lua’s string tables are randomly sorted ([url=http://www.lua.org/pil/19.3.html]http://www.lua.org/pil/19.3.html[/url]) so we will end up with a badly formatted SOAP Message (as below).
(I believe the code to properly format the SOAP Message as per the xml service file is missing.)

The same applies when using an http request, the sort order of the parameters in the SOAP Message will be the same as their appearance in the URI. (At least this way, the user/developer is able to control the sort order).

Properly formatted SOAP Message:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body><u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"> <ObjectID>0</ObjectID> <BrowseFlag>BrowseDirectChildren</BrowseFlag> <Filter>id,dc:title,upnp:class,res,res@duration</Filter> <StartingIndex>0</StartingIndex> <RequestedCount>10</RequestedCount> <SortCriteria>+dc:title</SortCriteria> </u:Browse> </s:Body> </s:Envelope>

Badly formatted SOAP Message:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body><u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"> <StartingIndex>0</StartingIndex> <ObjectID>0</ObjectID> <RequestedCount>10</RequestedCount> <BrowseFlag>BrowseDirectChildren</BrowseFlag> <Filter>id,dc:title,upnp:class,res,res@duration</Filter> <SortCriteria>+dc:title</SortCriteria> </u:Browse> </s:Body> </s:Envelope>

Please can a beta tester report this bug to MCV so we can get a fix some day ? :slight_smile:

Bug confirmed.

Test script:

local SID         = 'urn:upnp-org:serviceId:ContentDirectory'
local DEVICE_ID   = 38
local MARKER      = '----------------------------------'
local VERA_PREFIX = 'http://192.168.178.108:3480/'

--luup = { log = print, call_action = print }


function log_table( t, s )

 for k, v in pairs( t )
  do
   luup.log( MARKER .. '*' .. s .. '*' .. tostring( k ) .. '*' .. tostring( v ) .. '*' )
  end

end


local err, err_msg, job, arguments = luup.call_action( SID, 'GetSearchCapabilities', {}, DEVICE_ID )

log_table( arguments, 'TEST' )

local PARAMETER = { ObjectID       = '0'                   ,
                    BrowseFlag     = 'BrowseDirectChildren',
                    Filter         = '*'                   ,
                    StartingIndex  = '0'                   ,
                    RequestedCount = '10'                  ,
                    SortCriteria   = ''                      }

-- check order

log_table( PARAMETER, 'CHECK')

luup.log( MARKER .. '------------------------------------------------------' )

-- another try

PARAMETER[ 'ObjectID'       ] = '0'                   
PARAMETER[ 'BrowseFlag'     ] = 'BrowseDirectChildren'
PARAMETER[ 'Filter'         ] = '*'                   
PARAMETER[ 'StartingIndex'  ] = '0'                   
PARAMETER[ 'RequestedCount' ] = '10'                   
PARAMETER[ 'SortCriteria'   ] = ''

log_table( PARAMETER, 'CHECK')

-- call_action

local err, err_msg, job, arguments = luup.call_action( SID, 'Browse', PARAMETER, DEVICE_ID )

-- log results

luup.log( MARKER .. '*' .. tostring( err ) .. '*' .. tostring( err_msg ) .. '*' .. tostring( job ) .. '*' .. tostring( arguments ) )

log_table( arguments, 'RESULT' )

-- And now for something different: http ...

--http://192.168.178.108:3480/data_request?id=action&output_format=xml&DeviceNum=38&serviceId=urn:upnp-org:serviceId:ContentDirectory&action=Browse&ObjectID=0&BrowseFlag=BrowseDirectChildren&Filter=*&StartingIndex=0&RequestedCount=10&SortCriteria=''

local httpStatusCode, content = luup.inet.wget( VERA_PREFIX .. 'data_request?id=action&output_format=xml&DeviceNum=' .. DEVICE_ID .. '&serviceId=' .. SID .. "&action=Browse&ObjectID=0&BrowseFlag=BrowseDirectChildren&Filter=*&StartingIndex=0&RequestedCount=10&SortCriteria=''" )

luup.log( MARKER .. ' httpStatusCode*' .. tostring( httpStatusCode ) )
luup.log( MARKER .. ' content*'        .. tostring( content        ) )

luup.log( MARKER .. ' END' )

Result:

08      04/18/12 20:22:14.417   JobHandler_LuaUPnP::HandleActionRequest device: 38 service: urn:upnp-org:serviceId:ContentDirectory action: ^[[36;1mGetSearchC
50      04/18/12 20:22:14.478   luup_log:0: ----------------------------------*TEST*SearchCaps*upnp:class,dc:title,upnp:album,upnp:artist,upnp:author,dc:contr
50      04/18/12 20:22:14.478   luup_log:0: ----------------------------------*CHECK*RequestedCount*10* <0x2eca3680>
50      04/18/12 20:22:14.478   luup_log:0: ----------------------------------*CHECK*Filter*** <0x2eca3680>
50      04/18/12 20:22:14.479   luup_log:0: ----------------------------------*CHECK*ObjectID*0* <0x2eca3680>
50      04/18/12 20:22:14.479   luup_log:0: ----------------------------------*CHECK*BrowseFlag*BrowseDirectChildren* <0x2eca3680>
50      04/18/12 20:22:14.479   luup_log:0: ----------------------------------*CHECK*SortCriteria** <0x2eca3680>
50      04/18/12 20:22:14.479   luup_log:0: ----------------------------------*CHECK*StartingIndex*0* <0x2eca3680>
50      04/18/12 20:22:14.480   luup_log:0: ---------------------------------------------------------------------------------------- <0x2eca3680>
50      04/18/12 20:22:14.480   luup_log:0: ----------------------------------*CHECK*RequestedCount*10* <0x2eca3680>
50      04/18/12 20:22:14.480   luup_log:0: ----------------------------------*CHECK*Filter*** <0x2eca3680>
50      04/18/12 20:22:14.481   luup_log:0: ----------------------------------*CHECK*ObjectID*0* <0x2eca3680>
50      04/18/12 20:22:14.481   luup_log:0: ----------------------------------*CHECK*BrowseFlag*BrowseDirectChildren* <0x2eca3680>
50      04/18/12 20:22:14.481   luup_log:0: ----------------------------------*CHECK*SortCriteria** <0x2eca3680>
50      04/18/12 20:22:14.482   luup_log:0: ----------------------------------*CHECK*StartingIndex*0* <0x2eca3680>
08      04/18/12 20:22:14.482   JobHandler_LuaUPnP::HandleActionRequest device: 38 service: urn:upnp-org:serviceId:ContentDirectory action: ^[[36;1mBrowse^[[0
08      04/18/12 20:22:14.483   JobHandler_LuaUPnP::HandleActionRequest argument RequestedCount=10 <0x2eca3680>
08      04/18/12 20:22:14.483   JobHandler_LuaUPnP::HandleActionRequest argument Filter=* <0x2eca3680>
08      04/18/12 20:22:14.483   JobHandler_LuaUPnP::HandleActionRequest argument ObjectID=0 <0x2eca3680>
08      04/18/12 20:22:14.483   JobHandler_LuaUPnP::HandleActionRequest argument BrowseFlag=BrowseDirectChildren <0x2eca3680>
08      04/18/12 20:22:14.483   JobHandler_LuaUPnP::HandleActionRequest argument SortCriteria= <0x2eca3680>
08      04/18/12 20:22:14.484   JobHandler_LuaUPnP::HandleActionRequest argument StartingIndex=0 <0x2eca3680>
01      04/18/12 20:22:14.496   ^[[31;1mJobHandler_LuaUPnP::ForwardUPnPAction Device 38 url http://192.168.178.26:31416/http://192.168.178.26:31416/d4e40943-9
50      04/18/12 20:22:14.497   luup_log:0: ----------------------------------*0**0*table: 0xc65608 <0x2eca3680>
50      04/18/12 20:22:14.498   luup_log:0: ----------------------------------*RESULT*errorDescription*Invalid Arguments* <0x2eca3680>
50      04/18/12 20:22:14.498   luup_log:0: ----------------------------------*RESULT*errorCode*402* <0x2eca3680>
08      04/18/12 20:22:14.502   JobHandler_LuaUPnP::HandleActionRequest device: 38 service: urn:upnp-org:serviceId:ContentDirectory action: ^[[36;1mBrowse^[[0
08      04/18/12 20:22:14.503   JobHandler_LuaUPnP::HandleActionRequest argument DeviceNum=38 <0x2e2a3680>
08      04/18/12 20:22:14.503   JobHandler_LuaUPnP::HandleActionRequest argument serviceId=urn:upnp-org:serviceId:ContentDirectory <0x2e2a3680>
08      04/18/12 20:22:14.503   JobHandler_LuaUPnP::HandleActionRequest argument action=Browse <0x2e2a3680>
08      04/18/12 20:22:14.503   JobHandler_LuaUPnP::HandleActionRequest argument ObjectID=0 <0x2e2a3680>
08      04/18/12 20:22:14.503   JobHandler_LuaUPnP::HandleActionRequest argument BrowseFlag=BrowseDirectChildren <0x2e2a3680>
08      04/18/12 20:22:14.504   JobHandler_LuaUPnP::HandleActionRequest argument Filter=* <0x2e2a3680>
08      04/18/12 20:22:14.504   JobHandler_LuaUPnP::HandleActionRequest argument StartingIndex=0 <0x2e2a3680>
08      04/18/12 20:22:14.504   JobHandler_LuaUPnP::HandleActionRequest argument RequestedCount=10 <0x2e2a3680>
08      04/18/12 20:22:14.504   JobHandler_LuaUPnP::HandleActionRequest argument SortCriteria='' <0x2e2a3680>
50      04/18/12 20:22:14.536   luup_log:0: ---------------------------------- httpStatusCode*0 <0x2eca3680>
50      04/18/12 20:22:14.536   luup_log:0: ---------------------------------- content*<?xml version="1.0"?>^M
<u:BrowseResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">^M
<Result>&lt;DIDL-Lite xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0/upnp/&quot; xmlns=&quot;urn:sch
&lt;container id=&quot;6&quot; restricted=&quot;1&quot; parentID=&quot;0&quot;&gt;&lt;dc:title&gt;Artists&lt;/dc:title&gt;&lt;upnp:class&gt;object.container&l
<NumberReturned>8</NumberReturned>^M
<TotalMatches>8</TotalMatches>^M
<UpdateID>1334084267</UpdateID>^M
</u:BrowseResponse>^M
 <0x2eca3680>
50      04/18/12 20:22:14.537   luup_log:0: ---------------------------------- END <0x2eca3680>

Summary:
[tt]luup.call_action[/tt]: not usable due to arbitrary table order
[tt]http[/tt] request: OK

Question:
Is there a workaround for [tt]luup.call_action[/tt]?

I stopped filing bug reports a long time ago … AFAIK, you can signup for a Mantis account at [tt]http://bugs.micasaverde.com/signup_page.php[/tt].

Bug# 2329.

Just for reference:

Excerpt from UPnP™ Device Architecture 1.1:

<argumentName>
REQUIRED if and only if action has in arguments. Value to be passed to action. Repeat once for
each in argument. (An element name is not qualified by a namespace; element nesting
context is sufficient.) Case sensitive. Single data type as defined by UPnP service description.
Every “in” argument in the definition of the action in the service description MUST be
included, in the same order as specified in the service description (SCPD) that is available
from the device.

Please note that [tt]UPnP[/tt] actions defined in [tt]D_*.json[/tt] files might be affected as well (parameters for actions on tabs are defined by an ordered list of parameters, parameters for actions within [tt]sceneList[/tt]s are defined by an unordered collection of arguments.

Edit:
… and [tt]UPnP[/tt] actions defined via the ‘Advanced’ tab of scenes might be affected as well.