summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp')
-rw-r--r--lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp
new file mode 100644
index 0000000..ccac60d
--- /dev/null
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaConnect/PltMediaConnect.cpp
@@ -0,0 +1,348 @@
+/*****************************************************************
+|
+| Platinum - AV Media Connect Device
+|
+| 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 "Platinum.h"
+#include "PltMediaConnect.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.devices.mediaconnect")
+
+/*----------------------------------------------------------------------
+| forward references
++---------------------------------------------------------------------*/
+extern NPT_UInt8 X_MS_MediaReceiverRegistrarSCPD[];
+extern NPT_UInt8 MS_ContentDirectorySCPD[];
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::PLT_MediaConnect
++---------------------------------------------------------------------*/
+PLT_MediaConnect::PLT_MediaConnect(const char* friendly_name,
+ bool add_hostname /* = true */,
+ const char* udn /* = NULL */,
+ NPT_UInt16 port /* = 0 */,
+ bool port_rebind /* = false */) :
+ PLT_MediaServer(friendly_name, false, udn, port, port_rebind),
+ m_AddHostname(add_hostname)
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::~PLT_MediaConnect
++---------------------------------------------------------------------*/
+PLT_MediaConnect::~PLT_MediaConnect()
+{
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::SetupServices
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::SetupServices()
+{
+ NPT_Reference<PLT_Service> service(new PLT_Service(
+ this,
+ "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
+ "urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar",
+ "X_MS_MediaReceiverRegistrar"));
+
+ NPT_CHECK_FATAL(service->SetSCPDXML((const char*) X_MS_MediaReceiverRegistrarSCPD));
+ NPT_CHECK_FATAL(AddService(service.AsPointer()));
+
+ service->SetStateVariable("AuthorizationGrantedUpdateID", "1");
+ service->SetStateVariable("AuthorizationDeniedUpdateID", "1");
+ service->SetStateVariable("ValidationSucceededUpdateID", "0");
+ service->SetStateVariable("ValidationRevokedUpdateID", "0");
+
+ service.Detach();
+ return PLT_MediaServer::SetupServices();
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::ProcessGetDescription
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::ProcessGetDescription(NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response)
+{
+ // lock to make sure another request is not modifying the device while we are already
+ NPT_AutoLock lock(m_Lock);
+
+ NPT_Result res = NPT_SUCCESS;
+ NPT_String oldModelName = m_ModelName;
+ NPT_String oldModelNumber = m_ModelNumber;
+ NPT_String oldModelURL = m_ModelURL;
+ NPT_String oldManufacturerURL = m_ManufacturerURL;
+ NPT_String oldDlnaDoc = m_DlnaDoc;
+ NPT_String oldDlnaCap = m_DlnaCap;
+ NPT_String oldAggregationFlags = m_AggregationFlags;
+ NPT_String oldFriendlyName = m_FriendlyName;
+
+ NPT_String hostname;
+ NPT_System::GetMachineName(hostname);
+
+ PLT_DeviceSignature signature = PLT_HttpHelper::GetDeviceSignature(request);
+
+ if (signature == PLT_DEVICE_XBOX_360 || signature == PLT_DEVICE_XBOX_ONE /*|| signature == PLT_SONOS*/) {
+ // XBox needs to see something behind a ':' to even show it
+ if (m_AddHostname && hostname.GetLength() > 0) {
+ m_FriendlyName += ": " + hostname;
+ } else if (m_FriendlyName.Find(":") == -1) {
+ m_FriendlyName += ": 1";
+ }
+ }
+ else if (m_AddHostname && hostname.GetLength() > 0) {
+ m_FriendlyName += " (" + hostname + ")";
+ }
+
+ // change some things based on device signature from request
+ if (signature == PLT_DEVICE_XBOX_360 || signature == PLT_DEVICE_XBOX_ONE || signature == PLT_DEVICE_WMP /*|| signature == PLT_SONOS*/) {
+ m_ModelName = "Windows Media Player Sharing";
+ m_ModelNumber = (signature == PLT_DEVICE_SONOS)?"3.0":"12.0";
+ m_ModelURL = "http://www.microsoft.com/";//"http://go.microsoft.com/fwlink/?LinkId=105926";
+ m_Manufacturer = (signature == PLT_DEVICE_SONOS)?"Microsoft":"Microsoft Corporation";
+ m_ManufacturerURL = "http://www.microsoft.com/";
+ m_DlnaDoc = (signature == PLT_DEVICE_SONOS)?"DMS-1.00":"DMS-1.50";
+ m_DlnaCap = "";
+ m_AggregationFlags = "";
+
+ //PLT_UPnPMessageHelper::GenerateGUID(m_SerialNumber);
+ // TODO: http://msdn.microsoft.com/en-us/library/ff362657(PROT.10).aspx
+ // TODO: <serialNumber>GUID</serialNumber>
+
+ } else if (signature == PLT_DEVICE_SONOS) {
+ m_ModelName = "Rhapsody";
+ m_ModelNumber = "3.0";
+ } else if (signature == PLT_DEVICE_PS3) {
+ m_DlnaDoc = "DMS-1.50";
+ m_DlnaCap = "";
+ m_AggregationFlags = "10";
+ }
+
+ // return description with modified params
+ res = PLT_MediaServer::ProcessGetDescription(request, context, response);
+
+ // reset to old values now
+ m_FriendlyName = oldFriendlyName;
+ m_ModelName = oldModelName;
+ m_ModelNumber = oldModelNumber;
+ m_ModelURL = oldModelURL;
+ m_ManufacturerURL = oldManufacturerURL;
+ m_DlnaDoc = oldDlnaDoc;
+ m_DlnaCap = oldDlnaCap;
+ m_AggregationFlags = oldAggregationFlags;
+
+ return res;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::ProcessGetSCPD
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::ProcessGetSCPD(PLT_Service* service,
+ NPT_HttpRequest& request,
+ const NPT_HttpRequestContext& context,
+ NPT_HttpResponse& response)
+{
+ PLT_DeviceSignature signature = PLT_HttpHelper::GetDeviceSignature(request);
+
+ // Override SCPD response by providing an SCPD without a Search action
+ // to all devices except XBox or WMP which need it
+ if (service->GetServiceType() == "urn:schemas-upnp-org:service:ContentDirectory:1" &&
+ signature != PLT_DEVICE_XBOX_360 &&
+ signature != PLT_DEVICE_XBOX_ONE &&
+ signature != PLT_DEVICE_WMP &&
+ signature != PLT_DEVICE_SONOS) {
+ NPT_HttpEntity* entity;
+ PLT_HttpHelper::SetBody(response, (const char*) MS_ContentDirectorySCPD, &entity);
+ entity->SetContentType("text/xml; charset=\"utf-8\"");
+ return NPT_SUCCESS;
+ }
+
+ return PLT_MediaServer::ProcessGetSCPD(service, request, context, response);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnAction
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnAction(PLT_ActionReference& action,
+
+ const PLT_HttpRequestContext& context)
+{
+ /* parse the action name */
+ NPT_String name = action->GetActionDesc().GetName();
+
+ /* handle X_MS_MediaReceiverRegistrar actions here */
+ if (name.Compare("IsAuthorized") == 0) {
+ return OnIsAuthorized(action);
+ }
+ if (name.Compare("RegisterDevice") == 0) {
+ return OnRegisterDevice(action);
+ }
+ if (name.Compare("IsValidated") == 0) {
+ return OnIsValidated(action);
+ }
+
+ return PLT_MediaServer::OnAction(action, context);
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnIsAuthorized
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnIsAuthorized(PLT_ActionReference& action)
+{
+ NPT_CHECK_WARNING(action->SetArgumentValue("Result", "1"));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnRegisterDevice
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnRegisterDevice(PLT_ActionReference& action)
+{
+ NPT_String reqMsgBase64;
+ NPT_CHECK_WARNING(action->GetArgumentValue("RegistrationReqMsg", reqMsgBase64));
+
+ NPT_String respMsgBase64;
+ NPT_CHECK_WARNING(action->SetArgumentValue("RegistrationRespMsg", respMsgBase64));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::OnIsValidated
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::OnIsValidated(PLT_ActionReference& action)
+{
+ NPT_CHECK_WARNING(action->SetArgumentValue("Result", "1"));
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_MediaConnect::GetMappedObjectId
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_MediaConnect::GetMappedObjectId(const char* object_id, NPT_String& mapped_object_id)
+{
+ if (!object_id) return NPT_ERROR_INVALID_PARAMETERS;
+
+ // Reroute XBox 360 and WMP requests to our route
+ if (NPT_StringsEqual(object_id, "15")) {
+ mapped_object_id = "0/Videos"; // Videos
+ } else if (NPT_StringsEqual(object_id, "16")) {
+ mapped_object_id = "0/Photos"; // Photos
+ } else {
+ mapped_object_id = object_id;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaConnectDelegate::GetFilePath
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaConnectDelegate::GetFilePath(const char* object_id, NPT_String& filepath)
+{
+ if (!object_id) return NPT_ERROR_INVALID_PARAMETERS;
+
+ // Reroute XBox 360 and WMP requests to our route
+ if (NPT_StringsEqual(object_id, "15")) {
+ return PLT_FileMediaServerDelegate::GetFilePath("", filepath); // Videos
+ } else if (NPT_StringsEqual(object_id, "16")) {
+ return PLT_FileMediaServerDelegate::GetFilePath("", filepath); // Photos
+ } else if (NPT_StringsEqual(object_id, "13") || NPT_StringsEqual(object_id, "4")) {
+ return PLT_FileMediaServerDelegate::GetFilePath("", filepath); // Music
+ }
+
+ return PLT_FileMediaServerDelegate::GetFilePath(object_id, filepath);;
+}
+
+/*----------------------------------------------------------------------
+| PLT_FileMediaConnectDelegate::OnSearchContainer
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_FileMediaConnectDelegate::OnSearchContainer(PLT_ActionReference& action,
+ const char* object_id,
+ const char* search_criteria,
+ const char* filter,
+ NPT_UInt32 starting_index,
+ NPT_UInt32 requested_count,
+ const char* sort_criteria,
+ const PLT_HttpRequestContext& context)
+{
+ /* parse search criteria */
+
+ /* TODO: HACK TO PASS DLNA */
+ if (search_criteria && NPT_StringsEqual(search_criteria, "Unknownfieldname")) {
+ /* error */
+ NPT_LOG_WARNING_1("Unsupported or invalid search criteria %s", search_criteria);
+ action->SetError(708, "Unsupported or invalid search criteria");
+ return NPT_FAILURE;
+ }
+
+ /* locate the file from the object ID */
+ NPT_String dir;
+ if (NPT_FAILED(GetFilePath(object_id, dir))) {
+ /* error */
+ NPT_LOG_WARNING("ObjectID not found.");
+ action->SetError(710, "No Such Container.");
+ return NPT_FAILURE;
+ }
+
+ /* retrieve the item type */
+ NPT_FileInfo info;
+ NPT_Result res = NPT_File::GetInfo(dir, &info);
+ if (NPT_FAILED(res) || (info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY)) {
+ /* error */
+ NPT_LOG_WARNING("No such container");
+ action->SetError(710, "No such container");
+ return NPT_FAILURE;
+ }
+
+ /* hack for now to return something back to XBox 360 */
+ return OnBrowseDirectChildren(action,
+ object_id,
+ filter,
+ starting_index,
+ requested_count,
+ sort_criteria,
+ context);
+}