void sync_worker_deinit(struct sync_worker *w, pthread_mutex_t *lock, pthread_cond_t *cond) { int status; if (w == NULL) { log_debug("%s called with NULL ptr\n", __FUNCTION__); return; } log_verbose("%s: Requesting worker %p to stop...\n", __FUNCTION__, w); sync_worker_submit_request(w, SYNC_WORKER_STOP); if (lock != NULL && cond != NULL) { pthread_mutex_lock(lock); pthread_cond_signal(cond); pthread_mutex_unlock(lock); } status = sync_worker_wait_for_state(w, SYNC_WORKER_STATE_STOPPED, 3000); if (status != 0) { log_warning("Timed out while stopping worker. Canceling thread.\n"); pthread_cancel(w->thread); } pthread_join(w->thread, NULL); log_verbose("%s: Worker joined.\n", __FUNCTION__); bladerf_deinit_stream(w->stream); free(w); }
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); }
static void deinit(struct repeater *repeater) { if (repeater->device) { if (repeater->rx_stream) { bladerf_deinit_stream(repeater->rx_stream); } if (repeater->tx_stream) { bladerf_deinit_stream(repeater->tx_stream); } bladerf_enable_module(repeater->device, BLADERF_MODULE_RX, false); bladerf_enable_module(repeater->device, BLADERF_MODULE_TX, false); bladerf_close(repeater->device); repeater->device = NULL; } }
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; }
int main(int argc, char *argv[]) { int status; unsigned int actual; struct bladerf *dev; struct bladerf_stream *stream; struct test_data test_data; bool conv_ok; if (argc != 4 && argc != 5) { fprintf(stderr, "Usage: %s [tx|rx] <samples per buffer> <# buffers> [# samples]\n", argv[0]); return EXIT_FAILURE; } if (strcasecmp(argv[1], "rx") == 0 ) { test_data.module = BLADERF_MODULE_RX ; } else if (strcasecmp(argv[1], "tx") == 0 ) { test_data.module = BLADERF_MODULE_TX; } else { fprintf(stderr, "Invalid module: %s\n", argv[1]); return EXIT_FAILURE; } test_data.idx = 0; test_data.fout = NULL; test_data.samples_per_buffer = str2int(argv[2], 1, INT_MAX, &conv_ok); if (!conv_ok) { fprintf(stderr, "Invalid samples per buffer value: %s\n", argv[2]); return EXIT_FAILURE; } test_data.num_buffers = str2int(argv[3], 1, INT_MAX, &conv_ok); if (!conv_ok) { fprintf(stderr, "Invalid # buffers: %s\n", argv[3]); return EXIT_FAILURE; } if(test_data.module == BLADERF_MODULE_RX && argc == 5) { test_data.samples_left = str2int(argv[4], 1, INT_MAX, &conv_ok); if(!conv_ok) { fprintf(stderr, "Invalid number of samples: %s\n", argv[4]); return EXIT_FAILURE; } } if (signal(SIGINT, handler) == SIG_ERR || signal(SIGTERM, handler) == SIG_ERR) { fprintf(stderr, "Failed to set up signal handler\n"); return EXIT_FAILURE; } status = bladerf_open(&dev, NULL); if (status < 0) { fprintf(stderr, "Failed to open device: %s\n", bladerf_strerror(status)); return EXIT_FAILURE; } status = bladerf_is_fpga_configured(dev); if (status < 0) { fprintf(stderr, "Failed to determine FPGA state: %s\n", bladerf_strerror(status)); return EXIT_FAILURE; } else if (status == 0) { fprintf(stderr, "Error: FPGA is not loaded.\n"); bladerf_close(dev); return EXIT_FAILURE; } if (!status) { status = bladerf_set_frequency(dev, test_data.module, 1000000000); if (status < 0) { fprintf(stderr, "Failed to set frequency: %s\n", bladerf_strerror(status)); bladerf_close(dev); return EXIT_FAILURE; } } if (!status) { status = bladerf_set_sample_rate(dev, test_data.module, 40000000, &actual); if (status < 0) { fprintf(stderr, "Failed to set sample rate: %s\n", bladerf_strerror(status)); bladerf_close(dev); return EXIT_FAILURE; } } /* Initialize the stream */ status = bladerf_init_stream( &stream, dev, stream_callback, &test_data.buffers, test_data.num_buffers, BLADERF_FORMAT_SC16_Q12, test_data.samples_per_buffer, test_data.num_buffers, &test_data ) ; /* Populate buffers with test data */ if( test_data.module == BLADERF_MODULE_TX ) { if (populate_test_data(&test_data) ) { fprintf(stderr, "Failed to populated test data\n"); bladerf_deinit_stream(stream); bladerf_close(dev); return EXIT_FAILURE; } } else { /* Open up file we'll read test data to */ test_data.fout = fopen( "samples.txt", "w" ); if (!test_data.fout) { fprintf(stderr, "Failed to open samples.txt: %s\n", strerror(errno)); bladerf_deinit_stream(stream); bladerf_close(dev); return EXIT_FAILURE; } } status = bladerf_enable_module(dev, test_data.module, true); if (status < 0) { fprintf(stderr, "Failed to enable module: %s\n", bladerf_strerror(status)); } if (!status) { /* Start stream and stay there until we kill the stream */ status = bladerf_stream(stream, test_data.module); if (status < 0) { fprintf(stderr, "Stream error: %s\n", bladerf_strerror(status)); } } status = bladerf_enable_module(dev, test_data.module, false); if (status < 0) { fprintf(stderr, "Failed to enable module: %s\n", bladerf_strerror(status)); } bladerf_deinit_stream(stream); bladerf_close(dev); if (test_data.fout) { fclose(test_data.fout); } return 0; }
/* Initialization and stuff */ int main(int argc, char **argv) { struct bladerf_devinfo *devs; struct sigaction sigact; struct devinfo_s device; int show_help = false; int n, ret; char ch; /* Set up default values, bandwidth and num_transfers * are automatically calculated later */ device.device_id = DEFAULT_DEVICE_ID; device.frequency = DEFAULT_FREQUENCY; device.samplerate = DEFAULT_SAMPLERATE; device.bandwidth = 0; device.txvga1 = DEFAULT_TXVGA1; device.txvga2 = DEFAULT_TXVGA2; device.buffers.gain = DEFAULT_GAIN; device.buffers.again = DEFAULT_AGAIN; device.buffers.num_buffers = DEFAULT_BUFFERS; device.buffers.num_samples = DEFAULT_SAMPLES; device.buffers.num_transfers = 0; device.buffers.pos = 0; /* Evaluate command line options */ while((ch = getopt(argc, argv, "hd:f:r:b:g:G:a:m:n:s:t:")) != -1) { switch(ch) { case 'd': device.device_id = optarg; break; case 'f': device.frequency = atoi(optarg); break; case 'r': device.samplerate = atoi(optarg); break; case 'b': device.bandwidth = atoi(optarg); break; case 'g': device.txvga1 = atoi(optarg); break; case 'G': device.txvga2 = atoi(optarg); break; case 'm': device.buffers.gain = atof(optarg); break; case 'a': device.buffers.again = atof(optarg); break; case 'n': device.buffers.num_buffers = atoi(optarg); break; case 's': device.buffers.num_samples = atoi(optarg); break; case 't': device.buffers.num_transfers = atoi(optarg); break; case 'h': default: show_help = true; } } /* Now calculate bandwidth and num_transfers if the user didn't * configure them manually */ if(device.bandwidth == 0) device.bandwidth = device.samplerate * 3 / 4; if(device.buffers.num_transfers == 0) device.buffers.num_transfers = device.buffers.num_buffers / 2; if(show_help) { usage(argv[0], &device); return EXIT_FAILURE; } argc -= optind; argv += optind; /* Allocate the float input buffer */ device.buffers.fbuf = malloc(device.buffers.num_samples * 2 * sizeof(float)); /* Set up signal handler to enable clean shutdowns */ sigact.sa_handler = sighandler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); /* Look for devices attached */ ret = bladerf_get_device_list(&devs); if(ret < 1) { fprintf(stderr, "No devices found.\n"); return EXIT_FAILURE; } /* Print some information about all the devices */ for(n = 0; n < ret; n++) { fprintf(stderr, "Serial:\t%s\n" "USB bus:\t%i\n" "USB address:\t%i\n" "Instance:\t%i\n\n", devs[n].serial, devs[n].usb_bus, devs[n].usb_addr, devs[n].instance ); } /* the list is not needed any more */ bladerf_free_device_list(devs); /* Open a device by given device string */ ret = bladerf_open(&device.dev, device.device_id); if(ret != 0) { fprintf(stderr, "Error opening device %s: %s.\n", device.device_id, bladerf_strerror(ret)); goto out0; } else { fprintf(stderr, "Device \"%s\" opened successfully.\n", device.device_id); } /* Set the device parameters */ ret = bladerf_set_sample_rate(device.dev, BLADERF_MODULE_TX, device.samplerate, &device.samplerate); if(ret != 0) { fprintf(stderr, "Error setting sample rate to %i: %s.\n", device.samplerate, bladerf_strerror(ret)); goto out1; } else { fprintf(stderr, "Actual sample rate is %i.\n", device.samplerate); } ret = bladerf_set_frequency(device.dev, BLADERF_MODULE_TX, device.frequency); if(ret != 0) { fprintf(stderr, "Error setting frequency to %iHz: %s.\n", device.frequency, bladerf_strerror(ret)); goto out1; } else { fprintf(stderr, "Frequency set to %iHz.\n", device.frequency); } ret = bladerf_set_txvga1(device.dev, device.txvga1); if(ret != 0) { fprintf(stderr, "Error setting gain for txvga1: %s.\n", bladerf_strerror(ret)); goto out1; } ret = bladerf_set_txvga2(device.dev, device.txvga2); if(ret != 0) { fprintf(stderr, "Error setting gain for txvga2: %s.\n", bladerf_strerror(ret)); goto out1; } ret = bladerf_set_bandwidth(device.dev, BLADERF_MODULE_TX, device.bandwidth, &device.bandwidth); if(ret != 0) { fprintf(stderr, "Error setting LPF bandwidth: %s.\n", bladerf_strerror(ret)); goto out1; } else { fprintf(stderr, "Bandwidth set to %iHz.\n", device.bandwidth); } /* Set up the sample stream */ ret = bladerf_init_stream(&device.stream, device.dev, stream_callback, &device.buffers.sbuf, device.buffers.num_buffers, BLADERF_FORMAT_SC16_Q12, device.buffers.num_samples, device.buffers.num_transfers, &device.buffers); if(ret != 0) { fprintf(stderr, "Failed setting up stream: %s.\n", bladerf_strerror(ret)); goto out1; } /* Finally enable TX... */ ret = bladerf_enable_module(device.dev, BLADERF_MODULE_TX, true); if(ret != 0) { fprintf(stderr, "Error enabling TX module: %s.\n", bladerf_strerror(ret)); goto out1; } else { fprintf(stderr, "Successfully enabled TX module.\n"); } /* ...and start the stream. * Execution stops here until stream has finished. */ ret = bladerf_stream(device.stream, BLADERF_MODULE_TX); if(ret != 0) { fprintf(stderr, "Failed starting stream: %s.\n", bladerf_strerror(ret)); goto out2; } /* Cleanup the mess */ out2: bladerf_deinit_stream(device.stream); out1: ret = bladerf_enable_module(device.dev, BLADERF_MODULE_TX, false); if(ret != 0) { fprintf(stderr, "Error disabling TX module: %s.\n", bladerf_strerror(ret)); } else { fprintf(stderr, "Successfully disabled TX module.\n"); } bladerf_close(device.dev); fprintf(stderr, "Device closed.\n"); out0: return EXIT_SUCCESS; }
int main(int argc, char** argv) { int status, threads_waiting = 1, quick; struct bladerf* dev; struct bladerf_config* cfg; struct bladerf_stream* tx_stream; struct bladerf_stream* rx_stream; struct bladerf_stream_data* tx_stream_data; struct bladerf_stream_data* rx_stream_data; struct bladerf_thread_data* tx_thread_data; struct bladerf_thread_data* rx_thread_data; pthread_t tx_thread_pth; pthread_t rx_thread_pth; signal(SIGINT, ignore_sigint); cfg = malloc(sizeof(struct bladerf_config)); tx_stream_data = malloc(sizeof(struct bladerf_stream_data)); rx_stream_data = malloc(sizeof(struct bladerf_stream_data)); tx_thread_data = malloc(sizeof(struct bladerf_thread_data)); rx_thread_data = malloc(sizeof(struct bladerf_thread_data)); cfg->tx_freq = TXFREQ; cfg->rx_freq = RXFREQ; cfg->tx_bw = TXBW; cfg->rx_bw = RXBW; cfg->tx_sr = TXSR; cfg->rx_sr = RXSR; cfg->txvga1 = TXVGA1; cfg->txvga2 = TXVGA2; cfg->rxvga1 = RXVGA1; cfg->rxvga2 = RXVGA2; cfg->lna = LNA; if(argc == 2 && argv[1][0] == 'q') { quick = 1; } else { quick = 0; } if(!quick) { if(write_config(cfg)) { if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } if(configure_bladerf(&dev, cfg)) { if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } } else { status = bladerf_open(&dev, NULL); if(status) { return 1; } } tx_stream_data->num_buffers = TX_N_BUFFERS; tx_stream_data->samples_per_buffer = TX_SAMPLES_PER_BUFFER; tx_stream_data->samples_left = TX_N_SAMPLES; tx_stream_data->num_transfers = TX_N_TRANSFERS; if(setup_tx_stream(dev, &tx_stream, tx_stream_data)) { if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } rx_stream_data->num_buffers = RX_N_BUFFERS; rx_stream_data->samples_per_buffer = RX_SAMPLES_PER_BUFFER; rx_stream_data->samples_left = RX_N_SAMPLES; rx_stream_data->num_transfers = RX_N_TRANSFERS; if(setup_rx_stream(dev, &rx_stream, rx_stream_data)) { bladerf_deinit_stream(tx_stream); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } if(enable(dev, true)) { enable(dev, false); bladerf_deinit_stream(rx_stream); bladerf_deinit_stream(tx_stream); bladerf_close(dev); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } tx_thread_data->dev = dev; tx_thread_data->stream = tx_stream; tx_thread_data->stream_data = tx_stream_data; tx_thread_data->waiting = &threads_waiting; tx_thread_data->rv = 1; printf("%-50s", "Creating TX thread... "); status = pthread_create(&tx_thread_pth, NULL, txrx_thread, tx_thread_data); if(status) { printf(KRED "Failed: %s" KNRM "\n", strerror(status)); bladerf_deinit_stream(rx_stream); bladerf_close(dev); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } printf(KGRN "OK" KNRM "\n"); usleep(100); rx_thread_data->dev = dev; rx_thread_data->stream = rx_stream; rx_thread_data->stream_data = rx_stream_data; rx_thread_data->waiting = &threads_waiting; rx_thread_data->rv = 1; printf("%-50s", "Creating RX thread... "); status = pthread_create(&rx_thread_pth, NULL, txrx_thread, rx_thread_data); if(status) { printf(KRED "Failed: %s" KNRM "\n", strerror(status)); bladerf_deinit_stream(rx_stream); bladerf_deinit_stream(tx_stream); bladerf_close(dev); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } printf(KGRN "OK" KNRM "\n"); printf("%-50s", "Starting processing... "); threads_waiting = 0; printf(KGRN "OK" KNRM "\n"); printf("%-50s", "Waiting for completion... "); fflush(stdout); pthread_join(rx_thread_pth, NULL); pthread_join(tx_thread_pth, NULL); printf(KGRN "OK" KNRM "\n"); printf("%-50s", "All done, checking TX results... "); fflush(stdout); if(tx_thread_data->rv < 0) { printf(KRED "Failed: %s" KNRM "\n", bladerf_strerror(tx_thread_data->rv)); enable(dev, false); bladerf_deinit_stream(rx_stream); bladerf_close(dev); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } printf(KGRN "OK" KNRM "\n"); printf("%-50s", " checking RX results... "); fflush(stdout); if(rx_thread_data->rv < 0) { printf(KRED "Failed: %s" KNRM "\n", bladerf_strerror(tx_thread_data->rv)); enable(dev, false); bladerf_deinit_stream(rx_stream); bladerf_close(dev); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); return 1; } printf(KGRN "OK" KNRM "\n"); printf(KGRN "Success!" KNRM "\n"); save_rx_data(rx_stream_data); enable(dev, false); printf("%-50s", "Deinitialising stream... "); fflush(stdout); bladerf_deinit_stream(rx_stream); printf(KGRN "OK" KNRM "\n"); printf("%-50s", "Closing device... "); fflush(stdout); bladerf_close(dev); printf(KGRN "OK" KNRM "\n"); printf("%-50s", "Freeing memory... "); fflush(stdout); if(cfg) free(cfg); if(tx_stream_data) free(tx_stream_data); if(rx_stream_data) free(rx_stream_data); if(tx_thread_data) free(tx_thread_data); if(rx_thread_data) free(rx_thread_data); printf(KGRN "OK" KNRM "\n"); return 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; }