/*
 * Presents a list to the user, allows the user to choose one item.
 *
 * Parameters:
 *		PLT_StringMap: A map that contains the set of items from
 *                        which the user should choose.  The key should be a unique ID,
 *						 and the value should be a string describing the item.
 *       returns a NPT_String with the unique ID.
 */
const char*
PLT_MicroMediaController::ChooseIDFromTable(PLT_StringMap& table)
{
    printf("Select one of the following:\n");

    NPT_List<PLT_StringMapEntry*> entries = table.GetEntries();
    if (entries.GetItemCount() == 0) {
        printf("None available\n");
    } else {
        // display the list of entries
        NPT_List<PLT_StringMapEntry*>::Iterator entry = entries.GetFirstItem();
        int count = 0;
        while (entry) {
            printf("%d)\t%s (%s)\n", ++count, (const char*)(*entry)->GetValue(), (const char*)(*entry)->GetKey());
            ++entry;
        }

        int index, watchdog = 3;
        char buffer[1024];

        // wait for input

        /*while (watchdog > 0) {
            fgets(buffer, 1024, stdin);
            strchomp(buffer);

            if (1 != sscanf(buffer, "%d", &index)) {
                printf("Please enter a number\n");
            } else if (index < 0 || index > count)	{
                printf("Please choose one of the above, or 0 for none\n");
                watchdog--;
                index = 0;
            } else {
                watchdog = 0;
            }
        }*/

        index = 1;

        // find the entry back
        if (index != 0) {
            entry = entries.GetFirstItem();
            while (entry && --index) {
                ++entry;
            }
            if (entry) {
                return (*entry)->GetKey();
            }
        }
    }

    return NULL;
}
Пример #2
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Peek
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Peek(NPT_QueueItem*& item, NPT_Timeout timeout)
{
    struct timespec timed;
    if (timeout != NPT_TIMEOUT_INFINITE) {
        NPT_CHECK(GetTimeOut(timeout, timed));
    }

    // lock the mutex that protects the list
    if (pthread_mutex_lock(&m_Mutex)) {
        return NPT_FAILURE;
    }

    NPT_Result result = NPT_SUCCESS;
    NPT_List<NPT_QueueItem*>::Iterator head = m_Items.GetFirstItem();
    if (timeout) {
        while (!head) {
            // no item in the list, wait for one
            ++m_PoppersWaitingCount;
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPopCondition, &m_Mutex);
                --m_PoppersWaitingCount;
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPopCondition, 
                                                      &m_Mutex, 
                                                      &timed);
                --m_PoppersWaitingCount;
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }

            if (m_Aborting) {
                result = NPT_ERROR_INTERRUPTED;
                break;
            }

            head = m_Items.GetFirstItem();
        }
    } else {
        if (!head) result = NPT_ERROR_LIST_EMPTY;
    }

    item = head?*head:NULL;

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);

    return result;
}
Пример #3
0
/*----------------------------------------------------------------------
|   PLT_StateVariable::ValidateValue
+---------------------------------------------------------------------*/
NPT_Result
PLT_StateVariable::ValidateValue(const char* value)
{
    if (m_DataType.Compare("string", true) == 0) {
        // if we have a value allowed restriction, make sure the value is in our list
        if (m_AllowedValues.GetItemCount()) {
            // look for a comma separated list
            NPT_String _value = value;
            NPT_List<NPT_String> values = _value.Split(",");
            NPT_List<NPT_String>::Iterator val = values.GetFirstItem();
            while (val) {
                val->Trim(" ");
                if (!m_AllowedValues.Find(NPT_StringFinder(*val))) {
#if defined(NPT_CONFIG_ENABLE_LOGGING)
                    NPT_LOG_WARNING_2("Invalid value of %s for state variable %s",
                        (const char*)*val,
                        (const char*)m_Name);
                    for (unsigned long i=0; i < m_AllowedValues.GetItemCount(); i++) {
                        NPT_String *val2 = *m_AllowedValues.GetItem(i);
                        NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val2);
                    }
#endif
                    return NPT_ERROR_INVALID_PARAMETERS;
                }
                ++val;
            }
        }
    }

    // TODO: there are more to it than allowed values, we need to test for range, etc..
    return NPT_SUCCESS;    
}
Пример #4
0
/*----------------------------------------------------------------------
|   NPT_File::RemoveDir
+---------------------------------------------------------------------*/
NPT_Result 
NPT_File::RemoveDir(const char* path, bool force_if_not_empty)
{
    NPT_String root_path = path;

    // normalize path separators
    root_path.Replace((NPT_FilePath::Separator[0] == '/')?'\\':'/', NPT_FilePath::Separator);
    
    // remove superfluous delimiters at the end
    root_path.TrimRight(NPT_FilePath::Separator);

    // remove all entries in the directory if required
    if (force_if_not_empty) {
        // enumerate all entries
        NPT_File dir(root_path);
        NPT_List<NPT_String> entries;
        NPT_CHECK_WARNING(dir.ListDir(entries));
        for (NPT_List<NPT_String>::Iterator it = entries.GetFirstItem(); it; ++it) {
            NPT_File::Remove(NPT_FilePath::Create(root_path, *it), true);
        }
    }

    // remove the (now empty) directory
    return NPT_File::RemoveDir(root_path);
}
Пример #5
0
/*----------------------------------------------------------------------
|   PLT_MediaServer::ParseSort
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list)
{
    // reset output params first
    list.Clear();
    
    // easy out
    if (sort.GetLength() == 0 || sort == "*") return NPT_SUCCESS;
    
    list = sort.Split(",");
    
    // verify each property has a namespace
    NPT_List<NPT_String>::Iterator property = list.GetFirstItem();
    while (property) {
        NPT_List<NPT_String> parsed_property = (*property).Split(":");
        if (parsed_property.GetItemCount() != 2)
          parsed_property = (*property).Split("@");
        if (parsed_property.GetItemCount() != 2 || 
            (!(*property).StartsWith("-") && !(*property).StartsWith("+"))) {
            NPT_LOG_WARNING_1("Invalid SortCriteria property %s", (*property).GetChars());
            return NPT_FAILURE;
        }
        property++;
    }
    
    return NPT_SUCCESS;
}
Пример #6
0
Файл: UPnP.cpp Проект: MrMC/mrmc
/*----------------------------------------------------------------------
|   CUPnP::CUPnP
+---------------------------------------------------------------------*/
CUPnP::CUPnP() :
    m_MediaBrowser(NULL),
    m_MediaController(NULL),
    m_LogHandler(NULL),
    m_ServerHolder(new CDeviceHostReferenceHolder()),
    m_RendererHolder(new CRendererReferenceHolder()),
    m_CtrlPointHolder(new CCtrlPointReferenceHolder())
{
    NPT_LogManager::GetDefault().Configure("plist:.level=FINE;.handlers=CustomHandler;");
    NPT_LogHandler::Create("xbmc", "CustomHandler", m_LogHandler);
    m_LogHandler->SetCustomHandlerFunction(&UPnPLogger);

    // initialize upnp context
    m_UPnP = new PLT_UPnP();

    // keep main IP around
    if (g_application.getNetwork().GetFirstConnectedInterface()) {
        m_IP = g_application.getNetwork().GetFirstConnectedInterface()->GetCurrentIPAddress().c_str();
    }
    NPT_List<NPT_IpAddress> list;
    if (NPT_SUCCEEDED(PLT_UPnPMessageHelper::GetIPAddresses(list)) && list.GetItemCount()) {
        m_IP = (*(list.GetFirstItem())).ToString();
    }
    else if(m_IP.empty())
        m_IP = "localhost";

    // start upnp monitoring
    m_UPnP->Start();
}
Пример #7
0
/*----------------------------------------------------------------------
|   NPT_Win32Queue::Peek
+---------------------------------------------------------------------*/
NPT_Result
NPT_Win32Queue::Peek(NPT_QueueItem*& item, NPT_Timeout timeout)
{
    // default value
    item = NULL;

    // lock the mutex that protects the list
    NPT_CHECK(m_Mutex.Lock());

    NPT_Result result = NPT_SUCCESS;
    NPT_List<NPT_QueueItem*>::Iterator head = m_Items.GetFirstItem();
    if (timeout) {
        while (!head) {
            // no item in the list, wait for one

            // reset the condition to indicate that the queue is empty
            m_CanPopCondition->Reset();

            // unlock the mutex so that another thread can push
            m_Mutex.Unlock();

            // wait for the condition to signal that we can pop
            NPT_Result result = m_CanPopCondition->Wait(timeout);
            if (NPT_FAILED(result)) return result;

            // relock the mutex so that we can check the list again
            NPT_CHECK(m_Mutex.Lock());

            // try again
            head = m_Items.GetFirstItem();
        }
    } else {
        if (!head) result = NPT_ERROR_LIST_EMPTY;
    }

    if (head) item = *head;

    // unlock the mutex
    m_Mutex.Unlock();

    return result;
}
Пример #8
0
/*----------------------------------------------------------------------
|   NPT_String::Join
+---------------------------------------------------------------------*/
NPT_String
NPT_String::Join(NPT_List<NPT_String>& args, const char* separator)
{
    NPT_String output;
    NPT_List<NPT_String>::Iterator arg = args.GetFirstItem();
    while (arg) {
        output += *arg;
        if (++arg) output += separator;
    }
    
    return output;
}
Пример #9
0
/*----------------------------------------------------------------------
|   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;
}
Пример #10
0
/*----------------------------------------------------------------------
|   PLT_MediaServer::ParseTagList
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags)
{
    // reset output params first
    tags.Clear();

    NPT_List<NPT_String> split = updates.Split(",");
    NPT_XmlNode*        node = NULL;
    NPT_XmlElementNode* didl_partial = NULL;
    NPT_XmlParser       parser;

    // as these are single name value pairs, separated by commas we wrap in a tag
    // to create a valid tree
    NPT_String xml("<TagValueList>");
    for (NPT_List<NPT_String>::Iterator entry = split.GetFirstItem(); entry; entry++) {
        NPT_String& element = (*entry);
        if (element.IsEmpty())
           xml.Append("<empty>empty</empty>");
        else
           xml.Append(element);
    }
    xml.Append("</TagValueList>");

    NPT_LOG_FINE("Parsing TagList...");
    NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
    if (!node || !node->AsElementNode()) {
        NPT_LOG_SEVERE("Invalid node type");
        goto cleanup;
    }

    didl_partial = node->AsElementNode();
    if (didl_partial->GetTag().Compare("TagValueList", true)) {
        NPT_LOG_SEVERE("Invalid node tag");
        goto cleanup;
    }

    for (NPT_List<NPT_XmlNode*>::Iterator children = didl_partial->GetChildren().GetFirstItem(); children; children++) {
        NPT_XmlElementNode* child = (*children)->AsElementNode();
        if (!child) continue;
        tags[child->GetTag()] = *child->GetText();
    }

    return NPT_SUCCESS;

cleanup:
    if (node) delete node;
    return NPT_FAILURE;
}
Пример #11
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::SetupDevice
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaServer::SetupDevice()
{
    // FIXME: hack for now: find the first valid non local ip address
    // to use in item resources. TODO: we should advertise all ips as
    // multiple resources instead.
    NPT_List<NPT_String> ips;
    PLT_UPnPMessageHelper::GetIPAddresses(ips);
    if (ips.GetItemCount() == 0) return NPT_ERROR_INTERNAL;

    // set the base paths for content and album arts
    m_FileBaseUri     = NPT_HttpUrl(*ips.GetFirstItem(), GetPort(), "/content");
    m_AlbumArtBaseUri = NPT_HttpUrl(*ips.GetFirstItem(), GetPort(), "/albumart");

    return PLT_MediaServer::SetupDevice();
}
Пример #12
0
/*----------------------------------------------------------------------
|   main
+---------------------------------------------------------------------*/
int
main(int /* argc */, char** argv)
{
    /* parse command line */
    ParseCommandLine(argv+1);

    PLT_UPnP upnp(1900, !Options.broadcast);

    PLT_DeviceHostReference device(
        new PLT_FileMediaServer(
            Options.path, 
            Options.friendly_name?Options.friendly_name:"Platinum UPnP Media Server",
            false,
            "SAMEDEVICEGUID",
            (NPT_UInt16)Options.port)
            );

    NPT_List<NPT_String> list;
    NPT_CHECK_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(list));
    NPT_String ip = *(list.GetFirstItem());

    //device->m_PresentationURL = NPT_HttpUrl(ip, 80, "/").ToString();
    device->m_ModelDescription = "Platinum File Media Server";
    device->m_ModelURL = "http://www.plutinosoft.com/";
    device->m_ModelNumber = "1.0";
    device->m_ModelName = "Platinum File Media Server";
    device->m_Manufacturer = "Plutinosoft";
    device->m_ManufacturerURL = "http://www.plutinosoft.com/";

    if (Options.broadcast) device->SetBroadcast(true);

    upnp.AddDevice(device);
    NPT_String uuid = device->GetUUID();

    NPT_CHECK_SEVERE(upnp.Start());
    NPT_LOG_INFO("Press 'q' to quit.");

    char buf[256];
    while (gets(buf)) {
        if (*buf == 'q')
            break;
    }

    upnp.Stop();

    return 0;
}
/*----------------------------------------------------------------------
|   PLT_MicroMediaController::HandleCmd_seek
+---------------------------------------------------------------------*/
void
PLT_MicroMediaController::HandleCmd_seek(const char* command)
{
    PLT_DeviceDataReference device;
    GetCurMediaRenderer(device);
    if (!device.IsNull()) {
        // remove first part of command ("seek")
        NPT_String target = command;
        NPT_List<NPT_String> args = target.Split(" ");
        if (args.GetItemCount() < 2) return;

        args.Erase(args.GetFirstItem());
        target = NPT_String::Join(args, " ");

        Seek(device, 0, (target.Find(":")!=-1)?"REL_TIME":"X_DLNA_REL_BYTE", target, NULL);
    }
}
Пример #14
0
Файл: UPnP.cpp Проект: Ilia/xbmc
/*----------------------------------------------------------------------
|   CUPnP::CUPnP
+---------------------------------------------------------------------*/
CUPnP::CUPnP() :
    m_MediaBrowser(NULL),
    m_ServerHolder(new CDeviceHostReferenceHolder()),
    m_RendererHolder(new CRendererReferenceHolder()),
    m_CtrlPointHolder(new CCtrlPointReferenceHolder())
{
    // initialize upnp context
    m_UPnP = new PLT_UPnP();

    // keep main IP around
    m_IP = g_application.getNetworkManager().GetDefaultConnectionAddress().c_str();
    NPT_List<NPT_IpAddress> list;
    if (NPT_SUCCEEDED(PLT_UPnPMessageHelper::GetIPAddresses(list)) && list.GetItemCount()) {
        m_IP = (*(list.GetFirstItem())).ToString();
    }
    else if(m_IP.IsEmpty())
        m_IP = "localhost";

    // start upnp monitoring
    m_UPnP->Start();
}
Пример #15
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::Start
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaServer::Start(PLT_SsdpListenTask* task)
{   
    // start our file server
    m_FileServer = new PLT_HttpServer(m_FileServerPort);
    NPT_CHECK_SEVERE(m_FileServer->Start());
    m_FileServer->AddRequestHandler(m_FileServerHandler, "/", true);

    // FIXME: hack for now: find the first valid non local ip address
    // to use in item resources. TODO: we should advertise all ips as
    // multiple resources instead.
    NPT_List<NPT_String> ips;
    PLT_UPnPMessageHelper::GetIPAddresses(ips);
    if (ips.GetItemCount() == 0) return NPT_ERROR_INTERNAL;

    // set the base paths for content and album arts
    m_FileBaseUri     = NPT_HttpUrl(*ips.GetFirstItem(), m_FileServer->GetPort(), "/content");
    m_AlbumArtBaseUri = NPT_HttpUrl(*ips.GetFirstItem(), m_FileServer->GetPort(), "/albumart");

    return PLT_MediaServer::Start(task);
}
Пример #16
0
NPT_Result CHttpServer::SetupResponse(NPT_HttpRequest&              request, 
                              const NPT_HttpRequestContext& context,
                              NPT_HttpResponse&             response) 
{
    NPT_String prefix = NPT_String::Format("PLT_HttpServer::SetupResponse %s request from %s for \"%s\"", 
        (const char*) request.GetMethod(),
        (const char*) context.GetRemoteAddress().ToString(),
        (const char*) request.GetUrl().ToString());

    NPT_List<NPT_HttpRequestHandler*> handlers = FindRequestHandlers(request);
    if (handlers.GetItemCount() == 0) return NPT_ERROR_NO_SUCH_ITEM;

    // ask the handler to setup the response
    NPT_Result result = (*handlers.GetFirstItem())->SetupResponse(request, context, response);
    
    // DLNA compliance
    UPNPMessageHelper::SetDate(response);
    if (request.GetHeaders().GetHeader("Accept-Language")) {
        response.GetHeaders().SetHeader("Content-Language", "en");
    }
    return result;
}
/*----------------------------------------------------------------------
|   PLT_MicroMediaController::HandleCmd_cd
+---------------------------------------------------------------------*/
void
PLT_MicroMediaController::HandleCmd_cd(const char* command)
{
    NPT_String    newobject_id;
    PLT_StringMap containers;

    // if command has parameter, push it to stack and return
    NPT_String id = command;
    NPT_List<NPT_String> args = id.Split(" ");
    if (args.GetItemCount() >= 2) {
        args.Erase(args.GetFirstItem());
        id = NPT_String::Join(args, " ");
        m_CurBrowseDirectoryStack.Push(id);
        return;
    }

    // list current directory to let user choose
    DoBrowse();

    if (!m_MostRecentBrowseResults.IsNull()) {
        NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
        while (item) {
            if ((*item)->IsContainer()) {
                containers.Put((*item)->m_ObjectID, (*item)->m_Title);
            }
            ++item;
        }

        newobject_id = ChooseIDFromTable(containers);
        if (newobject_id.GetLength()) {
            m_CurBrowseDirectoryStack.Push(newobject_id);
        }

        m_MostRecentBrowseResults = NULL;
    }
}
Пример #18
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::BuildFromFilePath
+---------------------------------------------------------------------*/
PLT_MediaObject*
PLT_FileMediaServer::BuildFromFilePath(const NPT_String& filepath, 
                                       bool              with_count /* = true */,
                                       NPT_SocketInfo*   info /* = NULL */,
                                       bool              keep_extension_in_title /* = false */)
{
    NPT_String            delimiter = m_DirDelimiter;
    NPT_String            root = m_Path;
    PLT_MediaItemResource resource;
    PLT_MediaObject*      object = NULL;
    int                   dir_delim_index;

    /* make sure this is a valid entry */
    /* and retrieve the entry type (directory or file) */
    NPT_DirectoryEntryInfo entry_info; 
    if (!ProceedWithEntry(filepath, entry_info)) goto failure;

    /* find the last directory delimiter */
    dir_delim_index = filepath.ReverseFind(delimiter);
    if (dir_delim_index < 0) goto failure;

    if (entry_info.type == NPT_FILE_TYPE) {
        object = new PLT_MediaItem();

        /* we need a valid extension to retrieve the mimetype for the protocol info */
        int ext_index = filepath.ReverseFind('.');
        if (ext_index <= 0 || ext_index < dir_delim_index) {
            ext_index = filepath.GetLength();
        }

        /* Set the title using the filename for now */
        object->m_Title = filepath.SubString(dir_delim_index+1, 
            keep_extension_in_title?filepath.GetLength():ext_index - dir_delim_index -1);
        if (object->m_Title.GetLength() == 0) goto failure;

        /* Set the protocol Info from the extension */
        const char* ext = ((const char*)filepath) + ext_index;
        resource.m_ProtocolInfo = PLT_MediaItem::GetProtInfoFromExt(ext);
        if (resource.m_ProtocolInfo.GetLength() == 0)  goto failure;

        /* Set the resource file size */
        resource.m_Size = entry_info.size;
 
        /* format the resource URI */
        NPT_String url = filepath.SubString(root.GetLength());

        // get list of ip addresses
        NPT_List<NPT_String> ips;
        NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure);

        // if we're passed an interface where we received the request from
        // move the ip to the top
        if (info && info->local_address.GetIpAddress().ToString() != "0.0.0.0") {
            ips.Remove(info->local_address.GetIpAddress().ToString());
            ips.Insert(ips.GetFirstItem(), info->local_address.GetIpAddress().ToString());
        }

        // iterate through list and build list of resources
        NPT_List<NPT_String>::Iterator ip = ips.GetFirstItem();
        while (ip) {
            NPT_HttpUrl uri = m_FileBaseUri;
            NPT_HttpUrlQuery query;
            query.AddField("path", url);
            uri.SetHost(*ip);
            uri.SetQuery(query.ToString());
            //uri.SetPath(uri.GetPath() + url);

            /* prepend the base URI and url encode it */ 
            //resource.m_Uri = NPT_Uri::Encode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
            resource.m_Uri = uri.ToString();

            /* Look to see if a metadatahandler exists for this extension */
            PLT_MetadataHandler* handler = NULL;
            NPT_Result res = NPT_ContainerFind(m_MetadataHandlers, PLT_MetadataHandlerFinder(ext), handler);
            if (NPT_SUCCEEDED(res) && handler) {
                /* if it failed loading data, reset the metadatahandler so we don't use it */
                if (NPT_SUCCEEDED(handler->LoadFile(filepath))) {
                    /* replace the title with the one from the Metadata */
                    NPT_String newTitle;
                    if (handler->GetTitle(newTitle) != NULL) {
                        object->m_Title = newTitle;
                    }

                    /* assign description */
                    handler->GetDescription(object->m_Description.long_description);

                    /* assign album art uri if we haven't yet */
                    /* prepend the album art base URI and url encode it */ 
                    if (object->m_ExtraInfo.album_art_uri.GetLength() == 0) {
                        NPT_HttpUrl uri = m_AlbumArtBaseUri;
                        NPT_HttpUrlQuery query;
                        query.AddField("path", url);
                        uri.SetHost(*ip);
                        uri.SetQuery(query.ToString());
                        //uri.SetPath(uri.GetPath() + url);

                        object->m_ExtraInfo.album_art_uri = NPT_Uri::PercentEncode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
                    }

                    /* duration */
                    handler->GetDuration((NPT_UInt32&)resource.m_Duration);

                    /* protection */
                    handler->GetProtection(resource.m_Protection);
                }
            }

            object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClassFromExt(ext);
            object->m_Resources.Add(resource);

            ++ip;
        }
    } else {
        object = new PLT_MediaContainer;

        /* Assign a title for this container */
        if (filepath.Compare(root, true) == 0) {
            object->m_Title = "Root";
        } else {
            object->m_Title = filepath.SubString(dir_delim_index+1, filepath.GetLength() - dir_delim_index -1);
            if (object->m_Title.GetLength() == 0) goto failure;
        }

        /* Get the number of children for this container */
        if (with_count) {
            NPT_Cardinal count = 0;
            NPT_CHECK_LABEL_SEVERE(GetEntryCount(filepath, count), failure);
            ((PLT_MediaContainer*)object)->m_ChildrenCount = count;
        }

        object->m_ObjectClass.type = "object.container";
    }

    /* is it the root? */
    if (filepath.Compare(root, true) == 0) {
        object->m_ParentID = "-1";
        object->m_ObjectID = "0";
    } else {
        /* is the parent path the root? */
        if (dir_delim_index == (int)root.GetLength() - 1) {
            object->m_ParentID = "0";
        } else {
            object->m_ParentID = "0" + delimiter + filepath.SubString(root.GetLength(), dir_delim_index - root.GetLength());
        }
        object->m_ObjectID = "0" + delimiter + filepath.SubString(root.GetLength());
    }

    return object;

failure:
    delete object;
    return NULL;
}
Пример #19
0
/*----------------------------------------------------------------------
|   main
+---------------------------------------------------------------------*/
int main(void)
{
    // Create upnp engine
    PLT_UPnP upnp(1900, true);

    // Create control point
    PLT_CtrlPointReference ctrlPoint(new PLT_CtrlPoint());

    // Create controller
    PLT_MicroMediaController controller(ctrlPoint);

#ifdef HAS_SERVER
    // create device
    PLT_DeviceHostReference server(
        new PLT_FileMediaServer(
        "C:\\Music", 
        "Platinum UPnP Media Server"));

    NPT_String ip;
    NPT_List<NPT_String> list;
    if (NPT_SUCCEEDED(PLT_UPnPMessageHelper::GetIPAddresses(list))) {
        ip = *(list.GetFirstItem());
    }
    server->m_PresentationURL = NPT_HttpUrl(ip, 80, "/").ToString();
    server->m_ModelDescription = "Platinum File Media Server";
    server->m_ModelURL = "http://www.plutinosoft.com/";
    server->m_ModelNumber = "1.0";
    server->m_ModelName = "Platinum File Media Server";
    server->m_Manufacturer = "Plutinosoft";
    server->m_ManufacturerURL = "http://www.plutinosoft.com/";

    // add device
    upnp.AddDevice(server);

    // remove device uuid from ctrlpoint
    ctrlPoint->IgnoreUUID(server->GetUUID());
#endif

#ifdef HAS_RENDERER
    // create device
    PLT_DeviceHostReference renderer(
        new PLT_MediaRenderer(NULL, "Platinum Media Renderer"));
    renderer->m_SerialNumber = "308485761705";
    renderer->m_ModelDescription = "Platinum Renderer";
    renderer->m_ModelName = "Platinum";
    renderer->m_Manufacturer = "Plutinosoft";

    // add device
    upnp.AddDevice(renderer);
    ctrlPoint->IgnoreUUID(renderer->GetUUID());
#endif

    // add control point to upnp engine and start it
    upnp.AddCtrlPoint(ctrlPoint);

    upnp.Start();

#ifdef BROADCAST_EXTRA
    // tell control point to perform extra broadcast discover every secs
    // in case our device doesn't support multicast
    ctrlPoint->Discover(NPT_HttpUrl("255.255.255.255", 1900, "*"), "upnp:rootdevice", 1, 6000);
    ctrlPoint->Discover(NPT_HttpUrl("239.255.255.250", 1900, "*"), "upnp:rootdevice", 1, 6000);
#endif

    // start to process commands 
    controller.ProcessCommandLoop();

    upnp.Stop();

    return 0;
}
/*----------------------------------------------------------------------
 |       NPT_NetworkInterface::GetNetworkInterfaces
 +---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    int result = 0;
    struct ifaddrs * ifaddrsList = NULL;
    struct ifaddrs * ifaddr = NULL;
    NPT_Flags flags = 0;
    
    result = getifaddrs(&ifaddrsList);
    
    if( result != 0 || ifaddrsList == NULL)
        return NPT_FAILURE;
    
    for(ifaddr = ifaddrsList; NULL!= ifaddr; ifaddr = ifaddr->ifa_next) {
        
        if(ifaddr->ifa_addr == NULL /*|| ifaddr->ifa_addr->sa_family == AF_INET6*/)
            continue;
        
        // process the flags
        if ((ifaddr->ifa_flags & IFF_UP) == 0) {
            // the interface is not up, ignore it
            continue;
        }
        if (ifaddr->ifa_flags & IFF_BROADCAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
        }
        if (ifaddr->ifa_flags & IFF_LOOPBACK) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
        }
#if defined(IFF_POINTOPOINT)
        if (ifaddr->ifa_flags & IFF_POINTOPOINT) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
        }
#endif // defined(IFF_POINTOPOINT)
        if (ifaddr->ifa_flags & IFF_PROMISC) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS;
        }
        if (ifaddr->ifa_flags & IFF_MULTICAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
        }
        
        NPT_NetworkInterface* interface = NULL;
        for (NPT_List<NPT_NetworkInterface*>::Iterator iface_iter = interfaces.GetFirstItem();
             iface_iter;
             ++iface_iter) {
            if ((*iface_iter)->GetName() == (const char*)ifaddr->ifa_name) {
                interface = *iface_iter;
                break;
            }
        }
        
        // create a new interface object
        if(interface == NULL)
            interface = new NPT_NetworkInterface(ifaddr->ifa_name, flags);
        
        if (interface == NULL)
            continue;
            
            // get the mac address
            NPT_MacAddress::Type mac_addr_type;
            unsigned int         mac_addr_length = IFHWADDRLEN;
            switch (ifaddr->ifa_addr->sa_family) {
                case AF_LOCAL:
                case AF_INET:
#if defined(AF_LINK)
                case AF_LINK:
#endif
                    mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
#if defined(ARPHRD_LOOPBACK)      
                    mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
                    length = 0;
#endif               
                    break;
#if defined(AF_PPP)
                case AF_PPP:
                    mac_addr_type = NPT_MacAddress::TYPE_PPP;
                    mac_addr_length = 0;
                    break;
#endif
#if defined(AF_IEEE80211)
                case AF_IEEE80211:
                    mac_addr_type = NPT_MacAddress::TYPE_IEEE_802_11;
                    break;
#endif                    
                default:
                    mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
                    mac_addr_length = sizeof(ifaddr->ifa_addr->sa_data);
                    break;
            }


            if(interface->GetMacAddress().GetLength() == 0)
                interface->SetMacAddress(mac_addr_type, (const unsigned char*)ifaddr->ifa_addr->sa_data, mac_addr_length);
        
#if defined(NPT_CONFIG_HAVE_NET_IF_DL_H)        
        if (ifaddr->ifa_addr->sa_family == AF_LINK) {
            //Refer to LLADDR
            struct sockaddr_dl * socket_dl = (struct sockaddr_dl *)ifaddr->ifa_addr;
            
            interface->SetMacAddress(mac_addr_type, (const unsigned char*)socket_dl->sdl_data+socket_dl->sdl_nlen, socket_dl->sdl_alen);
        }
#endif
            switch (ifaddr->ifa_addr->sa_family) {
                case AF_INET: {
                    // primary address
                    NPT_IpAddress primary_address( ntohl(((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr.s_addr));
                    
                    // broadcast address
                    NPT_IpAddress broadcast_address;
                    if ((flags & NPT_NETWORK_INTERFACE_FLAG_BROADCAST) && ifaddr->ifa_dstaddr) {
                        broadcast_address.Set(ntohl(((struct sockaddr_in*)ifaddr->ifa_dstaddr)->sin_addr.s_addr));
                    }
                    
                    // point to point address
                    NPT_IpAddress destination_address;
                    if ((flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) && ifaddr->ifa_dstaddr) {
                        destination_address.Set(ntohl(((struct sockaddr_in*)ifaddr->ifa_dstaddr)->sin_addr.s_addr));
                    }
                    
                    // netmask
                    NPT_IpAddress netmask(0xFFFFFFFF);
                    if(ifaddr->ifa_netmask)
                        netmask.Set(ntohl(((struct sockaddr_in*)ifaddr->ifa_netmask)->sin_addr.s_addr));
                    
                    // add the address to the interface
                    NPT_NetworkInterfaceAddress iface_address(primary_address,
                                                              broadcast_address,
                                                              destination_address,
                                                              netmask);

                    interface->AddAddress(iface_address);
                    
                    break;
                }
                    
            }
            // add the interface to the list
            interfaces.Add(interface);
        
    }
    freeifaddrs(ifaddrsList);
    
    return NPT_SUCCESS;
}
Пример #21
0
/*----------------------------------------------------------------------
|       NPT_NetworkInterface::GetNetworkInterfaces
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
{
    int net = socket(AF_INET, SOCK_DGRAM, 0);

    // Try to get the config until we have enough memory for it
    // According to "Unix Network Programming", some implementations
    // do not return an error when the supplied buffer is too small
    // so we need to try, increasing the buffer size every time,
    // until we get the same size twice. We cannot assume success when
    // the returned size is smaller than the supplied buffer, because
    // some implementations can return less that the buffer size if
    // another structure does not fit.
    unsigned int buffer_size = 4096; // initial guess
    unsigned int last_size = 0;
    struct ifconf config;
    unsigned char* buffer;
    for (; buffer_size < 65536;) {
        buffer = new unsigned char[buffer_size];
        config.ifc_len = buffer_size;
        config.ifc_buf = (char*)buffer;
        if (ioctl(net, SIOCGIFCONF, &config) < 0) {
            if (errno != EINVAL || last_size != 0) {
                return NPT_ERROR_BASE_UNIX-errno;
            }
        } else {
            if ((unsigned int)config.ifc_len == last_size) {
                // same size, we can use the buffer
                break;
            }
            // different size, we need to reallocate
            last_size = config.ifc_len;
        }

        // supply 4096 more bytes more next time around
        buffer_size += 4096;
        delete[] buffer;
    }

    // iterate over all objects
    unsigned char *entries;
    for (entries = buffer; entries < buffer+config.ifc_len;) {
        struct ifreq* entry = (struct ifreq*)entries;
        // get the size of the addresses
        unsigned int address_length;
#if defined(NPT_CONFIG_HAVE_SOCKADDR_SA_LEN)
        address_length = sizeof(struct sockaddr) > entry->ifr_addr.sa_len ?
                         sizeof(sockaddr) : entry->ifr_addr.sa_len;
#else
        switch (entry->ifr_addr.sa_family) {
#if defined(AF_INET6)
        case AF_INET6:
            address_length = sizeof(struct sockaddr_in6);
            break;
#endif // defined(AF_INET6)

        default:
            address_length = sizeof(struct sockaddr);
            break;
        }
#endif

        // point to the next entry
        entries += address_length + sizeof(entry->ifr_name);

        // ignore anything except AF_INET and AF_LINK addresses
        if (entry->ifr_addr.sa_family != AF_INET
#if defined(AF_LINK)
                && entry->ifr_addr.sa_family != AF_LINK
#endif
           ) {
            continue;
        }

        // get detailed info about the interface
        NPT_Flags flags = 0;
#if defined(SIOCGIFFLAGS)
        struct ifreq query = *entry;
        if (ioctl(net, SIOCGIFFLAGS, &query) < 0) continue;

        // process the flags
        if ((query.ifr_flags & IFF_UP) == 0) {
            // the interface is not up, ignore it
            continue;
        }
        if (query.ifr_flags & IFF_BROADCAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
        }
        if (query.ifr_flags & IFF_LOOPBACK) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
        }
#if defined(IFF_POINTOPOINT)
        if (query.ifr_flags & IFF_POINTOPOINT) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
        }
#endif // defined(IFF_POINTOPOINT)
        if (query.ifr_flags & IFF_PROMISC) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS;
        }
        if (query.ifr_flags & IFF_MULTICAST) {
            flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
        }
#endif // defined(SIOCGIFFLAGS)

        // get a pointer to an interface we've looped over before
        // or create a new one
        NPT_NetworkInterface* interface = NULL;
        for (NPT_List<NPT_NetworkInterface*>::Iterator iface_iter = interfaces.GetFirstItem();
                iface_iter;
                ++iface_iter) {
            if ((*iface_iter)->GetName() == (const char*)entry->ifr_name) {
                interface = *iface_iter;
                break;
            }
        }
        if (interface == NULL) {
            // create a new interface object
            interface = new NPT_NetworkInterface(entry->ifr_name, flags);

            // add the interface to the list
            interfaces.Add(interface);

            // get the mac address
#if defined(SIOCGIFHWADDR)
            if (ioctl(net, SIOCGIFHWADDR, &query) == 0) {
                NPT_MacAddress::Type mac_addr_type;
                unsigned int         mac_addr_length = IFHWADDRLEN;
                switch (query.ifr_addr.sa_family) {
#if defined(ARPHRD_ETHER)
                case ARPHRD_ETHER:
                    mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
                    break;
#endif

#if defined(ARPHRD_LOOPBACK)
                case ARPHRD_LOOPBACK:
                    mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
                    length = 0;
                    break;
#endif

#if defined(ARPHRD_PPP)
                case ARPHRD_PPP:
                    mac_addr_type = NPT_MacAddress::TYPE_PPP;
                    mac_addr_length = 0;
                    break;
#endif

#if defined(ARPHRD_IEEE80211)
                case ARPHRD_IEEE80211:
                    mac_addr_type = NPT_MacAddress::TYPE_IEEE_802_11;
                    break;
#endif

                default:
                    mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
                    mac_addr_length = sizeof(query.ifr_addr.sa_data);
                    break;
                }

                interface->SetMacAddress(mac_addr_type, (const unsigned char*)query.ifr_addr.sa_data, mac_addr_length);
            }
#endif
        }

        switch (entry->ifr_addr.sa_family) {
        case AF_INET: {
            // primary address
            NPT_IpAddress primary_address(ntohl(((struct sockaddr_in*)&entry->ifr_addr)->sin_addr.s_addr));

            // broadcast address
            NPT_IpAddress broadcast_address;
#if defined(SIOCGIFBRDADDR)
            if (flags & NPT_NETWORK_INTERFACE_FLAG_BROADCAST) {
                if (ioctl(net, SIOCGIFBRDADDR, &query) == 0) {
                    broadcast_address.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
                }
            }
#endif

            // point to point address
            NPT_IpAddress destination_address;
#if defined(SIOCGIFDSTADDR)
            if (flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) {
                if (ioctl(net, SIOCGIFDSTADDR, &query) == 0) {
                    destination_address.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
                }
            }
#endif

            // netmask
            NPT_IpAddress netmask(0xFFFFFFFF);
#if defined(SIOCGIFNETMASK)
            if (ioctl(net, SIOCGIFNETMASK, &query) == 0) {
                netmask.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
            }
#endif

            // add the address to the interface
            NPT_NetworkInterfaceAddress iface_address(
                primary_address,
                broadcast_address,
                destination_address,
                netmask);
            interface->AddAddress(iface_address);

            break;
        }

#if defined(AF_LINK) && defined(NPT_CONFIG_HAVE_SOCKADDR_DL)
        case AF_LINK: {
            struct sockaddr_dl* mac_addr = (struct sockaddr_dl*)&entry->ifr_addr;
            NPT_MacAddress::Type mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
            switch (mac_addr->sdl_type) {
#if defined(IFT_LOOP)
            case IFT_LOOP:
                mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
                break;
#endif
#if defined(IFT_ETHER)
            case IFT_ETHER:
                mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
                break;
#endif
#if defined(IFT_PPP)
            case IFT_PPP:
                mac_addr_type = NPT_MacAddress::TYPE_PPP;
                break;
#endif
            }
            interface->SetMacAddress(mac_addr_type,
                                     (const unsigned char*)(&mac_addr->sdl_data[mac_addr->sdl_nlen]),
                                     mac_addr->sdl_alen);
            break;
        }
#endif
        }
    }

    // free resources
    delete[] buffer;
    close(net);

    return NPT_SUCCESS;
}
Пример #22
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::BuildFromFilePath
+---------------------------------------------------------------------*/
PLT_MediaObject*
PLT_FileMediaServer::BuildFromFilePath(const NPT_String&        filepath, 
                                       bool                     with_count /* = true */,
                                       const NPT_SocketAddress* req_local_address /* = NULL */,
                                       bool                     keep_extension_in_title /* = false */)
{
    NPT_String            root = m_Path;
    PLT_MediaItemResource resource;
    PLT_MediaObject*      object = NULL;

    /* retrieve the entry type (directory or file) */
    NPT_FileInfo info; 
    NPT_CHECK_LABEL_FATAL(NPT_File::GetInfo(filepath, &info), failure);

    if (info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR) {
        object = new PLT_MediaItem();

        /* Set the title using the filename for now */
        object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
        if (object->m_Title.GetLength() == 0) goto failure;

        /* Set the protocol Info from the extension */
        resource.m_ProtocolInfo = PLT_MediaItem::GetProtInfoFromExt(NPT_FilePath::FileExtension(filepath));
        if (resource.m_ProtocolInfo.GetLength() == 0)  goto failure;

        /* Set the resource file size */
        resource.m_Size = info.m_Size;
 
        /* format the resource URI */
        NPT_String url = filepath.SubString(root.GetLength()+1);

        // get list of ip addresses
        NPT_List<NPT_String> ips;
        NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure);

        // if we're passed an interface where we received the request from
        // move the ip to the top
        if (req_local_address && req_local_address->GetIpAddress().ToString() != "0.0.0.0") {
            ips.Remove(req_local_address->GetIpAddress().ToString());
            ips.Insert(ips.GetFirstItem(), req_local_address->GetIpAddress().ToString());
        }

        // iterate through list and build list of resources
        NPT_List<NPT_String>::Iterator ip = ips.GetFirstItem();
        while (ip) {
            /* prepend the base URI and url encode it */ 
            //resource.m_Uri = NPT_Uri::Encode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
            resource.m_Uri = BuildResourceUri(m_FileBaseUri, *ip, url);

            /* Look to see if a metadatahandler exists for this extension */
            PLT_MetadataHandler* handler = NULL;
            NPT_Result res = NPT_ContainerFind(
                m_MetadataHandlers, 
                PLT_MetadataHandlerFinder(NPT_FilePath::FileExtension(filepath)), 
                handler);
            if (NPT_SUCCEEDED(res) && handler) {
                /* if it failed loading data, reset the metadatahandler so we don't use it */
                if (NPT_SUCCEEDED(handler->LoadFile(filepath))) {
                    /* replace the title with the one from the Metadata */
                    NPT_String newTitle;
                    if (handler->GetTitle(newTitle) != NULL) {
                        object->m_Title = newTitle;
                    }

                    /* assign description */
                    handler->GetDescription(object->m_Description.long_description);

                    /* assign album art uri if we haven't yet */
                    /* prepend the album art base URI and url encode it */ 
                    if (object->m_ExtraInfo.album_art_uri.GetLength() == 0) {
                        object->m_ExtraInfo.album_art_uri = 
                            NPT_Uri::PercentEncode(BuildResourceUri(m_AlbumArtBaseUri, *ip, url), 
                                                   NPT_Uri::UnsafeCharsToEncode);
                    }

                    /* duration */
                    handler->GetDuration(resource.m_Duration);

                    /* protection */
                    handler->GetProtection(resource.m_Protection);
                }
            }

            object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClassFromExt(NPT_FilePath::FileExtension(filepath));
            object->m_Resources.Add(resource);

            ++ip;
        }
    } else {
        object = new PLT_MediaContainer;

        /* Assign a title for this container */
        if (filepath.Compare(root, true) == 0) {
            object->m_Title = "Root";
        } else {
            object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
            if (object->m_Title.GetLength() == 0) goto failure;
        }

        /* Get the number of children for this container */
        NPT_Cardinal count = 0;
        if (with_count && NPT_SUCCEEDED(NPT_File::GetCount(filepath, count))) {
            ((PLT_MediaContainer*)object)->m_ChildrenCount = count;
        }

        object->m_ObjectClass.type = "object.container";
    }

    /* is it the root? */
    if (filepath.Compare(root, true) == 0) {
        object->m_ParentID = "-1";
        object->m_ObjectID = "0";
    } else {
        NPT_String directory = NPT_FilePath::DirectoryName(filepath);
        /* is the parent path the root? */
        if (directory.GetLength() == root.GetLength()) {
            object->m_ParentID = "0";
        } else {
            object->m_ParentID = "0" + filepath.SubString(root.GetLength(), directory.GetLength() - root.GetLength());
        }
        object->m_ObjectID = "0" + filepath.SubString(root.GetLength());
    }

    return object;

failure:
    delete object;
    return NULL;
}
Пример #23
0
/*----------------------------------------------------------------------
|   PLT_EventSubscriber::Notify
+---------------------------------------------------------------------*/
NPT_Result
PLT_EventSubscriber::Notify(NPT_List<PLT_StateVariable*>& vars)
{
    // verify we have eventable variables
    bool foundVars = false;
    NPT_XmlElementNode* propertyset = 
        new NPT_XmlElementNode("e", "propertyset");
    NPT_CHECK_SEVERE(propertyset->SetNamespaceUri(
        "e", 
        "urn:schemas-upnp-org:event-1-0"));

    NPT_List<PLT_StateVariable*>::Iterator var = vars.GetFirstItem();
    while (var) {
        if ((*var)->IsSendingEvents()) {
            NPT_XmlElementNode* property = 
                new NPT_XmlElementNode("e", "property");
            propertyset->AddChild(property);
            PLT_XmlHelper::AddChildText(property, 
                                        (*var)->GetName(), 
                                        (*var)->GetValue());
            foundVars = true;
        }
        ++var;
    }

    // no eventable state variables found!
    if (foundVars == false) {
        delete propertyset;
        return NPT_FAILURE;
    }

    // format the body with the xml
    NPT_String xml;
    if (NPT_FAILED(PLT_XmlHelper::Serialize(*propertyset, xml))) {
        delete propertyset;
        NPT_CHECK_FATAL(NPT_FAILURE);
    }
    delete propertyset;

    // parse the callback url
    NPT_HttpUrl url(m_CallbackURLs[0]);
    if (!url.IsValid()) {
        NPT_CHECK_FATAL(NPT_FAILURE);
    }
    // format request
    NPT_HttpRequest* request = 
        new NPT_HttpRequest(url,
                            "NOTIFY",
                            NPT_HTTP_PROTOCOL_1_1);
    NPT_HttpEntity* entity;
    PLT_HttpHelper::SetBody(*request, xml, &entity);

    // add the extra headers
    entity->SetContentType("text/xml; charset=\"utf-8\"");
    PLT_UPnPMessageHelper::SetNT(*request, "upnp:event");
    PLT_UPnPMessageHelper::SetNTS(*request, "upnp:propchange");
    PLT_UPnPMessageHelper::SetSID(*request, m_SID);
    PLT_UPnPMessageHelper::SetSeq(*request, m_EventKey);

    // wrap around sequence to 1
    if (++m_EventKey == 0) m_EventKey = 1;

    // start the task now if not started already
    if (!m_SubscriberTask) {
        // TODO: the subscriber task should inform subscriber if
        // a notification failed to be received so it can be removed
        // from the list of subscribers inside the device host
        m_SubscriberTask = new PLT_HttpClientSocketTask(request, true);
        
        // short connection time out in case subscriber is not alive
        NPT_HttpClient::Config config;
        config.m_ConnectionTimeout = 2000;
        m_SubscriberTask->SetHttpClientConfig(config);
        
        // add initial delay to make sure ctrlpoint receives response to subscription
        // before our first NOTIFY. Also make sure task is not auto-destroy
        // since we want to destroy it manually when the subscriber goes away.
        NPT_TimeInterval delay(0.05f);
        NPT_CHECK_FATAL(m_TaskManager->StartTask(m_SubscriberTask, NULL /*&delay*/, false));
    } else {
        m_SubscriberTask->AddRequest(request);
    }
     
    return NPT_SUCCESS;
}
Пример #24
0
int SimpleDMR::onAction(const ServiceDecl *serviceDecl, const ActionDecl *actionDecl, AbortableTask *task, const FrontEnd::InterfaceContext *ifctx, const FrontEnd::RequestContext& reqCtx, const NPT_HttpRequest *req, const NPT_List<NPT_String>& inputArgNames, const NPT_List<NPT_String>& inputArgValues, NPT_List<NPT_String>& outputArgValues)
{
	WriteLocker locker(m_stateLock);
	if (NPT_String::Compare(serviceDecl->serviceId, "urn:upnp-org:serviceId:AVTransport") == 0) {

		if (NPT_String::Compare(actionDecl->name, "SetAVTransportURI") == 0) {
			if (inputArgValues.GetItemCount() != 3) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			NPT_HttpClient httpClient;
			NPT_HttpRequest req(*inputArgValues.GetItem(1), NPT_HTTP_METHOD_GET, NPT_HTTP_PROTOCOL_1_1);
			Helper::setupHttpRequest(req);
			NPT_HttpResponse *resp;
			NPT_Result nr;
			HttpClientAbortCallback abortCallback(&httpClient);
			if (task->registerAbortCallback(&abortCallback)) {
				nr = httpClient.SendRequest(req, resp);
				task->unregisterAbortCallback(&abortCallback);
			} else {
				return 715;
			}

			if (NPT_FAILED(nr)) {
				return 716;
			}

			PtrHolder<NPT_HttpResponse> resp1(resp);
			if (resp->GetStatusCode() != 200) {
				return 716;
			}

			NPT_HttpHeader *hdrContentType = resp->GetHeaders().GetHeader(NPT_HTTP_HEADER_CONTENT_TYPE);
			if (!hdrContentType) {
				return 714;
			}

			setVar(DMRVAR_AVTransportURI, *inputArgValues.GetItem(1));
			setVar(DMRVAR_AVTransportURIMetaData, *inputArgValues.GetItem(2));
			setVar(DMRVAR_CurrentTrackMetaData, *inputArgValues.GetItem(2));
			m_callback->doDmrOpen(this, *inputArgValues.GetItem(1), hdrContentType->GetValue(), *inputArgValues.GetItem(2));
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetMediaInfo") == 0) {
			if (inputArgValues.GetItemCount() != 1) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			*outputArgValues.GetItem(0) = m_avtVars[DMRVAR_NumberOfTracks - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(1) = m_avtVars[DMRVAR_CurrentMediaDuration - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(2) = m_avtVars[DMRVAR_AVTransportURI - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(3) = m_avtVars[DMRVAR_AVTransportURIMetaData - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(4) = m_avtVars[DMRVAR_NextAVTransportURI - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(5) = m_avtVars[DMRVAR_NextAVTransportURIMetaData - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(6) = m_avtVars[DMRVAR_PlaybackStorageMedium - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(7) = m_avtVars[DMRVAR_RecordStorageMedium - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(8) = m_avtVars[DMRVAR_RecordMediumWriteStatus - DMRVAR_BaseIndexAVT];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetTransportInfo") == 0) {
			if (inputArgValues.GetItemCount() != 1) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			*outputArgValues.GetItem(0) = m_avtVars[DMRVAR_TransportState - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(1) = m_avtVars[DMRVAR_TransportStatus - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(2) = m_avtVars[DMRVAR_TransportPlaySpeed - DMRVAR_BaseIndexAVT];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetPositionInfo") == 0) {
			if (inputArgValues.GetItemCount() != 1) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			*outputArgValues.GetItem(0) = m_avtVars[DMRVAR_CurrentTrack - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(1) = m_avtVars[DMRVAR_CurrentTrackDuration - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(2) = m_avtVars[DMRVAR_CurrentTrackMetaData - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(3) = m_avtVars[DMRVAR_CurrentTrackURI - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(4) = m_avtVars[DMRVAR_RelativeTimePosition - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(5) = m_avtVars[DMRVAR_AbsoluteTimePosition - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(6) = m_avtVars[DMRVAR_RelativeCounterPosition - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(7) = m_avtVars[DMRVAR_AbsoluteCounterPosition - DMRVAR_BaseIndexAVT];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetDeviceCapabilities") == 0) {
			if (inputArgValues.GetItemCount() != 1) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			*outputArgValues.GetItem(0) = m_avtVars[DMRVAR_PossiblePlaybackStorageMedia - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(1) = m_avtVars[DMRVAR_PossibleRecordStorageMedia - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(2) = m_avtVars[DMRVAR_PossibleRecordQualityModes - DMRVAR_BaseIndexAVT];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetTransportSettings") == 0) {
			if (inputArgValues.GetItemCount() != 1) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			*outputArgValues.GetItem(0) = m_avtVars[DMRVAR_CurrentPlayMode - DMRVAR_BaseIndexAVT];
			*outputArgValues.GetItem(1) = m_avtVars[DMRVAR_CurrentRecordQualityMode - DMRVAR_BaseIndexAVT];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "Stop") == 0) {
			m_callback->doDmrStop(this);
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "Play") == 0) {
			m_callback->doDmrPlay(this);
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "Pause") == 0) {
			m_callback->doDmrPause(this);
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "Seek") == 0) {
			if (inputArgValues.GetItemCount() != 3) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 718;
			}

			const NPT_String& seekMode = *inputArgValues.GetItem(1);
			const NPT_String& seekTarget = *inputArgValues.GetItem(2);
			if (seekMode.Compare("TRACK_NR") == 0) {
				// TODO:
			} else if (seekMode.Compare("REL_TIME") == 0) {
				NPT_UInt64 pos;
				if (NPT_FAILED(Helper::parseTrackDurationString(seekTarget, pos))) {
					// Illegal seek target
					return 711;
				}
				m_callback->doDmrSeekTo(this, pos);
			} else {
				// Seek mode not supported
				return 710;
			}

			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "Next") == 0) {
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "Previous") == 0) {
			return 0;
		}

		return 602;
	}

	if (NPT_String::Compare(serviceDecl->serviceId, "urn:upnp-org:serviceId:RenderingControl") == 0) {

		if (NPT_String::Compare(actionDecl->name, "ListPresets") == 0) {
			if (inputArgValues.GetItemCount() != 1) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 702;
			}

			*outputArgValues.GetItem(0) = m_rcsVars[DMRVAR_PresetNameList - DMRVAR_BaseIndexRCS];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "SelectPreset") == 0) {
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetMute") == 0) {
			if (inputArgValues.GetItemCount() != 2) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 702;
			}

			*outputArgValues.GetItem(0) = m_rcsVars[DMRVAR_Mute - DMRVAR_BaseIndexRCS];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "SetMute") == 0) {
			if (inputArgValues.GetItemCount() != 3) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 702;
			}

			const NPT_String& desiredMute = *inputArgValues.GetItem(2);
			m_callback->doDmrSetMute(this, desiredMute.Compare("true", true) == 0 || desiredMute.Compare("1") == 0);
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetVolume") == 0) {
			if (inputArgValues.GetItemCount() != 2) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 702;
			}

			*outputArgValues.GetItem(0) = m_rcsVars[DMRVAR_Volume - DMRVAR_BaseIndexRCS];
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "SetVolume") == 0) {
			if (inputArgValues.GetItemCount() != 3) {
				// Invalid Args
				return 402;
			}

			if (inputArgValues.GetFirstItem()->Compare("0") != 0) {
				// Invalid InstanceID
				return 702;
			}

			const NPT_String& desiredVolume = *inputArgValues.GetItem(2);
			int volume;
			if (NPT_FAILED(NPT_ParseInteger(desiredVolume, volume))) {
				// Invalid Args
				return 402;
			}
			m_callback->doDmrSetVolume(this, volume);
			return 0;
		}

		return 602;
	}

	if (NPT_String::Compare(serviceDecl->serviceId, "urn:upnp-org:serviceId:ConnectionManager") == 0) {

		if (NPT_String::Compare(actionDecl->name, "GetProtocolInfo") == 0) {
			NPT_String v;
			if (getStateValue(serviceDecl->serviceId, "SourceProtocolInfo", v)) {
				*outputArgValues.GetItem(0) = v;
			}

			if (getStateValue(serviceDecl->serviceId, "SinkProtocolInfo", v)) {
				*outputArgValues.GetItem(1) = v;
			}
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetCurrentConnectionIDs") == 0) {
			NPT_String v;
			if (getStateValue(serviceDecl->serviceId, "SourceProtocolInfo", v)) {
				*outputArgValues.GetItem(0) = v;
			}
			return 0;
		}

		if (NPT_String::Compare(actionDecl->name, "GetCurrentConnectionInfo") == 0) {
			*outputArgValues.GetItem(0) = "0";
			*outputArgValues.GetItem(1) = "0";
			*outputArgValues.GetItem(2) = "";
			*outputArgValues.GetItem(3) = "";
			*outputArgValues.GetItem(4) = "-1";
			*outputArgValues.GetItem(5) = "Input"; // or "Output"? WTF!
			*outputArgValues.GetItem(6) = "OK";
			return 0;
		}

		return 602;
	}

	return 501;
}
Пример #25
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnBrowseDirectChildren
+---------------------------------------------------------------------*/
NPT_Result
PLT_FileMediaServer::OnBrowseDirectChildren(PLT_ActionReference&          action, 
                                            const char*                   object_id, 
                                            const NPT_HttpRequestContext& context)
{
    /* locate the file from the object ID */
    NPT_String dir;
    if (NPT_FAILED(GetFilePath(object_id, dir))) {
        /* error */
        NPT_LOG_WARNING("PLT_FileMediaServer::OnBrowse - ObjectID not found.");
        action->SetError(701, "No Such Object.");
        return NPT_FAILURE;
    }

    /* retrieve the item type */
    NPT_FileInfo info;
    NPT_Result res = NPT_File::GetInfo(dir, &info);
    if (NPT_FAILED(res)) {
        /* Object does not exist */
        NPT_LOG_WARNING_1("PLT_FileMediaServer::OnBrowse - BROWSEDIRECTCHILDREN failed for item %s", dir.GetChars());
        action->SetError(800, "Can't retrieve info " + dir);
        return NPT_FAILURE;
    }

    if (info.m_Type != NPT_FileInfo::FILE_TYPE_DIRECTORY) {
        /* error */
        NPT_LOG_WARNING("PLT_FileMediaServer::OnBrowse - BROWSEDIRECTCHILDREN not allowed on an item.");
        action->SetError(710, "item is not a container.");
        return NPT_FAILURE;
    }

    NPT_String filter;
    NPT_String startingInd;
    NPT_String reqCount;

    NPT_CHECK_SEVERE(action->GetArgumentValue("Filter", filter));
    NPT_CHECK_SEVERE(action->GetArgumentValue("StartingIndex", startingInd));
    NPT_CHECK_SEVERE(action->GetArgumentValue("RequestedCount", reqCount));   

    NPT_UInt32 start_index, req_count;
    if (NPT_FAILED(startingInd.ToInteger(start_index)) ||
        NPT_FAILED(reqCount.ToInteger(req_count))) {        
        action->SetError(412, "Precondition failed");
        return NPT_FAILURE;
    }

    NPT_List<NPT_String> entries;
    res = NPT_File::ListDirectory(dir, entries, 0, 0);
    if (NPT_FAILED(res)) {
        NPT_LOG_WARNING_1("PLT_FileMediaServer::OnBrowseDirectChildren - failed to open dir %s", (const char*) dir);
        return res;
    }

    unsigned long cur_index = 0;
    unsigned long num_returned = 0;
    unsigned long total_matches = 0;
    NPT_String didl = didl_header;

    PLT_MediaObjectReference item;
    for (NPT_List<NPT_String>::Iterator it = entries.GetFirstItem();
        it;
        ++it) {
        NPT_String& filename = *it;
        item = BuildFromFilePath(
            NPT_FilePath::Create(dir, filename), 
            true, 
            &context.GetLocalAddress());

        if (!item.IsNull()) {
            if ((cur_index >= start_index) && ((num_returned < req_count) || (req_count == 0))) {
                NPT_String tmp;
                NPT_CHECK_SEVERE(PLT_Didl::ToDidl(*item.AsPointer(), filter, tmp));

                didl += tmp;
                num_returned++;
            }
            cur_index++;
            total_matches++;        
        }
    };

    didl += didl_footer;

    NPT_CHECK_SEVERE(action->SetArgumentValue("Result", didl));
    NPT_CHECK_SEVERE(action->SetArgumentValue("NumberReturned", NPT_String::FromInteger(num_returned)));
    NPT_CHECK_SEVERE(action->SetArgumentValue("TotalMatches", NPT_String::FromInteger(total_matches))); // 0 means we don't know how many we have but most browsers don't like that!!
    NPT_CHECK_SEVERE(action->SetArgumentValue("UpdateId", "1"));

    return NPT_SUCCESS;
}