Beispiel #1
0
int rxtx_startup(struct cli_state *s, bladerf_module module)
{
    int status;

    if (module != BLADERF_MODULE_RX && module != BLADERF_MODULE_TX) {
        return CMD_RET_INVPARAM;
    }

    if (module == BLADERF_MODULE_RX) {
        rxtx_set_state(s->rx, RXTX_STATE_INIT);
        status = pthread_create(&s->rx->task_mgmt.thread, NULL, rx_task, s);

        if (status < 0) {
            rxtx_set_state(s->rx, RXTX_STATE_FAIL);
        } else {
            status = rxtx_wait_for_state(s->rx, RXTX_STATE_IDLE, 1000);
        }

    } else {
        rxtx_set_state(s->tx, RXTX_STATE_INIT);
        status = pthread_create(&s->tx->task_mgmt.thread, NULL, tx_task, s);

        if (status < 0) {
            rxtx_set_state(s->tx, RXTX_STATE_FAIL);
        } else {
            status = rxtx_wait_for_state(s->tx, RXTX_STATE_IDLE, 1000);
        }
    }

    if (status < 0) {
        status = CMD_RET_UNKNOWN;
    }

    return status;
}
Beispiel #2
0
void rxtx_task_exec_stop(struct rxtx_data *rxtx, unsigned char *requests,
                         struct bladerf *dev)
{
    int status;

    *requests = rxtx_get_requests(rxtx,
                                  RXTX_TASK_REQ_STOP | RXTX_TASK_REQ_SHUTDOWN);

    pthread_mutex_lock(&rxtx->data_mgmt.lock);
    bladerf_deinit_stream(rxtx->data_mgmt.stream);
    rxtx->data_mgmt.stream = NULL;
    pthread_mutex_unlock(&rxtx->data_mgmt.lock);

    pthread_mutex_lock(&rxtx->file_mgmt.file_lock);
    if (rxtx->file_mgmt.file != NULL) {
        fclose(rxtx->file_mgmt.file);
        rxtx->file_mgmt.file = NULL;
    }
    pthread_mutex_unlock(&rxtx->file_mgmt.file_lock);

    if (*requests & RXTX_TASK_REQ_SHUTDOWN) {
        rxtx_set_state(rxtx, RXTX_STATE_SHUTDOWN);
    } else {
        rxtx_set_state(rxtx, RXTX_STATE_IDLE);
    }

    status = bladerf_enable_module(dev, rxtx->module, false);
    if (status < 0) {
        set_last_error(&rxtx->last_error, ETYPE_BLADERF, status);
    }

    *requests = 0;

    rxtx_release_wait(rxtx);
}
Beispiel #3
0
void rxtx_task_exec_running(struct rxtx_data *rxtx)
{
    int status = bladerf_stream(rxtx->data_mgmt.stream, rxtx->module);

    if (status < 0) {
        set_last_error(&rxtx->last_error, ETYPE_BLADERF, status);
    }

    rxtx_set_state(rxtx, RXTX_STATE_STOP);
}
Beispiel #4
0
void rxtx_task_exec_idle(struct rxtx_data *rxtx, unsigned char *requests)
{
    /* Wait until we're asked to start or shutdown */
    while (!(*requests & (RXTX_TASK_REQ_START | RXTX_TASK_REQ_SHUTDOWN))) {

        pthread_mutex_lock(&rxtx->task_mgmt.lock);
        pthread_cond_wait(&rxtx->task_mgmt.signal_req, &rxtx->task_mgmt.lock);
        *requests = rxtx->task_mgmt.req;
        pthread_mutex_unlock(&rxtx->task_mgmt.lock);
    }

    if (*requests & RXTX_TASK_REQ_SHUTDOWN) {
        rxtx_set_state(rxtx, RXTX_STATE_SHUTDOWN);
    } else if (*requests & RXTX_TASK_REQ_START) {
        rxtx_set_state(rxtx, RXTX_STATE_START);
    } else {
        /* Bug */
        assert(0);
    }

    *requests = 0;
}
Beispiel #5
0
void rxtx_task_exec_stop(struct rxtx_data *rxtx, unsigned char *requests)
{
    *requests = rxtx_get_requests(rxtx,
                                  RXTX_TASK_REQ_STOP | RXTX_TASK_REQ_SHUTDOWN);

    MUTEX_LOCK(&rxtx->file_mgmt.file_lock);
    if (rxtx->file_mgmt.file != NULL) {
        fclose(rxtx->file_mgmt.file);
        rxtx->file_mgmt.file = NULL;
    }
    MUTEX_UNLOCK(&rxtx->file_mgmt.file_lock);

    if (*requests & RXTX_TASK_REQ_SHUTDOWN) {
        rxtx_set_state(rxtx, RXTX_STATE_SHUTDOWN);
    } else {
        rxtx_set_state(rxtx, RXTX_STATE_IDLE);
    }

    *requests = 0;

    rxtx_release_wait(rxtx);
}
Beispiel #6
0
void *rx_task(void *cli_state_arg)
{
    int status = 0;
    unsigned char requests;
    enum rxtx_state task_state;
    struct cli_state *cli_state = (struct cli_state *) cli_state_arg;
    struct rxtx_data *rx = cli_state->rx;
    struct rx_params *rx_params = rx->params;
    struct rx_callback_data cb_data;

    task_state = rxtx_get_state(rx);
    assert(task_state == RXTX_STATE_INIT);

    set_last_error(&rx->last_error, ETYPE_BLADERF, 0);
    requests = 0;

    while (task_state != RXTX_STATE_SHUTDOWN) {
        switch (task_state) {
            case RXTX_STATE_INIT:
                rxtx_set_state(rx, RXTX_STATE_IDLE);
                break;

            case RXTX_STATE_IDLE:
                rxtx_task_exec_idle(rx, &requests);
                break;

            case RXTX_STATE_START:
            {
                /* This should be set to an appropriate value upon
                 * encountering an error condition */
                enum error_type err_type = ETYPE_BUG;

                /* Clear the last error */
                set_last_error(&rx->last_error, ETYPE_ERRNO, 0);

                /* Set up count of samples to receive */
                pthread_mutex_lock(&rx->param_lock);
                cb_data.samples_left = rx_params->n_samples;
                pthread_mutex_unlock(&rx->param_lock);

                cb_data.rx = rx;
                cb_data.inf = cb_data.samples_left == 0;

                /* Choose the callback appropriate for the desired file type */
                pthread_mutex_lock(&rx->file_mgmt.file_meta_lock);

                switch (rx->file_mgmt.format) {
                    case RXTX_FMT_CSV_SC16Q12:
                        cb_data.write_samples = rx_write_csv_sc16q12;
                        break;

                    case RXTX_FMT_BIN_SC16Q12:
                        cb_data.write_samples = rx_write_bin_sc16q12;
                        break;

                    default:
                        status = CMD_RET_INVPARAM;
                        set_last_error(&rx->last_error, ETYPE_CLI, status);
                        rxtx_set_state(rx, RXTX_STATE_IDLE);
                }

                /* Open the specified file */
                if (status == 0) {
                    assert(rx->file_mgmt.path);
                }

                pthread_mutex_unlock(&rx->file_mgmt.file_meta_lock);

                /* Set up the reception stream and buffer information */
                if (status == 0) {
                    pthread_mutex_lock(&rx->data_mgmt.lock);

                    rx->data_mgmt.next_idx = 0;

                    status = bladerf_init_stream(&rx->data_mgmt.stream,
                                cli_state->dev,
                                rx_callback,
                                &rx->data_mgmt.buffers,
                                rx->data_mgmt.num_buffers,
                                BLADERF_FORMAT_SC16_Q12,
                                rx->data_mgmt.samples_per_buffer,
                                rx->data_mgmt.num_transfers,
                                &cb_data);

                    if (status < 0) {
                        err_type = ETYPE_BLADERF;
                    }

                    pthread_mutex_unlock(&rx->data_mgmt.lock);
                }

                if (status == 0) {
                    rxtx_set_state(rx, RXTX_STATE_RUNNING);
                } else {
                    bladerf_deinit_stream(rx->data_mgmt.stream);
                    rx->data_mgmt.stream = NULL;
                    set_last_error(&rx->last_error, err_type, status);
                    rxtx_set_state(rx, RXTX_STATE_IDLE);
                }
            }
            break;

            case RXTX_STATE_RUNNING:
                rxtx_task_exec_running(rx, cli_state);
                break;

            case RXTX_STATE_STOP:
                rxtx_task_exec_stop(rx, &requests);
                break;

            case RXTX_STATE_SHUTDOWN:
                break;

            default:
                /* Bug - can only get here with a corrupted value */
                assert(0);
        }

        task_state = rxtx_get_state(rx);
    }

    return NULL;
}
Beispiel #7
0
void *tx_task(void *cli_state_arg)
{
    int status = 0;
    int disable_status;
    unsigned char requests;
    enum rxtx_state task_state;
    struct cli_state *cli_state = (struct cli_state *) cli_state_arg;
    struct rxtx_data *tx = cli_state->tx;
    MUTEX *dev_lock = &cli_state->dev_lock;

    /* We expect to be in the IDLE state when this is kicked off. We could
     * also get into the shutdown state if the program exits before we
     * finish up initialization */
    task_state = rxtx_get_state(tx);
    assert(task_state == RXTX_STATE_INIT);

    set_last_error(&tx->last_error, ETYPE_BLADERF, 0);
    requests = 0;

    while (task_state != RXTX_STATE_SHUTDOWN) {
        task_state = rxtx_get_state(tx);
        switch (task_state) {
            case RXTX_STATE_INIT:
                rxtx_set_state(tx, RXTX_STATE_IDLE);
                break;

            case RXTX_STATE_IDLE:
                rxtx_task_exec_idle(tx, &requests);
                break;

            case RXTX_STATE_START:
            {
                enum error_type err_type = ETYPE_BUG;

                /* Clear out the last error */
                set_last_error(&tx->last_error, ETYPE_ERRNO, 0);

                /* Bug catcher */
                MUTEX_LOCK(&tx->file_mgmt.file_meta_lock);
                assert(tx->file_mgmt.file != NULL);
                MUTEX_UNLOCK(&tx->file_mgmt.file_meta_lock);

                /* Initialize the TX synchronous data configuration */
                status = bladerf_sync_config(cli_state->dev,
                                             BLADERF_MODULE_TX,
                                             BLADERF_FORMAT_SC16_Q11,
                                             tx->data_mgmt.num_buffers,
                                             tx->data_mgmt.samples_per_buffer,
                                             tx->data_mgmt.num_transfers,
                                             tx->data_mgmt.timeout_ms);

                if (status < 0) {
                    err_type = ETYPE_BLADERF;
                }

                if (status == 0) {
                    rxtx_set_state(tx, RXTX_STATE_RUNNING);
                } else {
                    set_last_error(&tx->last_error, err_type, status);
                    rxtx_set_state(tx, RXTX_STATE_IDLE);
                }
            }
            break;

            case RXTX_STATE_RUNNING:
                MUTEX_LOCK(dev_lock);
                status = bladerf_enable_module(cli_state->dev,
                                               tx->module, true);
                MUTEX_UNLOCK(dev_lock);

                if (status < 0) {
                    set_last_error(&tx->last_error, ETYPE_BLADERF, status);
                } else {
                    status = tx_task_exec_running(tx, cli_state);

                    if (status < 0) {
                        set_last_error(&tx->last_error, ETYPE_BLADERF, status);
                    }

                    MUTEX_LOCK(dev_lock);
                    disable_status = bladerf_enable_module(cli_state->dev,
                                                           tx->module, false);
                    MUTEX_UNLOCK(dev_lock);

                    if (status == 0 && disable_status < 0) {
                        set_last_error(
                                &tx->last_error,
                                ETYPE_BLADERF,
                                disable_status);
                    }
                }
                rxtx_set_state(tx, RXTX_STATE_STOP);
                break;

            case RXTX_STATE_STOP:
                rxtx_task_exec_stop(tx, &requests);
                break;

            case RXTX_STATE_SHUTDOWN:
                break;

            default:
                /* Bug */
                assert(0);
                rxtx_set_state(tx, RXTX_STATE_IDLE);
        }
    }

    return NULL;
}
Beispiel #8
0
void *tx_task(void *cli_state_arg)
{
    int status = 0;
    unsigned char requests;
    enum rxtx_state task_state;
    struct cli_state *cli_state = (struct cli_state *) cli_state_arg;
    struct rxtx_data *tx = cli_state->tx;
    struct tx_params *tx_params = tx->params;
    struct tx_callback_data cb_data;

    /* We expect to be in the IDLE state when this is kicked off. We could
     * also get into the shutdown state if the program exits before we
     * finish up initialization */
    task_state = rxtx_get_state(tx);
    assert(task_state == RXTX_STATE_INIT);

    set_last_error(&tx->last_error, ETYPE_BLADERF, 0);
    requests = 0;

    while (task_state != RXTX_STATE_SHUTDOWN) {
        task_state = rxtx_get_state(tx);
        switch (task_state) {
            case RXTX_STATE_INIT:
                rxtx_set_state(tx, RXTX_STATE_IDLE);
                break;

            case RXTX_STATE_IDLE:
                rxtx_task_exec_idle(tx, &requests);
                break;

            case RXTX_STATE_START:
            {
                enum error_type err_type = ETYPE_BUG;

                /* Clear out the last error */
                set_last_error(&tx->last_error, ETYPE_ERRNO, 0);

                /* Set up repeat and delay parameters for this run */
                cb_data.tx = tx;
                cb_data.delay = 0;
                cb_data.done = false;

                pthread_mutex_lock(&tx->param_lock);
                cb_data.repeats_left = tx_params->repeat;
                pthread_mutex_unlock(&tx->param_lock);

                if (cb_data.repeats_left == 0) {
                    cb_data.repeat_inf = true;
                } else {
                    cb_data.repeat_inf = false;
                }

                /* Bug catcher */
                pthread_mutex_lock(&tx->file_mgmt.file_meta_lock);
                assert(tx->file_mgmt.file != NULL);
                pthread_mutex_unlock(&tx->file_mgmt.file_meta_lock);

                /* Initialize the stream */
                status = bladerf_init_stream(&tx->data_mgmt.stream,
                                             cli_state->dev,
                                             tx_callback,
                                             &tx->data_mgmt.buffers,
                                             tx->data_mgmt.num_buffers,
                                             BLADERF_FORMAT_SC16_Q11,
                                             tx->data_mgmt.samples_per_buffer,
                                             tx->data_mgmt.num_transfers,
                                             &cb_data);

                if (status < 0) {
                    err_type = ETYPE_BLADERF;
                }

                if (status == 0) {
                    rxtx_set_state(tx, RXTX_STATE_RUNNING);
                } else {
                    bladerf_deinit_stream(tx->data_mgmt.stream);
                    tx->data_mgmt.stream = NULL;
                    set_last_error(&tx->last_error, err_type, status);
                    rxtx_set_state(tx, RXTX_STATE_IDLE);
                }
            }
            break;

            case RXTX_STATE_RUNNING:
                rxtx_task_exec_running(tx, cli_state);
                break;

            case RXTX_STATE_STOP:
                rxtx_task_exec_stop(tx, &requests);
                break;

            case RXTX_STATE_SHUTDOWN:
                break;

            default:
                /* Bug */
                assert(0);
                rxtx_set_state(tx, RXTX_STATE_IDLE);
        }
    }

    return NULL;
}