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 <Helpers/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_METHOD0(getValue, std::string(void)); 116 0 : MOCK_METHOD2(setValue, void(uint8_t *data, size_t len)); 117 : }; 118 : 119 10 : class BLECharacteristicCallbacks { 120 : public: 121 10 : virtual ~BLECharacteristicCallbacks() = default; 122 0 : virtual void onRead(UNUSED_PARAM BLECharacteristic *pCharacteristic) {} 123 0 : virtual void onWrite(UNUSED_PARAM BLECharacteristic *pCharacteristic) {} 124 : }; 125 : 126 : class BLEServer {}; 127 : 128 10 : class BLEServerCallbacks { 129 : public: 130 10 : virtual ~BLEServerCallbacks() = default; 131 0 : virtual void onConnect(UNUSED_PARAM BLEServer *pServer) {} 132 0 : virtual void onDisconnect(UNUSED_PARAM BLEServer *pServer) {} 133 : }; 134 : 135 : BEGIN_CS_NAMESPACE 136 : 137 20 : class BLEMIDI { 138 : public: 139 : MOCK_METHOD1(setServerCallbacks, void(BLEServerCallbacks *)); 140 : MOCK_METHOD1(setCharacteristicsCallbacks, 141 : void(BLECharacteristicCallbacks *)); 142 20 : MOCK_METHOD2(begin, 143 : void(BLEServerCallbacks *, BLECharacteristicCallbacks *)); 144 0 : MOCK_METHOD2(notifyValue, void(uint8_t *data, size_t len)); 145 : MOCK_METHOD0(getValue, std::string(void)); 146 : }; 147 : 148 : END_CS_NAMESPACE 149 : 150 : #endif