예제 #1
0
/*----------------------------------------------------------------------
|   PLT_SsdpDeviceSearchResponseInterfaceIterator class
+---------------------------------------------------------------------*/
NPT_Result
PLT_SsdpDeviceSearchResponseInterfaceIterator::operator()(NPT_NetworkInterface*& net_if) const 
{
    const NPT_SocketAddress* remote_addr = &m_RemoteAddr;

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

    // don't try to bind on port 1900 or connect will fail later
    NPT_UdpSocket socket;
    //socket.Bind(NPT_SocketAddress(NPT_IpAddress::Any, 1900), true);

    // by connecting, the kernel chooses which interface to use to route to the remote
    // this is the IP we should use in our Location URL header
    NPT_CHECK_WARNING(socket.Connect(m_RemoteAddr, 5000));
    NPT_SocketInfo info;
    socket.GetInfo(info);

    // did we successfully connect and found out which interface is used?
    if (info.local_address.GetIpAddress().AsLong()) {
        // check that the interface the kernel chose matches the interface
        // we wanted to send on
        if ((*niaddr).GetPrimaryAddress().AsLong() != info.local_address.GetIpAddress().AsLong()) {
            return NPT_SUCCESS;
        }

        // socket already connected, so we don't need to specify where to go
        remote_addr = NULL;
    }

    NPT_HttpResponse response(200, "OK", NPT_HTTP_PROTOCOL_1_1);
    PLT_UPnPMessageHelper::SetLocation(response, m_Device->GetDescriptionUrl(info.local_address.GetIpAddress().ToString()));
    PLT_UPnPMessageHelper::SetLeaseTime(response, m_Device->GetLeaseTime());
    PLT_UPnPMessageHelper::SetServer(response, PLT_HTTP_DEFAULT_SERVER, false);
    response.GetHeaders().SetHeader("EXT", "");

    // process search response twice to be DLNA compliant
#if defined(PLATINUM_UPNP_SPECS_STRICT)
    {
        //NPT_UdpSocket socket;
        NPT_CHECK_SEVERE(m_Device->SendSsdpSearchResponse(response, socket, m_ST, remote_addr));
    }
    NPT_System::Sleep(NPT_TimeInterval(PLT_DLNA_SSDP_DELAY_GROUP));
#endif
    {
        //NPT_UdpSocket socket;
        NPT_CHECK_SEVERE(m_Device->SendSsdpSearchResponse(response, socket, m_ST, remote_addr));
    }
    
    return NPT_SUCCESS;
}
예제 #2
0
파일: PltSsdp.cpp 프로젝트: AWilco/xbmc
/*----------------------------------------------------------------------
|   PLT_SsdpDeviceSearchResponseInterfaceIterator class
+---------------------------------------------------------------------*/
NPT_Result
PLT_SsdpDeviceSearchResponseInterfaceIterator::operator()(NPT_NetworkInterface*& net_if) const 
{
    NPT_Result res;
    const NPT_SocketAddress* remote_addr = &m_RemoteAddr;

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

    NPT_UdpSocket socket;

    // by connecting, the kernel chooses which interface to use to route to the remote
    // this is the IP we should use in our Location URL header
    if (NPT_FAILED(res = socket.Connect(m_RemoteAddr, 5000))) {
        return res;
    }
    NPT_SocketInfo info;
    socket.GetInfo(info);

    // did we successfully connect and found out which interface is used?
    if (info.local_address.GetIpAddress().AsLong()) {
        // check that the interface the kernel chose matches the interface
        // we wanted to send on
        if ((*niaddr).GetPrimaryAddress().AsLong() != info.local_address.GetIpAddress().AsLong()) {
            return NPT_SUCCESS;
        }

        // socket already connected, so we don't need to specify where to go
        remote_addr = NULL;
    }

    NPT_HttpResponse response(200, "OK", NPT_HTTP_PROTOCOL_1_1);
    PLT_UPnPMessageHelper::SetLocation(response, m_Device->GetDescriptionUrl((*niaddr).GetPrimaryAddress().ToString()));
    PLT_UPnPMessageHelper::SetLeaseTime(response, (NPT_Timeout)((float)m_Device->GetLeaseTime()));
    PLT_UPnPMessageHelper::SetServer(response, NPT_HttpServer::m_ServerHeader, false);
    response.GetHeaders().SetHeader("EXT", "");

    // process search response twice to be NMPR compliant
    NPT_CHECK_SEVERE(m_Device->SendSsdpSearchResponse(response, socket, m_ST, remote_addr));
    NPT_CHECK_SEVERE(m_Device->SendSsdpSearchResponse(response, socket, m_ST, remote_addr));

    return NPT_SUCCESS;
}
예제 #3
0
파일: PltSsdp.cpp 프로젝트: Castlecard/plex
/*----------------------------------------------------------------------
|   PLT_SsdpDeviceSearchResponseInterfaceIterator class
+---------------------------------------------------------------------*/
NPT_Result
PLT_SsdpDeviceSearchResponseInterfaceIterator::operator()(NPT_NetworkInterface*& net_if) const 
{
    NPT_Result res;
    const NPT_SocketAddress* remote_addr = &m_RemoteAddr;

    NPT_List<NPT_NetworkInterfaceAddress>::Iterator netaddr = net_if->GetAddresses().GetFirstItem();
    if (!netaddr) {
        return NPT_SUCCESS;
    }

    // don't respond on loopback
    // windows media player on vista sends it's M-SEARCH to loopback interface if it's a local clients sometimes
    //if (net_if->GetFlags() & NPT_NETWORK_INTERFACE_FLAG_LOOPBACK) {
    //    return NPT_SUCCESS;
    //}

    NPT_SocketAddress local_addr((*netaddr).GetPrimaryAddress(), 0); // 1900?
    NPT_UdpSocket     socket;
    //if (NPT_FAILED(res = socket.Bind(local_addr))) {
    //    return res;
    //}

    // get the output socket stream
    NPT_OutputStreamReference stream;
    if (NPT_FAILED(res = socket.GetOutputStream(stream))) {
        return res;
    }

    NPT_HttpResponse response(200, "OK", NPT_HTTP_PROTOCOL_1_1);

    // get location URL based on ip address of interface
    // by connecting, the kernel chooses which interface to use to route to the remote
    // this is the IP we should use in our Location
    if (NPT_FAILED(res = socket.Connect(m_RemoteAddr, 5000))) {
        return res;
    }
    NPT_SocketInfo info;
    socket.GetInfo(info);

    // did we successfully connect and found out which interface is used?
    if (info.local_address.GetIpAddress().AsLong()) {
        // check that the interface the kernel chose matches the interface
        // we wanted to send on
        // FIXME: Should we fail instead and stop sending a response once we get NPT_SUCCESS?
        if (local_addr.GetIpAddress().AsLong() != info.local_address.GetIpAddress().AsLong()) {
            return NPT_SUCCESS;
        }

        // already connected, so we don't need to specify where to go
        remote_addr = NULL;
    }

    PLT_UPnPMessageHelper::SetLocation(response, m_Device->GetDescriptionUrl(local_addr.GetIpAddress().ToString()));
    PLT_UPnPMessageHelper::SetLeaseTime(response, (NPT_Timeout)((float)m_Device->GetLeaseTime()));
    PLT_UPnPMessageHelper::SetServer(response, "UPnP/1.0, Platinum UPnP SDK/" PLT_PLATINUM_VERSION_STRING, false);
    response.GetHeaders().SetHeader("EXT", "");

    // process search response twice to be NMPR compliant
    NPT_CHECK_SEVERE(m_Device->SendSsdpSearchResponse(response, socket, m_ST, remote_addr));
    NPT_CHECK_SEVERE(m_Device->SendSsdpSearchResponse(response, socket, m_ST, remote_addr));

    return NPT_SUCCESS;
}