bool CUPnPPlayer::QueueNextFile(const CFileItem& file) { CFileItem item(file); NPT_Reference<CThumbLoader> thumb_loader; NPT_Reference<PLT_MediaObject> obj; NPT_String path(file.GetPath().c_str()); NPT_String tmp; if (file.IsVideoDb()) thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader()); else if (item.IsMusicDb()) thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader()); obj = BuildObject(item, path, 0, thumb_loader, NULL, CUPnP::GetServer(), UPnPPlayer); if(!obj.IsNull()) { NPT_CHECK_LABEL_SEVERE(PLT_Didl::ToDidl(*obj, "", tmp), failed); tmp.Insert(didl_header, 0); tmp.Append(didl_footer); } NPT_CHECK_LABEL_WARNING(m_control->SetNextAVTransportURI(m_delegate->m_device , m_delegate->m_instance , file.GetPath().c_str() , (const char*)tmp , m_delegate), failed); if(!m_delegate->m_resevent.WaitMSec(10000)) goto failed; NPT_CHECK_LABEL_WARNING(m_delegate->m_resstatus, failed); return true; failed: CLog::Log(LOGERROR, "UPNP: CUPnPPlayer::QueueNextFile - unable to queue file %s", file.GetPath().c_str()); return false; }
NPT_Result GPAC_MediaController::Browse(GPAC_MediaServerItem *server, const char *object_id, const char *filter) { NPT_Result res = NPT_FAILURE; NPT_Int32 index = 0; // reset output params server->m_BrowseResults = NULL; do { PLT_BrowseDataReference browse_data(new PLT_BrowseData()); // send off the browse packet. Note that this will // not block. There is a call to WaitForResponse in order // to block until the response comes back. res = Browse(browse_data, server->m_device, (const char*)object_id, index, 1024, false, filter, ""); NPT_CHECK_LABEL_WARNING(res, done); if (NPT_FAILED(browse_data->res)) { res = browse_data->res; NPT_CHECK_LABEL_WARNING(res, done); } if (browse_data->info.items->GetItemCount() == 0) break; if (server->m_BrowseResults.IsNull()) { server->m_BrowseResults = browse_data->info.items; } else { server->m_BrowseResults->Add(*browse_data->info.items); // clear the list items so that the data inside is not // cleaned up by PLT_MediaItemList dtor since we copied // each pointer into the new list. browse_data->info.items->Clear(); } // stop now if our list contains exactly what the server said it had if (browse_data->info.tm && browse_data->info.tm == server->m_BrowseResults->GetItemCount()) break; // ask for the next chunk of entries index = server->m_BrowseResults->GetItemCount(); } while(1); done: return res; }
/*---------------------------------------------------------------------- | PLT_SsdpDeviceSearchResponseTask::DoRun() +---------------------------------------------------------------------*/ void PLT_SsdpDeviceSearchResponseTask::DoRun() { NPT_List<NPT_NetworkInterface*> if_list; NPT_CHECK_LABEL_WARNING(PLT_UPnPMessageHelper::GetNetworkInterfaces(if_list), done); if_list.Apply(PLT_SsdpDeviceSearchResponseInterfaceIterator( m_Device, m_RemoteAddr, m_ST)); if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); done: return; }
/*---------------------------------------------------------------------- | PLT_FileMediaServer::ProcessFileRequest +---------------------------------------------------------------------*/ NPT_Result PLT_FileMediaServer::ProcessFileRequest(NPT_HttpRequest& request, const NPT_HttpRequestContext& context, NPT_HttpResponse& response) { NPT_LOG_FINE("PLT_FileMediaServer::ProcessFileRequest Received Request:"); PLT_LOG_HTTP_MESSAGE(NPT_LOG_LEVEL_FINE, &request); response.GetHeaders().SetHeader("Accept-Ranges", "bytes"); if (request.GetMethod().Compare("GET") && request.GetMethod().Compare("HEAD")) { response.SetStatus(500, "Internal Server Error"); return NPT_SUCCESS; } // Extract uri path from url NPT_String uri_path = NPT_Uri::PercentDecode(request.GetUrl().GetPath()); // extract file path from query NPT_HttpUrlQuery query(request.GetUrl().GetQuery()); NPT_String file_path = query.GetField("path"); // hack for XBMC support for 360, we urlencoded the ? to that the 360 doesn't strip out the query // but then the query ends being parsed as part of the path int index = uri_path.Find("path="); if (index>0) file_path = uri_path.Right(uri_path.GetLength()-index-5); if (file_path.GetLength() == 0) goto failure; NPT_CHECK_LABEL_WARNING(ServeFile(request, context, response, uri_path, file_path), failure); return NPT_SUCCESS; failure: response.SetStatus(404, "File Not Found"); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | PLT_MediaRenderer::OnAction +---------------------------------------------------------------------*/ NPT_Result PLT_MediaRenderer::OnAction(PLT_ActionReference& action, const PLT_HttpRequestContext& context) { NPT_COMPILER_UNUSED(context); /* parse the action name */ NPT_String name = action->GetActionDesc().GetName(); // since all actions take an instance ID and we only support 1 instance // verify that the Instance ID is 0 and return an error here now if not NPT_String serviceType = action->GetActionDesc().GetService()->GetServiceType(); if (serviceType.Compare("urn:schemas-upnp-org:service:AVTransport:1", true) == 0) { if (NPT_FAILED(action->VerifyArgumentValue("InstanceID", "0"))) { action->SetError(718, "Not valid InstanceID"); return NPT_FAILURE; } } serviceType = action->GetActionDesc().GetService()->GetServiceType(); if (serviceType.Compare("urn:schemas-upnp-org:service:RenderingControl:1", true) == 0) { if (NPT_FAILED(action->VerifyArgumentValue("InstanceID", "0"))) { action->SetError(702, "Not valid InstanceID"); return NPT_FAILURE; } } /* Is it a ConnectionManager Service Action ? */ if (name.Compare("GetCurrentConnectionInfo", true) == 0) { return OnGetCurrentConnectionInfo(action); } /* Is it a AVTransport Service Action ? */ if (name.Compare("Next", true) == 0) { return OnNext(action); } if (name.Compare("Pause", true) == 0) { return OnPause(action); } if (name.Compare("Play", true) == 0) { return OnPlay(action); } if (name.Compare("Previous", true) == 0) { return OnPrevious(action); } if (name.Compare("Seek", true) == 0) { return OnSeek(action); } if (name.Compare("Stop", true) == 0) { return OnStop(action); } if (name.Compare("SetAVTransportURI", true) == 0) { return OnSetAVTransportURI(action); } if (name.Compare("SetNextAVTransportURI", true) == 0) { return OnSetNextAVTransportURI(action); } if (name.Compare("SetPlayMode", true) == 0) { return OnSetPlayMode(action); } /* Is it a RendererControl Service Action ? */ if (name.Compare("SetVolume", true) == 0) { return OnSetVolume(action); } if (name.Compare("SetVolumeDB", true) == 0) { return OnSetVolumeDB(action); } if (name.Compare("GetVolumeDBRange", true) == 0) { return OnGetVolumeDBRange(action); } if (name.Compare("SetMute", true) == 0) { return OnSetMute(action); } // other actions rely on state variables NPT_CHECK_LABEL_WARNING(action->SetArgumentsOutFromStateVariable(), failure); return NPT_SUCCESS; failure: action->SetError(401,"No Such Action."); return NPT_FAILURE; }
/*---------------------------------------------------------------------- | PLT_SyncMediaBrowser::BrowseSync +---------------------------------------------------------------------*/ NPT_Result PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference& device, const char* object_id, PLT_MediaObjectListReference& list, bool metadata, /* = false */ NPT_Int32 start, /* = 0 */ NPT_Cardinal max_results /* = 0 */) { NPT_Result res = NPT_FAILURE; NPT_Int32 index = start; // reset output params list = NULL; // look into cache first if (m_UseCache && NPT_SUCCEEDED(m_Cache.Get(device->GetUUID(), object_id, list))) return NPT_SUCCESS; do { PLT_BrowseDataReference browse_data(new PLT_BrowseData()); // send off the browse packet. Note that this will // not block. There is a call to WaitForResponse in order // to block until the response comes back. res = BrowseSync( browse_data, device, (const char*)object_id, index, metadata?1:30, // DLNA recommendations for browsing children is no more than 30 at a time metadata); NPT_CHECK_LABEL_WARNING(res, done); if (NPT_FAILED(browse_data->res)) { res = browse_data->res; NPT_CHECK_LABEL_WARNING(res, done); } if (browse_data->info.items->GetItemCount() == 0) break; if (list.IsNull()) { list = browse_data->info.items; } else { list->Add(*browse_data->info.items); // clear the list items so that the data inside is not // cleaned up by PLT_MediaItemList dtor since we copied // each pointer into the new list. browse_data->info.items->Clear(); } // stop now if our list contains exactly what the server said it had. // Note that the server could return 0 if it didn't know how many items were // available. In this case we have to continue browsing until // nothing is returned back by the server. // Unless we were told to stop after reaching a certain amount to avoid // length delays if ((browse_data->info.tm && browse_data->info.tm == list->GetItemCount()) || (max_results && list->GetItemCount() >= max_results)) break; // ask for the next chunk of entries index = list->GetItemCount(); } while(1); done: // cache the result if (m_UseCache && NPT_SUCCEEDED(res) && !list.IsNull() && list->GetItemCount()) { m_Cache.Put(device->GetUUID(), object_id, list); } // clear entire cache data for device if failed, the device could be gone if (NPT_FAILED(res) && m_UseCache) m_Cache.Clear(device->GetUUID()); return res; }
/*---------------------------------------------------------------------- | PLT_SyncMediaBrowser::Browse +---------------------------------------------------------------------*/ NPT_Result PLT_SyncMediaBrowser::Browse(PLT_DeviceDataReference& device, const char* object_id, PLT_MediaObjectListReference& list) { NPT_Result res = NPT_FAILURE; NPT_Int32 index = 0; // reset output params list = NULL; // look into cache first if (m_UseCache && NPT_SUCCEEDED(m_Cache.Get(device->GetUUID(), object_id, list))) return NPT_SUCCESS; do { PLT_BrowseDataReference browse_data(new PLT_BrowseData()); // send off the browse packet. Note that this will // not block. There is a call to WaitForResponse in order // to block until the response comes back. res = Browse(browse_data, device, (const char*)object_id, index, 1024, false, "*", ""); NPT_CHECK_LABEL_WARNING(res, done); if (NPT_FAILED(browse_data->res)) { res = browse_data->res; NPT_CHECK_LABEL_WARNING(res, done); } if (browse_data->info.items->GetItemCount() == 0) break; if (list.IsNull()) { list = browse_data->info.items; } else { list->Add(*browse_data->info.items); // clear the list items so that the data inside is not // cleaned up by PLT_MediaItemList dtor since we copied // each pointer into the new list. browse_data->info.items->Clear(); } // stop now if our list contains exactly what the server said it had if (browse_data->info.tm && browse_data->info.tm == list->GetItemCount()) break; // ask for the next chunk of entries index = list->GetItemCount(); } while(1); done: // cache the result if (m_UseCache && NPT_SUCCEEDED(res) && !list.IsNull() && list->GetItemCount()) { m_Cache.Put(device->GetUUID(), object_id, list); } // clear entire cache data for device if failed, the device could be gone if (NPT_FAILED(res) && m_UseCache) m_Cache.Clear(device->GetUUID()); return res; }