diff options
Diffstat (limited to 'lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp')
-rw-r--r-- | lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp | 1392 |
1 files changed, 1392 insertions, 0 deletions
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp new file mode 100644 index 0000000..87aabf3 --- /dev/null +++ b/lib/libUPnP/Platinum/Source/Devices/MediaRenderer/PltMediaController.cpp @@ -0,0 +1,1392 @@ +/***************************************************************** +| +| Platinum - AV Media Controller (Media Renderer Control Point) +| +| Copyright (c) 2004-2010, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| licensing@plutinosoft.com +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltMediaController.h" +#include "PltDidl.h" +#include "PltDeviceData.h" +#include "PltUtilities.h" + +NPT_SET_LOCAL_LOGGER("platinum.media.renderer.controller") + +/*---------------------------------------------------------------------- +| PLT_MediaController::PLT_MediaController ++---------------------------------------------------------------------*/ +PLT_MediaController::PLT_MediaController(PLT_CtrlPointReference& ctrl_point, + PLT_MediaControllerDelegate* delegate /* = NULL */) : + m_CtrlPoint(ctrl_point), + m_Delegate(delegate) +{ + m_CtrlPoint->AddListener(this); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::~PLT_MediaController ++---------------------------------------------------------------------*/ +PLT_MediaController::~PLT_MediaController() +{ + m_CtrlPoint->RemoveListener(this); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnDeviceAdded ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnDeviceAdded(PLT_DeviceDataReference& device) +{ + // verify the device implements the function we need + PLT_Service* serviceAVT = NULL; + PLT_Service* serviceCMR; + PLT_Service* serviceRC; + NPT_String type; + + if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer")) + return NPT_FAILURE; + + // optional service + type = "urn:schemas-upnp-org:service:AVTransport:*"; + if (NPT_SUCCEEDED(device->FindServiceByType(type, serviceAVT))) { + // in case it's a newer upnp implementation, force to 1 + NPT_LOG_FINE_1("Service %s found", (const char*)type); + serviceAVT->ForceVersion(1); + } + + // required services + type = "urn:schemas-upnp-org:service:ConnectionManager:*"; + if (NPT_FAILED(device->FindServiceByType(type, serviceCMR))) { + NPT_LOG_FINE_1("Service %s not found", (const char*)type); + return NPT_FAILURE; + } else { + // in case it's a newer upnp implementation, force to 1 + serviceCMR->ForceVersion(1); + } + + type = "urn:schemas-upnp-org:service:RenderingControl:*"; + if (NPT_FAILED(device->FindServiceByType(type, serviceRC))) { + NPT_LOG_FINE_1("Service %s not found", (const char*)type); + return NPT_FAILURE; + } else { + // in case it's a newer upnp implementation, force to 1 + serviceRC->ForceVersion(1); + } + + { + NPT_AutoLock lock(m_MediaRenderers); + + PLT_DeviceDataReference data; + NPT_String uuid = device->GetUUID(); + + // is it a new device? + if (NPT_SUCCEEDED(NPT_ContainerFind(m_MediaRenderers, + PLT_DeviceDataFinder(uuid), data))) { + NPT_LOG_WARNING_1("Device (%s) is already in our list!", (const char*)uuid); + return NPT_FAILURE; + } + + NPT_LOG_FINE_1("Device Found: %s", (const char*)*device); + + m_MediaRenderers.Add(device); + } + + if (m_Delegate && m_Delegate->OnMRAdded(device)) { + // subscribe to services eventing only if delegate wants it + if (serviceAVT) m_CtrlPoint->Subscribe(serviceAVT); + + // subscribe to required services + m_CtrlPoint->Subscribe(serviceCMR); + m_CtrlPoint->Subscribe(serviceRC); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnDeviceRemoved ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnDeviceRemoved(PLT_DeviceDataReference& device) +{ + if (!device->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer")) + return NPT_FAILURE; + + { + NPT_AutoLock lock(m_MediaRenderers); + + // only release if we have kept it around + PLT_DeviceDataReference data; + NPT_String uuid = device->GetUUID(); + + // Have we seen that device? + if (NPT_FAILED(NPT_ContainerFind(m_MediaRenderers, PLT_DeviceDataFinder(uuid), data))) { + NPT_LOG_WARNING_1("Device (%s) not found in our list!", (const char*)uuid); + return NPT_FAILURE; + } + + NPT_LOG_FINE_1("Device Removed: %s", (const char*)*device); + + m_MediaRenderers.Remove(device); + } + + if (m_Delegate) { + m_Delegate->OnMRRemoved(device); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::FindRenderer ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::FindRenderer(const char* uuid, PLT_DeviceDataReference& device) +{ + NPT_AutoLock lock(m_MediaRenderers); + + if (NPT_FAILED(NPT_ContainerFind(m_MediaRenderers, PLT_DeviceDataFinder(uuid), device))) { + NPT_LOG_FINE_1("Device (%s) not found in our list of renderers", (const char*)uuid); + return NPT_FAILURE; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetProtocolInfoSink ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetProtocolInfoSink(const NPT_String& device_uuid, + NPT_List<NPT_String>& sinks) +{ + PLT_DeviceDataReference renderer; + NPT_CHECK_WARNING(FindRenderer(device_uuid, renderer)); + + // look for ConnectionManager service + PLT_Service* serviceCMR; + NPT_CHECK_SEVERE(renderer->FindServiceByType("urn:schemas-upnp-org:service:ConnectionManager:*", + serviceCMR)); + + NPT_String value; + NPT_CHECK_SEVERE(serviceCMR->GetStateVariableValue("SinkProtocolInfo", + value)); + + sinks = value.Split(","); + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetTransportState ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetTransportState(const NPT_String& device_uuid, + NPT_String& state) +{ + PLT_DeviceDataReference renderer; + NPT_CHECK_WARNING(FindRenderer(device_uuid, renderer)); + + // look for AVTransport service + PLT_Service* serviceAVT; + NPT_CHECK_SEVERE(renderer->FindServiceByType("urn:schemas-upnp-org:service:AVTransport:*", + serviceAVT)); + + NPT_CHECK_SEVERE(serviceAVT->GetStateVariableValue("TransportState", + state)); + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetVolumeState ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetVolumeState(const NPT_String& device_uuid, + NPT_UInt32& volume) +{ + PLT_DeviceDataReference renderer; + NPT_CHECK_WARNING(FindRenderer(device_uuid, renderer)); + + // look for RenderingControl service + PLT_Service* serviceRC; + NPT_CHECK_SEVERE(renderer->FindServiceByType("urn:schemas-upnp-org:service:RenderingControl:*", + serviceRC)); + + NPT_String value; + NPT_CHECK_SEVERE(serviceRC->GetStateVariableValue("Volume", + value)); + + return value.ToInteger32(volume); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::FindMatchingProtocolInfo ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::FindMatchingProtocolInfo(NPT_List<NPT_String>& sinks, + const char* protocol_info) +{ + PLT_ProtocolInfo protocol(protocol_info); + for (NPT_List<NPT_String>::Iterator iter = sinks.GetFirstItem(); + iter; + iter++) { + PLT_ProtocolInfo sink(*iter); + if (sink.Match(protocol)) { + return NPT_SUCCESS; + } + } + + return NPT_ERROR_NO_SUCH_ITEM; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::FindBestResource ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::FindBestResource(PLT_DeviceDataReference& device, + PLT_MediaObject& item, + NPT_Cardinal& resource_index) +{ + if (item.m_Resources.GetItemCount() <= 0) return NPT_ERROR_INVALID_PARAMETERS; + + NPT_List<NPT_String> sinks; + NPT_CHECK_SEVERE(GetProtocolInfoSink(device->GetUUID(), sinks)); + + // look for best resource + for (NPT_Cardinal i=0; i< item.m_Resources.GetItemCount(); i++) { + if (NPT_SUCCEEDED(FindMatchingProtocolInfo( + sinks, + item.m_Resources[i].m_ProtocolInfo.ToString()))) { + resource_index = i; + return NPT_SUCCESS; + } + } + + return NPT_ERROR_NO_SUCH_ITEM; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::InvokeActionWithInstance ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::InvokeActionWithInstance(PLT_ActionReference& action, + NPT_UInt32 instance_id, + void* userdata) +{ + // Set the object id + NPT_CHECK_SEVERE(action->SetArgumentValue( + "InstanceID", + NPT_String::FromInteger(instance_id))); + + // set the arguments on the action, this will check the argument values + return m_CtrlPoint->InvokeAction(action, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetCurrentTransportActions ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetCurrentTransportActions(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "GetCurrentTransportActions", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetDeviceCapabilities ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetDeviceCapabilities(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "GetDeviceCapabilities", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetMediaInfo ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetMediaInfo(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "GetMediaInfo", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetPositionInfo ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetPositionInfo(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "GetPositionInfo", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetTransportInfo ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetTransportInfo(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "GetTransportInfo", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetTransportSettings ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetTransportSettings(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "GetTransportSettings", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::Next ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::Next(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "Next", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::Pause ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::Pause(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "Pause", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::Play ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::Play(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + NPT_String speed, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "Play", + action)); + + // Set the speed + if (NPT_FAILED(action->SetArgumentValue("Speed", speed))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::Previous ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::Previous(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "Previous", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::Seek ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::Seek(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + NPT_String unit, + NPT_String target, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "Seek", + action)); + + // Set the unit + if (NPT_FAILED(action->SetArgumentValue("Unit", unit))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + // Set the target + if (NPT_FAILED(action->SetArgumentValue("Target", target))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::CanSetNextAVTransportURI ++---------------------------------------------------------------------*/ +bool +PLT_MediaController::CanSetNextAVTransportURI(PLT_DeviceDataReference &device) +{ + if (device.IsNull()) return false; + + PLT_ActionDesc* action_desc; + NPT_Result result = m_CtrlPoint->FindActionDesc(device, + "urn:schemas-upnp-org:service:AVTransport:1", + "SetNextAVTransportURI", + action_desc); + return (result == NPT_SUCCESS); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::SetAVTransportURI ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::SetAVTransportURI(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + const char* uri, + const char* metadata, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "SetAVTransportURI", + action)); + + // set the uri + if (NPT_FAILED(action->SetArgumentValue("CurrentURI", uri))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + // set the uri metadata + if (NPT_FAILED(action->SetArgumentValue("CurrentURIMetaData", metadata))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::SetNextAVTransportURI ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::SetNextAVTransportURI(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + const char* next_uri, + const char* next_metadata, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction(device, + "urn:schemas-upnp-org:service:AVTransport:1", + "SetNextAVTransportURI", + action)); + + // set the uri + if (NPT_FAILED(action->SetArgumentValue("NextURI", next_uri))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + // set the uri metadata + if (NPT_FAILED(action->SetArgumentValue("NextURIMetaData", next_metadata))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::SetPlayMode ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::SetPlayMode(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + NPT_String new_play_mode, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "SetPlayMode", + action)); + + // set the New PlayMode + if (NPT_FAILED(action->SetArgumentValue("NewPlayMode", new_play_mode))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::Stop ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::Stop(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:AVTransport:1", + "Stop", + action)); + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetCurrentConnectionIDs ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetCurrentConnectionIDs(PLT_DeviceDataReference& device, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:ConnectionManager:1", + "GetCurrentConnectionIDs", + action)); + + // set the arguments on the action, this will check the argument values + if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetCurrentConnectionInfo ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetCurrentConnectionInfo(PLT_DeviceDataReference& device, + NPT_UInt32 connection_id, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:ConnectionManager:1", + "GetCurrentConnectionInfo", + action)); + + // set the New PlayMode + if (NPT_FAILED(action->SetArgumentValue("ConnectionID", + NPT_String::FromInteger(connection_id)))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + // set the arguments on the action, this will check the argument values + if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetProtocolInfo ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetProtocolInfo(PLT_DeviceDataReference& device, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:ConnectionManager:1", + "GetProtocolInfo", + action)); + + // set the arguments on the action, this will check the argument values + if (NPT_FAILED(m_CtrlPoint->InvokeAction(action, userdata))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::SetMute ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::SetMute(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + const char* channel, + bool mute, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:RenderingControl:1", + "SetMute", + action)); + + // set the channel + if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + // set the channel + if (NPT_FAILED(action->SetArgumentValue("DesiredMute", + mute?"1":"0"))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::SetVolume ++---------------------------------------------------------------------*/ +NPT_Result PLT_MediaController::SetVolume(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + const char* channel, + int volume, + void* userdata) +{ + + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:RenderingControl:1", + "SetVolume", + action)); + + // set the channel + if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + if (NPT_FAILED(action->SetArgumentValue("DesiredVolume", + NPT_String::FromInteger(volume)))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetMute ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::GetMute(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + const char* channel, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:RenderingControl:1", + "GetMute", + action)); + + // set the channel + if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::GetVolume ++---------------------------------------------------------------------*/ +NPT_Result PLT_MediaController::GetVolume(PLT_DeviceDataReference& device, + NPT_UInt32 instance_id, + const char* channel, + void* userdata) +{ + PLT_ActionReference action; + NPT_CHECK_SEVERE(m_CtrlPoint->CreateAction( + device, + "urn:schemas-upnp-org:service:RenderingControl:1", + "GetVolume", + action)); + + // set the channel + if (NPT_FAILED(action->SetArgumentValue("Channel", channel))) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + return InvokeActionWithInstance(action, instance_id, userdata); +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnActionResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnActionResponse(NPT_Result res, + PLT_ActionReference& action, + void* userdata) +{ + if (m_Delegate == NULL) return NPT_SUCCESS; + + PLT_DeviceDataReference device; + NPT_String uuid = action->GetActionDesc().GetService()->GetDevice()->GetUUID(); + + /* extract action name */ + NPT_String actionName = action->GetActionDesc().GetName(); + + /* AVTransport response ? */ + if (actionName.Compare("GetCurrentTransportActions", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetCurrentTransportActionsResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetDeviceCapabilities", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetDeviceCapabilitiesResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetMediaInfo", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetMediaInfoResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetPositionInfo", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetPositionInfoResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetTransportInfo", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetTransportInfoResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetTransportSettings", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetTransportSettingsResponse(res, device, action, userdata); + } + else if (actionName.Compare("Next", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnNextResult(res, device, userdata); + } + else if (actionName.Compare("Pause", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnPauseResult(res, device, userdata); + } + else if (actionName.Compare("Play", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnPlayResult(res, device, userdata); + } + else if (actionName.Compare("Previous", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnPreviousResult(res, device, userdata); + } + else if (actionName.Compare("Seek", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnSeekResult(res, device, userdata); + } + else if (actionName.Compare("SetAVTransportURI", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnSetAVTransportURIResult(res, device, userdata); + } + else if (actionName.Compare("SetNextAVTransportURI", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnSetNextAVTransportURIResult(res, device, userdata); + } + else if (actionName.Compare("SetPlayMode", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnSetPlayModeResult(res, device, userdata); + } + else if (actionName.Compare("Stop", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnStopResult(res, device, userdata); + } + else if (actionName.Compare("GetCurrentConnectionIDs", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetCurrentConnectionIDsResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetCurrentConnectionInfo", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetCurrentConnectionInfoResponse(res, device, action, userdata); + } + else if (actionName.Compare("GetProtocolInfo", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetProtocolInfoResponse(res, device, action, userdata); + } + else if (actionName.Compare("SetMute", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnSetMuteResult(res, device, userdata); + } + else if (actionName.Compare("GetMute", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetMuteResponse(res, device, action, userdata); + } + else if (actionName.Compare("SetVolume", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + m_Delegate->OnSetVolumeResult(res, device, userdata); + } + else if (actionName.Compare("GetVolume", true) == 0) { + if (NPT_FAILED(FindRenderer(uuid, device))) res = NPT_FAILURE; + return OnGetVolumeResponse(res, device, action, userdata); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetCurrentTransportActionsResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetCurrentTransportActionsResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String actions; + PLT_StringList values; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("Actions", actions))) { + goto bad_action; + } + + // parse the list of actions and return a list to listener + ParseCSV(actions, values); + + m_Delegate->OnGetCurrentTransportActionsResult(NPT_SUCCESS, device, &values, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetCurrentTransportActionsResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetDeviceCapabilitiesResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetDeviceCapabilitiesResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String value; + PLT_DeviceCapabilities capabilities; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("PlayMedia", value))) { + goto bad_action; + } + // parse the list of medias and return a list to listener + ParseCSV(value, capabilities.play_media); + + if (NPT_FAILED(action->GetArgumentValue("RecMedia", value))) { + goto bad_action; + } + // parse the list of rec and return a list to listener + ParseCSV(value, capabilities.rec_media); + + if (NPT_FAILED(action->GetArgumentValue("RecQualityModes", value))) { + goto bad_action; + } + // parse the list of modes and return a list to listener + ParseCSV(value, capabilities.rec_quality_modes); + + m_Delegate->OnGetDeviceCapabilitiesResult(NPT_SUCCESS, device, &capabilities, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetDeviceCapabilitiesResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetMediaInfoResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetMediaInfoResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String value; + PLT_MediaInfo info; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("NrTracks", info.num_tracks))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("MediaDuration", value))) { + goto bad_action; + } + if (NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.media_duration))) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("CurrentURI", info.cur_uri))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("CurrentURIMetaData", info.cur_metadata))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("NextURI", info.next_uri))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("NextURIMetaData", info.next_metadata))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("PlayMedium", info.play_medium))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("RecordMedium", info.rec_medium))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("WriteStatus", info.write_status))) { + goto bad_action; + } + + m_Delegate->OnGetMediaInfoResult(NPT_SUCCESS, device, &info, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetMediaInfoResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetPositionInfoResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetPositionInfoResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String value; + PLT_PositionInfo info; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("Track", info.track))) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("TrackDuration", value))) { + goto bad_action; + } + if (NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.track_duration))) { + // some renderers return garbage sometimes + info.track_duration = NPT_TimeStamp(0.); + } + + if (NPT_FAILED(action->GetArgumentValue("TrackMetaData", info.track_metadata))) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("TrackURI", info.track_uri))) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("RelTime", value))) { + goto bad_action; + } + + // NOT_IMPLEMENTED is a valid value according to spec + if (value != "NOT_IMPLEMENTED" && NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.rel_time))) { + // some dogy renderers return garbage sometimes + info.rel_time = NPT_TimeStamp(-1.0f); + } + + if (NPT_FAILED(action->GetArgumentValue("AbsTime", value))) { + goto bad_action; + } + + // NOT_IMPLEMENTED is a valid value according to spec + if (value != "NOT_IMPLEMENTED" && NPT_FAILED(PLT_Didl::ParseTimeStamp(value, info.abs_time))) { + // some dogy renderers return garbage sometimes + info.abs_time = NPT_TimeStamp(-1.0f); + } + + if (NPT_FAILED(action->GetArgumentValue("RelCount", info.rel_count))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("AbsCount", info.abs_count))) { + goto bad_action; + } + + m_Delegate->OnGetPositionInfoResult(NPT_SUCCESS, device, &info, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetPositionInfoResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetTransportInfoResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetTransportInfoResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + PLT_TransportInfo info; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("CurrentTransportState", info.cur_transport_state))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("CurrentTransportStatus", info.cur_transport_status))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("CurrentSpeed", info.cur_speed))) { + goto bad_action; + } + + m_Delegate->OnGetTransportInfoResult(NPT_SUCCESS, device, &info, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetTransportInfoResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetTransportSettingsResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetTransportSettingsResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + PLT_TransportSettings settings; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("PlayMode", settings.play_mode))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("RecQualityMode", settings.rec_quality_mode))) { + goto bad_action; + } + + m_Delegate->OnGetTransportSettingsResult(NPT_SUCCESS, device, &settings, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetTransportSettingsResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetCurrentConnectionIDsResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetCurrentConnectionIDsResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String value; + PLT_StringList IDs; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("ConnectionIDs", value))) { + goto bad_action; + } + // parse the list of medias and return a list to listener + ParseCSV(value, IDs); + + m_Delegate->OnGetCurrentConnectionIDsResult(NPT_SUCCESS, device, &IDs, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetCurrentConnectionIDsResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetCurrentConnectionInfoResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetCurrentConnectionInfoResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String value; + PLT_ConnectionInfo info; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("RcsID", info.rcs_id))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("AVTransportID", info.avtransport_id))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("ProtocolInfo", info.protocol_info))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("PeerConnectionManager", info.peer_connection_mgr))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("PeerConnectionID", info.peer_connection_id))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("Direction", info.direction))) { + goto bad_action; + } + if (NPT_FAILED(action->GetArgumentValue("Status", info.status))) { + goto bad_action; + } + m_Delegate->OnGetCurrentConnectionInfoResult(NPT_SUCCESS, device, &info, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetCurrentConnectionInfoResult(NPT_FAILURE, device, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetProtocolInfoResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetProtocolInfoResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String source_info, sink_info; + PLT_StringList sources, sinks; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("Source", source_info))) { + goto bad_action; + } + ParseCSV(source_info, sources); + + if (NPT_FAILED(action->GetArgumentValue("Sink", sink_info))) { + goto bad_action; + } + ParseCSV(sink_info, sinks); + + m_Delegate->OnGetProtocolInfoResult(NPT_SUCCESS, device, &sources, &sinks, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetProtocolInfoResult(NPT_FAILURE, device, NULL, NULL, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetMuteResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetMuteResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String channel, mute; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("Channel", channel))) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("CurrentMute", mute))) { + goto bad_action; + } + + m_Delegate->OnGetMuteResult( + NPT_SUCCESS, + device, + channel, + PLT_Service::IsTrue(mute)?true:false, + userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetMuteResult(NPT_FAILURE, device, "", false, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnGetVolumeResponse ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnGetVolumeResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata) +{ + NPT_String channel; + NPT_String current_volume; + NPT_UInt32 volume; + + if (NPT_FAILED(res) || action->GetErrorCode() != 0) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("Channel", channel))) { + goto bad_action; + } + + if (NPT_FAILED(action->GetArgumentValue("CurrentVolume", current_volume))) { + goto bad_action; + } + + if (NPT_FAILED(current_volume.ToInteger(volume))) { + goto bad_action; + } + + m_Delegate->OnGetVolumeResult(NPT_SUCCESS, device, channel, volume, userdata); + return NPT_SUCCESS; + +bad_action: + m_Delegate->OnGetVolumeResult(NPT_FAILURE, device, "", 0, userdata); + return NPT_FAILURE; +} + +/*---------------------------------------------------------------------- +| PLT_MediaController::OnEventNotify ++---------------------------------------------------------------------*/ +NPT_Result +PLT_MediaController::OnEventNotify(PLT_Service* service, + NPT_List<PLT_StateVariable*>* vars) +{ + if (!service->GetDevice()->GetType().StartsWith("urn:schemas-upnp-org:device:MediaRenderer")) + return NPT_FAILURE; + + if (!m_Delegate) return NPT_SUCCESS; + + /* make sure device associated to service is still around */ + PLT_DeviceDataReference data; + NPT_CHECK_WARNING(FindRenderer(service->GetDevice()->GetUUID(), data)); + + m_Delegate->OnMRStateVariablesChanged(service, vars); + return NPT_SUCCESS; +} |