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); } }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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(); }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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); } }
/*---------------------------------------------------------------------- | 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); }
/*---------------------------------------------------------------------- | 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(); }
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; }
/*---------------------------------------------------------------------- | 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; }
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; } }
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; }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | 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; }
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); }
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; }
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>()); }