Wifi/BLE Paxcounter Project with ESP32 boards

(Verkehrsrot) #41

But please share to us then, not just consuming the inspiration of the open source :wink:

(Bingo600) #42

I’ll just have to get my head around platform.io & FreeRTOS, normally using make

(LoRaTracker) #43

That might be the case for the code changes, but of course the changes would need to be tested in the real world, I can’t say how long that would take.

With a new branch of the code there would then be the invetible updates, dealing with support issues etc, all of which takes ‘someones’ time.

And this is for a program with no TTN or even LoRa component.


If @bingo600 not familiar with git, this is the part that will give him headache and take most of the time needed to remove LoRa from source code.
He need to have a github account, learn how to do a fork, do the fork, how to sync fork, working pushing from his fork and manage pull request :wink:


Nice project. Compliments on it! Tested the counter with my TTGO V1. Did a measurement on power consumption and get 646mw with display off on 5V;

(Verkehrsrot) #46

I found something similar to Paxcounter, but working with BLE, not Wifi.
Could help to improve the BLE count in Paxcounter.

And another one, using wifi sniffing, here:


Looks like all BLE stuff is written in python :wink:

(Verkehrsrot) #48

I hoped someone here can read it. For me Phython is a snake.

(Verkehrsrot) #49

I improved privacy with new version 1.2.6: MAC adresses are no longer recorded in an internal table, they are now substituted by identifiers. An identifier ist generated by salting and hashing a sniffed MAC adress. This happenes in code at the earliest possible point, when an MAC adress reaches the protocol buffer. Immediately after generating the identifier from it, the MAC is cleared from RAM.

The salt value changes after every scan cycle (default 240 secs.).

I’m using a simple hash function, not a cryptographic one, so there could (and probably will) be collisions. The salt value is generated by standard c randomizer, without caring about a random seed for it.

I think for this purpose this should be satisfying.


I had made some changes that I need to integrate back,

  • RGB Led working (luminosity as new parameter for config and Lora)
  • On board LED reverse option (IE light when applying VCC on GPIO or GND on GPIO)
  • added new total counter of BLE device (not just count the one seen during scan). We’ll need to check for duplicate, IE if a BLE has same MAC address than Wifi, just count one.
  • alternate scanning of ble/wifi, IE not just scanning BLE before Lora send packet

Does this makes sense for you?

(Verkehrsrot) #51

You’re welcome!
Use the actual version 1.2.62, this should be stable.
I reworked the wifi sniffing code and added hash/salt features.
This should be done to the BLE sniffing part, too. I did not rework the BLE part yet. So feel free to focus on that. I am not sure that the BLE sniffing is running correctly, the resulting values from BLE seem very low compared to that from Wifi.


Yeah I saw that, I was wondering to sort mac add/hash/salt to a function to be able to be called by wifi sniffer and BLE also

This is because BLE return the number of devices seen in SCAN, not the total, that’s why I added a total ble count, and it works better :wink:

(Verkehrsrot) #53

Mac counter shows result of scan or total, depending on mode setting (see rcommand 0x02). For privacy reasons i did not want to grow internal MAC recording table to big, but since we store hashed values now, it should be okay. I’m using 16bit associative container (std::set) now, so we can count max. 65535 unique MACs.

Good idea to capsule the hash/salt logic in a separate function, so that it can be used for BLE and wifi same way. The essentials are in this part of the code:

// salt and hash MAC, and if new unique one, store identifier in container and increment counter on display
		// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
		addr2int |= (uint64_t) salt << 48;		// prepend 16-bit salt to 48-bit MAC
		snprintf(macbuf, 21, "%llx", addr2int);	// convert unsigned 64-bit salted MAC to 16 digit hex string
		hashedmac = rokkit(macbuf, 5);			// hash MAC string, use 5 chars to fit hash in uint16_t container
		newmac = macs.insert(hashedmac);		// store hashed MAC only if first time seen
		if (newmac.second) {					// if first time seen MAC
			macnum++;								// increment MAC counter
			snprintf(counter, 6, "%i", macnum);		// convert 16-bit MAC counter to decimal counter value
			u8x8.draw2x2String(0, 0, counter);		// display counter
			ESP_LOGI(TAG, "#%05i: RSSI %04d -> Hash %04x", macnum, ppkt->rx_ctrl.rssi, hashedmac);



I’m on it, I’ll do a PR in 1 or 2 hours :wink:

BTW where do you want me to put the function?

(Verkehrsrot) #55

you’re welcome to PR, i keep my fingers off now for today & night.

I would suggest we consolidate blecount.cpp and wifisniffer.cpp to a new macsniff.cpp


sounds good to me, I’ll do that

(Verkehrsrot) #57

Feel free to improve code whereever.
I am a beginner in C/C++, probably i did wrong in some more cases… :wink:

(Verkehrsrot) #58

I had some serious trouble to get the bits&byte shifting magics working properly, so that the generated hashes are really anonymized and not only looking curly :wink:

It should work, using a 16bit hash table. Now i hope the salt&hash code does not slow down the packet sniffer too much, otherwise we get packets lost and count to less.

[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00001: RSSI -092 -> Hash 206e
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00002: RSSI -091 -> Hash 4e78
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00003: RSSI -089 -> Hash 7c15
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00004: RSSI -089 -> Hash e50c
[I][lorawan.cpp:95] do_send(): Packet queued
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00001: RSSI -091 -> Hash 930a
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00002: RSSI -095 -> Hash 073e
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00003: RSSI -077 -> Hash 9731
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00004: RSSI -089 -> Hash 7ca1
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00005: RSSI -086 -> Hash 4b30
[I][lorawan.cpp:95] do_send(): Packet queued
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00001: RSSI -093 -> Hash 91a0
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00002: RSSI -094 -> Hash 13df
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00003: RSSI -090 -> Hash c824
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00004: RSSI -082 -> Hash e170
[I][lorawan.cpp:95] do_send(): Packet queued
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00001: RSSI -090 -> Hash ad08
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00002: RSSI -092 -> Hash c12a
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00003: RSSI -092 -> Hash ea5a
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00004: RSSI -083 -> Hash bfda
[I][lorawan.cpp:95] do_send(): Packet queued
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00001: RSSI -088 -> Hash 72bb
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00002: RSSI -083 -> Hash c718
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00003: RSSI -093 -> Hash fcc9
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00004: RSSI -089 -> Hash 7f03
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00005: RSSI -079 -> Hash 2c79
[I][lorawan.cpp:95] do_send(): Packet queued
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00001: RSSI -093 -> Hash cff0
[I][wifisniffer.cpp:88] wifi_sniffer_packet_handler(): #00002: RSSI -093 -> Hash 4e36

(Verkehrsrot) #59

New version 1.2.8 out now!
Thanks to @Charles for contributing:

  • new RGB LED support (e.g. for LoLin & LoPy boards)
  • new combined wifi & BLE scan
  • live channel switching display


@Verkehrsrot, you’re welcome
I’m trying to understand “vendor filtering”, I imagine there is into network devices such as router or other (cisco, netgear, …) Is that correct? I’ve got plenty of devices at home and just looking which are excluded and which are not :wink:
Where did you get this file from? you handly made it?