static int extract_field(char *ptr, int len, char *field, char *val, size_t maxlen) { int c; unsigned char *ub, *end; unsigned short a1, a2; size_t flen, wlen; flen = strlen(field); ub = (unsigned char *)ptr; end = ub + len; while (ub < end) { c = *ub; if (c == 0xff) // flash and OTP are 0xff if they've never been written to break; a1 = LE16_TO_HOST(*(unsigned short *)(&ub[c+1])); // read checksum a2 = crc16mp(0, ub, c+1); // calculated checksum if (a1 == a2) { if (!strncmp((char *)ub + 1, field, flen)) { wlen = min_sz(c - flen, maxlen); strncpy(val, (char *)ub + 1 + flen, wlen); val[wlen] = 0; return 0; } } else { log_warning( "%s: Field checksum mismatch\n", __FUNCTION__); return BLADERF_ERR_INVAL; } ub += c + 3; //skip past `c' bytes, 2 byte CRC field, and 1 byte len field } return BLADERF_ERR_INVAL; }
int NuandExtractField(char *ptr, int len, char *field, char *val, size_t maxlen) { int c, wlen; unsigned char *ub, *end; unsigned short a1, a2; int flen; flen = strlen(field); ub = (unsigned char *)ptr; end = ub + len; while (ub < end) { c = *ub; if (c == 0xff) // flash and OTP are 0xff if they've never been written to break; a1 = *(unsigned short *)(&ub[c+1]); // read checksum a2 = crc16mp(0, ub, c+1); // calculated checksum if (a1 == a2 || 1) { if (!strncmp((char *)ub + 1, field, flen)) { wlen = min_sz(c - flen, maxlen); strncpy(val, (char *)ub + 1 + flen, wlen); val[wlen] = 0; return 0; } } else { return 1; } ub += c + 3; //skip past `c' bytes, 2 byte CRC field, and 1 byte len field } return 1; }
static void *rx_callback(struct bladerf *dev, struct bladerf_stream *stream, struct bladerf_metadata *meta, void *samples, size_t num_samples, void *user_data) { struct rx_callback_data *cb_data = (struct rx_callback_data *)user_data; struct rxtx_data *rx = cb_data->rx; unsigned char requests; void *ret; size_t n_to_write; /* Stop stream on STOP or SHUTDOWN, but only clear STOP. This will keep * the SHUTDOWN request around so we can read it when determining * our state transition */ requests = rxtx_get_requests(rx, RXTX_TASK_REQ_STOP); if (requests & (RXTX_TASK_REQ_STOP | RXTX_TASK_REQ_SHUTDOWN)) { return NULL; } pthread_mutex_lock(&rx->data_mgmt.lock); if (!cb_data->inf) { n_to_write = min_sz(cb_data->samples_left, num_samples); cb_data->samples_left -= n_to_write; } else { n_to_write = num_samples; } /* We assume we have IQ pairs */ assert((n_to_write & 1) == 0); if (n_to_write > 0) { sc16q12_sample_fixup(samples, n_to_write); /* Write the samples out */ cb_data->write_samples(rx, (int16_t*)samples, n_to_write); /* Fetch the next buffer */ rx->data_mgmt.next_idx++; rx->data_mgmt.next_idx %= rx->data_mgmt.num_buffers; ret = rx->data_mgmt.buffers[rx->data_mgmt.next_idx]; } else { /* We've already written the request number of samples */ ret = NULL; } pthread_mutex_unlock(&rx->data_mgmt.lock); return ret; }
static int linux_load_fpga(struct bladerf *dev, uint8_t *image, size_t image_size) { int ret, fpga_status, end_prog_status; size_t written = 0; /* Total # of bytes written */ size_t to_write; ssize_t write_tmp; /* # bytes written in a single write() call */ struct timeval end_time, curr_time; bool timed_out; struct bladerf_linux *backend = (struct bladerf_linux *)dev->backend; assert(dev && image); ret = linux_begin_fpga_programming(backend->fd); if (ret < 0) { return ret; } /* FIXME This loops is just here to work around the fact that the * driver currently can't handle large writes... */ while (written < image_size) { do { to_write = min_sz(1024, image_size - written); write_tmp = write(backend->fd, image + written, to_write); if (write_tmp < 0) { /* Failing out...at least attempt to "finish" programming */ ioctl(backend->fd, BLADE_END_PROG, &ret); log_error("Write failure: %s\n", strerror(errno)); return BLADERF_ERR_IO; } else { assert(write_tmp == (ssize_t)to_write); written += write_tmp; } } while(written < image_size); } /* FIXME? Perhaps it would be better if the driver blocked on the * write call, rather than sleeping in userspace? */ usleep(4000); /* Time out within 1 second */ gettimeofday(&end_time, NULL); end_time.tv_sec++; ret = 0; do { fpga_status = linux_is_fpga_configured(dev); if (fpga_status < 0) { ret = fpga_status; } else { gettimeofday(&curr_time, NULL); timed_out = time_past(end_time, curr_time); } } while(!fpga_status && !timed_out && !ret); end_prog_status = linux_end_fpga_programming(backend->fd); /* Return the first error encountered */ if (end_prog_status < 0 && ret == 0) { ret = end_prog_status; } return ret; }