Пример #1
0
/*----------------------------------------------------------------------
|   PLT_SsdpAnnounceInterfaceIterator class
+---------------------------------------------------------------------*/
NPT_Result
PLT_SsdpAnnounceInterfaceIterator::operator()(NPT_NetworkInterface*& net_if) const 
{
    // don't use this interface address if it's not broadcast capable
    if (m_Broadcast && !(net_if->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_BROADCAST)) {
        return NPT_FAILURE;
    }

    NPT_List<NPT_NetworkInterfaceAddress>::Iterator niaddr = 
        net_if->GetAddresses().GetFirstItem();
    if (!niaddr) return NPT_FAILURE;

    // Remove disconnected interfaces
    NPT_IpAddress addr = (*niaddr).GetPrimaryAddress();
    if (!addr.ToString().Compare("0.0.0.0")) return NPT_FAILURE;
    
    if (!m_Broadcast && 
        !(net_if->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_MULTICAST) && 
        !(net_if->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK)) {
        NPT_LOG_INFO_2("Not a valid interface: %s (flags: %d)", 
                       (const char*)addr.ToString(), net_if->GetFlags());
        return NPT_FAILURE;
    }

    NPT_HttpUrl            url;
    NPT_UdpMulticastSocket multicast_socket;
    NPT_UdpSocket          broadcast_socket;
    NPT_UdpSocket*         socket;

    if (m_Broadcast) {
        url = NPT_HttpUrl((*niaddr).GetBroadcastAddress().ToString(), 1900, "*");
        socket = &broadcast_socket;
    } else {
        url = NPT_HttpUrl("239.255.255.250", 1900, "*");    
        NPT_CHECK_SEVERE(multicast_socket.SetInterface(addr));
        socket = &multicast_socket;
        multicast_socket.SetTimeToLive(PLT_Constants::GetInstance().GetAnnounceMulticastTimeToLive());
    }
    
    NPT_HttpRequest req(url, "NOTIFY", NPT_HTTP_PROTOCOL_1_1);
    PLT_HttpHelper::SetHost(req, "239.255.255.250:1900");
    
    // Location header valid only for ssdp:alive or ssdp:update messages
    if (m_Type != PLT_ANNOUNCETYPE_BYEBYE) {
        PLT_UPnPMessageHelper::SetLocation(req, m_Device->GetDescriptionUrl(addr.ToString()));
    }

    NPT_CHECK_SEVERE(m_Device->Announce(req, *socket, m_Type));

#if defined(PLATINUM_UPNP_SPECS_STRICT)
    // delay alive only as we don't want to delay when stopping
    if (m_Type != PLT_ANNOUNCETYPE_BYEBYE) {
        NPT_System::Sleep(NPT_TimeInterval(PLT_DLNA_SSDP_DELAY_GROUP));
    }
    
    NPT_CHECK_SEVERE(m_Device->Announce(req, *socket, m_Type));
#endif

    return NPT_SUCCESS;
}
Пример #2
0
/*----------------------------------------------------------------------
|   PLT_HttpServer::Start
+---------------------------------------------------------------------*/
NPT_Result
PLT_HttpServer::Start()
{
    NPT_Result res = NPT_FAILURE;
    
    // we can't restart an aborted server
    if (m_Aborted) return NPT_ERROR_INVALID_STATE;
    
    // if we're given a port for our http server, try it
    if (m_Port) {
        res = SetListenPort(m_Port, m_ReuseAddress);
        // return right away if failed and not allowed to try again randomly
        if (NPT_FAILED(res) && !m_AllowRandomPortOnBindFailure) {
            NPT_CHECK_SEVERE(res);
        }
    }
    
    // try random port now
    if (!m_Port || NPT_FAILED(res)) {
        int retries = 100;
        do {    
            int random = NPT_System::GetRandomInteger();
            int port = (unsigned short)(1024 + (random % 1024));
            if (NPT_SUCCEEDED(SetListenPort(port, m_ReuseAddress))) {
                break;
            }
        } while (--retries > 0);

        if (retries == 0) NPT_CHECK_SEVERE(NPT_FAILURE);
    }

    // keep track of port server has successfully bound
    m_Port = m_BoundPort;

    // Tell server to try to listen to more incoming sockets
    // (this could fail silently)
    if (m_TaskManager->GetMaxTasks() > 20) {
        m_Socket.Listen(m_TaskManager->GetMaxTasks());
    }
    
    // start a task to listen for incoming connections
    // and keep it around so we can abort the server
    m_HttpListenTask = new PLT_HttpListenTask(this, &m_Socket, false);
    m_TaskManager->StartTask(m_HttpListenTask, NULL, false);

    NPT_SocketInfo info;
    m_Socket.GetInfo(info);
    NPT_LOG_INFO_2("HttpServer listening on %s:%d", 
        (const char*)info.local_address.GetIpAddress().ToString(), 
        m_Port);
    return NPT_SUCCESS;
}
Пример #3
0
NPT_Result TaskGroup::wait(NPT_Timeout timeout)
{
	NPT_Result nr;
	{
		WriteLocker locker(m_stateLock);
		if (m_state != State_Stopping) {
			return NPT_ERROR_INVALID_STATE;
		}
	}

	if (timeout == NPT_TIMEOUT_INFINITE) {
		/*for (NPT_Ordinal i = 0; i < m_threadList.GetItemCount(); i++) {
			TaskThread *thread = *m_threadList.GetItem(i);
			thread->Wait();
			delete thread;
		}
		m_threadList.Clear();*/
		NPT_LOG_INFO_2("TaskGroup %p waiting for %d threads", this, m_threadList.GetItemCount());
		while (m_threadList.GetItemCount() > 0) {
			NPT_Cardinal count = m_threadList.GetItemCount();
			for (NPT_Ordinal i = 0; i < count; ) {
				NPT_List<TaskThread*>::Iterator it = m_threadList.GetItem(i);
				TaskThread *thread = *it;
				NPT_LOG_INFO_2("TaskGroup %p waiting for thread %p", this, thread);
				if (NPT_SUCCEEDED(thread->Wait(3000))) {
					NPT_LOG_INFO_2("TaskGroup %p waited thread %p, fine!", this, thread);
					delete thread;
					m_threadList.Erase(it);
					count--;
				} else {
					NPT_LOG_INFO_2("TaskGroup %p thread %p still pending, continue", this, thread);
					i++;
				}
			}
		}
	} else {
		NPT_Timeout waitTick = 10;
		if (waitTick > timeout) {
			waitTick = timeout;
		}

		NPT_TimeStamp ts1, ts2;
		NPT_Timeout totalTick = 0;

		while (m_threadList.GetItemCount() != 0 && timeout >= totalTick) {

			NPT_Cardinal count = m_threadList.GetItemCount();
			NPT_Ordinal i = 0;
			while (i < count) {
				NPT_List<TaskThread*>::Iterator it = m_threadList.GetItem(i);
				TaskThread *thread = *it;
				NPT_System::GetCurrentTimeStamp(ts1);
				nr = thread->Wait(waitTick);
				NPT_System::GetCurrentTimeStamp(ts2);
				totalTick += (ts2 - ts1).ToMillis();

				if (NPT_SUCCEEDED(nr)) {
					m_threadList.Erase(it);
					delete thread;
					--count;
				} else {
					i++;
				}

				if (timeout >= totalTick) {
					NPT_Timeout remainTick = timeout - totalTick;
					if (waitTick > remainTick) {
						waitTick = remainTick;
					}
				} else {
					waitTick = 0;
				}
			}
		}
	}

	if (m_threadList.GetItemCount() == 0) {
		m_state = State_Stopped;
	}

	return m_threadList.GetItemCount() == 0 ? NPT_SUCCESS : NPT_ERROR_TIMEOUT;
}