static int rx_cmd_config(struct cli_state *s, int argc, char **argv) { int i; char *val; int status; struct rx_params *rx_params = s->rx->params; assert(argc >= 2); if (argc == 2) { rx_print_config(s->rx); return 0; } for (i = 2; i < argc; i++) { status = rxtx_handle_config_param(s, s->rx, argv[0], argv[i], &val); if (status < 0) { return status; } else if (status == 0) { if (!strcasecmp("n", argv[i])) { /* Configure number of samples to receive */ unsigned int n; bool ok; n = str2uint_suffix(val, 0, UINT_MAX, rxtx_kmg_suffixes, (int)rxtx_kmg_suffixes_len, &ok); if (ok) { pthread_mutex_lock(&s->rx->param_lock); rx_params->n_samples = n; pthread_mutex_unlock(&s->rx->param_lock); } else { cli_err(s, argv[0], RXTX_ERRMSG_VALUE(argv[1], val)); return CMD_RET_INVPARAM; } } else { cli_err(s, argv[0], "Unrecognized command: %s", argv[1]); return CMD_RET_INVPARAM; } } } return 0; }
int set_frequency(struct cli_state *state, int argc, char **argv) { /* Usage: set frequency [<rx|tx>] <frequency in Hz> */ int rv = CLI_RET_OK; int status; unsigned int freq; bladerf_module module = BLADERF_MODULE_RX; if( argc == 4 ) { /* Parse module */ bool ok; module = get_module( argv[2], &ok ); if( !ok ) { invalid_module(state, argv[0], argv[2]); rv = CLI_RET_INVPARAM; } } else if( argc != 3 ) { /* Assume both RX & TX if not specified */ rv = CLI_RET_NARGS; } if( argc > 2 && rv == CLI_RET_OK ) { bool ok; /* Parse out frequency */ freq = str2uint_suffix( argv[argc-1], BLADERF_FREQUENCY_MIN, BLADERF_FREQUENCY_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &ok ); if( !ok ) { cli_err(state, argv[0], "Invalid frequency (%s)", argv[argc - 1]); rv = CLI_RET_INVPARAM; } else { printf( "\n" ); /* Change RX frequency */ if( argc == 3 || module == BLADERF_MODULE_RX ) { int status = bladerf_set_frequency( state->dev, BLADERF_MODULE_RX, freq ); if (status < 0) { state->last_lib_error = status; rv = CLI_RET_LIBBLADERF; } else { printf( " Set RX frequency: %10uHz\n", freq ); } } /* Change TX frequency */ if( argc == 3 || module == BLADERF_MODULE_TX ) { status = bladerf_set_frequency( state->dev, BLADERF_MODULE_TX, freq ); if (status < 0) { state->last_lib_error = status; rv = CLI_RET_LIBBLADERF; } else { printf( " Set TX frequency: %10uHz\n", freq ); } } printf( "\n" ); } } return rv; }
int rxtx_handle_wait(struct cli_state *s, struct rxtx_data *rxtx, int argc, char **argv) { int status; bool ok; unsigned int timeout_ms = 0; struct timespec timeout_abs; enum rxtx_state state; static const struct numeric_suffix times[] = { { "ms", 1 }, { "s", 1000 }, { "m", 60 * 1000 }, { "h", 60 * 60 * 1000 }, }; if (argc < 2 || argc > 3) { return CMD_RET_NARGS; } /* The start cmd should have waited until we entered the RUNNING state */ state = rxtx_get_state(rxtx); if (state != RXTX_STATE_RUNNING) { return 0; } if (argc == 3) { timeout_ms = str2uint_suffix(argv[2], 0, UINT_MAX, times, sizeof(times)/sizeof(times[0]), &ok); if (!ok) { cli_err(s, argv[0], "Invalid wait timeout: \"%s\"\n", argv[2]); return CMD_RET_INVPARAM; } } if (timeout_ms != 0) { const unsigned int timeout_sec = timeout_ms / 1000; status = clock_gettime(CLOCK_REALTIME, &timeout_abs); if (status != 0) { return CMD_RET_UNKNOWN; } timeout_abs.tv_sec += timeout_sec; timeout_abs.tv_nsec += (timeout_ms % 1000) * 1000 * 1000; if (timeout_abs.tv_nsec >= NSEC_PER_SEC) { timeout_abs.tv_sec += timeout_abs.tv_nsec / NSEC_PER_SEC; timeout_abs.tv_nsec %= NSEC_PER_SEC; } pthread_mutex_lock(&rxtx->task_mgmt.lock); rxtx->task_mgmt.main_task_waiting = true; while (rxtx->task_mgmt.main_task_waiting) { status = pthread_cond_timedwait(&rxtx->task_mgmt.signal_done, &rxtx->task_mgmt.lock, &timeout_abs); if (status == ETIMEDOUT) { rxtx->task_mgmt.main_task_waiting = false; } } pthread_mutex_unlock(&rxtx->task_mgmt.lock); /* Expected and OK condition */ if (status == ETIMEDOUT) { status = 0; } } else { pthread_mutex_lock(&rxtx->task_mgmt.lock); rxtx->task_mgmt.main_task_waiting = true; while (rxtx->task_mgmt.main_task_waiting) { status = pthread_cond_wait(&rxtx->task_mgmt.signal_done, &rxtx->task_mgmt.lock); } pthread_mutex_unlock(&rxtx->task_mgmt.lock); } if (status != 0) { status = CMD_RET_UNKNOWN; } return status; }
int set_bandwidth(struct cli_state *state, int argc, char **argv) { /* Usage: set bandwidth [rx|tx] <bandwidth in Hz> */ int rv = CLI_RET_OK; int status; bladerf_module module = BLADERF_MODULE_RX; unsigned int bw = 28000000, actual; /* Check for extended help */ if( argc == 2 ) { printf( "\n" ); printf( "Usage: set bandwidth [module] <bandwidth>\n" ); printf( "\n" ); printf( " module Optional argument to set single module bandwidth\n" ); printf( " bandwidth Bandwidth in Hz - will be rounded up to closest bandwidth\n" ); printf( "\n" ); } /* Check for optional module */ else if( argc == 4 ) { /* Parse module */ bool ok; module = get_module( argv[2], &ok ); if( !ok ) { invalid_module(state, argv[0], argv[2]); rv = CLI_RET_INVPARAM; } /* Parse bandwidth */ bw = str2uint_suffix( argv[3], BLADERF_BANDWIDTH_MIN, BLADERF_BANDWIDTH_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &ok ); if( !ok ) { cli_err(state, argv[0], "Invalid bandwidth (%s)", argv[3]); rv = CLI_RET_INVPARAM; } } /* No module, just bandwidth */ else if( argc == 3 ) { bool ok; bw = str2uint_suffix( argv[2], BLADERF_BANDWIDTH_MIN, BLADERF_BANDWIDTH_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &ok ); if( !ok ) { cli_err(state, argv[0], "Invalid bandwidth (%s)", argv[2]); rv = CLI_RET_INVPARAM; } } /* Weird number of arguments */ else { rv = CLI_RET_NARGS; } /* Problem parsing arguments? */ if( argc > 2 && rv == CLI_RET_OK ) { printf( "\n" ); /* Lack of option, so set both or RX only */ if( argc == 3 || module == BLADERF_MODULE_RX ) { status = bladerf_set_bandwidth( state->dev, BLADERF_MODULE_RX, bw, &actual ); if (status < 0) { state->last_lib_error = status; rv = CLI_RET_LIBBLADERF; } else { printf( " Set RX bandwidth - req:%9uHz actual:%9uHz\n", bw, actual ); } } /* Lack of option, so set both or TX only */ if( argc == 3 || module == BLADERF_MODULE_TX ) { status = bladerf_set_bandwidth( state->dev, BLADERF_MODULE_TX, bw, &actual ); if (status < 0) { state->last_lib_error = status; rv = CLI_RET_LIBBLADERF; } else { printf( " Set TX bandwidth - req:%9uHz actual:%9uHz\n", bw, actual ); } } printf( "\n" ); } return rv; }
static int handle_args(int argc, char *argv[], struct app_params *p) { int c, idx; bool ok; bladerf_log_level log_level; /* Print help */ if (argc == 1) { return 1; } while ((c = getopt_long(argc, argv, OPTSTR, long_options, &idx)) >= 0) { switch (c) { case 'v': log_level = str2loglevel(optarg, &ok); if (!ok) { fprintf(stderr, "Invalid log level: %s\n", optarg); return -1; } else { bladerf_log_set_verbosity(log_level); } break; case 'h': return 1; case 'd': if (p->device_str != NULL) { fprintf(stderr, "Device already specified: %s\n", p->device_str); return -1; } else { p->device_str = strdup(optarg); if (p->device_str == NULL) { perror("strdup"); return -1; } } break; case 's': p->samplerate = str2uint_suffix(optarg, BLADERF_SAMPLERATE_MIN, BLADERF_SAMPLERATE_REC_MAX, freq_suffixes, ARRAY_SIZE(freq_suffixes), &ok); if (!ok) { fprintf(stderr, "Invalid sample rate: %s\n", optarg); return -1; } break; case 'B': p->buf_size = str2uint_suffix(optarg, 1024, UINT_MAX, len_suffixes, ARRAY_SIZE(len_suffixes), &ok); if (!ok || (p->buf_size % 1024) != 0) { fprintf(stderr, "Invalid buffer length: %s\n", optarg); return -1; } break; case 't': p->test_name = strdup(optarg); if (p->test_name == NULL) { perror("strdup"); return -1; } break; case 'S': p->prng_seed = str2uint64(optarg, 1, UINT64_MAX, &ok); if (!ok) { fprintf(stderr, "Invalid seed value: %s\n", optarg); return -1; } break; default: return -1; } } return 0; }
int rxtx_handle_config_param(struct cli_state *s, struct rxtx_data *rxtx, const char *argv0, char *param, char **val) { int status = 0; unsigned int tmp; bool ok; if (!param) { return CMD_RET_MEM; } *val = strchr(param, '='); if (!*val || strlen(&(*val)[1]) < 1) { cli_err(s, argv0, "No value provided for parameter \"%s\"", param); status = CMD_RET_INVPARAM; } if (status == 0) { (*val)[0] = '\0'; (*val) = (*val) + 1; if (!strcasecmp("file", param)) { status = rxtx_set_file_path(rxtx, *val); if (status == 0) { status = 1; } } else if (!strcasecmp("format", param)) { enum rxtx_fmt fmt; fmt = rxtx_str2fmt(*val); if (fmt == RXTX_FMT_INVALID) { cli_err(s, argv0, RXTX_ERRMSG_VALUE(param, *val)); status = CMD_RET_INVPARAM; } else { rxtx_set_file_format(rxtx, fmt); status = 1; } } else if (!strcasecmp("buffers", param)) { tmp = str2uint_suffix(*val, RXTX_BUFFERS_MIN, UINT_MAX, rxtx_kmg_suffixes, (int)rxtx_kmg_suffixes_len, &ok); if (!ok) { cli_err(s, argv0, RXTX_ERRMSG_VALUE(param, *val)); status = CMD_RET_INVPARAM; } else { pthread_mutex_lock(&rxtx->data_mgmt.lock); rxtx->data_mgmt.num_buffers = tmp; pthread_mutex_unlock(&rxtx->data_mgmt.lock); status = 1; } } else if (!strcasecmp("samples", param)) { tmp = str2uint_suffix(*val, RXTX_BUFFERS_MIN, UINT_MAX, rxtx_kmg_suffixes, (int)rxtx_kmg_suffixes_len, &ok); if (!ok) { cli_err(s, argv0, RXTX_ERRMSG_VALUE(param, *val)); status = CMD_RET_INVPARAM; } else if (tmp % RXTX_SAMPLES_MIN != 0) { cli_err(s, argv0, "The '%s' paramter must be a multiple of %u.", param, RXTX_BUFFERS_MIN); status = CMD_RET_INVPARAM; } else { pthread_mutex_lock(&rxtx->data_mgmt.lock); rxtx->data_mgmt.samples_per_buffer= tmp; pthread_mutex_unlock(&rxtx->data_mgmt.lock); status = 1; } } else if (!strcasecmp("xfers", param)) { tmp = str2uint_suffix(*val, RXTX_BUFFERS_MIN - 1, UINT_MAX, rxtx_kmg_suffixes, (int)rxtx_kmg_suffixes_len, &ok); if (!ok) { cli_err(s, argv0, RXTX_ERRMSG_VALUE(param, *val)); status = CMD_RET_INVPARAM; } else { pthread_mutex_lock(&rxtx->data_mgmt.lock); rxtx->data_mgmt.num_transfers= tmp; pthread_mutex_unlock(&rxtx->data_mgmt.lock); status = 1; } } } return status; }
int handle_cmdline(int argc, char *argv[], struct test_params *p) { int c; int idx; bool ok; bladerf_log_level level; test_init_params(p); while ((c = getopt_long(argc, argv, OPTSTR, long_options, &idx)) >= 0) { switch (c) { case 1: level = str2loglevel(optarg, &ok); if (!ok) { log_error("Invalid log level provided: %s\n", optarg); return -1; } else { log_set_verbosity(level); } break; case 2: level = str2loglevel(optarg, &ok); if (!ok) { log_error("Invalid log level provided: %s\n", optarg); return -1; } else { bladerf_log_set_verbosity(level); } break; case 'h': return 1; case 'd': if (p->device_str != NULL) { log_error("Device was already specified.\n"); return -1; } p->device_str = strdup(optarg); if (p->device_str == NULL) { perror("strdup"); return -1; } break; case 's': p->samplerate = str2uint_suffix(optarg, BLADERF_SAMPLERATE_MIN, BLADERF_SAMPLERATE_REC_MAX, freq_suffixes, num_freq_suffixes, &ok); if (!ok) { log_error("Invalid sample rate: %s\n", optarg); return -1; } break; case 'f': p->frequency = str2uint_suffix(optarg, BLADERF_FREQUENCY_MIN, BLADERF_FREQUENCY_MAX, freq_suffixes, num_freq_suffixes, &ok); if (!ok) { log_error("Invalid frequency: %s\n", optarg); return -1; } break; case 'l': if (str2loopback(optarg, &p->loopback) != 0) { log_error("Invalid loopback mode: %s\n", optarg); return -1; } break; case 'i': if (p->in_file) { log_error("Input file already provided.\n"); return -1; } p->in_file = fopen(optarg, "rb"); if (p->in_file == NULL) { log_error("Failed to open input file - %s\n", strerror(errno)); return -1; } break; case 'o': if (p->out_file) { log_error("Output file already provided.\n"); return -1; } p->out_file = fopen(optarg, "wb"); if (p->out_file == NULL) { log_error("Failed to open output file - %s\n", strerror(errno)); return -1; } break; case 'r': p->tx_repetitions = str2uint_suffix(optarg, 1, UINT_MAX, count_suffixes, num_count_suffixes, &ok); if (!ok) { log_error("Invalid TX repetition value: %s\n", optarg); return -1; } break; case 'c': p->rx_count = str2uint_suffix(optarg, 1, UINT_MAX, count_suffixes, num_count_suffixes, &ok); if (!ok) { log_error("Invalid RX count: %s\n", optarg); return -1; } break; case 'b': p->block_size = str2uint_suffix(optarg, 1, UINT_MAX, size_suffixes, num_size_suffixes, &ok); if (!ok) { log_error("Invalid block size: %s\n", optarg); return -1; } break; case 'X': p->num_xfers = str2uint(optarg, 1, UINT_MAX, &ok); if (!ok) { log_error("Invalid stream transfer count: %s\n", optarg); return -1; } break; case 'B': p->stream_buffer_size = str2uint(optarg, 1, UINT_MAX, &ok); if (!ok) { log_error("Invalid stream buffer size: %s\n", optarg); return -1; } break; case 'C': p->stream_buffer_count = str2uint(optarg, 1, UINT_MAX, &ok); if (!ok) { log_error("Invalid stream buffer count: %s\n", optarg); return -1; } break; case 'T': p->timeout_ms = str2uint(optarg, 0, UINT_MAX, &ok); if (!ok) { log_error("Invalid stream timeout: %s\n", optarg); return -1; } break; } } if (p->in_file == NULL && p->out_file == NULL) { log_error("An input or output file is required.\n"); return -1; } if (p->frequency == 0) { p->frequency = DEFAULT_FREQUENCY; } if (p->samplerate == 0) { p->samplerate = DEFAULT_SAMPLERATE; } if (p->tx_repetitions == 0) { p->tx_repetitions = DEFAULT_TX_REPETITIONS; } if (p->rx_count == 0) { p->rx_count = DEFAULT_RX_COUNT; } if (p->block_size == 0) { p->block_size = DEFAULT_BLOCK_SIZE; } return 0; }
int rxtx_handle_wait(struct cli_state *s, struct rxtx_data *rxtx, int argc, char **argv) { int status = CLI_RET_UNKNOWN; bool ok; unsigned int timeout_ms = 0; struct timespec timeout_abs; enum rxtx_state state; static const struct numeric_suffix times[] = { { "ms", 1 }, { "s", 1000 }, { "m", 60 * 1000 }, { "h", 60 * 60 * 1000 }, }; if (argc < 2 || argc > 3) { return CLI_RET_NARGS; } /* The start cmd should have waited until we entered the RUNNING state */ state = rxtx_get_state(rxtx); if (state != RXTX_STATE_RUNNING) { return 0; } if (argc == 3) { timeout_ms = str2uint_suffix(argv[2], 0, UINT_MAX, times, sizeof(times)/sizeof(times[0]), &ok); if (!ok) { cli_err(s, argv[0], "Invalid wait timeout: \"%s\"\n", argv[2]); return CLI_RET_INVPARAM; } } /* Release the device lock (acquired in cmd_handle()) while we wait * because we won't be doing device-control operations during this time. * This ensures that when the associated rx/tx task completes, it will be * able to acquire the device control lock to release this wait. */ MUTEX_UNLOCK(&s->dev_lock); if (timeout_ms != 0) { const unsigned int timeout_sec = timeout_ms / 1000; status = clock_gettime(CLOCK_REALTIME, &timeout_abs); if (status != 0) { goto out; } timeout_abs.tv_sec += timeout_sec; timeout_abs.tv_nsec += (timeout_ms % 1000) * 1000 * 1000; if (timeout_abs.tv_nsec >= NSEC_PER_SEC) { timeout_abs.tv_sec += timeout_abs.tv_nsec / NSEC_PER_SEC; timeout_abs.tv_nsec %= NSEC_PER_SEC; } MUTEX_LOCK(&rxtx->task_mgmt.lock); rxtx->task_mgmt.main_task_waiting = true; while (rxtx->task_mgmt.main_task_waiting) { status = pthread_cond_timedwait(&rxtx->task_mgmt.signal_done, &rxtx->task_mgmt.lock, &timeout_abs); if (status == ETIMEDOUT) { rxtx->task_mgmt.main_task_waiting = false; } } MUTEX_UNLOCK(&rxtx->task_mgmt.lock); } else { MUTEX_LOCK(&rxtx->task_mgmt.lock); rxtx->task_mgmt.main_task_waiting = true; while (rxtx->task_mgmt.main_task_waiting) { status = pthread_cond_wait(&rxtx->task_mgmt.signal_done, &rxtx->task_mgmt.lock); } MUTEX_UNLOCK(&rxtx->task_mgmt.lock); } out: /* Re-acquire the device control lock, as the top-level command handler * will be unlocking this when it's done */ MUTEX_LOCK(&s->dev_lock); /* Expected and OK condition */ if (status == ETIMEDOUT) { status = 0; } if (status != 0) { status = CLI_RET_UNKNOWN; } return status; }
int config_init_from_cmdline(int argc, char * const argv[], struct config **config_out) { int status = 0; struct config *config = NULL; int c, idx; bool valid; struct stat file_info; config = alloc_config_with_defaults(); if (config == NULL) { pr_dbg("%s: Failed to alloc config.\n", __FUNCTION__); return -2; } while ((c = getopt_long(argc, argv, OPTIONS, long_options, &idx)) != -1) { switch (c) { case OPTION_HELP: status = 1; goto out; case OPTION_DEVICE: if (config->bladerf_dev == NULL) { status = bladerf_open(&config->bladerf_dev, optarg); if (status < 0) { fprintf(stderr, "Failed to open bladeRF=%s: %s\n", optarg, bladerf_strerror(status)); goto out; } } break; case OPTION_OUTPUT: if (config->rx_output == NULL) { if (!strcasecmp(optarg, "stdout")) { config->rx_output = stdout; } else { config->rx_output = fopen(optarg, "wb"); if (config->rx_output == NULL) { status = -errno; fprintf(stderr, "Failed to open %s for writing: %s\n", optarg, strerror(-status)); goto out; } } } break; case OPTION_RXLNA: status = str2lnagain(optarg, &config->params.rx_lna_gain); if (status != 0) { fprintf(stderr, "Invalid RX LNA gain: %s\n", optarg); goto out; } break; case OPTION_RXVGA1: config->params.rx_vga1_gain = str2int(optarg, BLADERF_RXVGA1_GAIN_MIN, BLADERF_RXVGA1_GAIN_MAX, &valid); if (!valid) { status = -1; fprintf(stderr, "Invalid RX VGA1 gain: %s\n", optarg); goto out; } break; case OPTION_RXVGA2: config->params.rx_vga2_gain = str2int(optarg, BLADERF_RXVGA2_GAIN_MIN, BLADERF_RXVGA2_GAIN_MAX, &valid); if (!valid) { status = -1; fprintf(stderr, "Invalid RX VGA2 gain: %s\n", optarg); goto out; } break; case OPTION_RXFREQ: config->params.rx_freq = str2uint_suffix(optarg, BLADERF_FREQUENCY_MIN, BLADERF_FREQUENCY_MAX, freq_suffixes, num_freq_suffixes, &valid); if (!valid) { status = -1; fprintf(stderr, "Invalid RX frequency: %s\n", optarg); goto out; } break; case OPTION_INPUT: if (config->tx_input == NULL) { if (!strcasecmp(optarg, "stdin")) { config->tx_input = stdin; config->tx_filesize = -1; } else { config->tx_input = fopen(optarg, "rb"); if (config->tx_input == NULL) { status = -errno; fprintf(stderr, "Failed to open %s for reading: %s\n", optarg, strerror(-status)); goto out; } //Get file size status = stat(optarg, &file_info); if (status != 0){ fprintf(stderr, "Couldn't filesize of %s: %s\n", optarg, strerror(status)); } config->tx_filesize = file_info.st_size; } } break; case OPTION_TXVGA1: config->params.tx_vga1_gain = str2int(optarg, BLADERF_TXVGA1_GAIN_MIN, BLADERF_TXVGA2_GAIN_MAX, &valid); if (!valid) { status = -1; fprintf(stderr, "Invalid TX VGA1 gain: %s\n", optarg); goto out; } break; case OPTION_TXVGA2: config->params.tx_vga2_gain = str2int(optarg, BLADERF_TXVGA2_GAIN_MIN, BLADERF_TXVGA2_GAIN_MAX, &valid); if (!valid) { status = -1; fprintf(stderr, "Invalid TX VGA2 gain: %s\n", optarg); goto out; } break; case OPTION_TXFREQ: config->params.tx_freq = str2uint_suffix(optarg, BLADERF_FREQUENCY_MIN, BLADERF_FREQUENCY_MAX, freq_suffixes, num_freq_suffixes, &valid); if (!valid) { status = -1; fprintf(stderr, "Invalid TX frequency: %s\n", optarg); goto out; } break; case OPTION_QUIET: config->quiet = true; break; } } /* Initialize any properties not covered by user input */ status = init_remaining_params(config); out: if (status != 0) { config_deinit(config); *config_out = NULL; } else { *config_out = config; } return status; }
int cmd_mimo(struct cli_state *state, int argc, char **argv) { int status = 0; printf("\n"); printf(" IMPORTANT: This command is deprecated and has been superseded\n"); printf(" by `print|set smb_mode`. Run `set smb_mode` for usage.\n"); if (argc < 2) { printf("\n"); printf(" Usage: %s <slave>\n", argv[0]); printf(" %s <master> [frequency]\n", argv[0]); printf("\n"); return 0; } if (!strcasecmp(argv[1], "slave")) { uint8_t val; if (argc != 2) { return CLI_RET_NARGS; } status = bladerf_si5338_write(state->dev, 6, 4); if (status != 0) { goto out; } status = bladerf_si5338_write(state->dev, 28, 0x2b); if (status != 0) { goto out; } status = bladerf_si5338_write(state->dev, 29, 0x28); if (status != 0) { goto out; } status = bladerf_si5338_write(state->dev, 30, 0xa8); if (status != 0) { goto out; } /* Turn off any SMB connector output */ status = bladerf_si5338_read(state->dev, 39, &val); if (status != 0) { goto out; } val &= ~(1); status = bladerf_si5338_write(state->dev, 39, val); if (status != 0) { goto out; } printf("\n Successfully set device to slave MIMO mode.\n\n"); } else if (!strcmp(argv[1], "master")) { if (argc == 2) { /* Output the 38.4MHz clock on the SMB connector. */ uint8_t val ; status = bladerf_si5338_read(state->dev, 39, &val); if (status != 0) { goto out; } val |= 1; status = bladerf_si5338_write(state->dev, 39, val); if (status != 0) { goto out; } status = bladerf_si5338_write(state->dev, 34, 0x22); if (status != 0) { goto out; } printf("\n Successfully set device to master MIMO mode.\n\n"); } else if (argc == 3) { /* Output a specific frequency on the SMB connector. */ unsigned int freq, actual; bool ok; freq = str2uint_suffix(argv[2], BLADERF_SMB_FREQUENCY_MIN, BLADERF_SMB_FREQUENCY_MAX, freq_suffixes, NUM_FREQ_SUFFIXES, &ok); if (!ok) { cli_err(state, argv[0], "Invalid SMB frequency (%s)\n", argv[2]); return CLI_RET_INVPARAM; } else { status = bladerf_set_smb_frequency(state->dev, freq, &actual); if(status >= 0) { printf("\n Set device to master MIMO, " "req freq:%9uHz, actual:%9uHz\n\n", freq, actual); } else { goto out; } } } else { return CLI_RET_NARGS; } } else { cli_err(state, argv[0], "Invalid mode: %s\n", argv[1]); } out: if (status != 0) { state->last_lib_error = status; status = CLI_RET_LIBBLADERF; } return status; }
static int handle_args(int argc, char *argv[], struct repeater_config *config) { int opt, opt_idx; bool conv_ok; repeater_config_init(config); opt = getopt_long(argc, argv, OPTARG_STR, long_options, &opt_idx); while (opt != -1) { switch(opt) { case 'd': if (!config->device_str) { config->device_str = strdup(optarg); if (!config->device_str) { perror("strdup"); return -1; } } else { fprintf(stderr, "\nError: Device already specified: %s\n", config->device_str); return -1; } break; case 't': config->tx_freq = str2uint_suffix(optarg, 1, INT_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &conv_ok); if (!conv_ok) { fprintf(stderr, "\nError: Invalid TX frequency: %d\n\n", config->tx_freq); return -1; } break; case 'r': config->rx_freq = str2uint_suffix(optarg, 1, INT_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &conv_ok); if (!conv_ok) { fprintf(stderr, "\nError: Invalid RX frequency: %d\n\n", config->rx_freq); return -1; } break; case 's': config->sample_rate = str2uint_suffix(optarg, 1, INT_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &conv_ok); if (!conv_ok) { fprintf(stderr, "\nError: Invalid sample rate: %d\n", config->sample_rate); } break; case 'b': config->bandwidth = str2uint_suffix(optarg, 1, INT_MAX, FREQ_SUFFIXES, NUM_FREQ_SUFFIXES, &conv_ok); if (!conv_ok) { fprintf(stderr, "\nError: Invalid bandwidth: %d\n", config->bandwidth); } break; case 'S': config->samples_per_buffer = str2int(optarg, 1024, INT_MAX, &conv_ok); if (!conv_ok || config->samples_per_buffer % 1024 != 0) { fprintf(stderr, "\nError: Invalid samples value: %d\n\n", config->samples_per_buffer); return -1; } break; case 'B': config->num_buffers = str2int(optarg, 1, INT_MAX, &conv_ok); if (!conv_ok) { fprintf(stderr, "\nError: " "Invalid number of buffers: %d\n\n", config->num_buffers); return -1; } break; case 'T': config->num_transfers = str2int(optarg, 1, INT_MAX, &conv_ok); if (!conv_ok) { fprintf(stderr, "\nError: " "Invalid number of transfers: %d\n\n", config->num_buffers); return -1; } break; case 'v': if (!strcasecmp(optarg, "critical")) { config->verbosity = BLADERF_LOG_LEVEL_CRITICAL; } else if (!strcasecmp(optarg, "error")) { config->verbosity = BLADERF_LOG_LEVEL_ERROR; } else if (!strcasecmp(optarg, "warning")) { config->verbosity = BLADERF_LOG_LEVEL_WARNING; } else if (!strcasecmp(optarg, "info")) { config->verbosity = BLADERF_LOG_LEVEL_INFO; } else if (!strcasecmp(optarg, "debug")) { config->verbosity = BLADERF_LOG_LEVEL_DEBUG; } else if (!strcasecmp(optarg, "verbose")) { config->verbosity = BLADERF_LOG_LEVEL_VERBOSE; } else { fprintf(stderr, "Unknown verbosity level: %s\n", optarg); return -1; } break; case 'h': return 1; default: return -1; } opt = getopt_long(argc, argv, OPTARG_STR, long_options, &opt_idx); } if (config->samples_per_buffer < 1024 || config->samples_per_buffer % 1024 != 0) { fprintf(stderr, "\nError: " "# samples must be >= 1024 and a multiple of 1024\n\n"); return -1; } if (config->num_buffers < (config->num_transfers + 2)) { fprintf(stderr, "\nError: " "# buffers (%u) must be at least 2 greater than " "# transfers (%u)\n\n", config->num_buffers, config->num_transfers); return -1; } return 0; }