From owner-svn-src-user@FreeBSD.ORG Fri Jun 22 22:50:50 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id E0733106564A; Fri, 22 Jun 2012 22:50:50 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CA5DC8FC0A; Fri, 22 Jun 2012 22:50:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5MMoock004860; Fri, 22 Jun 2012 22:50:50 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5MMooJN004853; Fri, 22 Jun 2012 22:50:50 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201206222250.q5MMooJN004853@svn.freebsd.org> From: Adrian Chadd Date: Fri, 22 Jun 2012 22:50:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237462 - user/adrian/ath_radar_stuff/src/qt-hpktlog X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Jun 2012 22:50:51 -0000 Author: adrian Date: Fri Jun 22 22:50:50 2012 New Revision: 237462 URL: http://svn.freebsd.org/changeset/base/237462 Log: Flesh out some basic 'live' pcap support. * Add a new method to pktsource that opens a live pcap handle and sets it to non blocking; * Correct handle the "nothing available at the moment" case from pcap rather than just erroring out. TODO: * I should create derived classes of PktSource; * I should support non-blocking socket notification of the pcap socket, as well as having an occasional "check and flush" timer. * I am only handling one event every 2ms, which is just plain stupid; I should handle all the events from pcap when in live mode, rather than only one. * I'm still rendering it on each received event, whichi is also plain stupid. Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.cpp user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.h user/adrian/ath_radar_stuff/src/qt-hpktlog/Makefile user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.cpp user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.h user/adrian/ath_radar_stuff/src/qt-hpktlog/main.cpp Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.cpp ============================================================================== --- user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.cpp Fri Jun 22 22:45:34 2012 (r237461) +++ user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.cpp Fri Jun 22 22:50:50 2012 (r237462) @@ -26,7 +26,7 @@ MainApp::MainApp(QMainWindow *parent) // Scale // y-scale? q_plot->setAxisScale(QwtPlot::xBottom, 0.0, 256.0); - q_plot->setAxisScale(QwtPlot::yLeft, -128.0, 128.0); + q_plot->setAxisScale(QwtPlot::yLeft, -16.0, 80.0); // The default is a single 1 pixel dot. // This makes it very difficult to see. @@ -89,3 +89,9 @@ MainApp::RePlot() q_plot->replot(); q_plot->show(); } + +void +MainApp::timerEvent(QTimerEvent *event) +{ + +} Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.h ============================================================================== --- user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.h Fri Jun 22 22:45:34 2012 (r237461) +++ user/adrian/ath_radar_stuff/src/qt-hpktlog/MainApp.h Fri Jun 22 22:50:50 2012 (r237462) @@ -33,11 +33,22 @@ class MainApp : public QMainWindow std::vector q_dur; std::vector q_rssi; + // TODO When rendering the screen, we only want to do it + // every say, 3ms. + public: MainApp(QMainWindow *parent = 0); ~MainApp(); + + // Replot the screen. This does the actual work of + // taking the current set of dur/rssi values and plotting + // them. + + // It doesn't do any pacing of the rendering requests. void RePlot(); + void timerEvent(QTimerEvent *event); + public slots: void getRadarEntry(struct radar_entry re); Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/Makefile ============================================================================== --- user/adrian/ath_radar_stuff/src/qt-hpktlog/Makefile Fri Jun 22 22:45:34 2012 (r237461) +++ user/adrian/ath_radar_stuff/src/qt-hpktlog/Makefile Fri Jun 22 22:50:50 2012 (r237462) @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: qt-hpktlog -# Generated by qmake (2.01a) (Qt 4.7.4) on: Fri Jun 22 00:53:09 2012 +# Generated by qmake (2.01a) (Qt 4.7.4) on: Fri Jun 22 14:06:40 2012 # Project: qt-hpktlog.pro # Template: app # Command: /usr/local/bin/qmake-qt4 -o Makefile qt-hpktlog.pro Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.cpp ============================================================================== --- user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.cpp Fri Jun 22 22:45:34 2012 (r237461) +++ user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.cpp Fri Jun 22 22:50:50 2012 (r237462) @@ -1,6 +1,7 @@ #include #include +#include #include "net80211/ieee80211_radiotap.h" @@ -8,6 +9,12 @@ #include "libradarpkt/pkt.h" #include "libradarpkt/ar5416_radar.h" +#include "libradarpkt/ar9280_radar.h" + +// +// This particular class _should_ just be a base class that +// a couple of derivates use for the live versus load stuff. +// So yes, I should do that. PktSource::~PktSource() { @@ -37,6 +44,65 @@ PktSource::Load(const char *filename) return (true); } +#define PKTRULE "radio[73] == 0x2 && (radio[72] == 5 || radio[72] == 24)" + +bool +PktSource::OpenLive(const char *ifname) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + struct bpf_program fp; + + this->Close(); + + PcapHdl = pcap_open_live(ifname, 65536, 1, 1000, errbuf); + if (! PcapHdl) { + err(1, "pcap_create: %s\n", errbuf); + return (false); + } + + if (pcap_set_datalink(PcapHdl, DLT_IEEE802_11_RADIO) != 0) { + pcap_perror(PcapHdl, (char *) "pcap_set_datalink"); + return (false); + } + + /* XXX pcap_is_swapped() ? */ + + if (pcap_compile(PcapHdl, &fp, PKTRULE, 1, 0) != 0) { + pcap_perror(PcapHdl, (char *) "pkg_compile compile error\n"); + this->Close(); + return (false); + } + + if (pcap_setfilter(PcapHdl, &fp) != 0) { + pcap_perror(PcapHdl, (char *) "pcap_setfilter error\n"); + this->Close(); + return (false); + } + + // Register a timer event _and_ make the socket non-blocking. + if (pcap_setnonblock(PcapHdl, 1, errbuf) == -1) { + pcap_perror(PcapHdl, (char *) "pcap_set_nonblock error\n"); + this->Close(); + return (false); + } + + // For now, we'll just do a 2ms check to see what's going on. + // Eventually we'll do a 1s timer event to flush the queue + // _and_ do non-blocking IO via QT. + + // TODO: turn this into a method + if (timerId != -1) + killTimer(timerId); + + //Kick-start the first timer! + timerId = startTimer(2); + + return (true); + +} + +#undef PKTRULE + void PktSource::Close() { @@ -64,9 +130,7 @@ PktSource::timerEvent(QTimerEvent *event r = pcap_next_ex(PcapHdl, &hdr, &pkt); // Error? Delete the timer. - // TODO: this should handle the "error/EOF" versus "none just for now, - // but more are coming" errors correctly! - if (r <= 0) { + if (r < 0) { killTimer(timerId); timerId = -1; printf("%s: final event (r=%d), finish timer!\n", @@ -76,6 +140,11 @@ PktSource::timerEvent(QTimerEvent *event return; } + // Nothing available? Just skip + if (r == 0) { + return; + } + rt = (struct ieee80211_radiotap_header *) pkt; if (rt->it_version != 0) { printf("%s: unknown version (%d)\n", @@ -85,10 +154,22 @@ PktSource::timerEvent(QTimerEvent *event } // TODO: just assume AR5416 for now.. - r = ar5416_radar_decode(rt, - (pkt + le16toh(rt->it_len)), - hdr->caplen - le16toh(rt->it_len), &re); - + switch (chipid) { + case CHIP_AR5416: + r = ar5416_radar_decode(rt, + (pkt + le16toh(rt->it_len)), + hdr->caplen - le16toh(rt->it_len), &re); + break; + case CHIP_AR9280: + r = ar9280_radar_decode(rt, + (pkt + le16toh(rt->it_len)), + hdr->caplen - le16toh(rt->it_len), &re); + break; + default: + printf("%s: unknown chip id? (%d)\n", + __func__, + chipid); + } // Error? Just wait for the next one? if (r == 0) { printf("%s: parse failed\n", __func__); Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.h ============================================================================== --- user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.h Fri Jun 22 22:45:34 2012 (r237461) +++ user/adrian/ath_radar_stuff/src/qt-hpktlog/PktSource.h Fri Jun 22 22:50:50 2012 (r237462) @@ -26,11 +26,15 @@ class PktSource : public QObject { private: pcap_t *PcapHdl; int timerId; + int chipid; public: - PktSource() : PcapHdl(NULL), timerId(-1) { }; + PktSource() : PcapHdl(NULL), timerId(-1), chipid(0) { }; ~PktSource(); + void SetChipId(int chip_id) { chipid = chip_id; }; + int GetChipId() { return (chipid); }; bool Load(const char *filename); + bool OpenLive(const char *ifname); void Close(); signals: Modified: user/adrian/ath_radar_stuff/src/qt-hpktlog/main.cpp ============================================================================== --- user/adrian/ath_radar_stuff/src/qt-hpktlog/main.cpp Fri Jun 22 22:45:34 2012 (r237461) +++ user/adrian/ath_radar_stuff/src/qt-hpktlog/main.cpp Fri Jun 22 22:50:50 2012 (r237462) @@ -92,13 +92,16 @@ main(int argc, char *argv[]) else usage(); + // Ensure the chip is correct + ps.SetChipId(type); + // Connect the ps source -> mainapp handler QObject::connect(&ps, SIGNAL(emitRadarEntry(struct radar_entry)), &m, SLOT(getRadarEntry(struct radar_entry))); // Now that it's connected, begin firing off events // by opening a file - if (ps.Load(argv[2]) == false) { + if (ps.OpenLive(argv[2]) == false) { err(1, "open"); }