static bladerf_devinfo kwargs_to_devinfo(const SoapySDR::Kwargs &args) { std::stringstream ss; if (args.count("backend") != 0) { ss << args.at("backend") << ":"; } else ss << "*:"; if (args.count("device") != 0) { ss << "device=" << args.at("device") << " "; } if (args.count("instance") != 0) { ss << "instance=" << args.at("instance") << " "; } if (args.count("serial") != 0) { ss << "serial=" << args.at("serial") << " "; } bladerf_devinfo info; bladerf_init_devinfo(&info); bladerf_get_devinfo_from_str(ss.str().c_str(), &info); return info; }
std::vector<SoapySDR::Kwargs> findNullDevice(const SoapySDR::Kwargs &args) { std::vector<SoapySDR::Kwargs> results; //require that the user specify type=null if (args.count("type") == 0) return results; if (args.at("type") != "null") return results; SoapySDR::Kwargs nullArgs; nullArgs["type"] = "null"; results.push_back(nullArgs); return results; }
/*********************************************************************** * 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; }