diff options
Diffstat (limited to 'src/receiver.cpp')
-rw-r--r-- | src/receiver.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/receiver.cpp b/src/receiver.cpp new file mode 100644 index 0000000..c6c5bdc --- /dev/null +++ b/src/receiver.cpp @@ -0,0 +1,71 @@ +#include "wifi-triangulator/core.h" + +#include <iostream> +#include <unistd.h> + +#include <arpa/inet.h> +#include <cstring> + +using namespace std; +using namespace wifi_triangulator; + +void on_probe_request(const pb::probe &p) { + cerr << "PROBE REQUEST" + << ", src=" << eth_mac(p.src()).to_string() + << ", dst=" << eth_mac(p.dst()).to_string() + << ", rssi=" << p.rssi() + << endl; +} + +int main(int argc, char *argv[]) { + if (argc != 1) { + fprintf(stderr, "usage: %s\n", argv[0]); + return EXIT_FAILURE; + } + + GOOGLE_PROTOBUF_VERIFY_VERSION; + + uint16_t port = 3333; + int s; + struct sockaddr_in si_me; + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + throw std::runtime_error("socket"); + + memset((char *) &si_me, 0, sizeof(si_me)); + si_me.sin_family = AF_INET; + si_me.sin_port = htons(port); + si_me.sin_addr.s_addr = htonl(INADDR_ANY); + if (::bind(s, reinterpret_cast<struct sockaddr *>(&si_me), sizeof(si_me)) == -1) { + throw std::runtime_error("bind"); + } + + pb::envelope envelope; + while (true) { + size_t len = 64 * 1024; + uint8_t bytes[len]; + ssize_t n_read; + + struct sockaddr_in si_other; + socklen_t addr_len; + if ((n_read = ::recvfrom(s, bytes, len, 0, reinterpret_cast<struct sockaddr *>(&si_other), &addr_len)) == -1) { + throw std::runtime_error("recvfrom"); + } + + string str; + for (socklen_t i = 0; i < n_read; i++) { + str += bytes[i]; + } + + istringstream ss{str}; + bool ok = envelope.ParseFromIstream(&ss); + if (ok) { + if (envelope.type() == pb::probe_request) { + on_probe_request(envelope.probe()); + } + } else { + cerr << "FAIL n_read=" << n_read << flush << endl; + } + } + + google::protobuf::ShutdownProtobufLibrary(); +} |