diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2017-04-07 17:45:02 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2017-04-07 17:45:02 +0200 |
commit | 84939234eb66fe7957eaf39956f18224e3108c25 (patch) | |
tree | 97a6d77c92ad373199cd3aecb2cbcb6488357480 /capture.cpp | |
parent | bed4c80f31051ec47463caa3e9511374062c6536 (diff) | |
download | wifi-triangulator-84939234eb66fe7957eaf39956f18224e3108c25.tar.gz wifi-triangulator-84939234eb66fe7957eaf39956f18224e3108c25.tar.bz2 wifi-triangulator-84939234eb66fe7957eaf39956f18224e3108c25.tar.xz wifi-triangulator-84939234eb66fe7957eaf39956f18224e3108c25.zip |
o Refactoring into two parts, sender and receiver that sends protobuf messages over UDP.
Diffstat (limited to 'capture.cpp')
-rw-r--r-- | capture.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/capture.cpp b/capture.cpp new file mode 100644 index 0000000..7e51fcd --- /dev/null +++ b/capture.cpp @@ -0,0 +1,108 @@ +#include <iostream> +#include "wifi-triangulator/core.h" +#include "wifi-triangulator.pb.h" + +#include <sstream> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <exception> +#include <cstring> + +using namespace std; +using namespace wifi_triangulator; + +class output { +public: + virtual void handle(const data &) = 0; +}; + +class human_output : public output { +public: + void handle(const data &data) { + printf("timestamp=%lu, rssi=%d, src=%s, dst=%s, type=%s\n", ((data.sec * 1000 * 1000) + data.usec) * 1000, + data.rssi, data.src.to_string().c_str(), data.dst.to_string().c_str(), to_string(data.type).c_str()); + fflush(stdout); + }; +}; + +class protobuf_output : public output { + int s; + struct sockaddr_in addr_si; + struct sockaddr *addr; + socklen_t addr_len; + +public: + protobuf_output(string host, uint16_t port) { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + throw std::runtime_error("socket"); + + + memset((char *) &addr_si, 0, sizeof(addr_si)); + addr_si.sin_family = AF_INET; + addr_si.sin_port = htons(port); + if (inet_aton(host.c_str(), &addr_si.sin_addr) == 0) { + throw std::runtime_error("inet_aton() failed"); + } + + addr = reinterpret_cast<struct sockaddr *>(&addr_si); + addr_len = sizeof(addr_si); + } + + ~protobuf_output() { + google::protobuf::ShutdownProtobufLibrary(); + } + + void handle(const data &data) override { + pb::envelope envelope; + envelope.set_type(data.type); + + if (data.type == pb::packet_type::probe_request) { + pb::probe *probe = envelope.mutable_probe(); + probe->set_src(data.src); + probe->set_dst(static_cast<uint64_t>(data.dst)); + probe->set_rssi(data.rssi); + } + + std::string str; + envelope.SerializeToString(&str); + + if (sendto(s, str.c_str(), str.length(), 0, addr, addr_len) == -1) { + throw std::runtime_error("sendto failed"); + } + cout << flush; + + static int count = 0; + cerr << "count=" << count << ", len=" << str.length() << "!\r" << flush; + count++; + } +}; + +bool human = false; + +int main(int argc, char *argv[]) { + if (argc != 3) { + fprintf(stderr, "usage: %s [interface] [host]\n", argv[0]); + return EXIT_FAILURE; + } + + string dev = argv[1]; + string host = argv[2]; + + output *output; + if (human) { + output = new human_output; + } else { + cerr << "Sending to stdout" << flush << endl; + output = new protobuf_output(host, 3333); + } + + return launch_capture(dev, [&](const data &data) { + output->handle(data); + }); +} |