esp32_loraprs/src/ble_serial.cpp

182 wiersze
4.9 KiB
C++

// Copyright 2019 Ian Archbell / oddWires
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ble_serial.h"
class BLESerialServerCallbacks: public BLEServerCallbacks {
friend class BLESerial;
BLESerial* bleSerial;
void onConnect(BLEServer* pServer) {
// do anything needed on connection
LOG_INFO("BLE client connected");
delay(1000); // wait for connection to complete or messages can be lost
};
void onDisconnect(BLEServer* pServer) {
pServer->startAdvertising(); // restart advertising
LOG_INFO("BLE client disconnected, started advertising");
}
};
class BLESerialCharacteristicCallbacks: public BLECharacteristicCallbacks {
friend class BLESerial;
BLESerial* bleSerial;
void onWrite(BLECharacteristic *pCharacteristic) {
bleSerial->receiveBuffer = bleSerial->receiveBuffer + pCharacteristic->getValue();
}
};
// Constructor
BLESerial::BLESerial()
: pService(NULL)
, pTxCharacteristic(NULL)
, receiveBuffer("")
{
}
// Destructor
BLESerial::~BLESerial(void)
{
// clean up
}
// Begin bluetooth serial
bool BLESerial::begin(const char* localName)
{
// Create the BLE Device
BLEDevice::init(localName);
// Create the BLE Server
pServer = BLEDevice::createServer();
if (pServer == nullptr)
return false;
BLESerialServerCallbacks* bleSerialServerCallbacks = new BLESerialServerCallbacks();
bleSerialServerCallbacks->bleSerial = this;
pServer->setCallbacks(bleSerialServerCallbacks);
// Create the BLE Service
pService = pServer->createService(SERVICE_UUID);
if (pService == nullptr)
return false;
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
if (pTxCharacteristic == nullptr)
return false;
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR
);
if (pRxCharacteristic == nullptr)
return false;
BLESerialCharacteristicCallbacks* bleSerialCharacteristicCallbacks = new BLESerialCharacteristicCallbacks();
bleSerialCharacteristicCallbacks->bleSerial = this;
pRxCharacteristic->setCallbacks(bleSerialCharacteristicCallbacks);
// Start the service
pService->start();
LOG_INFO("BLE started service");
// Start advertising
pServer->getAdvertising()->addServiceUUID(pService->getUUID());
pServer->getAdvertising()->setScanResponse(true);
pServer->getAdvertising()->setMinPreferred(0x06);
pServer->getAdvertising()->setMaxPreferred(0x12);
pServer->getAdvertising()->start();
LOG_INFO("BLE started advertising and waiting for client connection...");
return true;
}
int BLESerial::available(void)
{
// reply with data available
return receiveBuffer.length();
}
int BLESerial::peek(void)
{
// return first character available
// but don't remove it from the buffer
if ((receiveBuffer.length() > 0)){
uint8_t c = receiveBuffer[0];
return c;
}
else
return -1;
}
bool BLESerial::connected(void)
{
// true if connected
if (pServer->getConnectedCount() > 0)
return true;
else
return false;
}
int BLESerial::read(void)
{
// read a character
if ((receiveBuffer.length() > 0)){
uint8_t c = receiveBuffer[0];
receiveBuffer.erase(0,1); // remove it from the buffer
return c;
}
else
return -1;
}
size_t BLESerial::write(uint8_t c)
{
// write a character
uint8_t _c = c;
pTxCharacteristic->setValue(&_c, 1);
pTxCharacteristic->notify();
delay(3); // bluetooth stack will go into congestion, if too many packets are sent
return 1;
}
size_t BLESerial::write(const uint8_t *buffer, size_t size)
{
// write a buffer
for(int i=0; i < size; i++){
write(buffer[i]);
}
return size;
}
void BLESerial::flush()
{
// remove buffered data
receiveBuffer.clear();
}
void BLESerial::end()
{
// close connection
}