예제 #1
0
void JNICore::onMediaServerStateVariablesChanged(DeviceDesc *deviceDesc, ServiceDesc *serviceDesc, const NPT_List<NPT_String>& nameList, const NPT_List<NPT_String>& valueList)
{
	NPT_LOG_FINEST("onMediaServerStateVariablesChanged aaaa");
	VMGuard vmguard;
	if (JNIEnv *env = vmguard.env()) {
	
		NPT_UInt64 u1, u2;
		deviceDesc->uuid().getData(u1, u2);
		jobject uuidObj = env->NewObject(CG::c_UUID, CG::m_UUID_Init, u1, u2);

		jstring serviceIdObj = env->NewStringUTF(serviceDesc->serviceId().GetChars());
		
		jobjectArray nameArr = env->NewObjectArray(nameList.GetItemCount(), CG::c_String, NULL);
		jobjectArray valueArr = env->NewObjectArray(valueList.GetItemCount(), CG::c_String, NULL);
		
		jstring sObj;
		for (NPT_Ordinal i = 0; i < nameList.GetItemCount(); i++) {
			sObj = env->NewStringUTF(nameList.GetItem(i)->GetChars());
			env->SetObjectArrayElement(nameArr, i, sObj);
			env->DeleteLocalRef(sObj);

			sObj = env->NewStringUTF(valueList.GetItem(i)->GetChars());
			env->SetObjectArrayElement(valueArr, i, sObj);
			env->DeleteLocalRef(sObj);
		}
		
		NPT_LOG_FINEST("onMediaServerStateVariablesChanged bbbb");
		env->CallVoidMethod(m_delegateObj, CG::f_DLNACore_hookMSSVC, uuidObj, serviceIdObj, nameArr, valueArr);
		env->DeleteLocalRef(uuidObj);
		env->DeleteLocalRef(serviceIdObj);
		env->DeleteLocalRef(nameArr);
		env->DeleteLocalRef(valueArr);
	}
}
예제 #2
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Push(NPT_QueueItem* item, NPT_Timeout timeout)
{    
    struct     timespec timed;
    struct     timeval  now;

    // get current time from system
    if (gettimeofday(&now, NULL)) {
        return NPT_FAILURE;
    }

    now.tv_usec += timeout * 1000;
    if (now.tv_usec >= 1000000) {
        now.tv_sec += now.tv_usec / 1000000;
        now.tv_usec = now.tv_usec % 1000000;
    }

    // setup timeout
    timed.tv_sec  = now.tv_sec;
    timed.tv_nsec = now.tv_usec * 1000;

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

    NPT_Result result = NPT_SUCCESS;
    // check that we have not exceeded the max
    if (m_MaxItems) {
        while (m_Items.GetItemCount() >= m_MaxItems) {
            // wait until some items have been removed
            //NPT_Debug(":: NPT_PosixQueue::Push - waiting for queue to empty\n");
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex);
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPushOrPopCondition, &m_Mutex, &timed);
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }
        }
    }

    // add the item to the list
    if (result == NPT_SUCCESS) {
        m_Items.Add(item);

        // if the list was previously empty, signal the condition
        // to wake up the waiting thread
        if (m_Items.GetItemCount() == 1) {    
            pthread_cond_signal(&m_CanPushOrPopCondition);
        }
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);

    return result;
}
예제 #3
0
/*----------------------------------------------------------------------
|   NPT_File::GetSize
+---------------------------------------------------------------------*/
NPT_Result
NPT_File::GetSize(NPT_LargeSize& size)
{
    // default value
    size = 0;
    
    // get the file info
    NPT_FileInfo info;
    GetInfo(info);
    
    switch (info.m_Type) {
        case NPT_FileInfo::FILE_TYPE_DIRECTORY: {
            NPT_List<NPT_String> entries;
            NPT_CHECK_WARNING(ListDir(entries));
            size = entries.GetItemCount();
            break;
        }
        
        case NPT_FileInfo::FILE_TYPE_REGULAR:
        case NPT_FileInfo::FILE_TYPE_OTHER:
            size = info.m_Size;
            return NPT_SUCCESS;
            
        default:
            break;
    } 
    
    return NPT_SUCCESS;
}
예제 #4
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();
}
예제 #5
0
/*----------------------------------------------------------------------
|   NPT_NetworkNameResolver::Resolve
+---------------------------------------------------------------------*/
NPT_Result
NPT_NetworkNameResolver::Resolve(const char*              name, 
                                 NPT_List<NPT_IpAddress>& addresses,
                                 NPT_Timeout              /*timeout*/)
{
    // empty the list first
    addresses.Clear();
    
    
    // get the addr list

    //struct addrinfo hints;
    //NPT_SetMemory(&hints, 0, sizeof(hints));
    //hints.ai_family   = PF_UNSPEC;
    //hints.ai_socktype = SOCK_STREAM;
    //hints.ai_flags    = AI_DEFAULT;
    struct addrinfo *infos = NULL;
    int result = getaddrinfo(name,  /* hostname */
                             NULL,  /* servname */
                             NULL,  /* hints    */
                             &infos /* res      */);
    if (result != 0) {
        return MapGetAddrInfoErrorCode(result);
    }
    
    for (struct addrinfo* info = infos; 
                          info && addresses.GetItemCount() < NPT_BSD_NETWORK_MAX_ADDR_LIST_LENGTH;
                          info = info->ai_next) {
        unsigned int expected_length;
        if (info->ai_family == AF_INET) {
            expected_length = sizeof(struct sockaddr_in);
#if defined(NPT_CONFIG_ENABLE_IPV6)
        } else if (info->ai_family == AF_INET6) {
            expected_length = sizeof(struct sockaddr_in6);
#endif
        } else {
            continue;
        }
        if ((unsigned int)info->ai_addrlen < expected_length) continue;
        if (info->ai_protocol != 0 && info->ai_protocol != IPPROTO_TCP) continue;
    
        if (info->ai_family == AF_INET) {
            struct sockaddr_in* inet_addr = (struct sockaddr_in*)info->ai_addr;
            NPT_IpAddress address(ntohl(inet_addr->sin_addr.s_addr));
            addresses.Add(address);
        }
#if defined(NPT_CONFIG_ENABLE_IPV6)
        else if (info->ai_family == AF_INET6) {
            struct sockaddr_in6* inet_addr = (struct sockaddr_in6*)info->ai_addr;
            NPT_IpAddress address(NPT_IpAddress::IPV6, inet_addr->sin6_addr.s6_addr, 16, inet_addr->sin6_scope_id);
            addresses.Add(address);
        }
#endif
    }
    freeaddrinfo(infos);
    
    return NPT_SUCCESS;
}
예제 #6
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Pop
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Pop(NPT_QueueItem*& item, NPT_Timeout timeout)
{
    struct     timespec timed;
    struct     timeval  now;

    // get current time from system
    if (gettimeofday(&now, NULL)) {
        return NPT_FAILURE;
    }

    now.tv_usec += timeout * 1000;
    if (now.tv_usec >= 1000000) {
        now.tv_sec += now.tv_usec / 1000000;
        now.tv_usec = now.tv_usec % 1000000;
    }

    // setup timeout
    timed.tv_sec  = now.tv_sec;
    timed.tv_nsec = now.tv_usec * 1000;

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

    NPT_Result result;
    if (timeout) {
        while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) {
            // no item in the list, wait for one
            //NPT_Debug(":: NPT_PosixQueue::Pop - waiting for queue to fill up\n");
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex);
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPushOrPopCondition, &m_Mutex, &timed);
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }
        }
    } else {
        result = m_Items.PopHead(item);
    }
    
    // if the list was previously full, signal the condition
    // to wake up the waiting thread
    if (m_MaxItems && (result == NPT_SUCCESS)) {
        if (m_Items.GetItemCount() == m_MaxItems-1) {    
            pthread_cond_signal(&m_CanPushOrPopCondition);
        }
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);
 
    return result;
}
예제 #7
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Push(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;
    // check that we have not exceeded the max
    if (m_MaxItems) {
        while (m_Items.GetItemCount() >= m_MaxItems) {
            // wait until we can push
            ++m_PushersWaitingCount;
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPushCondition, &m_Mutex);
                --m_PushersWaitingCount;
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPushCondition, 
                                                      &m_Mutex, 
                                                      &timed);
                --m_PushersWaitingCount;
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }

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

    // add the item to the list
    if (result == NPT_SUCCESS) {
        m_Items.Add(item);

        // wake up any thread that may be waiting to pop
        if (m_PoppersWaitingCount) { 
            pthread_cond_broadcast(&m_CanPopCondition);
        }
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);

    return result;
}
/*
 * 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;
}
예제 #9
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();
}
/*----------------------------------------------------------------------
|   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);
    }
}
예제 #11
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);
}
예제 #12
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();
}
예제 #13
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;
}
예제 #14
0
/*----------------------------------------------------------------------
|   NPT_Win32Queue::Push
+---------------------------------------------------------------------*/
NPT_Result
NPT_Win32Queue::Push(NPT_QueueItem* item, NPT_Timeout timeout)
{
    // lock the mutex that protects the list
    NPT_CHECK(m_Mutex.Lock());

    // check that we have not exceeded the max
    if (m_MaxItems) {
        while (m_Items.GetItemCount() >= m_MaxItems) {
            // we must wait until some items have been removed

            // reset the condition to indicate that the queue is full
            m_CanPushCondition->Reset();

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

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

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

    // add the item to the list
    m_Items.Add(item);

    // wake up the threads waiting to pop
    m_CanPopCondition->Signal();

    // unlock the mutex
    m_Mutex.Unlock();

    return NPT_SUCCESS;
}
예제 #15
0
NPT_String RootContainer::generateDidl(const NPT_List<const Object*>& ls, const NPT_String& resUriTmpl)
{
	NPT_StringOutputStream outputStream;
	NPT_XmlSerializer xml(&outputStream, 0, true, true);

	xml.StartDocument();
	xml.StartElement(NULL, "DIDL-Lite");
	xml.Attribute(NULL, "xmlns", "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/");
	xml.Attribute("xmlns", "dc", "http://purl.org/dc/elements/1.1/");
	xml.Attribute("xmlns", "upnp", "urn:schemas-upnp-org:metadata-1-0/upnp/");

	for (NPT_Ordinal i = 0; i < ls.GetItemCount(); i++) {
		const Object *obj = *ls.GetItem(i);
		if (const Item *item = obj->asItem()) {
			outputItem(xml, item, resUriTmpl);
		} else if (const Container *container = obj->asContainer()) {
			outputContainer(xml, container, resUriTmpl);
		}
	}

	xml.EndElement(NULL, "DIDL-Lite");
	xml.EndDocument();
	return outputStream.GetString();
}
/*----------------------------------------------------------------------
|   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;
    }
}
예제 #17
0
NPT_Result FrontEnd::start()
{
	WriteLocker locker(m_stateLock);
	if (m_state != State_Stopped) {
		return NPT_ERROR_INVALID_STATE;
	}

	NPT_Result nr;

	NPT_List<NPT_NetworkInterface*> ifList;
	nr = NPT_NetworkInterface::GetNetworkInterfaces(ifList);
	if (NPT_FAILED(nr)) {
		return nr;
	}

	for (NPT_Ordinal i = 0; i < ifList.GetItemCount(); i++) {
		NPT_NetworkInterface *nif = *ifList.GetItem(i);
		if (nif->GetAddresses().GetFirstItem() && (m_includeLoopback || ((nif->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK) == 0))) {
			Interface *intf = new Interface();
			intf->m_owner = this;
			intf->m_nif = nif;
			intf->m_context.m_ifAddr = nif->GetAddresses().GetFirstItem()->GetPrimaryAddress();
			intf->m_httpConnector = new HttpConnector(intf, intf->m_context.m_ifAddr);
			intf->m_ssdpConnector = new SsdpConnector(intf, intf->m_context.m_ifAddr);
			intf->m_context.m_httpPort = 0;
			intf->m_context.m_ssdpPort = 0;
			m_ifList.Add(intf);
			m_interfaceContextList.Add(&intf->m_context);
		} else {
			delete nif;
		}
	}

	if (m_ifList.GetItemCount() == 0) {
		return NPT_FAILURE;
	}

	for (NPT_Ordinal i = 0; i < m_ifList.GetItemCount(); i++) {
		Interface *intf = *m_ifList.GetItem(i);
		if (NPT_SUCCEEDED(intf->m_httpConnector->start())) {
			intf->m_context.m_httpPort = intf->m_httpConnector->port();
		}
		if (NPT_SUCCEEDED(intf->m_ssdpConnector->start())) {
			intf->m_context.m_ssdpPort = intf->m_ssdpConnector->port();
		}
	}

	m_taskGroup->reset();

	{
		ReadLocker locker1(m_cpLock);
		for (NPT_Ordinal i = 0; i < m_controlPointList.GetItemCount(); i++) {
			ControlPointInfo *info = *m_controlPointList.GetItem(i);
			info->m_controlPoint->implAttach(this, info->m_context);
		}

		for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
			DeviceImplInfo *info = *m_deviceImplList.GetItem(i);
			info->m_deviceImpl->implAttach(this, info->m_context);
		}

		broadcastLocked(NULL, true);
	}

	m_taskGroup->startTask(new SsdpBroadcastTask(this));

	m_state = State_Running;
	return NPT_SUCCESS;
}
예제 #18
0
/*----------------------------------------------------------------------
|       main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
    NPT_Result result;
    NPT_FileInfo info;

    NPT_ASSERT(NPT_File::GetInfo("foobar.doesnotexist", NULL) == NPT_ERROR_NO_SUCH_FILE);
    NPT_ASSERT(!NPT_File::Exists("foobar.doesnotexist"));

    // test special names
    NPT_File file(NPT_FILE_STANDARD_INPUT);
    NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info)));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL);
    file = NPT_File(NPT_FILE_STANDARD_OUTPUT);

    NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info)));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL);
    file = NPT_File(NPT_FILE_STANDARD_ERROR);
    NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info)));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL);

    if (NPT_File::Exists("foobar.file1")) {
        result = NPT_File::DeleteFile("foobar.file1");
        NPT_ASSERT(NPT_SUCCEEDED(result));
    }

    result = CreateNewFile("foobar.file1", 9);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(NPT_File::Exists("foobar.file1"));
    result = NPT_File::GetInfo("foobar.file1", &info);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR);
    NPT_ASSERT(info.m_Size == 9);

    {
        NPT_File f1("foobar.file1");
        result = f1.GetInfo(info);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR);
        NPT_ASSERT(info.m_Size == 9);
    }
    {
        NPT_File f1("foobar.file1");
        NPT_LargeSize size;
        result = f1.GetSize(size);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(size == 9);
    }

    {
        NPT_File f1("foobar.file1");
        result = f1.Rename("foobar.file1-r");
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(f1.GetPath() == "foobar.file1-r");
    }
    NPT_ASSERT(NPT_File::Exists("foobar.file1-r"));
    result = NPT_File::GetInfo("foobar.file1-r", &info);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR);
    NPT_ASSERT(info.m_Size == 9);

    // dirs
    NPT_ASSERT(!NPT_File::Exists("foobar.dir"));
    result = NPT_File::CreateDirectory("foobar.dir");
    NPT_ASSERT(NPT_SUCCEEDED(result));
    result = NPT_File::GetInfo("foobar.dir", &info);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY);
    {
        NPT_File f1("foobar.dir");
        result = f1.GetInfo(info);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY);
    }

    NPT_String dirname = "foobar.dir";
    NPT_String fname;
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file1";
    result = CreateNewFile(fname, 1);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file2";
    result = CreateNewFile(fname, 2);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file3";
    result = CreateNewFile(fname, 3);
    NPT_ASSERT(NPT_SUCCEEDED(result));

    NPT_List<NPT_String> entries;
    result = NPT_File::ListDirectory("foobar.dir", entries);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(entries.GetItemCount() == 3);

    result = NPT_File::DeleteFile("foobar.dir");
    NPT_ASSERT(NPT_FAILED(result));
    result = NPT_File::DeleteDirectory("foobar.dir");
    NPT_ASSERT(result == NPT_ERROR_DIRECTORY_NOT_EMPTY);

    result = NPT_File::Rename("foobar.dir", "foobar.dir-r");
    NPT_ASSERT(NPT_SUCCEEDED(result));

    dirname = "foobar.dir-r";
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file1";
    result = NPT_File::DeleteFile(fname);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file2";
    result = NPT_File::DeleteFile(fname);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file3";
    result = NPT_File::DeleteFile(fname);
    NPT_ASSERT(NPT_SUCCEEDED(result));

    result = NPT_File::DeleteDirectory("foobar.dir-r");
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(!NPT_File::Exists("foobar.dir-r"));

    // paths
    NPT_String test;
    test = NPT_FilePath::BaseName("");
    NPT_ASSERT(test == "");
    test = NPT_FilePath::BaseName("a");
    NPT_ASSERT(test == "a");
    test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b");
    NPT_ASSERT(test == "b");
    test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator);
    NPT_ASSERT(test == "");
    test = NPT_FilePath::BaseName(NPT_FilePath::Separator+"a");
    NPT_ASSERT(test == "a");
    test = NPT_FilePath::BaseName(NPT_FilePath::Separator);
    NPT_ASSERT(test == "");

    test = NPT_FilePath::DirectoryName("");
    NPT_ASSERT(test == "");
    test = NPT_FilePath::DirectoryName("a");
    NPT_ASSERT(test == "");
    test = NPT_FilePath::DirectoryName("a"+NPT_FilePath::Separator+"b");
    NPT_ASSERT(test == "a");
    test = NPT_FilePath::DirectoryName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator);
    NPT_ASSERT(test == "a"+NPT_FilePath::Separator+"b");
    test = NPT_FilePath::DirectoryName(NPT_FilePath::Separator+"a");
    NPT_ASSERT(test == NPT_FilePath::Separator);
    test = NPT_FilePath::DirectoryName(NPT_FilePath::Separator);
    NPT_ASSERT(test == NPT_FilePath::Separator);

    // large files
    if (argc == 2) {
        result = CreateNewFile(argv[1], 0x10000, 0x10007);
        NPT_ASSERT(NPT_SUCCEEDED(result));

        NPT_String new_name = argv[1];
        new_name += ".renamed";
        result = NPT_File::Rename(argv[1], new_name);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        file = NPT_File(new_name);
        result = file.Open(NPT_FILE_OPEN_MODE_READ);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_InputStreamReference input;
        file.GetInputStream(input);
        NPT_Position position;
        result = input->Tell(position);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(position == 0);
        NPT_LargeSize large_size = (NPT_LargeSize)0x10007 * (NPT_LargeSize)0x10000;
        result = input->Seek(large_size-0x10007);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        result = input->Tell(position);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(position == large_size-0x10007);
        unsigned char* buffer = new unsigned char[0x10007];
        result = input->ReadFully(buffer, 0x10007);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        result = input->Tell(position);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(position == large_size);
        for (unsigned int i=0; i<0x10007; i++) {
            NPT_ASSERT(buffer[i] == (unsigned char)i);
        }
        file.Close();
        NPT_File::DeleteFile(new_name);
    }

    return 0;
}
예제 #19
0
파일: FileTest1.cpp 프로젝트: AWilco/xbmc
/*----------------------------------------------------------------------
|       main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
    NPT_Result result;
    NPT_FileInfo info;
    
    NPT_ASSERT(NPT_File::GetInfo("foobar.doesnotexist", NULL) == NPT_ERROR_NO_SUCH_FILE);
    NPT_ASSERT(!NPT_File::Exists("foobar.doesnotexist"));
    
    // test special names
    NPT_File file(NPT_FILE_STANDARD_INPUT);
    NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info)));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL);
    file = NPT_File(NPT_FILE_STANDARD_OUTPUT);
    
    NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info)));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL);
    file = NPT_File(NPT_FILE_STANDARD_ERROR);
    NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info)));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL);

    if (NPT_File::Exists("foobar.file1")) {
        result = NPT_File::RemoveFile("foobar.file1");
        NPT_ASSERT(NPT_SUCCEEDED(result));
    }
    
    result = CreateNewFile("foobar.file1", 9);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(NPT_File::Exists("foobar.file1"));
    result = NPT_File::GetInfo("foobar.file1", &info);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR);
    NPT_ASSERT(info.m_Size == 9);
    
    {
        NPT_File f1("foobar.file1");
        result = f1.GetInfo(info);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR);
        NPT_ASSERT(info.m_Size == 9);
    }
    {
        NPT_File f1("foobar.file1");
        NPT_LargeSize size;
        result = f1.GetSize(size);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(size == 9);
    }
    
    {
        NPT_File f1("foobar.file1");
        result = f1.Rename("foobar.file1-r");
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(f1.GetPath() == "foobar.file1-r");
    }
    NPT_ASSERT(NPT_File::Exists("foobar.file1-r"));
    result = NPT_File::GetInfo("foobar.file1-r", &info);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR);
    NPT_ASSERT(info.m_Size == 9);

    // dirs
    NPT_ASSERT(!NPT_File::Exists("foobar.dir"));
    result = NPT_File::CreateDir("foobar.dir");
    NPT_ASSERT(NPT_SUCCEEDED(result));
    result = NPT_File::GetInfo("foobar.dir", &info);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY);
    {
        NPT_File f1("foobar.dir");
        result = f1.GetInfo(info);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY);
    }

    NPT_String dirname = "foobar.dir";
    NPT_String fname;
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file1";
    result = CreateNewFile(fname, 1);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file2";
    result = CreateNewFile(fname, 2);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file3";
    result = CreateNewFile(fname, 3);
    NPT_ASSERT(NPT_SUCCEEDED(result));

    NPT_List<NPT_String> entries;
    result = NPT_File::ListDir("foobar.dir", entries);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(entries.GetItemCount() == 3);
    
    result = NPT_File::RemoveFile("foobar.dir");
    NPT_ASSERT(NPT_FAILED(result));
    result = NPT_File::RemoveDir("foobar.dir");
    NPT_ASSERT(result == NPT_ERROR_DIRECTORY_NOT_EMPTY);
    
    result = NPT_File::Rename("foobar.dir", "foobar.dir-r");
    NPT_ASSERT(NPT_SUCCEEDED(result));
    
    dirname = "foobar.dir-r";
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file1";
    result = NPT_File::RemoveFile(fname);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file2";
    result = NPT_File::RemoveFile(fname);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    fname = dirname;
    fname += NPT_FilePath::Separator;
    fname += "file3";
    result = NPT_File::RemoveFile(fname);
    NPT_ASSERT(NPT_SUCCEEDED(result));

    result = NPT_File::RemoveDir("foobar.dir-r");
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(!NPT_File::Exists("foobar.dir-r"));

    // paths
    NPT_String test;
    test = NPT_FilePath::BaseName("");
    NPT_ASSERT(test == "");
    test = NPT_FilePath::BaseName("a");
    NPT_ASSERT(test == "a");
    test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b");
    NPT_ASSERT(test == "b");
    test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator);
    NPT_ASSERT(test == "");
    test = NPT_FilePath::BaseName(NPT_FilePath::Separator+"a");
    NPT_ASSERT(test == "a");
    test = NPT_FilePath::BaseName(NPT_FilePath::Separator);
    NPT_ASSERT(test == "");

    test = NPT_FilePath::DirName("");
    NPT_ASSERT(test == "");
    test = NPT_FilePath::DirName("a");
    NPT_ASSERT(test == "");
    test = NPT_FilePath::DirName("a"+NPT_FilePath::Separator+"b");
    NPT_ASSERT(test == "a");
    test = NPT_FilePath::DirName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator);
    NPT_ASSERT(test == "a"+NPT_FilePath::Separator+"b");
    test = NPT_FilePath::DirName(NPT_FilePath::Separator+"a");
    NPT_ASSERT(test == NPT_FilePath::Separator);
    test = NPT_FilePath::DirName(NPT_FilePath::Separator);
    NPT_ASSERT(test == NPT_FilePath::Separator);
    
    // small files
    result = CreateNewFile("small.bin", 0x100, 0x107);
    NPT_ASSERT(NPT_SUCCEEDED(result));

    file = NPT_File("small.bin");
    result = file.Open(NPT_FILE_OPEN_MODE_READ);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_InputStreamReference input;
    file.GetInputStream(input);
    NPT_Position position;
    result = input->Tell(position);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(position == 0);
    NPT_LargeSize large_size = (NPT_LargeSize)0x107 * (NPT_LargeSize)0x100;
    result = input->Seek(large_size-0x107);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    result = input->Tell(position);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(position == large_size-0x107);        
    unsigned char* buffer = new unsigned char[0x107];
    result = input->ReadFully(buffer, 0x107);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    result = input->Tell(position);
    NPT_ASSERT(NPT_SUCCEEDED(result));
    NPT_ASSERT(position == large_size);
    for (unsigned int i=0; i<0x107; i++) {
        NPT_ASSERT(buffer[i] == (unsigned char)i);
    }        
    file.Close();
    NPT_File::RemoveFile(file.GetPath());

    // large files
    if (argc == 2) {
        result = CreateNewFile(argv[1], 0x10000, 0x10007);
        NPT_ASSERT(NPT_SUCCEEDED(result));

        NPT_String new_name = argv[1];
        new_name += ".renamed";
        result = NPT_File::Rename(argv[1], new_name);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        file = NPT_File(new_name);
        result = file.Open(NPT_FILE_OPEN_MODE_READ);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        file.GetInputStream(input);
        result = input->Tell(position);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(position == 0);
        large_size = (NPT_LargeSize)0x10007 * (NPT_LargeSize)0x10000;
        result = input->Seek(large_size-0x10007);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        result = input->Tell(position);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(position == large_size-0x10007);        
        buffer = new unsigned char[0x10007];
        result = input->ReadFully(buffer, 0x10007);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        result = input->Tell(position);
        NPT_ASSERT(NPT_SUCCEEDED(result));
        NPT_ASSERT(position == large_size);
        for (unsigned int i=0; i<0x10007; i++) {
            NPT_ASSERT(buffer[i] == (unsigned char)i);
        }        
        file.Close();
        NPT_File::RemoveFile(new_name);
    }
    
    // test dynamic size
    //NPT_LargeSize             size;
    unsigned char             buff[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};  
    const char*               filename = "pi.\xCF\x80.test";
    NPT_TimeInterval          wait(2.0f);
    
    if (argc > 1) {
        filename = argv[1];
    }
    
    NPT_File                  file1(filename);
    NPT_OutputStreamReference output;

    NPT_ASSERT(NPT_SUCCEEDED(file1.Open(NPT_FILE_OPEN_MODE_CREATE | NPT_FILE_OPEN_MODE_WRITE | NPT_FILE_OPEN_MODE_READ | NPT_FILE_OPEN_MODE_TRUNCATE)));
    NPT_ASSERT(NPT_SUCCEEDED(file1.GetSize(size)));
    NPT_ASSERT(size == 0);
    NPT_ASSERT(NPT_SUCCEEDED(file1.GetOutputStream(output)));
    NPT_ASSERT(NPT_SUCCEEDED(file1.GetInputStream(input)));
    NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position)));
    NPT_ASSERT(position == 0);
    NPT_ASSERT(NPT_SUCCEEDED(input->Tell(position)));
    NPT_ASSERT(position == 0);
    NPT_ASSERT(NPT_SUCCEEDED(output->WriteFully(buff, 16)));
    output->Flush();
    NPT_System::Sleep(wait);
    NPT_ASSERT(NPT_SUCCEEDED(file1.GetSize(size)));
    NPT_ASSERT(size == 16);
    NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position)));
    NPT_ASSERT(NPT_SUCCEEDED(input->GetSize(size)));
    NPT_ASSERT(size == 16);
    NPT_ASSERT(position == 16);
    NPT_ASSERT(NPT_SUCCEEDED(input->Tell(position)));
    NPT_ASSERT(position == 16);
    NPT_ASSERT(NPT_SUCCEEDED(output->Seek(8)));
    NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position)));
    NPT_ASSERT(position == 8);
    
    NPT_File                 file2(filename);
    NPT_InputStreamReference input2;

    NPT_ASSERT(NPT_SUCCEEDED(file2.Open(NPT_FILE_OPEN_MODE_READ)));
    NPT_ASSERT(NPT_SUCCEEDED(file2.GetSize(size)));
    NPT_ASSERT(size == 16);
    NPT_ASSERT(NPT_SUCCEEDED(file2.GetInputStream(input2)));
    NPT_ASSERT(NPT_SUCCEEDED(input2->GetSize(size)));
    NPT_ASSERT(size == 16);
    NPT_ASSERT(NPT_SUCCEEDED(input2->Tell(position)));
    NPT_ASSERT(position == 0);
    NPT_ASSERT(NPT_SUCCEEDED(input2->Seek(8)));
    NPT_ASSERT(NPT_SUCCEEDED(input2->Tell(position)));
    NPT_ASSERT(position == 8);
    
    NPT_ASSERT(NPT_SUCCEEDED(output->WriteFully(buff, 16)));
    output->Flush();
    NPT_System::Sleep(wait);
    NPT_ASSERT(NPT_SUCCEEDED(file2.GetSize(size)));
    NPT_ASSERT(size == 24);
    NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position)));
    NPT_ASSERT(position == 24);
    NPT_ASSERT(NPT_SUCCEEDED(input->Tell(position)));
    NPT_ASSERT(position == 24);
    
    NPT_ASSERT(NPT_SUCCEEDED(input2->GetSize(size)));
    NPT_ASSERT(size == 24);
    NPT_ASSERT(NPT_SUCCEEDED(input2->Seek(20)));
    NPT_ASSERT(NPT_SUCCEEDED(input2->Read(buff, 4, NULL)));
    
    return 0;
}
예제 #20
0
void FrontEnd::processSsdpSearch(SsdpServerTask *task, Interface *intf, const NPT_DataBuffer& data, const NPT_SocketAddress& fromAddr)
{
	do {
		NPT_HttpRequest *req;
		NPT_InputStreamReference inputStream0(new NPT_MemoryStream(data.GetData(), data.GetDataSize()));
		NPT_BufferedInputStream inputStream(inputStream0);
		if (NPT_FAILED(NPT_HttpRequest::Parse(inputStream, NULL, req))) {
			break;
		}

		PtrHolder<NPT_HttpRequest> req1(req);
		if (req->GetMethod().Compare("M-SEARCH") != 0 || req->GetProtocol().Compare(NPT_HTTP_PROTOCOL_1_1) != 0 || req->GetUrl().GetPath().Compare("*") != 0) {
			break;
		}

		NPT_HttpHeader *hdrMan = req->GetHeaders().GetHeader("MAN");
		if (!hdrMan || hdrMan->GetValue().Compare("\"ssdp:discover\"") != 0) {
			break;
		}

		NPT_HttpHeader *hdrHost = req->GetHeaders().GetHeader("HOST");
		if (!hdrHost || (hdrHost->GetValue().Compare("239.255.255.250:1900") != 0 && hdrHost->GetValue().Compare("239.255.255.250") != 0)) {
			break;
		}

		int mx;
		NPT_HttpHeader *hdrMX = req->GetHeaders().GetHeader("MX");
		if (!hdrMX || NPT_FAILED(NPT_ParseInteger(hdrMX->GetValue(), mx)) || mx < 1) {
			break;
		}

		if (mx > 120) {
			mx = 120;
		}

		NPT_HttpHeader *hdrST = req->GetHeaders().GetHeader("ST");
		if (!hdrST) {
			break;
		}

		NPT_List<MatchContext*> matchList;

		NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE);
		sock.Bind(NPT_SocketAddress(intf->m_context.m_ifAddr, 0));
		NPT_SharedVariable waitVar;
		waitVar.SetValue(0);

		{
			ReadLocker locker(m_dsLock);
			for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
				NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
				DeviceImplInfo *info = *it;
				MatchContext *matchContext = new MatchContext();
				if (info->m_deviceImpl->match(hdrST->GetValue(), matchContext->matches)) {
					matchList.Add(matchContext);
					matchContext->deviceUuid = info->m_deviceImpl->uuid();
					matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds;
					matchContext->descPath = info->m_deviceImpl->m_descPath;
					matchContext->httpRoot = info->m_context.m_httpRoot;
				} else {
					delete matchContext;
				}
			}
		}

		SsdpSearchAbortCallback abortCallback(&sock, &waitVar);
		if (task->registerAbortCallback(&abortCallback)) {

			for (NPT_Ordinal i = 0; i < matchList.GetItemCount(); i++) {
				MatchContext *matchContext = *matchList.GetItem(i);

				NPT_String location = NPT_String::Format("http://%s:%d%s%s", intf->m_context.m_ifAddr.ToString().GetChars(), intf->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars());

				bool broken = false;

				for (NPT_Ordinal j = 0; j < matchContext->matches.GetItemCount(); j++) {
					NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(j);

					NPT_Timeout timeout = NPT_System::GetRandomInteger() % (mx * 1000);
					// TODO: wait or not ???
					timeout = 0;
					if (NPT_SUCCEEDED(waitVar.WaitWhileEquals(0, timeout))) {
						break;
					}

					{
						ReadLocker locker(m_dsLock);
						if (m_deviceImplIndex.HasKey(matchContext->deviceUuid)) {
							NPT_TimeStamp ts;
							NPT_System::GetCurrentTimeStamp(ts);
							NPT_String dateStr = NPT_DateTime(ts).ToString(NPT_DateTime::FORMAT_RFC_1123);
							NPT_String resp = NPT_String::Format("HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=%d\r\nDATE: %s\r\nEXT: \r\nLOCATION: %s\r\nSERVER: %s\r\nST: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
														matchContext->expireSeconds, dateStr.GetChars(), location.GetChars(), m_serverHeader.GetChars(), it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
							NPT_DataBuffer packet(resp.GetChars(), resp.GetLength(), false);
							sock.Send(packet, &fromAddr);
						}
					}
				}

				if (broken) {
					break;
				}
			}

			task->unregisterAbortCallback(&abortCallback);
		}

		matchList.Apply(NPT_ObjectDeleter<MatchContext>());
	} while (false);
}
예제 #21
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;
}
예제 #22
0
void FrontEnd::broadcastLocked(DeviceImplInfo *deviceInfo, bool avail)
{
	NPT_TimeStamp ts;
	NPT_System::GetCurrentTimeStamp(ts);

	NPT_List<MatchContext*> matchList;

	if (deviceInfo) {
		deviceInfo->m_updateTS = ts;
		MatchContext *matchContext = new MatchContext();
		if (deviceInfo->m_deviceImpl->match("ssdp:all", matchContext->matches)) {
			matchList.Add(matchContext);
			matchContext->deviceUuid = deviceInfo->m_deviceImpl->uuid();
			matchContext->expireSeconds = deviceInfo->m_deviceImpl->m_expireSeconds;
			matchContext->descPath = deviceInfo->m_deviceImpl->m_descPath;
			matchContext->httpRoot = deviceInfo->m_context.m_httpRoot;
		} else {
			delete matchContext;
		}
	} else {
		for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
			NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
			DeviceImplInfo *info = *it;
			info->m_updateTS = ts;
			MatchContext *matchContext = new MatchContext();
			if (info->m_deviceImpl->match("ssdp:all", matchContext->matches)) {
				matchList.Add(matchContext);
				matchContext->deviceUuid = info->m_deviceImpl->uuid();
				matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds;
				matchContext->descPath = info->m_deviceImpl->m_descPath;
				matchContext->httpRoot = info->m_context.m_httpRoot;
			} else {
				delete matchContext;
			}
		}
	}

	NPT_SocketAddress targetAddr(NPT_IpAddress(239, 255, 255, 250), 1900);

	for (NPT_Ordinal i = 0; i < m_ifList.GetItemCount(); i++) {
		Interface *nif = *m_ifList.GetItem(i);
		NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE);
		sock.Bind(NPT_SocketAddress(nif->m_context.m_ifAddr, 0));
		for (NPT_Ordinal j = 0; j < matchList.GetItemCount(); j++) {
			MatchContext *matchContext = *matchList.GetItem(j);
			NPT_String location = NPT_String::Format("http://%s:%d%s%s", nif->m_context.m_ifAddr.ToString().GetChars(), nif->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars());
			for (NPT_Ordinal k = 0; k < matchContext->matches.GetItemCount(); k++) {
				NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(k);
				NPT_String msg;
				if (avail) {
					//msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=%d\r\nLOCATION: %s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\n\r\n",
					//		matchContext->expireSeconds, location.GetChars(), it2->m_st.GetChars(), m_serverHeader.GetChars(), it2->m_usn.GetChars());
					msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=%d\r\nLOCATION: %s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
											matchContext->expireSeconds, location.GetChars(), it2->m_st.GetChars(), m_serverHeader.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
				} else {
					msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nNT: %s\r\nNTS: ssdp:byebye\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
											it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
				}
				NPT_DataBuffer packet(msg.GetChars(), msg.GetLength(), false);
				sock.Send(packet, &targetAddr);
			}
		}
	}

	matchList.Apply(NPT_ObjectDeleter<MatchContext>());
}