Skip to content

Commit

Permalink
Convert to absolute mouse (Android)
Browse files Browse the repository at this point in the history
  • Loading branch information
sobrinho committed Oct 28, 2021
1 parent 8f1a15b commit d578801
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 428 deletions.
168 changes: 168 additions & 0 deletions BleAbsMouse.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "BLE2902.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
#include <driver/adc.h>
#include "sdkconfig.h"

#include "BleConnectionStatus.h"
#include "BleAbsMouse.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

#define REPORTID_TOUCH 0x01

#define LSB(v) ((v >> 8) & 0xff)
#define MSB(v) (v & 0xff)

static const uint8_t _hidReportDescriptor[] = {
0x05, 0x0d, /* USAGE_PAGE (Digitizer) */
0x09, 0x04, /* USAGE (Touch Screen) */
0xa1, 0x01, /* COLLECTION (Application) */
0x85, REPORTID_TOUCH, /* REPORT_ID */

/* declare a finger collection */
0x09, 0x20, /* Usage (Stylus) */
0xA1, 0x00, /* Collection (Physical) */

/* Declare a finger touch (finger up/down) */
0x09, 0x42, /* Usage (Tip Switch) */
0x09, 0x32, /* USAGE (In Range) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x95, 0x02, /* REPORT_COUNT (2) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */

/* Declare the remaining 6 bits of the first data byte as constant -> the driver will ignore them */
0x75, 0x01, /* REPORT_SIZE (1) */
0x95, 0x06, /* REPORT_COUNT (6) */
0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */

/* Define absolute X and Y coordinates of 16 bit each (percent values multiplied with 100) */
/* http://www.usb.org/developers/hidpage/Hut1_12v2.pdf */
/* Chapter 16.2 says: "In the Stylus collection a Pointer physical collection will contain the axes reported by the stylus." */
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x01, /* Usage (Pointer) */
0xA1, 0x00, /* Collection (Physical) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x16, 0x00, 0x00, /* Logical Minimum (0) */
0x26, 0x10, 0x27, /* Logical Maximum (10000) */
0x36, 0x00, 0x00, /* Physical Minimum (0) */
0x46, 0x10, 0x27, /* Physical Maximum (10000) */
0x66, 0x00, 0x00, /* UNIT (None) */
0x75, 0x10, /* Report Size (16), */
0x95, 0x02, /* Report Count (2), */
0x81, 0x02, /* Input (Data,Var,Abs) */
0xc0, /* END_COLLECTION */
0xc0, /* END_COLLECTION */
0xc0 /* END_COLLECTION */

// With this declaration a data packet must be sent as:
// byte 1 -> "touch" state (bit 0 = pen up/down, bit 1 = In Range)
// byte 2,3 -> absolute X coordinate (0...10000)
// byte 4,5 -> absolute Y coordinate (0...10000)
};

BleAbsMouse::BleAbsMouse(std::string deviceName, std::string deviceManufacturer, uint8_t batteryLevel) :
hid(0)
{
this->deviceName = deviceName;
this->deviceManufacturer = deviceManufacturer;
this->batteryLevel = batteryLevel;
this->connectionStatus = new BleConnectionStatus();
}

void BleAbsMouse::begin(void)
{
xTaskCreate(this->taskServer, "server", 20000, (void *)this, 5, NULL);
}

void BleAbsMouse::end(void)
{
}

void BleAbsMouse::click(int16_t x, int16_t y)
{
this->move(x, y);
this->release();
}

void BleAbsMouse::move(int16_t x, int16_t y)
{
this->send(1, x, y);
}

void BleAbsMouse::release()
{
this->send(0, 0, 0);
}

void BleAbsMouse::send(int state, int16_t x, int16_t y)
{
if (this->isConnected())
{
uint8_t m[5];
m[0] = state;
m[1] = MSB(x);
m[2] = LSB(x);
m[3] = MSB(y);
m[4] = LSB(y);
this->inputAbsMouse->setValue(m, 5);
this->inputAbsMouse->notify();
}
}

bool BleAbsMouse::isConnected(void) {
return this->connectionStatus->connected;
}

void BleAbsMouse::setBatteryLevel(uint8_t level) {
this->batteryLevel = level;
if (hid != 0)
this->hid->setBatteryLevel(this->batteryLevel);
}

void BleAbsMouse::taskServer(void* pvParameter) {
BleAbsMouse* bleMouseInstance = (BleAbsMouse *) pvParameter; //static_cast<BleAbsMouse *>(pvParameter);
BLEDevice::init(bleMouseInstance->deviceName);
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(bleMouseInstance->connectionStatus);

bleMouseInstance->hid = new BLEHIDDevice(pServer);
bleMouseInstance->inputAbsMouse = bleMouseInstance->hid->inputReport(REPORTID_TOUCH); // <-- input REPORTID from report map
bleMouseInstance->connectionStatus->inputAbsMouse = bleMouseInstance->inputAbsMouse;

bleMouseInstance->hid->manufacturer()->setValue(bleMouseInstance->deviceManufacturer);

bleMouseInstance->hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
bleMouseInstance->hid->hidInfo(0x00,0x02);

BLESecurity *pSecurity = new BLESecurity();

pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);

bleMouseInstance->hid->reportMap((uint8_t*)_hidReportDescriptor, sizeof(_hidReportDescriptor));
bleMouseInstance->hid->startServices();

bleMouseInstance->onStarted(pServer);

BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_MOUSE);
pAdvertising->addServiceUUID(bleMouseInstance->hid->hidService()->getUUID());
pAdvertising->start();
bleMouseInstance->hid->setBatteryLevel(bleMouseInstance->batteryLevel);

ESP_LOGD(LOG_TAG, "Advertising started!");
vTaskDelay(portMAX_DELAY); //delay(portMAX_DELAY);
}
35 changes: 35 additions & 0 deletions BleAbsMouse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef ESP32_BLE_ABS_MOUSE_H
#define ESP32_BLE_ABS_MOUSE_H
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)

#include "BleConnectionStatus.h"
#include "BLEHIDDevice.h"
#include "BLECharacteristic.h"

class BleAbsMouse {
private:
BleConnectionStatus* connectionStatus;
BLEHIDDevice* hid;
BLECharacteristic* inputAbsMouse;
void rawAction(uint8_t msg[], char msgSize);
static void taskServer(void* pvParameter);
public:
BleAbsMouse(std::string deviceName = "ESP32 Bluetooth Abs Mouse", std::string deviceManufacturer = "Espressif", uint8_t batteryLevel = 100);
void begin(void);
void end(void);
void click(int16_t x, int16_t y);
void move(int16_t x, int16_t y);
void release(void);
void send(int state, int16_t x, int16_t y);
bool isConnected(void);
void setBatteryLevel(uint8_t level);
uint8_t batteryLevel;
std::string deviceManufacturer;
std::string deviceName;
protected:
virtual void onStarted(BLEServer *pServer) { };
};

#endif // CONFIG_BT_ENABLED
#endif // ESP32_BLE_ABS_MOUSE_H
4 changes: 2 additions & 2 deletions BleConnectionStatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ BleConnectionStatus::BleConnectionStatus(void) {
void BleConnectionStatus::onConnect(BLEServer* pServer)
{
this->connected = true;
BLE2902* desc = (BLE2902*)this->inputMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
BLE2902* desc = (BLE2902*)this->inputAbsMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(true);
}

void BleConnectionStatus::onDisconnect(BLEServer* pServer)
{
this->connected = false;
BLE2902* desc = (BLE2902*)this->inputMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
BLE2902* desc = (BLE2902*)this->inputAbsMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(false);
}
2 changes: 1 addition & 1 deletion BleConnectionStatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class BleConnectionStatus : public BLEServerCallbacks
bool connected = false;
void onConnect(BLEServer* pServer);
void onDisconnect(BLEServer* pServer);
BLECharacteristic* inputMouse;
BLECharacteristic* inputAbsMouse;
};

#endif // CONFIG_BT_ENABLED
Expand Down
Loading

0 comments on commit d578801

Please sign in to comment.