/*---------------------------------------------------------------------- | NPT_PSPQueue::Push +---------------------------------------------------------------------*/ NPT_Result NPT_PSPQueue::Push(NPT_QueueItem* item) { // lock the mutex that protects the list m_Items.Lock(); // 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_PSPQueue::Push - waiting for queue to empty\n"); // pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex); // } //} // add the item to the list 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 m_Items.Unlock(); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | PLT_UPnP::Start() +---------------------------------------------------------------------*/ NPT_Result PLT_UPnP::Start() { NPT_LOG_INFO("Starting UPnP..."); NPT_AutoLock lock(m_Lock); if (m_Started == true) NPT_CHECK_SEVERE(NPT_ERROR_INVALID_STATE); NPT_List<NPT_IpAddress> ips; PLT_UPnPMessageHelper::GetIPAddresses(ips); /* Create multicast socket and bind on 1900. If other apps didn't play nicely by setting the REUSE_ADDR flag, this could fail */ NPT_UdpMulticastSocket* socket = new NPT_UdpMulticastSocket(); NPT_CHECK_SEVERE(socket->Bind(NPT_SocketAddress(NPT_IpAddress::Any, 1900), true)); /* Join multicast group for every ip we found */ NPT_CHECK_SEVERE(ips.ApplyUntil(PLT_SsdpInitMulticastIterator(socket), NPT_UntilResultNotEquals(NPT_SUCCESS))); /* create the ssdp listener */ m_SsdpListenTask = new PLT_SsdpListenTask(socket); NPT_CHECK_SEVERE(m_TaskManager.StartTask(m_SsdpListenTask)); /* start devices & ctrlpoints */ // TODO: Starting devices and ctrlpoints could fail? m_CtrlPoints.Apply(PLT_UPnP_CtrlPointStartIterator(m_SsdpListenTask)); m_Devices.Apply(PLT_UPnP_DeviceStartIterator(m_SsdpListenTask)); m_Started = true; return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | PLT_StateVariable::ValidateValue +---------------------------------------------------------------------*/ NPT_Result PLT_StateVariable::ValidateValue(const char* value) { if (m_DataType.Compare("string", true) == 0) { // if we have a value allowed restriction, make sure the value is in our list if (m_AllowedValues.GetItemCount()) { // look for a comma separated list NPT_String _value = value; NPT_List<NPT_String> values = _value.Split(","); NPT_List<NPT_String>::Iterator val = values.GetFirstItem(); while (val) { val->Trim(" "); if (!m_AllowedValues.Find(NPT_StringFinder(*val))) { #if defined(NPT_CONFIG_ENABLE_LOGGING) NPT_LOG_WARNING_2("Invalid value of %s for state variable %s", (const char*)*val, (const char*)m_Name); for (unsigned long i=0; i < m_AllowedValues.GetItemCount(); i++) { NPT_String *val2 = *m_AllowedValues.GetItem(i); NPT_LOG_WARNING_1("Allowed: %s", (const char*)*val2); } #endif return NPT_ERROR_INVALID_PARAMETERS; } ++val; } } } // TODO: there are more to it than allowed values, we need to test for range, etc.. return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_File::GetRoots +---------------------------------------------------------------------*/ NPT_Result NPT_File::GetRoots(NPT_List<NPT_String>& roots) { roots.Clear(); roots.Add("/"); return NPT_SUCCESS; }
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; }
/*---------------------------------------------------------------------- | 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_File::RemoveDir +---------------------------------------------------------------------*/ NPT_Result NPT_File::RemoveDir(const char* path, bool force_if_not_empty) { NPT_String root_path = path; // normalize path separators root_path.Replace((NPT_FilePath::Separator[0] == '/')?'\\':'/', NPT_FilePath::Separator); // remove superfluous delimiters at the end root_path.TrimRight(NPT_FilePath::Separator); // remove all entries in the directory if required if (force_if_not_empty) { // enumerate all entries NPT_File dir(root_path); NPT_List<NPT_String> entries; NPT_CHECK_WARNING(dir.ListDir(entries)); for (NPT_List<NPT_String>::Iterator it = entries.GetFirstItem(); it; ++it) { NPT_File::Remove(NPT_FilePath::Create(root_path, *it), true); } } // remove the (now empty) directory return NPT_File::RemoveDir(root_path); }
/*---------------------------------------------------------------------- | NPT_PSPQueue::Pop +---------------------------------------------------------------------*/ NPT_Result NPT_PSPQueue::Pop(NPT_QueueItem*& item, NPT_Boolean blocking) { // lock the mutex that protects the list m_Items.Lock(); NPT_Result result; //if (blocking) { // while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) { // // no item in the list, wait for one // //NPT_Debug(":: NPT_PSPQueue::Pop - waiting for queue to fill up\n"); // pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex); // } //} 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 m_Items.Unlock(); return result; }
/*---------------------------------------------------------------------- | PLT_MediaServer::ParseSort +---------------------------------------------------------------------*/ NPT_Result PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list) { // reset output params first list.Clear(); // easy out if (sort.GetLength() == 0 || sort == "*") return NPT_SUCCESS; list = sort.Split(","); // verify each property has a namespace NPT_List<NPT_String>::Iterator property = list.GetFirstItem(); while (property) { NPT_List<NPT_String> parsed_property = (*property).Split(":"); if (parsed_property.GetItemCount() != 2) parsed_property = (*property).Split("@"); if (parsed_property.GetItemCount() != 2 || (!(*property).StartsWith("-") && !(*property).StartsWith("+"))) { NPT_LOG_WARNING_1("Invalid SortCriteria property %s", (*property).GetChars()); return NPT_FAILURE; } property++; } return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | 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; }
NPT_List<const Object*> Container::getChildren() const { NPT_List<const Object*> ls; for (NPT_Ordinal i = 0; i < childCount(); i++) { ls.Add(childAt(i)); } return ls; }
/*---------------------------------------------------------------------- | 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_File::ListDir +---------------------------------------------------------------------*/ NPT_Result NPT_File::ListDir(const char* path, NPT_List<NPT_String>& entries, NPT_Ordinal start /* = 0 */, NPT_Cardinal max /* = 0 */) { // default return value entries.Clear(); // check the arguments if (path == NULL) return NPT_ERROR_INVALID_PARAMETERS; // list the entries DIR *directory = opendir(path); if (directory == NULL) return NPT_ERROR_NO_SUCH_ITEM; NPT_Cardinal count = 0; for (;;) { struct dirent* entry_pointer = NULL; #if defined(NPT_CONFIG_HAVE_READDIR_R) struct dirent entry; int result = readdir_r(directory, &entry, &entry_pointer); if (result != 0 || entry_pointer == NULL) break; #else entry_pointer = readdir(directory); if (entry_pointer == NULL) break; #endif // ignore odd names if (entry_pointer->d_name[0] == '\0') continue; // ignore . and .. if (entry_pointer->d_name[0] == '.' && entry_pointer->d_name[1] == '\0') { continue; } if (entry_pointer->d_name[0] == '.' && entry_pointer->d_name[1] == '.' && entry_pointer->d_name[2] == '\0') { continue; } // continue if we still have some items to skip if (start > 0) { --start; continue; } entries.Add(NPT_String(entry_pointer->d_name)); // stop when we have reached the maximum requested if (max && ++count == max) break; } closedir(directory); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | NPT_PosixQueue::Pop +---------------------------------------------------------------------*/ NPT_Result NPT_PosixQueue::Pop(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; if (timeout) { while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) { // no item in the list, wait for one ++m_PoppersWaitingCount; if (timeout == NPT_TIMEOUT_INFINITE) { pthread_cond_wait(&m_CanPopCondition, &m_Mutex); --m_PoppersWaitingCount; } else { int wait_res = pthread_cond_timedwait(&m_CanPopCondition, &m_Mutex, &timed); --m_PoppersWaitingCount; if (wait_res == ETIMEDOUT) { result = NPT_ERROR_TIMEOUT; break; } } if (m_Aborting) { result = NPT_ERROR_INTERRUPTED; break; } } } else { result = m_Items.PopHead(item); } // wake up any thread that my be waiting to push if (m_MaxItems && (result == NPT_SUCCESS) && m_PushersWaitingCount) { pthread_cond_broadcast(&m_CanPushCondition); } // unlock the mutex pthread_mutex_unlock(&m_Mutex); return result; }
/*---------------------------------------------------------------------- | NPT_PosixQueue::Peek +---------------------------------------------------------------------*/ NPT_Result NPT_PosixQueue::Peek(NPT_QueueItem*& item, NPT_Timeout timeout) { struct timespec timed; if (timeout != NPT_TIMEOUT_INFINITE) { NPT_CHECK(GetTimeOut(timeout, timed)); } // lock the mutex that protects the list if (pthread_mutex_lock(&m_Mutex)) { return NPT_FAILURE; } NPT_Result result = NPT_SUCCESS; NPT_List<NPT_QueueItem*>::Iterator head = m_Items.GetFirstItem(); if (timeout) { while (!head) { // no item in the list, wait for one ++m_PoppersWaitingCount; if (timeout == NPT_TIMEOUT_INFINITE) { pthread_cond_wait(&m_CanPopCondition, &m_Mutex); --m_PoppersWaitingCount; } else { int wait_res = pthread_cond_timedwait(&m_CanPopCondition, &m_Mutex, &timed); --m_PoppersWaitingCount; if (wait_res == ETIMEDOUT) { result = NPT_ERROR_TIMEOUT; break; } } if (m_Aborting) { result = NPT_ERROR_INTERRUPTED; break; } head = m_Items.GetFirstItem(); } } else { if (!head) result = NPT_ERROR_LIST_EMPTY; } item = head?*head:NULL; // unlock the mutex pthread_mutex_unlock(&m_Mutex); return result; }
/*---------------------------------------------------------------------- | PLT_MediaServer::ParseTagList +---------------------------------------------------------------------*/ NPT_Result PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags) { // reset output params first tags.Clear(); NPT_List<NPT_String> split = updates.Split(","); NPT_XmlNode* node = NULL; NPT_XmlElementNode* didl_partial = NULL; NPT_XmlParser parser; // as these are single name value pairs, separated by commas we wrap in a tag // to create a valid tree NPT_String xml("<TagValueList>"); for (NPT_List<NPT_String>::Iterator entry = split.GetFirstItem(); entry; entry++) { NPT_String& element = (*entry); if (element.IsEmpty()) xml.Append("<empty>empty</empty>"); else xml.Append(element); } xml.Append("</TagValueList>"); NPT_LOG_FINE("Parsing TagList..."); NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup); if (!node || !node->AsElementNode()) { NPT_LOG_SEVERE("Invalid node type"); goto cleanup; } didl_partial = node->AsElementNode(); if (didl_partial->GetTag().Compare("TagValueList", true)) { NPT_LOG_SEVERE("Invalid node tag"); goto cleanup; } for (NPT_List<NPT_XmlNode*>::Iterator children = didl_partial->GetChildren().GetFirstItem(); children; children++) { NPT_XmlElementNode* child = (*children)->AsElementNode(); if (!child) continue; tags[child->GetTag()] = *child->GetText(); } return NPT_SUCCESS; cleanup: if (node) delete node; return NPT_FAILURE; }
/*---------------------------------------------------------------------- | 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(); }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /* argc */, char** argv) { /* parse command line */ ParseCommandLine(argv+1); PLT_UPnP upnp(1900, !Options.broadcast); PLT_DeviceHostReference device( new PLT_FileMediaServer( Options.path, Options.friendly_name?Options.friendly_name:"Platinum UPnP Media Server", false, "SAMEDEVICEGUID", (NPT_UInt16)Options.port) ); NPT_List<NPT_String> list; NPT_CHECK_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(list)); NPT_String ip = *(list.GetFirstItem()); //device->m_PresentationURL = NPT_HttpUrl(ip, 80, "/").ToString(); device->m_ModelDescription = "Platinum File Media Server"; device->m_ModelURL = "http://www.plutinosoft.com/"; device->m_ModelNumber = "1.0"; device->m_ModelName = "Platinum File Media Server"; device->m_Manufacturer = "Plutinosoft"; device->m_ManufacturerURL = "http://www.plutinosoft.com/"; if (Options.broadcast) device->SetBroadcast(true); upnp.AddDevice(device); NPT_String uuid = device->GetUUID(); NPT_CHECK_SEVERE(upnp.Start()); NPT_LOG_INFO("Press 'q' to quit."); char buf[256]; while (gets(buf)) { if (*buf == 'q') break; } upnp.Stop(); return 0; }
/*---------------------------------------------------------------------- | PLT_SsdpListenTask::DoInit +---------------------------------------------------------------------*/ void PLT_SsdpListenTask::DoInit() { if (m_Multicast) { if (m_JoinHard) { NPT_List<NPT_IpAddress> ips; PLT_UPnPMessageHelper::GetIPAddresses(ips); /* Join multicast group for every ip we found */ ips.Apply(PLT_SsdpInitMulticastIterator((NPT_UdpMulticastSocket*)m_Socket)); } else { NPT_IpAddress addr; addr.ResolveName("239.255.255.250"); ((NPT_UdpMulticastSocket*)m_Socket)->JoinGroup(addr, NPT_IpAddress::Any); } } }
/*---------------------------------------------------------------------- | 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); } }
/*---------------------------------------------------------------------- | NPT_File::ListDir +---------------------------------------------------------------------*/ NPT_Result NPT_File::ListDir(const char* path, NPT_List<NPT_String>& entries, NPT_Ordinal start /* = 0 */, NPT_Cardinal max /* = 0 */) { NPT_WIN32_USE_CHAR_CONVERSION; // default return value entries.Clear(); // check the arguments if (path == NULL || path[0] == '\0') return NPT_ERROR_INVALID_PARAMETERS; // construct a path name with a \* wildcard at the end NPT_String path_pattern = path; if (path_pattern.EndsWith("\\") || path_pattern.EndsWith("/")) { path_pattern += "*"; } else { path_pattern += "\\*"; } // list the entries WIN32_FIND_DATAW find_data; HANDLE find_handle = FindFirstFileW(NPT_WIN32_A2W(path_pattern.GetChars()), &find_data); if (find_handle == INVALID_HANDLE_VALUE) return MapError(GetLastError()); NPT_Cardinal count = 0; do { if (NPT_File_ProcessFindData(&find_data)) { // continue if we still have entries to skip if (start > 0) { --start; continue; } entries.Add(NPT_WIN32_W2A(find_data.cFileName)); // stop when we have reached the maximum requested if (max && ++count == max) return NPT_SUCCESS; } } while (FindNextFileW(find_handle, &find_data)); DWORD last_error = GetLastError(); FindClose(find_handle); if (last_error != ERROR_NO_MORE_FILES) return MapError(last_error); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_File::GetRoots +---------------------------------------------------------------------*/ NPT_Result NPT_File::GetRoots(NPT_List<NPT_String>& roots) { roots.Clear(); #if defined(_WIN32_WCE) || defined(_XBOX) return NPT_ERROR_NOT_IMPLEMENTED; #else DWORD drives = GetLogicalDrives(); for (unsigned int i=0; i<26; i++) { if (drives & (1<<i)) { char drive_name[4] = {'A'+i, ':', '\\', 0}; roots.Add(drive_name); } } return NPT_SUCCESS; #endif }
/*---------------------------------------------------------------------- | NPT_Win32Queue::Peek +---------------------------------------------------------------------*/ NPT_Result NPT_Win32Queue::Peek(NPT_QueueItem*& item, NPT_Timeout timeout) { // default value item = NULL; // lock the mutex that protects the list NPT_CHECK(m_Mutex.Lock()); NPT_Result result = NPT_SUCCESS; NPT_List<NPT_QueueItem*>::Iterator head = m_Items.GetFirstItem(); if (timeout) { while (!head) { // no item in the list, wait for one // reset the condition to indicate that the queue is empty m_CanPopCondition->Reset(); // unlock the mutex so that another thread can push m_Mutex.Unlock(); // wait for the condition to signal that we can pop NPT_Result result = m_CanPopCondition->Wait(timeout); if (NPT_FAILED(result)) return result; // relock the mutex so that we can check the list again NPT_CHECK(m_Mutex.Lock()); // try again head = m_Items.GetFirstItem(); } } else { if (!head) result = NPT_ERROR_LIST_EMPTY; } if (head) item = *head; // unlock the mutex m_Mutex.Unlock(); return result; }
/*---------------------------------------------------------------------- | NPT_File::ListDir +---------------------------------------------------------------------*/ NPT_Result NPT_File::ListDir(const char* path, NPT_List<NPT_String>& entries, NPT_Ordinal start /* = 0 */, NPT_Cardinal max /* = 0 */) { // default return value entries.Clear(); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_Win32Queue::Pop +---------------------------------------------------------------------*/ NPT_Result NPT_Win32Queue::Pop(NPT_QueueItem*& item, NPT_Timeout timeout) { // default value item = NULL; // lock the mutex that protects the list NPT_CHECK(m_Mutex.Lock()); NPT_Result result; if (timeout) { while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) { // no item in the list, wait for one // reset the condition to indicate that the queue is empty m_CanPopCondition->Reset(); // unlock the mutex so that another thread can push m_Mutex.Unlock(); // wait for the condition to signal that we can pop NPT_Result result = m_CanPopCondition->Wait(timeout); if (NPT_FAILED(result)) return result; // relock the mutex so that we can check the list again NPT_CHECK(m_Mutex.Lock()); } } else { result = m_Items.PopHead(item); } if (m_MaxItems && (result == NPT_SUCCESS)) { // wake up the threads waiting to push m_CanPushCondition->Signal(); } // unlock the mutex m_Mutex.Unlock(); return result; }
/*---------------------------------------------------------------------- | NPT_String::Join +---------------------------------------------------------------------*/ NPT_String NPT_String::Join(NPT_List<NPT_String>& args, const char* separator) { NPT_String output; NPT_List<NPT_String>::Iterator arg = args.GetFirstItem(); while (arg) { output += *arg; if (++arg) output += separator; } return output; }