예제 #1
0
파일: PltSsdp.cpp 프로젝트: Castlecard/plex
/*----------------------------------------------------------------------
|   PLT_SsdpSender::SendSsdp
+---------------------------------------------------------------------*/
NPT_Result
PLT_SsdpSender::SendSsdp(NPT_HttpResponse&  response,
                         const char*        usn,
                         const char*        target,
                         NPT_UdpSocket&     socket,
                         bool               notify, 
                         const NPT_SocketAddress* addr /* = NULL */)
{
    NPT_CHECK_SEVERE(FormatPacket(response, usn, target, socket, notify));

    // logging
    NPT_LOG_FINE("Sending SSDP:");
    PLT_LOG_HTTP_MESSAGE(NPT_LOG_LEVEL_FINE, &response);

    // use a memory stream to write all the data
    NPT_MemoryStream stream;
    NPT_Result res = response.Emit(stream);
    if (NPT_FAILED(res)) return res;

    // copy stream into a data packet and send it
    NPT_LargeSize size;
    stream.GetSize(size);
    if (size != (NPT_Size)size) return NPT_ERROR_OUT_OF_RANGE;

    NPT_DataBuffer packet(stream.GetData(), (NPT_Size)size);
    return socket.Send(packet, addr);
}
예제 #2
0
/*----------------------------------------------------------------------
|   PLT_SsdpSender::SendSsdp
+---------------------------------------------------------------------*/
NPT_Result
PLT_SsdpSender::SendSsdp(NPT_HttpRequest&   request,
                         const char*        usn,
                         const char*        target,
                         NPT_UdpSocket&     socket,
                         bool               notify,
                         const NPT_SocketAddress* addr /* = NULL */)
{
    NPT_CHECK_SEVERE(FormatPacket(request, usn, target, socket, notify));

    // logging
    NPT_String prefix = NPT_String::Format("Sending SSDP %s packet for %s",
        (const char*)request.GetMethod(), 
        usn);
    PLT_LOG_HTTP_MESSAGE(NPT_LOG_LEVEL_FINER, prefix, &request);

    // use a memory stream to write all the data
    NPT_MemoryStream stream;
    NPT_Result res = request.Emit(stream);
    NPT_CHECK(res);

    // copy stream into a data packet and send it
    NPT_LargeSize size;
    stream.GetSize(size);
    if (size != (NPT_Size)size) NPT_CHECK(NPT_ERROR_OUT_OF_RANGE);

    NPT_DataBuffer packet(stream.GetData(), (NPT_Size)size);
    NPT_CHECK_WARNING(socket.Send(packet, addr));
    return NPT_SUCCESS;
}
예제 #3
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;
}
예제 #4
0
/*----------------------------------------------------------------------
|   NPT_LogUdpHandler::Log
+---------------------------------------------------------------------*/
void
NPT_LogUdpHandler::Log(const NPT_LogRecord& record)
{
    // format the record
    NPT_String msg;
    NPT_LogTcpHandler::FormatRecord(record, msg);
    
    // send it in a datagram
    NPT_DataBuffer buffer(msg.GetChars(), msg.GetLength()+1, false);
    m_Socket.Send(buffer, &m_Target);
}
예제 #5
0
/*----------------------------------------------------------------------
|       GetEndPointStreams
+---------------------------------------------------------------------*/
static NPT_Result
GetEndPointStreams(EndPoint*                  endpoint, 
                   NPT_InputStreamReference*  input_stream,
                   NPT_OutputStreamReference* output_stream)
{
    // default return values
    if (input_stream) *input_stream = NULL;
    if (output_stream) *output_stream = NULL;

    switch (endpoint->type) {
      case ENDPOINT_TYPE_UDP_CLIENT:
        {
            NPT_UdpSocket sender;

            // info
            if (Options.verbose) {
                NPT_Debug("sending to %s on port %d\n",
                         endpoint->info.udp_client.hostname,
                         endpoint->info.udp_client.port);
            }

            // resolve name
            NPT_IpAddress address;
            NPT_CHECK(address.ResolveName(endpoint->info.udp_client.hostname));

            // connect socket
            NPT_CHECK(sender.Connect(NPT_SocketAddress(address,
                                                       endpoint->info.udp_client.port)));

            // get the streams
            if (input_stream) {
                NPT_CHECK(sender.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(sender.GetOutputStream(*output_stream));
            }
                        
            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_TCP_CLIENT:
        {
            NPT_TcpClientSocket client;

            // info
            if (Options.verbose) {
                NPT_Debug("connecting to %s on port %d\n", 
                         endpoint->info.tcp_client.hostname,
                         endpoint->info.tcp_client.port);
            }

            // resolve the name
            NPT_IpAddress address;
            NPT_CHECK(address.ResolveName(endpoint->info.tcp_client.hostname));

            // connect
            NPT_CHECK(client.Connect(NPT_SocketAddress(address,
                                                       endpoint->info.tcp_client.port)));

            // info
            if (Options.verbose) {
                NPT_Debug("connected\n"); 
            }

            // get the streams
            if (input_stream) {
                NPT_CHECK(client.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(client.GetOutputStream(*output_stream));
            }
            
            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_MULTICAST_CLIENT:
        {
            NPT_UdpMulticastSocket sender;

            // info
            if (Options.verbose) {
                NPT_Debug("sending to %s on port %d\n",
                          endpoint->info.multicast_client.groupname,
                          endpoint->info.multicast_client.port);
            }

            // set time to live
            NPT_CHECK(sender.SetTimeToLive(endpoint->info.multicast_client.ttl));

            // resolve name
            NPT_IpAddress address;
            NPT_CHECK(address.ResolveName(endpoint->info.multicast_client.groupname));

            // connect socket
            NPT_CHECK(sender.Connect(NPT_SocketAddress(address, endpoint->info.multicast_client.port)));

            // get the streams
            if (input_stream) {
                NPT_CHECK(sender.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(sender.GetOutputStream(*output_stream));
            }

            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_UDP_SERVER:
        {
            NPT_UdpSocket listener;

            // info
            if (Options.verbose) {
                NPT_Debug("listening on port %d", endpoint->info.udp_server.port);
            }

            // listen on port, any addr
            NPT_CHECK(listener.Bind(NPT_SocketAddress(NPT_IpAddress::Any, endpoint->info.udp_server.port)));

            // get the streams
            if (input_stream) {
                NPT_CHECK(listener.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(listener.GetOutputStream(*output_stream));
            }

            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_TCP_SERVER:
        {
            NPT_TcpServerSocket server;
            NPT_Socket*         client;

            // info
            if (Options.verbose) {
                NPT_Debug("waiting for client on port %d\n", 
                          endpoint->info.tcp_server.port);
            }

            // bind to the address
            NPT_CHECK(server.Bind(NPT_SocketAddress(NPT_IpAddress::Any, 
                        endpoint->info.tcp_server.port)));

            // wait for connection
            NPT_CHECK(server.WaitForNewClient(client));

            // info
            if (Options.verbose) {
                NPT_Debug("client connected\n");
            }

            // get the streams
            if (input_stream) {
                NPT_CHECK(client->GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(client->GetOutputStream(*output_stream));
            }

            delete client;
            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_MULTICAST_SERVER:
        {
            NPT_UdpMulticastSocket listener;

            // info
            if (Options.verbose) {
                NPT_Debug("listening on port %d\n", endpoint->info.multicast_server.port);
            }

            // listen on port, any addr
            NPT_CHECK(listener.Bind(NPT_SocketAddress(NPT_IpAddress::Any, endpoint->info.multicast_server.port)));

            // info
            if (Options.verbose) {
                NPT_Debug("joining multicast group %s\n", endpoint->info.multicast_server.groupname);
            }

            // resolve name
            NPT_IpAddress address;
            NPT_CHECK(address.ResolveName(endpoint->info.multicast_server.groupname));

            // join the group
            NPT_CHECK(listener.JoinGroup(address));

            // get the streams
            if (input_stream) {
                NPT_CHECK(listener.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(listener.GetOutputStream(*output_stream));
            }

            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_FILE:
        {
            // create a file object
            NPT_File file(endpoint->info.file.name);
            if (endpoint->direction == ENDPOINT_DIRECTION_IN) {
                NPT_CHECK(file.Open(NPT_FILE_OPEN_MODE_READ | 
                                    NPT_FILE_OPEN_MODE_UNBUFFERED));
            } else {
                NPT_CHECK(file.Open(NPT_FILE_OPEN_MODE_WRITE | 
                                    NPT_FILE_OPEN_MODE_CREATE|
                                    NPT_FILE_OPEN_MODE_UNBUFFERED));
            }

            // get the streams
            if (input_stream) {
                NPT_CHECK(file.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(file.GetOutputStream(*output_stream));
            }

            return NPT_SUCCESS;
        }
        break;

      case ENDPOINT_TYPE_SERIAL_PORT:
        {
            // create a serial port object
            NPT_SerialPort serial_port(endpoint->info.serial_port.name);
            NPT_CHECK(serial_port.Open(endpoint->info.serial_port.speed));

            // get the streams
            if (input_stream) {
                NPT_CHECK(serial_port.GetInputStream(*input_stream));
            }
            if (output_stream) {
                NPT_CHECK(serial_port.GetOutputStream(*output_stream));
            }

            return NPT_SUCCESS;
        }
        break;
    }

    return NPT_SUCCESS;
}
예제 #6
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;
}