Line data Source code
1 : #pragma once 2 : 3 : #ifdef ARDUINO 4 : 5 : #ifndef ARDUINO_ARCH_ESP32 6 : #error "MIDI over Bluetooth is only supported on ESP32 boards" 7 : #endif 8 : 9 : #include <BLE2902.h> 10 : #include <BLEDevice.h> 11 : #include <BLEServer.h> 12 : #include <BLEUtils.h> 13 : 14 : #include <AH/Error/Error.hpp> 15 : 16 : BEGIN_CS_NAMESPACE 17 : 18 : // https://www.midi.org/specifications/item/bluetooth-le-midi 19 : const char *SERVICE_UUID = "03b80e5a-ede8-4b33-a751-6ce34ec4c700"; 20 : const char *CHARACTERISTIC_UUID = "7772e5db-3868-4112-a1a9-f2669d106bf3"; 21 : 22 : constexpr const char *BLE_MIDI_NAME = "Control Surface (BLE)"; 23 : 24 : class BLEMIDI { 25 : public: 26 : ~BLEMIDI() { 27 : // TODO 28 : } 29 : 30 : /** 31 : * @note Must be called after begin. 32 : */ 33 : void setServerCallbacks(BLEServerCallbacks *cb) { 34 : if (pServer == nullptr) { 35 : ERROR(F("Error: pServer has not been initialized"), 0x2020); 36 : return; 37 : } 38 : pServer->setCallbacks(cb); 39 : } 40 : 41 : /** 42 : * @note Must be called after begin. 43 : */ 44 : void setCharacteristicsCallbacks(BLECharacteristicCallbacks *cb) { 45 : if (pCharacteristic == nullptr) { 46 : ERROR(F("Error: Characteristic has not been initialized"), 0x2021); 47 : return; 48 : } 49 : pCharacteristic->setCallbacks(cb); 50 : } 51 : 52 : void begin(BLEServerCallbacks *serverCallbacks, 53 : BLECharacteristicCallbacks *midiCallbacks) { 54 : DEBUGFN("Initializing BLE MIDI Interface"); 55 : if (BLEDevice::getInitialized()) { 56 : ERROR(F("Error: BLEDevice is initialized already"), 0x2022); 57 : return; // TODO: What to do here? 58 : } 59 : 60 : // Initialize the BLE device 61 : BLEDevice::init(BLE_MIDI_NAME); 62 : 63 : // Create the BLE server 64 : pServer = BLEDevice::createServer(); 65 : setServerCallbacks(serverCallbacks); 66 : 67 : // Create the BLE service 68 : BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID)); 69 : 70 : // Create a BLE characteristic 71 : pCharacteristic = pService->createCharacteristic( 72 : BLEUUID(CHARACTERISTIC_UUID), 73 : BLECharacteristic::PROPERTY_READ | 74 : BLECharacteristic::PROPERTY_NOTIFY | 75 : BLECharacteristic::PROPERTY_WRITE_NR); 76 : 77 : // Create a BLE descriptor 78 : descriptor = new BLE2902(); 79 : pCharacteristic->addDescriptor(descriptor); 80 : // descriptor.setNotifications(true); 81 : setCharacteristicsCallbacks(midiCallbacks); 82 : 83 : // Start the service 84 : pService->start(); 85 : 86 : // Start advertising 87 : BLEAdvertising *pAdvertising = pServer->getAdvertising(); 88 : pAdvertising->addServiceUUID(pService->getUUID()); 89 : pAdvertising->start(); 90 : } 91 : 92 : void notifyValue(uint8_t *data, size_t len) { 93 : pCharacteristic->setValue(data, len); 94 : pCharacteristic->notify(); 95 : } 96 : 97 : std::string getValue() { return pCharacteristic->getValue(); } 98 : 99 : private: 100 : BLECharacteristic *pCharacteristic = nullptr; 101 : BLEServer *pServer = nullptr; 102 : BLE2902 *descriptor; 103 : }; 104 : 105 : END_CS_NAMESPACE 106 : 107 : #else 108 : 109 : #include <Def/Def.hpp> 110 : #include <gmock-wrapper.h> 111 : #include <string> 112 : 113 : class BLECharacteristic { 114 : public: 115 0 : MOCK_METHOD(std::string, getValue, ()); 116 0 : MOCK_METHOD(void, setValue, (uint8_t * data, size_t len)); 117 : }; 118 : 119 10 : class BLECharacteristicCallbacks { 120 : public: 121 10 : virtual ~BLECharacteristicCallbacks() = default; 122 0 : virtual void onRead(BLECharacteristic *pCharacteristic) { 123 : (void)pCharacteristic; 124 0 : } 125 0 : virtual void onWrite(BLECharacteristic *pCharacteristic) { 126 : (void)pCharacteristic; 127 0 : } 128 : }; 129 : 130 : class BLEServer {}; 131 : 132 10 : class BLEServerCallbacks { 133 : public: 134 10 : virtual ~BLEServerCallbacks() = default; 135 0 : virtual void onConnect(BLEServer *pServer) { (void)pServer; } 136 0 : virtual void onDisconnect(BLEServer *pServer) { (void)pServer; } 137 : }; 138 : 139 : BEGIN_CS_NAMESPACE 140 : 141 20 : class BLEMIDI { 142 : public: 143 : MOCK_METHOD(void, setServerCallbacks, (BLEServerCallbacks *)); 144 : MOCK_METHOD(void, setCharacteristicsCallbacks, 145 : (BLECharacteristicCallbacks *)); 146 20 : MOCK_METHOD(void, begin, 147 : (BLEServerCallbacks *, BLECharacteristicCallbacks *)); 148 0 : MOCK_METHOD(void, notifyValue, (uint8_t * data, size_t len)); 149 : MOCK_METHOD(std::string, getValue, ()); 150 : }; 151 : 152 : END_CS_NAMESPACE 153 : 154 : #endif