-
Notifications
You must be signed in to change notification settings - Fork 258
Expand file tree
/
Copy pathBleFeatureReport.cpp
More file actions
69 lines (59 loc) · 2.93 KB
/
Copy pathBleFeatureReport.cpp
File metadata and controls
69 lines (59 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "BleFeatureReport.h"
#include "BleReportUtils.h"
BleFeatureReceiver::BleFeatureReceiver(uint16_t featureReportLength, BleGamepadConfiguration *configuration)
{
this->featureReportLength = featureReportLength;
this->configuration = configuration;
featureBuffer = new uint8_t[featureReportLength];
memset(featureBuffer, 0, featureReportLength);
buildFeatureReport(); // seed the buffer with the capability defaults, once
}
BleFeatureReceiver::~BleFeatureReceiver()
{
// Release memory
if (featureBuffer)
{
delete[] featureBuffer;
}
}
// Seeds featureBuffer[0..3] with a capability report modeled on the SInput
// "Features 0x02" layout. Called once at construction so a host that reads the
// Feature Report without anything having written it still sees sane defaults.
// It is NOT re-run on every read -- that would clobber whatever the sketch put
// there with setFeatureBuffer() (the bidirectional buffer in GattVsHid.md B).
// https://docs.handheldlegend.com/s/sinput/doc/features-response-bytes-1lMp7WL7bq
void BleFeatureReceiver::buildFeatureReport()
{
uint8_t caps = 0;
if (configuration->getEnableRumble()) caps |= FEAT_CAP_RUMBLE;
if (configuration->getEnablePlayerLED()) caps |= FEAT_CAP_PLAYERLED;
if (configuration->getIncludeAccelerometer()) caps |= FEAT_CAP_ACCELEROMETER;
if (configuration->getIncludeGyroscope()) caps |= FEAT_CAP_GYROSCOPE;
if (configuration->getIncludeXAxis() || configuration->getIncludeYAxis()) caps |= FEAT_CAP_LEFT_STICK;
if (configuration->getIncludeZAxis() || configuration->getIncludeRzAxis()) caps |= FEAT_CAP_RIGHT_STICK;
if (configuration->getIncludeRxAxis()) caps |= FEAT_CAP_LEFT_TRIGGER;
if (configuration->getIncludeRyAxis()) caps |= FEAT_CAP_RIGHT_TRIGGER;
if (featureReportLength > 0) featureBuffer[0] = caps;
if (featureReportLength > 1) featureBuffer[1] = (uint8_t)configuration->getButtonCount();
if (featureReportLength > 2) featureBuffer[2] = configuration->getAxisCount();
if (featureReportLength > 3) featureBuffer[3] = configuration->getHatSwitchCount();
}
void BleFeatureReceiver::onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo)
{
// Serve whatever is in the buffer -- the capability defaults from the
// constructor, or whatever setFeatureBuffer() / a host onWrite last stored.
pCharacteristic->setValue(featureBuffer, featureReportLength);
}
void BleFeatureReceiver::onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo)
{
// Retrieve data sent from the host
std::string value = pCharacteristic->getValue();
const uint8_t* raw = (const uint8_t*)value.c_str();
size_t length = 0;
const uint8_t* data = stripReportIdIfPresent(raw, value.length(), featureReportLength, length);
if (length <= featureReportLength && memcmp(data, featureBuffer, length) != 0)
{
memcpy(featureBuffer, data, length);
}
featureFlag = true;
}