/ RNode_Firmware_CE_G2 / BLESerial.cpp
BLESerial.cpp
1 // Copyright (C) 2024, Mark Qvist 2 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 #include "Boards.h" 17 18 #if PLATFORM != PLATFORM_NRF52 19 #if HAS_BLE 20 21 #include "BLESerial.h" 22 23 uint32_t bt_passkey_callback(); 24 void bt_passkey_notify_callback(uint32_t passkey); 25 bool bt_security_request_callback(); 26 void bt_authentication_complete_callback(esp_ble_auth_cmpl_t auth_result); 27 bool bt_confirm_pin_callback(uint32_t pin); 28 void bt_connect_callback(BLEServer *server); 29 void bt_disconnect_callback(BLEServer *server); 30 bool bt_client_authenticated(); 31 32 uint32_t BLESerial::onPassKeyRequest() { return bt_passkey_callback(); } 33 void BLESerial::onPassKeyNotify(uint32_t passkey) { bt_passkey_notify_callback(passkey); } 34 bool BLESerial::onSecurityRequest() { return bt_security_request_callback(); } 35 void BLESerial::onAuthenticationComplete(esp_ble_auth_cmpl_t auth_result) { bt_authentication_complete_callback(auth_result); } 36 void BLESerial::onConnect(BLEServer *server) { bt_connect_callback(server); } 37 void BLESerial::onDisconnect(BLEServer *server) { bt_disconnect_callback(server); ble_server->startAdvertising(); } 38 bool BLESerial::onConfirmPIN(uint32_t pin) { return bt_confirm_pin_callback(pin); }; 39 bool BLESerial::connected() { return ble_server->getConnectedCount() > 0; } 40 41 int BLESerial::read() { 42 int result = this->rx_buffer.pop(); 43 if (result == '\n') { this->numAvailableLines--; } 44 return result; 45 } 46 47 size_t BLESerial::readBytes(uint8_t *buffer, size_t bufferSize) { 48 int i = 0; 49 while (i < bufferSize && available()) { buffer[i] = (uint8_t)this->rx_buffer.pop(); i++; } 50 return i; 51 } 52 53 int BLESerial::peek() { 54 if (this->rx_buffer.getLength() == 0) return -1; 55 return this->rx_buffer.get(0); 56 } 57 58 int BLESerial::available() { return this->rx_buffer.getLength(); } 59 60 size_t BLESerial::print(const char *str) { 61 if (ble_server->getConnectedCount() <= 0) return 0; 62 size_t written = 0; for (size_t i = 0; str[i] != '\0'; i++) { written += this->write(str[i]); } 63 flush(); 64 65 return written; 66 } 67 68 size_t BLESerial::write(const uint8_t *buffer, size_t bufferSize) { 69 if (ble_server->getConnectedCount() <= 0) { return 0; } else { 70 size_t written = 0; for (int i = 0; i < bufferSize; i++) { written += this->write(buffer[i]); } 71 flush(); 72 73 return written; 74 } 75 } 76 77 size_t BLESerial::write(uint8_t byte) { 78 if (bt_client_authenticated()) { 79 if (ble_server->getConnectedCount() <= 0) { return 0; } else { 80 this->transmitBuffer[this->transmitBufferLength] = byte; 81 this->transmitBufferLength++; 82 if (this->transmitBufferLength == maxTransferSize) { flush(); } 83 return 1; 84 } 85 } else { 86 return 0; 87 } 88 } 89 90 void BLESerial::flush() { 91 if (this->transmitBufferLength > 0) { 92 TxCharacteristic->setValue(this->transmitBuffer, this->transmitBufferLength); 93 this->transmitBufferLength = 0; 94 this->lastFlushTime = millis(); 95 TxCharacteristic->notify(true); 96 } 97 } 98 99 void BLESerial::disconnect() { 100 if (ble_server->getConnectedCount() > 0) { 101 uint16_t conn_id = ble_server->getConnId(); 102 // Serial.printf("Have connected: %d\n", conn_id); 103 ble_server->disconnect(conn_id); 104 // Serial.println("Disconnected"); 105 } else { 106 // Serial.println("No connected"); 107 } 108 } 109 110 void BLESerial::begin(const char *name) { 111 ConnectedDeviceCount = 0; 112 BLEDevice::init(name); 113 114 esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9); 115 esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9); 116 esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_SCAN ,ESP_PWR_LVL_P9); 117 118 ble_server = BLEDevice::createServer(); 119 ble_server->setCallbacks(this); 120 // Use level 0 so esp_ble_set_encryption is not auto-called on connect (BLEDevice.cpp). 121 // ESP-IDF 5+ may define ESP_BLE_SEC_NONE; Arduino-ESP32 2.0.x does not — use (esp_ble_sec_act_t)0. 122 #if defined(ESP_BLE_SEC_NONE) 123 BLEDevice::setEncryptionLevel(ESP_BLE_SEC_NONE); 124 #else 125 BLEDevice::setEncryptionLevel((esp_ble_sec_act_t)0); 126 #endif 127 BLEDevice::setSecurityCallbacks(this); 128 129 SetupSerialService(); 130 this->startAdvertising(); 131 } 132 133 void BLESerial::startAdvertising() { 134 ble_adv = BLEDevice::getAdvertising(); 135 ble_adv->addServiceUUID(BLE_SERIAL_SERVICE_UUID); 136 ble_adv->setMinPreferred(0x20); 137 ble_adv->setMaxPreferred(0x40); 138 ble_adv->setScanResponse(true); 139 ble_adv->start(); 140 } 141 142 void BLESerial::stopAdvertising() { 143 ble_adv = BLEDevice::getAdvertising(); 144 ble_adv->stop(); 145 } 146 147 void BLESerial::end() { BLEDevice::deinit(); } 148 149 void BLESerial::onWrite(BLECharacteristic *characteristic) { 150 if (characteristic->getUUID().toString() == BLE_RX_UUID) { 151 auto value = characteristic->getValue(); 152 for (int i = 0; i < value.length(); i++) { rx_buffer.push(value[i]); } 153 } 154 } 155 156 void BLESerial::SetupSerialService() { 157 SerialService = ble_server->createService(BLE_SERIAL_SERVICE_UUID); 158 159 RxCharacteristic = SerialService->createCharacteristic(BLE_RX_UUID, BLECharacteristic::PROPERTY_WRITE); 160 RxCharacteristic->setAccessPermissions(ESP_GATT_PERM_WRITE_ENC_MITM); 161 RxCharacteristic->addDescriptor(new BLE2902()); 162 RxCharacteristic->setWriteProperty(true); 163 RxCharacteristic->setCallbacks(this); 164 165 TxCharacteristic = SerialService->createCharacteristic(BLE_TX_UUID, BLECharacteristic::PROPERTY_NOTIFY); 166 TxCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENC_MITM); 167 TxCharacteristic->addDescriptor(new BLE2902()); 168 TxCharacteristic->setNotifyProperty(true); 169 TxCharacteristic->setReadProperty(true); 170 171 SerialService->start(); 172 } 173 174 BLESerial::BLESerial() { } 175 176 #endif 177 #endif