Beispiel #1
0
  /**
   * Callback to parse scan results
   */
  int wireless_network::scan_cb(struct nl_msg* msg, void* instance) {
    auto wn = static_cast<wireless_network*>(instance);
    auto gnlh = static_cast<genlmsghdr*>(nlmsg_data(nlmsg_hdr(msg)));
    struct nlattr* tb[NL80211_ATTR_MAX + 1];
    struct nlattr* bss[NL80211_BSS_MAX + 1];

    struct nla_policy bss_policy[NL80211_BSS_MAX + 1]{};
    bss_policy[NL80211_BSS_TSF].type = NLA_U64;
    bss_policy[NL80211_BSS_FREQUENCY].type = NLA_U32;
    bss_policy[NL80211_BSS_BSSID].type = NLA_UNSPEC;
    bss_policy[NL80211_BSS_BEACON_INTERVAL].type = NLA_U16;
    bss_policy[NL80211_BSS_CAPABILITY].type = NLA_U16;
    bss_policy[NL80211_BSS_INFORMATION_ELEMENTS].type = NLA_UNSPEC;
    bss_policy[NL80211_BSS_SIGNAL_MBM].type = NLA_U32;
    bss_policy[NL80211_BSS_SIGNAL_UNSPEC].type = NLA_U8;
    bss_policy[NL80211_BSS_STATUS].type = NLA_U32;

    if (nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), nullptr) < 0) {
      return NL_SKIP;
    }

    if (tb[NL80211_ATTR_BSS] == nullptr) {
      return NL_SKIP;
    }

    if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS], bss_policy) != 0) {
      return NL_SKIP;
    }

    if (!wn->associated_or_joined(bss)) {
      return NL_SKIP;
    }

    wn->parse_essid(bss);
    wn->parse_frequency(bss);
    wn->parse_signal(bss);
    wn->parse_quality(bss);

    return NL_SKIP;
  }
Beispiel #2
0
void frequency_range(char *arg, struct misc_settings *ms)
/* flesh out the tunes[] for scanning */
{
	struct channel_solve c;
	struct tuning_state *ts;
	int r, i, j, buf_len, length, hop_bins, logged_bins, planned_bins;
	int lower_edge, actual_bw, upper_perfect, remainder;

	fprintf(stderr, "Range: %s\n", arg);
	parse_frequency(arg, &c);
	c.downsample = 1;
	c.downsample_passes = 0;
	c.crop = ms->crop;

	if (ms->target_rate < 2 * MINIMUM_RATE) {
		ms->target_rate = 2 * MINIMUM_RATE;
	}
	if (ms->target_rate > MAXIMUM_RATE) {
		ms->target_rate = MAXIMUM_RATE;
	}
	if ((ms->crop < 0.0) || (ms->crop > 1.0)) {
		fprintf(stderr, "Crop value outside of 0 to 1.\n");
		exit(1);
	}

	r = -1;
	if (c.bin_spec >= MINIMUM_RATE) {
		fprintf(stderr, "Mode: rms power\n");
		solve_giant_bins(&c);
	} else if ((c.upper - c.lower) < MINIMUM_RATE) {
		fprintf(stderr, "Mode: downsampling\n");
		solve_downsample(&c, ms->target_rate, ms->boxcar);
	} else if ((c.upper - c.lower) < MAXIMUM_RATE) {
		r = solve_single(&c, ms->target_rate);
	} else {
		fprintf(stderr, "Mode: hopping\n");
		solve_hopping(&c, ms->target_rate);
	}

	if (r == 0) {
		fprintf(stderr, "Mode: single\n");
	} else if (r == 1) {
		fprintf(stderr, "Mode: hopping\n");
		solve_hopping(&c, ms->target_rate);
	}
	c.crop = c.crop_tmp;

	if ((tune_count+c.hops) > MAX_TUNES) {
		fprintf(stderr, "Error: bandwidth too wide.\n");
		exit(1);
	}
	buf_len = 2 * (1<<c.bin_e) * c.downsample;
	if (buf_len < DEFAULT_BUF_LENGTH) {
		buf_len = DEFAULT_BUF_LENGTH;
	}
	/* build the array */
	logged_bins = 0;
	lower_edge = c.lower;
	planned_bins = (c.upper - c.lower) / c.bin_spec;
	for (i=0; i < c.hops; i++) {
		ts = &tunes[tune_count + i];
		/* copy common values */
		ts->rate = c.bw_needed;
		ts->gain = ms->gain;
		ts->bin_e = c.bin_e;
		ts->samples = 0;
		ts->bin_spec = c.bin_spec;
		ts->crop = c.crop;
		ts->downsample = c.downsample;
		ts->downsample_passes = c.downsample_passes;
		ts->comp_fir_size = ms->comp_fir_size;
		ts->peak_hold = ms->peak_hold;
		ts->linear = ms->linear;
		ts->avg = (int64_t*)malloc((1<<c.bin_e) * sizeof(int64_t));
		if (!ts->avg) {
			fprintf(stderr, "Error: malloc.\n");
			exit(1);
		}
		for (j=0; j<(1<<c.bin_e); j++) {
			if (ts->peak_hold == -1) {
				ts->avg[j] = 1e6;
			} else {
				ts->avg[j] = 0L;}
		}
		ts->buf8 = (uint8_t*)malloc(buf_len * sizeof(uint8_t));
		if (!ts->buf8) {
			fprintf(stderr, "Error: malloc.\n");
			exit(1);
		}
		ts->buf_len = buf_len;
		length = 1 << c.bin_e;
		ts->window_coefs = malloc(length * sizeof(int));
		for (j=0; j<length; j++) {
			ts->window_coefs[j] = (int)(256*ms->window_fn(j, length));
		}
		/* calculate unique values */
		ts->freq_low = lower_edge;
		hop_bins = c.bw_wanted / c.bin_spec;
		actual_bw = hop_bins * c.bin_spec;
		ts->freq_high = lower_edge + actual_bw;
		upper_perfect = c.lower + (i+1) * c.bw_wanted;
		if (ts->freq_high + c.bin_spec <= upper_perfect) {
			hop_bins += 1;
			actual_bw = hop_bins * c.bin_spec;
			ts->freq_high = lower_edge + actual_bw;
		}
		remainder = planned_bins - logged_bins - hop_bins;
		if (i == c.hops-1 && remainder > 0) {
			hop_bins += remainder;
			actual_bw = hop_bins * c.bin_spec;
			ts->freq_high = lower_edge + actual_bw;
		}
		logged_bins += hop_bins;
		ts->crop_i1 = (length - hop_bins) / 2;
		ts->crop_i2 = ts->crop_i1 + hop_bins - 1;
		ts->freq = (lower_edge - ts->crop_i1 * c.bin_spec) + c.bw_needed/(2*c.downsample);
		/* prep for next hop */
		lower_edge = ts->freq_high;
	}
	tune_count += c.hops;
	/* report */
	fprintf(stderr, "Number of frequency hops: %i\n", c.hops);
	fprintf(stderr, "Dongle bandwidth: %iHz\n", c.bw_needed);
	fprintf(stderr, "Downsampling by: %ix\n", c.downsample);
	fprintf(stderr, "Cropping by: %0.2f%%\n", c.crop*100);
	fprintf(stderr, "Total FFT bins: %i\n", c.hops * (1<<c.bin_e));
	fprintf(stderr, "Logged FFT bins: %i\n", logged_bins);
	fprintf(stderr, "FFT bin size: %iHz\n", c.bin_spec);
	fprintf(stderr, "Buffer size: %i bytes (%0.2fms)\n", buf_len, 1000 * 0.5 * (float)buf_len / (float)c.bw_needed);
	fprintf(stderr, "\n");
}