Send mac-addresses over Lora

Hi
I am aware that there are topics out there that partly cover this question, but even after a lot of trying and tinkering i was not able to achive my goal.

I try to transmit 2-3 BSSIDs from WiFi-APs with LoRa (TTN). I am able to extract the BSSID of nearby Wifis (WiFi.BSSIDstr(i) or WiFi.BSSID(i)).

In order to use the Function ttn.sendBytes() i need an array of bytes. But here comes the issue: I was not able to either loop over the BSSIDstr-return, remove the : and convert them, nor have i been able to concatenate WiFi.BSSID into one variable.

To be honest, i have an absolute mess between these variable-types. I come from php and ruby and do - even while trying hard - not understand what to use when...

I would be really happy if someone could give me a hint how to proceed!
Chris
p.s is there a "high-level" language available for esp32 that covers such kind of things? i tried to google it, but results were non-promissing

p. p.s., here's my code. but actually, it does not really make sense to look at it. it's really just try and error and every time i change something, it only gets worse :confused:

#include <TTN_esp32.h>
#include <WiFi.h>

const char* devAddr = "asdf"; // Change to TTN Device Address
const char* nwkSKey = "asdf"; // Change to TTN Network Session Key
const char* appSKey = "sadf"; // Change to TTN Application Session Key
RTC_DATA_ATTR int bootCount = 0;
uint8_t b[18]; // = {};
int i;


TTN_esp32 ttn ;

void printHex(uint8_t num) {
  char hexCar[2];

  sprintf(hexCar, "%02X", num);
  Serial.print(hexCar);
}

void setup() {
  Serial.begin(115200);
  ++bootCount;

}

void loop() {

  if (bootCount % 20 == 0) {
    //regular report
  } else {
    Serial.println("begin wifiscan");
    if (true) {
      String bssids = "";
      String a;
      int numberOfNetworks = WiFi.scanNetworks();
      if (numberOfNetworks > 1) {
        if (numberOfNetworks > 3) {
          numberOfNetworks = 3;
        }
        char cstr[6 * numberOfNetworks];
        int reslength = 12 * numberOfNetworks + 1;
        for (int i = 0; i < numberOfNetworks; i++) {
          a = WiFi.BSSIDstr(i);
          a.replace(":", "");
          bssids += a;          
Serial.println(WiFi.BSSIDstr(i));
          strcpy(cstr, bssids.c_str());
          ///Serial.println(cstr);
        }
        for (int y = 0; y < sizeof(bssids) / 2; y++) {
          //uint8_t tmp = sscanf(bssids.substring(0,2),"%x");
          //b[y] = (uint8_t)strtoul(cstr[0], NULL, 10);
        }
      }


      /*for (i = 0; i < sizeof(b); i++) {
        printHex(b[i]);
      }*/
      //ttn.sendBytes(b, 16);

    }
    delay(10000);
  }
}

can you provide a link to a description of the format of the data packet you are either receiving or transmitting, or are you just transceiving ascii data.

Well, i try to send up to 3 mac-addresses (BSSIDs) which are 6 bytes or 12 characters each. I'd like to concatenate these into one payload in order to save airtime and battery.

ttn.sendBytes seems to accept uint8_t as a datatype which i don't really know how to fill with up to three WiFi.BSSID():

uint8_t payload[18];

What does the library you are using say about the sendBytes function, it could provide a clue ..................

are you asking about something like this? ??

#include <stdint.h>

#define MAC_SIZE    6

uint8_t mac1 [6];
uint8_t mac2 [6];
uint8_t mac3 [6];

uint8_t payload [3*MAC_SIZE];

void
prep (void)
{
    int i = 0;

    for (unsigned n = 0; n < MAC_SIZE; n++)
        payload [i++] = mac1 [n];

    for (unsigned n = 0; n < MAC_SIZE; n++)
        payload [i++] = mac2 [n];

    for (unsigned n = 0; n < MAC_SIZE; n++)
        payload [i++] = mac3 [n];
}

Well, thats one part (thanks a lot, this will for sure bring me forward).

But how to convert char into uint8_t? I tried looping over the char-array and do something like that, but this was / is still the main issue:

uint8_t b[18]; // = {};
for (int y = 0; y < sizeof(bssids) / 2; y++) {
  //uint8_t tmp = sscanf(bssids.substring(0,2),"%x");
  //b[y] = (uint8_t)strtoul(cstr[0], NULL, 10);
}

i know, it's a mess :frowning:

what char? are you passing a MAC address as a string? (need to see)

uint8_t mac1 [6] = { 0xa5, 01, 02, 03, 04, 05 };

Thanks a lot. The last issue i was able to figure out myself. BSSID() is returning a pointer (?) and i had to use memcpy in order to store it in "your" mac1/2/3 var:

#include <TTN_esp32.h>
#include <WiFi.h>

const char* devAddr = "asdf"; // Change to TTN Device Address
const char* nwkSKey = "asdf"; // Change to TTN Network Session Key
const char* appSKey = "asdf"; // Change to TTN Application Session Key
uint8_t mac1 [6];
uint8_t mac2 [6];
uint8_t payload[12];
TTN_esp32 ttn ;

void prep(void)
{
  int i = 0;

  for (unsigned n = 0; n < 6; n++)
    payload [i++] = mac1 [n];

  for (unsigned n = 0; n < 6; n++)
    payload [i++] = mac2 [n];
}

void setup() {
  Serial.begin(115200);
  WiFi.scanNetworks();
  Serial.println(WiFi.BSSIDstr(0));

  memcpy(mac1,WiFi.BSSID(0),6);
  memcpy(mac2,WiFi.BSSID(1),6);

  prep();

  ttn.begin();
  ttn.personalize(devAddr, nwkSKey, appSKey);

  ttn.sendBytes(payload, sizeof(payload));
}

void loop() {}

Now i will have to build the main code around it, but that should be doable :slight_smile:

Thank you very much @gcjr !!

i don't understand. are you saying these Keys are mac addresses?

No. Sorry for the confusion. These are just obfuscated TTN access-codes used in ttn.personalize()

WiFi.BSSID(i) returns the MAC of each Wifi found by WiFi.scanNetworks.

I will search for the three strongest or skip if less than 2 are closeby.

These macs will be sent over lora to an mqtt-client which will ask google location api where (approx) these wifis are. This makes a simple, (hopefully) power-efficient device which will help me find my stolen (or lost on a saturday night :-)) bike. In a more or less urban area this should be working quite well, but lets see in real life...

Thanks again for your help!
Chris

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.