Work on decoding using structs
This commit is contained in:
4
TODO
4
TODO
@@ -2,3 +2,7 @@
|
||||
|
||||
* Consider support for upper/lower case MAC address and optionaly ":"
|
||||
* Scanning - list devices publishing, should be able to get list even without knowing MAC / Encryption key
|
||||
* Struct vs Manual
|
||||
* Sh3dNg version and examples uses structs to get data - seems to work
|
||||
* Example generated uses manually managing a string
|
||||
* Reconsider what is best and use
|
||||
|
||||
@@ -213,6 +213,8 @@ void VictronBLE::processDevice(BLEAdvertisedDevice advertisedDevice) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX Use struct like code in Sh3dNg
|
||||
|
||||
// Check if it's Victron (manufacturer ID 0x02E1)
|
||||
uint16_t mfgId = (uint8_t)mfgData[1] << 8 | (uint8_t)mfgData[0];
|
||||
if (mfgId != VICTRON_MANUFACTURER_ID) {
|
||||
@@ -236,9 +238,11 @@ bool VictronBLE::parseAdvertisement(const uint8_t* manufacturerData, size_t len,
|
||||
const String& macAddress) {
|
||||
auto it = devices.find(macAddress);
|
||||
if (it == devices.end()) {
|
||||
debugPrint("parseAdvertisement: Device not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX Work out second?
|
||||
DeviceInfo* deviceInfo = it->second;
|
||||
|
||||
if (len < 6) {
|
||||
@@ -246,18 +250,29 @@ bool VictronBLE::parseAdvertisement(const uint8_t* manufacturerData, size_t len,
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX map to struct - NOTE: Check size first (exact? or bigger?)
|
||||
victronManufacturerData * vicData=(victronManufacturerData *)manufacturerData;
|
||||
debugPrint("VendorID" + String(vicData->vendorID));
|
||||
debugPrint("Record Type" + String(vicData->victronRecordType));
|
||||
|
||||
// Structure: [MfgID(2)] [DeviceType(1)] [IV(2)] [EncryptedData(n)]
|
||||
uint8_t deviceType = manufacturerData[2];
|
||||
// XXX This is actually 4 - Struct would help - it was 2
|
||||
uint8_t deviceType = manufacturerData[4];
|
||||
|
||||
// Extract IV (initialization vector) - bytes 3-4, little-endian
|
||||
// XXX These look wrong
|
||||
uint8_t iv[16] = {0};
|
||||
iv[0] = manufacturerData[3];
|
||||
iv[1] = manufacturerData[4];
|
||||
// Rest of IV is zero-padded
|
||||
|
||||
// Encrypted data starts at byte 5
|
||||
const uint8_t* encryptedData = manufacturerData + 5;
|
||||
size_t encryptedLen = len - 5;
|
||||
// const uint8_t* encryptedData = manufacturerData + 5;
|
||||
// size_t encryptedLen = len - 5;
|
||||
|
||||
// XXX Experiment
|
||||
const uint8_t* encryptedData = vicData->victronEncryptedData;
|
||||
size_t encryptedLen = sizeof(vicData->victronEncryptedData);
|
||||
|
||||
if (debugEnabled) {
|
||||
debugPrintHex("Encrypted data", encryptedData, encryptedLen);
|
||||
|
||||
@@ -53,6 +53,39 @@ enum SolarChargerState {
|
||||
CHARGER_EXTERNAL_CONTROL = 252
|
||||
};
|
||||
|
||||
// XXX HARD Core structs
|
||||
// Used for decoding
|
||||
// But then data is put into specific device structs
|
||||
// Which means a lot of overlap - reconsider...
|
||||
// NOTE: c struct vs classes
|
||||
|
||||
// Must use the "packed" attribute to make sure the compiler doesn't add any padding to deal with
|
||||
// word alignment.
|
||||
typedef struct {
|
||||
uint8_t deviceState;
|
||||
uint8_t errorCode;
|
||||
int16_t batteryVoltage;
|
||||
int16_t batteryCurrent;
|
||||
uint16_t todayYield;
|
||||
uint16_t inputPower;
|
||||
uint8_t outputCurrentLo; // Low 8 bits of output current (in 0.1 Amp increments)
|
||||
uint8_t outputCurrentHi; // High 1 bit of ourput current (must mask off unused bits)
|
||||
uint8_t unused[4];
|
||||
} __attribute__((packed)) victronPanelData; // XXX Specific type -
|
||||
|
||||
typedef struct {
|
||||
uint16_t vendorID; // vendor ID
|
||||
uint8_t beaconType; // Should be 0x10 (Product Advertisement) for the packets we want
|
||||
uint8_t unknownData1[3]; // Unknown data
|
||||
uint8_t victronRecordType; // Should be 0x01 (Solar Charger) for the packets we want
|
||||
uint16_t nonceDataCounter; // Nonce
|
||||
uint8_t encryptKeyMatch; // Should match pre-shared encryption key byte 0
|
||||
uint8_t victronEncryptedData[21]; // (31 bytes max per BLE spec - size of previous elements)
|
||||
uint8_t nullPad; // extra byte because toCharArray() adds a \0 byte.
|
||||
} __attribute__((packed)) victronManufacturerData;
|
||||
|
||||
// XXX End of new bit above
|
||||
|
||||
// Base structure for all device data
|
||||
struct VictronDeviceData {
|
||||
String deviceName;
|
||||
|
||||
Reference in New Issue
Block a user