SoapyRPCSocket *SoapyRPCSocket::accept(void)
{
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof(addr);
    int client = ::accept(_sock, (struct sockaddr*)&addr, &addrlen);
    if (client == INVALID_SOCKET) return NULL;
    SoapyRPCSocket *clientSock = new SoapyRPCSocket();
    clientSock->_sock = client;
    clientSock->setDefaultTcpSockOpts();
    return clientSock;
}
示例#2
0
/***********************************************************************
 * Launch the server
 **********************************************************************/
static int runServer(void)
{
    std::string url;
    if (optarg != NULL) url = optarg;
    if (url.empty()) url = combineURL("tcp", "::", "");

    //default url parameters when not specified
    std::string scheme, node, service; splitURL(url, scheme, node, service);
    url = combineURL(scheme.empty()?"tcp":scheme, node, service.empty()?SOAPY_REMOTE_DEFAULT_SERVICE:service);

    std::cout << uniqueProcessId() << std::endl;
    std::cout << "Launching the server... " << url << std::endl;
    SoapySocketSession sess;
    SoapyRPCSocket s;
    if (s.bind(url) != 0)
    {
        std::cerr << "Server socket bind FAIL: " << s.lastErrorMsg() << std::endl;
        return EXIT_FAILURE;
    }
    std::cout << "Server bound to " << s.getsockname() << std::endl;
    s.listen(SOAPY_REMOTE_LISTEN_BACKLOG);
    auto serverListener = new SoapyServerListener(s);

    std::cout << "Press Ctrl+C to stop the server" << std::endl;
    signal(SIGINT, sigIntHandler);
    while (not serverDone) serverListener->handleOnce();

    std::cout << "Shutdown client handler threads" << std::endl;
    delete serverListener;
    s.close();

    std::cout << "Cleanup complete, exiting" << std::endl;
    return EXIT_SUCCESS;
}
示例#3
0
/***********************************************************************
 * Discovery routine -- connect to server when key specified
 **********************************************************************/
static std::vector<SoapySDR::Kwargs> findRemote(const SoapySDR::Kwargs &args)
{
    std::vector<SoapySDR::Kwargs> result;

    if (args.count(SOAPY_REMOTE_KWARG_STOP) != 0) return result;

    //no remote specified, use the discovery protocol
    if (args.count("remote") == 0)
    {
        //On non-windows platforms the endpoint instance can last the
        //duration of the process because it can be cleaned up safely.
        //Windows has issues cleaning up threads and sockets on exit.
        #ifndef _MSC_VER
        static
        #endif //_MSC_VER
        auto ssdpEndpoint = SoapySSDPEndpoint::getInstance();

        //enable forces new search queries
        ssdpEndpoint->enablePeriodicSearch(true);

        //wait maximum timeout for replies
        std::this_thread::sleep_for(std::chrono::microseconds(SOAPY_REMOTE_SOCKET_TIMEOUT_US));

        for (const auto &url : SoapySSDPEndpoint::getInstance()->getServerURLs())
        {
            auto argsWithURL = args;
            argsWithURL["remote"] = url;
            const auto subResult = findRemote(argsWithURL);
            result.insert(result.end(), subResult.begin(), subResult.end());
        }

        return result;
    }

    //otherwise connect to a specific url and enumerate
    auto url = SoapyURL(args.at("remote"));

    //default url parameters when not specified
    if (url.getScheme().empty()) url.setScheme("tcp");
    if (url.getService().empty()) url.setService(SOAPY_REMOTE_DEFAULT_SERVICE);

    //try to connect to the remote server
    SoapySocketSession sess;
    SoapyRPCSocket s;
    int ret = s.connect(url.toString());
    if (ret != 0)
    {
        SoapySDR::logf(SOAPY_SDR_ERROR, "SoapyRemote::find() -- connect(%s) FAIL: %s", url.toString().c_str(), s.lastErrorMsg());
        return result;
    }

    //find transaction
    try
    {
        SoapyLogAcceptor logAcceptor(url.toString(), s);

        SoapyRPCPacker packer(s);
        packer & SOAPY_REMOTE_FIND;
        packer & translateArgs(args);
        packer();
        SoapyRPCUnpacker unpacker(s);
        unpacker & result;

        //graceful disconnect
        SoapyRPCPacker packerHangup(s);
        packerHangup & SOAPY_REMOTE_HANGUP;
        packerHangup();
        SoapyRPCUnpacker unpackerHangup(s);
    }
    catch (const std::exception &ex)
    {
        SoapySDR::logf(SOAPY_SDR_ERROR, "SoapyRemote::find() -- transact FAIL: %s", ex.what());
    }

    //remove instances of the stop key from the result
    for (auto &resultArgs : result)
    {
        resultArgs.erase(SOAPY_REMOTE_KWARG_STOP);
        if (resultArgs.count("driver") != 0)
        {
            resultArgs["remote:driver"] = resultArgs.at("driver");
            resultArgs.erase("driver");
        }
        if (resultArgs.count("type") != 0)
        {
            resultArgs["remote:type"] = resultArgs.at("type");
            resultArgs.erase("type");
        }
        resultArgs["remote"] = url.toString();
    }

    return result;
}