Beispiel #1
0
/***********************************************************************
 * Factory routine -- connect to server and create remote device
 **********************************************************************/
static SoapySDR::Device *makeRemote(const SoapySDR::Kwargs &args)
{
    if (args.count(SOAPY_REMOTE_KWARG_STOP) != 0) //probably wont happen
    {
        throw std::runtime_error("SoapyRemoteDevice() -- factory loop");
    }

    if (args.count("remote") == 0)
    {
        throw std::runtime_error("SoapyRemoteDevice() -- missing URL");
    }

    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);

    return new SoapyRemoteDevice(url.toString(), translateArgs(args));
}
Beispiel #2
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;
}
Beispiel #3
0
/**
 * @function    executeCommand
 *
 * @abstract    Execute the command, using the given pipe as stdin.
 * @discussion  Loads input / output files, create pipes, and forks off children
 *              to execute the task.
 *
 * @param       command - a struct representing the command
 *              pipe - one end of a pipe to be used as stdin, or NULL if there is none
 *
 * @result      Returns nothing.
 */
void executeCommand(Command* command, int inPipe) {
    if (strcmp(command->args->arg, "exit") == 0) {
        printf("Exiting\n");
        exit(0);
    }
    else if (strcmp(command->args->arg, "cd") == 0
             || strcmp(command->args->arg, "chdir") == 0) {
        // Change directories
        char* path;
        if (command->args->nextArg == NULL) {
            char buff[PATH_MAX];
            char* username = getpwuid(getuid())->pw_name;
            sprintf(buff, "/home/%s", username);
            path = buff;
        }
        else {
            path = command->args->nextArg->arg;
        }
        if (chdir(path) == -1) {
            printf("%s\n", strerror(errno));
        }
        return;
    }
    else if (strcmp(command->args->arg, "history") == 0) {
        // Print history or error as to why that cannot be done.
        print_sh_history(command);
        return;
    }
    else if (command->args->arg[0] == '!') {
        // If !n is argued, rerun the n-th line in history.
        rerun_cmd_n(command);
        return;
    }

    // Create a pipe if there is a next command
    int pipefd[2] = {-1, -1};
    if (command->pipe_destination != NULL) {
        if (pipe(pipefd) == -1) {
            printf("%s\n", strerror(errno));
        }
    }

    pid_t pid = fork();
    if (pid < 0) {
        printf("Fork failed!\n");
        exit(1);
    }
    else if (pid == 0) {
        char** args = translateArgs(command->args);

        // Load the input and output
        // Use the pipe if it exists
        // (output and input take precedence over pipe)

        int in_fd, out_fd;

        if (inPipe > -1) {
            dup2(inPipe, STDIN_FILENO);
            close(inPipe);
        }
        else if (command->input != NULL) {
            in_fd = open(command->input, O_RDONLY);
            if (in_fd == -1) {
                printf("Failed to open input file \n");
                return;
            }
            dup2(in_fd, STDIN_FILENO); /* Replace stdin */
            close(in_fd);
        }
        if (pipefd[1] > -1) {
            dup2(pipefd[1], STDOUT_FILENO);
            close(pipefd[1]);
        }
        else if (command->output != NULL) {
            out_fd = open(command->output, O_CREAT | O_TRUNC | O_WRONLY,
                          S_IRUSR | S_IRGRP | S_IROTH);
            if (out_fd == -1) {
                printf("Failed to open output file \n");
                return;
            }
            dup2(out_fd, STDOUT_FILENO); /* Replace stdout */
            close(out_fd);
        }

        if (execvp(args[0], args) == -1) {
            printf("Could not execute %s!\n", args[0]);
            exit(1);
        }
    }
    else {
        // Recurse on the next command if there is one, pass along the pipe
        if (inPipe > -1) {
            close(inPipe);
        }
        if (pipefd[1] > -1) {
            close(pipefd[1]);
        }
        if (command->pipe_destination != NULL) {
            executeCommand(command->pipe_destination, pipefd[0]);
        }

    }
}