Rounak Datta
Rounak Datta

Reputation: 460

How to send and receive data with ESP32 over BLE?

The ESP32 needs to communicate with a Crosss-Platform app through BLE (Bluetooth Low Energy).

Upvotes: 1

Views: 12413

Answers (2)

monkey
monkey

Reputation: 1671

Assume you're talking about ionic. In which case, you can use a BLE plugin, use protobufs to implement the transport layer, then add in curce25519 cryptography & SHA256 hashing for the proof of possession (if you're using it) to create a shared key. Then use AES (CTR mode) encryption / decryption. Lastly you'll need to create your protobuf _pb.js files to shove into something like google-protobuf.js to actually generate your messages.

It's not simple.

BLE Plugin

First thing to so is get it up and running:

import { BLE } from '@ionic-native/ble/ngx'; 

is a good one. There are good tutorials out there to get this working.

Protobuffers

I'd recommend google-protobuf. Use commonJS imports to bring in your .proto files as _pb.js:

$ protoc --js_out=import_style=commonjs,binary:. messages.proto base.proto

Then in the your .ts file, use something like:

var messages = require("../../assets/js/wifi_scan_pb");
var message = new messages.RespScanStatus();

as an example for how to use the Scan Results end point.

Cryptography

It says it's optional, but realistically, if you aren't using it, you are an idiot. So, don't skip this step because it's hard. You can use something like:

import { sharedKey, generateKeyPair } from 'curve25519-js';

let keyPairClient = generateKeyPair(seedClient);
let keyPairDevice = generateKeyPair(seedDevice);
let shared_key = sharedKey(keyPairClient.private, keyPairDevice.public);

...  you get the picture... 

and then maybe use crypto-js to piece together the rest of teh encryption. it comes rolled up with AES, SHA256. Don't forget to incorportate the Proof of Possession in the shared keyt generation. It offers a worthwhile level of security.

Then What

Send and receive stuff from the device. It's all standard BLE stuff. And I don't say that whimsically because I know everything about BLE, I can say it because the library I recommended handles it fine, despite the fact that I know nothing about BLE.

Sorry it's a massive pain in the backside, but that's the honest answer of what you'll need to do to send stuff with ESP32 using BLE.

Upvotes: 0

Rounak Datta
Rounak Datta

Reputation: 460

Sending data over BLE

  1. Define the function and the logic to send data byte-by-byte
void sendSomeDataBLE(uint8_t *message, int messageSize) {
        uint8_t txValue = 0;

        while (txValue < messageSize) {
          pTxCharacteristic->setValue(&message[txValue], 1);
          pTxCharacteristic->notify();
          txValue++;
          delay(100); // bluetooth stack will go into congestion, if too many packets are sent
        }
}
  1. Calculate the message length, malloc a character array
int messageLength = 10; // or measure someway
uint8_t* message = (uint8_t*)malloc(sizeof(uint8_t)*messageLength);
  1. Pass the pointer of the uint8_t array to the function
sendSomeDataBLE(&message[0], messageLength);

Receiving data over BLE

  1. Define the function to compare the received value with a string
bool compareData(std::string received, std::string predefined) {
  int receivedLength = received.length();
  int predefinedLength = predefined.length();

  if ((receivedLength / 2) != predefinedLength) {
    return false;
  }

  for (int i = 0; i < predefinedLength; i++) {
    if (received[i * 2] != predefined[i]) {
      return false;
    }
  }

  return true;
}
  1. Capture all the data received through the callback function
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      std::string lwnCommand = "lwn";
      if (compareData(rxValue, lwnCommand)) {
        Serial.println("lwn command received");
      }
   }
}

Also, you do need to initiate the BLE and set up the characterestics for RX and TX.

Upvotes: 1

Related Questions