Beispiel #1
0
/**
 * Construct file name for a log file and return it's file descriptor.
 * Name and location depends on pattern, default_pattern params and access
 * permissions.
 */
static int prepare_log_file(const char* pattern, const char* default_pattern, char* buf, size_t buflen) {
  int fd = -1;

  // If possible, use specified pattern to construct log file name
  if (pattern != NULL) {
    fd = expand_and_open(pattern, buf, buflen, 0);
  }

  // Either user didn't specify, or the user's location failed,
  // so use the default name in the current directory
  if (fd == -1) {
    const char* cwd = os::get_current_directory(buf, buflen);
    if (cwd != NULL) {
      size_t pos = strlen(cwd);
      int fsep_len = jio_snprintf(&buf[pos], buflen-pos, "%s", os::file_separator());
      pos += fsep_len;
      if (fsep_len > 0) {
        fd = expand_and_open(default_pattern, buf, buflen, pos);
      }
    }
  }

   // try temp directory if it exists.
   if (fd == -1) {
     const char* tmpdir = os::get_temp_directory();
     if (tmpdir != NULL && strlen(tmpdir) > 0) {
       int pos = jio_snprintf(buf, buflen, "%s%s", tmpdir, os::file_separator());
       if (pos > 0) {
         fd = expand_and_open(default_pattern, buf, buflen, pos);
       }
     }
   }

  return fd;
}
Beispiel #2
0
static int write_image(struct cli_state *s, struct params *p, const char *argv0)
{
    int status;
    FILE *f;
    long data_size;
    struct bladerf_image *image = NULL;

    f = expand_and_open(p->data_file, "rb");
    if (!f) {
        return CMD_RET_FILEOP;
    }

    if (fseek(f, 0, SEEK_END) != 0) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    data_size = ftell(f);
    if (data_size < 0) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    if ((uint32_t)data_size > p->max_length) {
        status = CMD_RET_INVPARAM;
        cli_err(s, argv0, "The provided data file is too large for the specified flash region.");
        goto write_image_out;
    }

    if (fseek(f, 0, SEEK_SET) != 0) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    image = bladerf_alloc_image(p->type, p->address, data_size);
    if (!image) {
        status = CMD_RET_MEM;
        goto write_image_out;
    }

    if (fread(image->data, 1, data_size, f) != (size_t)data_size) {
        status = CMD_RET_FILEOP;
        goto write_image_out;
    }

    memcpy(image->serial, p->serial, BLADERF_SERIAL_LENGTH - 1);

    status = bladerf_image_write(image, p->img_file);
    if (status != 0) {
        s->last_lib_error = status;
        status = CMD_RET_LIBBLADERF;
    }

write_image_out:
    fclose(f);
    bladerf_free_image(image);
    return status;
}
Beispiel #3
0
static int tx_cmd_start(struct cli_state *s)
{
    int status = 0;

    /* Check that we're able to start up in our current state */
    status = rxtx_cmd_start_check(s, s->tx, "tx");
    if (status != 0) {
        return status;
    }

    /* Perform file conversion (if needed) and open input file */
    MUTEX_LOCK(&s->tx->file_mgmt.file_meta_lock);

    if (s->tx->file_mgmt.format == RXTX_FMT_CSV_SC16Q11) {
        status = tx_csv_to_sc16q11(s);

        if (status == 0) {
            printf("  Converted CSV to SC16 Q11 file and "
                    "switched to converted file.\n\n");
        }
    }

    if (status == 0) {
        MUTEX_LOCK(&s->tx->file_mgmt.file_lock);

        assert(s->tx->file_mgmt.format == RXTX_FMT_BIN_SC16Q11);
        status = expand_and_open(s->tx->file_mgmt.path, "rb",
                                 &s->tx->file_mgmt.file);
        MUTEX_UNLOCK(&s->tx->file_mgmt.file_lock);
    }

    MUTEX_UNLOCK(&s->tx->file_mgmt.file_meta_lock);

    if (status != 0) {
        return status;
    }

    /* Request thread to start running */
    rxtx_submit_request(s->tx, RXTX_TASK_REQ_START);
    status = rxtx_wait_for_state(s->tx, RXTX_STATE_RUNNING, 3000);

    /* This should never occur. If it does, there's likely a defect
     * present in the tx task */
    if (status != 0) {
        cli_err(s, "tx", "TX did not start up in the alloted time\n");
        status = CLI_RET_UNKNOWN;
    }

    return status;
}
Beispiel #4
0
/* Create a temp (binary) file from a CSV so we don't have to waste time
 * parsing it in between sending samples.
 *
 * Postconditions: TX cfg's file descriptor, filename, and format will be
 *                 changed. (On success they'll be set to the binary file,
 *                 and on failure the csv will be closed.)
 *
 * return 0 on success, CLI_RET_* on failure
 */
static int tx_csv_to_sc16q11(struct cli_state *s)
{
    struct rxtx_data *tx = s->tx;
    const char delim[] = " \r\n\t,.:";
    char buf[81] = { 0 };
    char *token, *saveptr;
    int tmp_int;
    int16_t tmp_iq[2];
    bool ok;
    int status;
    FILE *bin = NULL;
    FILE *csv = NULL;
    char *bin_name = NULL;
    int line = 1;
    unsigned int n_clamped = 0;

    assert(tx->file_mgmt.path != NULL);

    status = expand_and_open(tx->file_mgmt.path, "r", &csv);
    if (status != 0) {
        goto tx_csv_to_sc16q11_out;
    }

    bin_name = strdup(TMP_FILE_NAME);
    if (!bin_name) {
        status = CLI_RET_MEM;
        goto tx_csv_to_sc16q11_out;
    }

    status = expand_and_open(bin_name, "wb+", &bin);
    if (status != 0) {
        goto tx_csv_to_sc16q11_out;
    }

    while (fgets(buf, sizeof(buf), csv))
    {
        /* I */
        token = strtok_r(buf, delim, &saveptr);

        if (token) {
            tmp_int = str2int(token, INT16_MIN, INT16_MAX, &ok);

            if (tmp_int < SC16Q11_IQ_MIN) {
                tmp_int = SC16Q11_IQ_MIN;
                n_clamped++;
            } else if (tmp_int > SC16Q11_IQ_MAX) {
                tmp_int = SC16Q11_IQ_MAX;
                n_clamped++;
            }

            if (ok) {
                tmp_iq[0] = tmp_int;
            } else {
                cli_err(s, "tx",
                        "Line %d: Encountered invalid I value.\n", line);
                status = CLI_RET_INVPARAM;
                break;
            }

            /* Q */
            token = strtok_r(NULL, delim, &saveptr);

            if (token) {
                tmp_int = str2int(token, INT16_MIN, INT16_MAX, &ok);

                if (tmp_int < SC16Q11_IQ_MIN) {
                    tmp_int = SC16Q11_IQ_MIN;
                    n_clamped++;
                } else if (tmp_int > SC16Q11_IQ_MAX) {
                    tmp_int = SC16Q11_IQ_MAX;
                    n_clamped++;
                }

                if (ok) {
                    tmp_iq[1] = tmp_int;
                } else {
                    cli_err(s, "tx",
                            "Line %d: encountered invalid Q value.\n", line);
                    status = CLI_RET_INVPARAM;
                    break;
                }

            } else {
                cli_err(s, "tx", "Error: Q value missing.\n");
                status = CLI_RET_INVPARAM;
                break;
            }

            /* Check for extraneous tokens */
            token = strtok_r(NULL, delim, &saveptr);
            if (!token) {
                if (fwrite(tmp_iq, sizeof(tmp_iq[0]), 2, bin) != 2) {
                    status = CLI_RET_FILEOP;
                    break;
                }
            } else {
                cli_err(s, "tx",
                        "Line (%d): Encountered extra token(s).\n", line);
                status = CLI_RET_INVPARAM;
                break;
            }
        }

        line++;
    }

    if (status == 0) {
        if (feof(csv)) {
            tx->file_mgmt.format = RXTX_FMT_BIN_SC16Q11;
            free(tx->file_mgmt.path);
            tx->file_mgmt.path = bin_name;

            if (n_clamped != 0) {
                printf("  Warning: %u values clamped within DAC SC16 Q11 "
                       "range of [%d, %d].\n",
                       n_clamped, SC16Q11_IQ_MIN, SC16Q11_IQ_MAX);
            }
        } else {
            status = CLI_RET_FILEOP;
        }
    }

tx_csv_to_sc16q11_out:
    if (status != 0) {
        free(bin_name);
    }

    if (csv) {
        fclose(csv);
    }

    if (bin) {
        fclose(bin);
    }

    return status;
}