1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
/*
* Generic spectrum tool container class for physical and logic devices,
* sample sweeps, and aggregations of sample sweeps
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SPECTOOL_DEVCONTAINER_H__
#define __SPECTOOL_DEVCONTAINER_H__
#include <time.h>
#include <sys/time.h>
#ifdef HAVE_STDINT
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
/* A sweep record. Because the sample array is allocated dynamically we
* re-use this same record as the definition of what sweep ranges a device
* can handle.
*/
typedef struct _spectool_sample_sweep {
/* Name of sweep (if used as a range marker */
char *name;
/* Starting frequency of the sweep, in KHz */
uint32_t start_khz;
/* Ending frequency of the sweep, in KHz */
uint32_t end_khz;
/* Sample resolution, in KHz */
uint32_t res_hz;
/* RSSI conversion information in mdbm
* db = (rssi * (amp_res_mdbm / 1000)) - (amp_offset_mdbm / 1000) */
int amp_offset_mdbm;
int amp_res_mdbm;
unsigned int rssi_max;
/* Lowest RSSI seen by the device */
unsigned int min_rssi_seen;
/* This could be derived from start, end, and resolution, but we include
* it here to save on math */
unsigned int num_samples;
/* Filter resolution in hz, hw config */
unsigned int filter_bw_hz;
/* Samples per point (hw aggregation) */
unsigned int samples_per_point;
/* Timestamp for when the sweep begins and ends */
struct timeval tm_start;
struct timeval tm_end;
/* Phy reference */
void *phydev;
/* Actual sample data. This is num_samples of uint8_t RSSI */
uint8_t sample_data[0];
} spectool_sample_sweep;
#define SPECTOOL_RSSI_CONVERT(O,R,D) (int) ((D) * ((double) (R) / 1000.0f) + \
((double) (O) / 1000.0f))
#define SPECTOOL_SWEEP_SIZE(y) (sizeof(spectool_sample_sweep) + (y))
/* Sweep record for aggregating multiple sweep points */
typedef struct _spectool_sweep_cache {
spectool_sample_sweep **sweeplist;
spectool_sample_sweep *avg;
spectool_sample_sweep *peak;
spectool_sample_sweep *roll_peak;
spectool_sample_sweep *latest;
int num_alloc, pos, looped;
int calc_peak, calc_avg;
int num_used;
uint32_t device_id;
} spectool_sweep_cache;
typedef struct _spectool_sweep_cache_itr {
int pos_start;
int pos_cur;
int looped_start;
} spectool_sweep_cache_itr;
/* Allocate and manipulate sweep caches */
spectool_sweep_cache *spectool_cache_alloc(int nsweeps, int calc_peak, int calc_avg);
void spectool_cache_append(spectool_sweep_cache *c, spectool_sample_sweep *s);
void spectool_cache_clear(spectool_sweep_cache *c);
void spectool_cache_free(spectool_sweep_cache *c);
void spectool_cache_itr_init(spectool_sweep_cache *c, spectool_sweep_cache_itr *i);
spectool_sample_sweep *spectool_cache_itr_next(spectool_sweep_cache *c, spectool_sweep_cache_itr *i);
#define SPECTOOL_ERROR_MAX 512
#define SPECTOOL_PHY_NAME_MAX 256
typedef struct _spectool_dev_spec {
/* A unique ID fetched from the firmware (in the future) or extracted from the
* USB bus (currently) */
uint32_t device_id;
/* User-specified name */
char device_name[SPECTOOL_PHY_NAME_MAX];
/* Version of the physical source device.
* 0x01 WiSPY generation 1 USB device
* 0x02 WiSPY generation 2 USB device
* 0x03 WiSPY generation 3 USB device
*/
uint8_t device_version;
/* Device flags */
uint8_t device_flags;
spectool_sample_sweep *default_range;
/* Number of sweep ranges this device supports.
* Gen1 supports 1 range.
*/
unsigned int num_sweep_ranges;
/* Supported sweep ranges */
spectool_sample_sweep *supported_ranges;
int cur_profile;
} spectool_dev_spec;
/* Device flags */
#define SPECTOOL_DEV_FL_NONE 0
/* Variable sweep supported */
#define SPECTOOL_DEV_FL_VAR_SWEEP 1
#define SPECTOOL_DEV_SIZE(y) (sizeof(spectool_dev_spec))
/* Central tracking structure for spectool device data and API callbacks */
typedef struct _spectool_phy {
/* Phy capabilities */
spectool_dev_spec *device_spec;
/* Running state */
int state;
/* Min RSSI seen */
unsigned int min_rssi_seen;
/* External phy-specific data */
void *auxptr;
/* Function pointers to be filled in by the device init system */
int (*open_func)(struct _spectool_phy *);
int (*close_func)(struct _spectool_phy *);
int (*poll_func)(struct _spectool_phy *);
int (*pollfd_func)(struct _spectool_phy *);
void (*setcalib_func)(struct _spectool_phy *, int);
int (*setposition_func)(struct _spectool_phy *, int, int, int);
spectool_sample_sweep *(*getsweep_func)(struct _spectool_phy *);
char errstr[SPECTOOL_ERROR_MAX];
/* Linked list elements incase we need them in our implementation */
struct _spectool_phy *next;
/* Suggested delay for drawing */
int draw_agg_suggestion;
} spectool_phy;
#define SPECTOOL_PHY_SIZE (sizeof(spectool_phy))
int spectool_get_state(spectool_phy *phydev);
char *spectool_get_error(spectool_phy *phydev);
int spectool_phy_open(spectool_phy *phydev);
int spectool_phy_close(spectool_phy *phydev);
int spectool_phy_poll(spectool_phy *phydev);
int spectool_phy_getpollfd(spectool_phy *phydev);
spectool_sample_sweep *spectool_phy_getsweep(spectool_phy *phydev);
void spectool_phy_setcalibration(spectool_phy *phydev, int enable);
int spectool_phy_setposition(spectool_phy *phydev, int in_profile,
int start_khz, int res_hz);
char *spectool_phy_getname(spectool_phy *phydev);
void spectool_phy_setname(spectool_phy *phydev, char *name);
int spectool_phy_getdevid(spectool_phy *phydev);
int spectool_phy_get_flags(spectool_phy *phydev);
spectool_sample_sweep *spectool_phy_getcurprofile(spectool_phy *phydev);
/* Running states */
#define SPECTOOL_STATE_CLOSED 0
#define SPECTOOL_STATE_CONFIGURING 1
#define SPECTOOL_STATE_CALIBRATING 2
#define SPECTOOL_STATE_RUNNING 3
#define SPECTOOL_STATE_ERROR 255
/* Poll return states */
/* Failure */
#define SPECTOOL_POLL_ERROR 256
/* No state - partial poll, etc */
#define SPECTOOL_POLL_NONE 1
/* Sweep is complete, caller should pull data */
#define SPECTOOL_POLL_SWEEPCOMPLETE 2
/* Device has finished configuring */
#define SPECTOOL_POLL_CONFIGURED 4
/* Device has additional pending data and poll should be called again */
#define SPECTOOL_POLL_ADDITIONAL 8
/* Device scan handling */
typedef struct _spectool_device_rec {
/* Name of device */
char name[SPECTOOL_PHY_NAME_MAX];
/* ID of device */
uint32_t device_id;
/* Init function */
int (*init_func)(struct _spectool_phy *, struct _spectool_device_rec *);
/* Hardware record pointing to the aux handling */
void *hw_rec;
/* Supported sweep ranges identified from hw type */
unsigned int num_sweep_ranges;
spectool_sample_sweep *supported_ranges;
} spectool_device_rec;
typedef struct _spectool_device_list {
int num_devs;
int max_devs;
spectool_device_rec *list;
} spectool_device_list;
/* Hopefully this doesn't come back and bite us, but, really, 32 SAs on one system? */
#define MAX_SCAN_RESULT 32
/* Scan for all attached devices we can handle */
void spectool_device_scan_init(spectool_device_list *list);
int spectool_device_scan(spectool_device_list *list);
void spectool_device_scan_free(spectool_device_list *list);
int spectool_device_init(spectool_phy *phydev, spectool_device_rec *rec);
struct spectool_channels {
/* Name of the channel set */
char *name;
/* Start and end khz for matching */
int startkhz;
int endkhz;
/* Number of channels */
int chan_num;
/* Offsets in khz */
int *chan_freqs;
/* Width of channels in khz */
int chan_width;
/* Text of channel numbers */
char **chan_text;
};
/* Some channel lists */
static int chan_freqs_24[] = {
2411000, 2416000, 2421000, 2426000, 2431000, 2436000, 2441000,
2446000, 2451000, 2456000, 2461000, 2466000, 2471000, 2483000
};
static char *chan_text_24[] = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"
};
static int chan_freqs_5[] = {
5180000, 5200000, 5220000, 5240000, 5260000, 5280000, 5300000, 5320000,
5500000, 5520000, 5540000, 5560000, 5580000, 5600000, 5620000, 5640000,
5660000, 5680000, 5700000, 5745000, 5765000, 5785000, 5805000, 5825000
};
static char *chan_text_5[] = {
"36", "40", "44", "48", "52", "56", "60", "64", "100", "104",
"108", "112", "116", "120", "124", "128", "132", "136", "140",
"149", "153", "157", "161", "165"
};
static int chan_freqs_900[] = {
905000, 910000, 915000, 920000, 925000
};
static char *chan_text_900[] = {
"905", "910", "915", "920", "925"
};
/* Allocate all our channels in a big nasty array */
static struct spectool_channels channel_list[] = {
{ "802.11b/g", 2400000, 2483000, 14, chan_freqs_24, 22000, chan_text_24 },
{ "802.11b/g", 2402000, 2480000, 14, chan_freqs_24, 22000, chan_text_24 },
{ "802.11a", 5100000, 5832000, 24, chan_freqs_5, 20000, chan_text_5 },
{ "802.11a UN-II", 5100000, 5483000, 14, chan_freqs_5, 20000, chan_text_5 },
{ "900 ISM", 902000, 927000, 5, chan_freqs_900, 5000, chan_text_900 },
{ NULL, 0, 0, 0, NULL, 0, NULL }
};
#endif
|