--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int parse_packet(unsigned char *buf, unsigned bytes, int sock)
+{
+ char *ptr;
+ int ret = 0;
+ buf[bytes + 1] = 0;
+
+ ptr = strtok((char *)buf, "\n");
+ while (ptr) {
+ if (strncmp(ptr, "*NETWORK: ", 10) == 0) {
+ char bssid[32];
+ int crypted, weak, signal, noise;
+ if (sscanf(ptr, "*NETWORK: %s %d %d %d %d", bssid, &crypted, &weak, &signal, &noise) != 5) {
+ printf("Couldn't parse NETWORK packet\n");
+ } else {
+ if (strcmp(bssid, "00:0D:54:A0:27:7F") == 0) {
+ char str1[64], str2[64], str3[64], str4[64];
+ short len;
+ sprintf(str1, "Crypted: %d", crypted);
+ sprintf(str2, "Weak IVs: %d", weak);
+ sprintf(str3, "Signal level: %d dB", signal);
+ sprintf(str4, "Noise level: %d dB", noise);
+
+ write(sock, "\000\001", 2);
+ len = htons(2 * 4 + strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4));
+ write(sock, (char*)&len, 2);
+
+ len = htons(strlen(str1));
+ write(sock, (char*)&len, 2);
+ write(sock, str1, strlen(str1));
+
+ len = htons(strlen(str2));
+ write(sock, (char*)&len, 2);
+ write(sock, str2, strlen(str2));
+
+ len = htons(strlen(str3));
+ write(sock, (char*)&len, 2);
+ write(sock, str3, strlen(str3));
+
+ len = htons(strlen(str4));
+ write(sock, (char*)&len, 2);
+ write(sock, str4, strlen(str4));
+
+ ret = 1;
+ }
+ }
+ }
+ ptr = strtok(NULL, "\n");
+ }
+
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
+ struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
+ struct sockaddr_in addr;
+ unsigned char buf[1024] = { 0 };
+ char initstr[] = "!1 ENABLE NETWORK bssid,cryptpackets,weakpackets,signal,noise\n";
+ int s, client, kismet, bytes_read;
+ size_t opt = sizeof(rem_addr);
+ unsigned one = 1;
+
+ // allocate socket
+ s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+
+ // bind socket to port 1 of the first available
+ // local bluetooth adapter
+ loc_addr.rc_family = AF_BLUETOOTH;
+ loc_addr.rc_bdaddr = *BDADDR_ANY;
+ loc_addr.rc_channel = (uint8_t) 1;
+ bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
+
+ // put socket into listening mode
+ listen(s, 1);
+
+ // accept one connection
+ client = accept(s, (struct sockaddr *)&rem_addr, &opt);
+
+ ba2str( &rem_addr.rc_bdaddr, buf );
+ fprintf(stderr, "accepted connection from %s\n", buf);
+ memset(buf, 0, sizeof(buf));
+
+ ioctl(client, FIONBIO, &one);
+
+ // connect to kismet
+ kismet = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ addr.sin_port = htons(2501);
+
+ if (connect(kismet, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ perror("connect()");
+ exit(1);
+ }
+ ioctl(kismet, FIONBIO, &one);
+ write(kismet, initstr, strlen(initstr));
+
+ printf("Connected to Kismet.\n");
+
+ // read data from the client
+ for ( ;; ) {
+ int flag = 1;
+
+ // gobble up data from the phone
+ bytes_read = read(client, buf, sizeof(buf) - 1);
+ if( bytes_read > 0 ) {
+ unsigned i;
+ printf("received [");
+ for (i = 0; i < bytes_read; ++i)
+ printf("0x%02x ", buf[i]);
+ printf("]\n");
+ }
+
+ // read from kismet
+ bytes_read = read(kismet, buf, sizeof(buf));
+ if( bytes_read > 0 ) {
+ unsigned i;
+ for (i = 0; i < bytes_read; ++i)
+ printf("%c", buf[i]);
+
+ flag = parse_packet(buf, bytes_read, client);
+ }
+
+ if (flag) {
+ // alive?
+ write(client, "\000\012\000\000", 4);
+ sleep(1);
+ }
+ }
+
+ // close connection
+ close(client);
+ close(s);
+ return 0;
+}
+
--- /dev/null
+#include <stdio.h>
+#include <math.h>
+#include <vector>
+#include <algorithm>
+
+#define EPS 1e-12
+#define WIDTH 1280
+#define HEIGHT 1024
+
+float nom[WIDTH * HEIGHT], denom[WIDTH * HEIGHT];
+unsigned char pix[WIDTH * HEIGHT * 3];
+
+struct point {
+ double lat, lon;
+ double strength;
+
+ int x, y;
+ double radius;
+
+ bool operator< (const point &other) const
+ {
+ if (fabs(lat - other.lat) > EPS)
+ return (lat < other.lat);
+ if (fabs(lon - other.lon) > EPS)
+ return (lon < other.lon);
+ return (strength < other.strength);
+ }
+
+ bool same_place_as(const point &other) const
+ {
+ return !((fabs(lat - other.lat) > EPS) || (fabs(lon - other.lon) > EPS));
+ }
+};
+
+void collapse_points(std::vector<point> &points, std::vector<point> &upoints)
+{
+ // average non-unique points
+ point cp = { 0.0, 0.0, 0 };
+ unsigned np = 0;
+
+ for (std::vector<point>::const_iterator i = points.begin(); i != points.end(); ++i) {
+ if (np == 0) {
+ // first point
+ cp = *i;
+ np = 1;
+ continue;
+ }
+ if (i->same_place_as(cp)) {
+ cp.strength += i->strength;
+ ++np;
+ } else {
+ cp.strength /= np;
+ upoints.push_back(cp);
+
+ cp = *i;
+ np = 1;
+ }
+ }
+
+ cp.strength /= np;
+ upoints.push_back(cp);
+}
+
+int main()
+{
+ std::vector<point> points, upoints;
+ double max_lat = -HUGE_VAL, min_lat = HUGE_VAL;
+ double max_lon = -HUGE_VAL, min_lon = HUGE_VAL;
+
+ for ( ;; ) {
+ struct point p;
+ if (scanf("%lf %lf %lf", &p.lat, &p.lon, &p.strength) != 3)
+ break;
+
+ max_lon = std::max(max_lon, p.lon);
+ min_lon = std::min(min_lon, p.lon);
+
+ max_lat = std::max(max_lat, p.lat);
+ min_lat = std::min(min_lat, p.lat);
+
+ points.push_back(p);
+ }
+
+ double x_res = WIDTH / (max_lon - min_lon);
+ double y_res = HEIGHT / (max_lat - min_lat);
+
+ if (y_res > x_res) {
+ double lat_dist = max_lat - min_lat;
+ double lat_wanted = HEIGHT / x_res;
+ double extra_lat = lat_wanted - lat_dist;
+
+ min_lat -= extra_lat * 0.5;
+ max_lat += extra_lat * 0.5;
+
+ y_res = HEIGHT / (max_lat - min_lat);
+ } else {
+ fprintf(stderr, "FIXME\n");
+ }
+
+ std::sort(points.begin(), points.end());
+ collapse_points(points, upoints);
+
+ // map to x/y
+ for (std::vector<point>::iterator i = upoints.begin(); i != upoints.end(); ++i) {
+ i->x = (int)((i->lon - min_lon) * WIDTH / (max_lon - min_lon));
+ i->y = (int)((i->lat - min_lat) * HEIGHT / (max_lat - min_lat));
+ i->strength = 0.02 * (i->strength + 80);
+ if (i->strength < 0.0)
+ i->strength = 0.0;
+ }
+
+ // find the radius
+ for (std::vector<point>::iterator i = upoints.begin(); i != upoints.end(); ++i) {
+ int min_rad = 65536;
+ for (std::vector<point>::iterator j = upoints.begin(); j != upoints.end(); ++j) {
+ int rad =
+ (i->x - j->x) * (i->x - j->x) +
+ (i->y - j->y) * (i->y - j->y);
+ if (rad == 0)
+ continue;
+ min_rad = std::min(min_rad, rad);
+ }
+
+ i->radius = std::min(sqrt(min_rad), 15.0);
+ }
+
+ // clear the drawing
+ std::fill(nom, nom + WIDTH*HEIGHT, 0.0);
+ std::fill(denom, denom + WIDTH*HEIGHT, 0.001);
+
+ for (std::vector<point>::iterator i = upoints.begin(); i != upoints.end(); ++i) {
+ double r = i->radius * 3.0;
+ double sigma = i->radius;
+
+ for (int y = -r; y <= r; ++y) {
+ for (int x = -r; x <= r; ++x) {
+ int rx = i->x + x;
+ int ry = i->y + y;
+
+ if (rx < 0 || ry < 0 || rx >= WIDTH || ry >= HEIGHT)
+ continue;
+
+ double z = - (x*x + y*y) / (2.0 * sigma * sigma);
+ double fac = exp(z) / sigma;
+
+ nom [ry * WIDTH + rx] += i->strength * fac;
+ denom[ry * WIDTH + rx] += fac;
+ }
+ }
+ }
+
+ // draw!
+ for (unsigned y = 0; y < HEIGHT; ++y) {
+ for (unsigned x = 0; x < WIDTH; ++x) {
+ unsigned ch;
+ if (denom[y * WIDTH + x] < EPS)
+ ch = 0;
+ else {
+ ch = (unsigned)(255.0 * nom[y * WIDTH + x] / denom[y * WIDTH + x]);
+ if (ch > 255)
+ ch = 255;
+ }
+
+ pix[(y * WIDTH + x) * 3] = ch;
+ pix[(y * WIDTH + x) * 3 + 1] = ch;
+ pix[(y * WIDTH + x) * 3 + 2] = ch;
+ }
+ }
+
+ // add the track
+ FILE *track = fopen("track.txt", "r");
+ for ( ;; ) {
+ double lat, lon;
+ if (fscanf(track, "%lf %lf", &lat, &lon) != 2)
+ break;
+
+ int x = (int)((lon - min_lon) * WIDTH / (max_lon - min_lon));
+ int y = (int)((lat - min_lat) * HEIGHT / (max_lat - min_lat));
+
+ if (x < 0 || y < 0 || x >= WIDTH || y >= HEIGHT)
+ continue;
+ pix[(y * WIDTH + x) * 3] = 255;
+ }
+
+ // and the sampling points
+ for (std::vector<point>::iterator i = upoints.begin(); i != upoints.end(); ++i) {
+ int x = (int)((i->lon - min_lon) * WIDTH / (max_lon - min_lon));
+ int y = (int)((i->lat - min_lat) * HEIGHT / (max_lat - min_lat));
+
+ if (x < 0 || y < 0 || x >= WIDTH || y >= HEIGHT)
+ continue;
+ pix[(y * WIDTH + x) * 3 + 2] = 255;
+ }
+
+ // and write PPM
+ printf("P6\n%u %u\n255\n", WIDTH, HEIGHT);
+ fwrite(pix, 3, WIDTH*HEIGHT, stdout);
+}