118 lines
3.5 KiB
C++
118 lines
3.5 KiB
C++
#ifndef ESP32_BLE_GAMEPAD_H
|
|
#define ESP32_BLE_GAMEPAD_H
|
|
#include "sdkconfig.h"
|
|
#if defined(CONFIG_BT_ENABLED)
|
|
|
|
#ifndef GAMEPAD_CLASS
|
|
#define GAMEPAD_CLASS BleGamepad
|
|
#endif
|
|
|
|
#include "../common.h"
|
|
|
|
#include "BLE2902.h"
|
|
#include "BLEHIDDevice.h"
|
|
#include "HIDKeyboardTypes.h"
|
|
#include "HIDTypes.h"
|
|
#include <BLEDevice.h>
|
|
#include <BLEServer.h>
|
|
#include <BLEUtils.h>
|
|
#include <driver/adc.h>
|
|
|
|
#include "BLECharacteristic.h"
|
|
#include "BLEHIDDevice.h"
|
|
#include "BleConnectionStatus.h"
|
|
|
|
#if defined(CONFIG_ARDUHAL_ESP_LOG)
|
|
#include "esp32-hal-log.h"
|
|
#define LOG_TAG ""
|
|
#else
|
|
#include "esp_log.h"
|
|
static const char *LOG_TAG = "BLEDevice";
|
|
#endif
|
|
|
|
class BleGamepad : public AbstractGamepad {
|
|
private:
|
|
BleConnectionStatus *connectionStatus;
|
|
BLEHIDDevice *hid;
|
|
BLECharacteristic *inputGamepad[GAMEPAD_COUNT];
|
|
void rawAction(uint8_t msg[], char msgSize);
|
|
static void taskServer(void *pvParameter) {
|
|
BleGamepad *BleGamepadInstance = (BleGamepad *)pvParameter; // static_cast<BleGamepad *>(pvParameter);
|
|
BLEDevice::init(BleGamepadInstance->deviceName);
|
|
BLEServer *pServer = BLEDevice::createServer();
|
|
pServer->setCallbacks(BleGamepadInstance->connectionStatus);
|
|
|
|
BleGamepadInstance->hid = new BLEHIDDevice(pServer);
|
|
|
|
for (int c = 0; c < GAMEPAD_COUNT; c++) {
|
|
BleGamepadInstance->inputGamepad[c] = BleGamepadInstance->hid->inputReport(c); // <-- input REPORTID from report map
|
|
BleGamepadInstance->connectionStatus->inputGamepad[c] = BleGamepadInstance->inputGamepad[c];
|
|
}
|
|
|
|
BleGamepadInstance->hid->manufacturer()->setValue(BleGamepadInstance->deviceManufacturer);
|
|
|
|
// todo: is this change required for 2 inputs???
|
|
// BleGamepadInstance->hid->pnp(0x01,0x02e5,0xabcc,0x0110);
|
|
BleGamepadInstance->hid->pnp(0x02, 0x8282, 0x0132, 0x0106);
|
|
|
|
BleGamepadInstance->hid->hidInfo(0x00, 0x01);
|
|
|
|
BLESecurity *pSecurity = new BLESecurity();
|
|
|
|
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
|
|
|
|
BleGamepadInstance->hid->reportMap((uint8_t *)_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
|
BleGamepadInstance->hid->startServices();
|
|
|
|
BleGamepadInstance->onStarted(pServer);
|
|
|
|
BLEAdvertising *pAdvertising = pServer->getAdvertising();
|
|
pAdvertising->setAppearance(HID_GAMEPAD);
|
|
pAdvertising->addServiceUUID(BleGamepadInstance->hid->hidService()->getUUID());
|
|
pAdvertising->start();
|
|
BleGamepadInstance->hid->setBatteryLevel(BleGamepadInstance->batteryLevel);
|
|
|
|
ESP_LOGD(LOG_TAG, "Advertising started!");
|
|
vTaskDelay(portMAX_DELAY); // delay(portMAX_DELAY);
|
|
}
|
|
|
|
public:
|
|
uint8_t batteryLevel;
|
|
std::string deviceManufacturer;
|
|
std::string deviceName;
|
|
|
|
BleGamepad(std::string deviceName = "8BitDo SN30 Pro+", std::string deviceManufacturer = "8Bitdo SF30 Pro", uint8_t batteryLevel = 100) : AbstractGamepad(), hid(0) {
|
|
this->deviceName = deviceName;
|
|
this->deviceManufacturer = deviceManufacturer;
|
|
this->batteryLevel = batteryLevel;
|
|
this->connectionStatus = new BleConnectionStatus();
|
|
}
|
|
|
|
virtual void begin(void) {
|
|
xTaskCreate(this->taskServer, "server", 20000, (void *)this, 5, NULL);
|
|
}
|
|
|
|
virtual void sendHidReport(const uint8_t cIdx, const void *d, int len) {
|
|
if (this->isConnected()) {
|
|
this->inputGamepad[cIdx]->setValue((uint8_t *)d, len);
|
|
this->inputGamepad[cIdx]->notify();
|
|
}
|
|
}
|
|
|
|
virtual bool isConnected(void) {
|
|
return this->connectionStatus->connected;
|
|
}
|
|
|
|
virtual void setBatteryLevel(uint8_t level) {
|
|
this->batteryLevel = level;
|
|
if (hid != 0)
|
|
this->hid->setBatteryLevel(this->batteryLevel);
|
|
}
|
|
|
|
protected:
|
|
virtual void onStarted(BLEServer *pServer){};
|
|
};
|
|
|
|
#endif // CONFIG_BT_ENABLED
|
|
#endif // ESP32_BLE_GAMEPAD_H
|