Skip to content

Add support for bambu tags #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d90b989
Working KDF
spuder Nov 27, 2024
ca846f6
add pn532 component
spuder Nov 27, 2024
69a860d
Add working reading of bambu tag
spuder Nov 29, 2024
1bcc5a5
Read Mifare tags
spuder Nov 30, 2024
6ecdc63
add components
spuder Nov 30, 2024
6418478
Auth not quite workign
spuder Nov 30, 2024
6faeab6
Add test file
spuder Nov 30, 2024
08a35ff
Merge branch 'main' into bambu-rfid
spuder Nov 30, 2024
941fe73
Revert
spuder Nov 30, 2024
09b9440
not yet working
spuder Dec 1, 2024
0e3a07b
Not yet working
spuder Dec 1, 2024
5e1484c
Merge branch 'main' into bambu-rfid
spuder Dec 4, 2024
af535c3
Add host option
spuder Dec 4, 2024
f82e95e
Add comments
spuder Dec 4, 2024
f36fe60
Fix logging output
spuder Dec 4, 2024
9316837
Change parameter order
spuder Dec 4, 2024
a411b42
Fix kdf
spuder Dec 4, 2024
907997c
Add images
spuder Dec 5, 2024
b22afe9
Add todos
spuder Dec 5, 2024
4c2df0e
Merge branch 'main' into bambu-rfid
spuder Dec 5, 2024
8d00f17
Merge branch 'main' into bambu-rfid
spuder Dec 6, 2024
89d6cca
Parameterize generate_keys()
spuder Dec 6, 2024
17b5537
Clean up logs
spuder Dec 7, 2024
7e9348a
Add external component
spuder Dec 7, 2024
ed556a6
Simplified reading data for mifare tags
spuder Dec 7, 2024
3a53f48
Add logging for raw data
spuder Dec 7, 2024
b680056
Add logging for tag raw data
spuder Dec 7, 2024
a9abefc
Add data
spuder Dec 7, 2024
a98b658
Parse bambu data
spuder Dec 7, 2024
4639b30
Working color
spuder Dec 7, 2024
07c14b8
Cleanup
spuder Dec 8, 2024
6abfb4f
Move KDF to nfc_helpers
spuder Dec 8, 2024
4188c32
Read all tags
spuder Dec 8, 2024
c681b80
Cleanup bambu.h
spuder Dec 8, 2024
e1acf1f
Merge branch 'main' into bambu-rfid
spuder Dec 8, 2024
2594a16
Cleanup
spuder Dec 8, 2024
678695e
Switch vector to array, still crashing
spuder Dec 8, 2024
c61f78a
Merge branch 'main' into bambu-rfid
spuder Dec 8, 2024
9a5ee1e
Break faster if reading fails, use const for safety
spuder Dec 8, 2024
b352413
Speed up parsing by auth only to sectors
spuder Dec 8, 2024
211b463
Fix type (PLA) due to skipping sector 0
spuder Dec 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion firmware/Makefile
Original file line number Diff line number Diff line change
@@ -71,4 +71,6 @@ lolin_s3_mini:
run lolin_s3_mini.yaml --device $(USB_ADDRESS)
devkit:
esphome \
run esp32-s3-devkitc-1.yaml --device $(USB_ADDRESS)
run esp32-s3-devkitc-1.yaml --device $(USB_ADDRESS)
host:
esphome run host.yaml
97 changes: 96 additions & 1 deletion firmware/bambu.h
Original file line number Diff line number Diff line change
@@ -5,8 +5,22 @@
#include <unordered_map>
#include <string>

#ifdef ESP_PLATFORM
#include "esp_idf_version.h"
#include "mbedtls/hkdf.h"
#include "mbedtls/md.h"
#else
#include <mbedtls/hkdf.h>
#include <mbedtls/md.h>
#include <ArduinoJson.h>
#endif

namespace bambulabs
{
struct FilamentInfo {
std::string color_code;
std::string type;
};
const std::unordered_map<std::string, std::string> filament_mappings = {
{"TPU", "GFU99"},
{"PLA", "GFL99"},
@@ -132,4 +146,85 @@ namespace bambulabs
return result;
}

}
//TODO: move this to a utils file or find a more native esphome way to convert to ascii
// inline std::string hex_to_ascii(const std::string& hex) {
// std::string ascii;
// for (size_t i = 0; i < hex.length(); i += 2) {
// std::string byte = hex.substr(i, 2);
// char chr = static_cast<char>(std::stoi(byte, nullptr, 16));
// ascii.push_back(chr);
// }
// return ascii;
// }

inline FilamentInfo parse_tag_data(const std::vector<uint8_t>& tag_data) {
FilamentInfo info;
const int block_size = 16;
ESP_LOGD("bambu", "Parsing tag data");

for (int block = 0; block < 16; ++block) {
if (block * block_size >= tag_data.size()) {
break;
}

const uint8_t* block_data = tag_data.data() + (block * block_size);

switch (block) {
case 0:
ESP_LOGV("bambu", "UID: %s", format_hex(block_data, 4).c_str());
break;
case 1:
ESP_LOGV("bambu", "Material Variant: %s", format_hex(block_data, 8).c_str());
ESP_LOGV("bambu", "Unique Material Type: %s", format_hex(block_data + 8, 8).c_str());
break;
case 2:
ESP_LOGV("bambu", "Filament Type: %s", format_hex(block_data, 16).c_str());
// info.type = hex_to_ascii(format_hex(block_data, 16));
info.type = std::string(reinterpret_cast<const char*>(block_data), 16);
ESP_LOGV("bambu", "Filament Type Ascii: %s", info.type.c_str());
break;
case 4:
ESP_LOGV("bambu", "Detailed Filament Type: %s", format_hex(block_data, 16).c_str());
break;
case 5:
ESP_LOGV("bambu", "Color Code: %s", format_hex(block_data, 4).c_str());
info.color_code = format_hex(block_data, 4);
ESP_LOGV("bambu", "Spool Weight: %s", format_hex(block_data + 4, 2).c_str());
ESP_LOGV("bambu", "Filament Diameter: %s", format_hex(block_data + 8, 4).c_str());
break;
case 6:
ESP_LOGV("bambu", "Temperatures: %s", format_hex(block_data, 8).c_str());
ESP_LOGV("bambu", "Drying Info: %s", format_hex(block_data + 8, 8).c_str());
break;
case 8:
ESP_LOGV("bambu", "X Cam Info: %s", format_hex(block_data, 8).c_str());
ESP_LOGV("bambu", "Nozzle Diameter: %s", format_hex(block_data + 8, 8).c_str());
break;
case 9:
ESP_LOGV("bambu", "Tray UID: %s", format_hex(block_data, 16).c_str());
break;
case 10:
ESP_LOGV("bambu", "Spool Width: %s", format_hex(block_data, 16).c_str());
break;
case 12:
ESP_LOGV("bambu", "Production Date/Time: %s", format_hex(block_data, 16).c_str());
break;
case 13:
ESP_LOGV("bambu", "Short Production Date/Time: %s", format_hex(block_data, 16).c_str());
break;
case 14:
ESP_LOGV("bambu", "Filament Length: %s", format_hex(block_data, 16).c_str());
break;
case 16:
ESP_LOGV("bambu", "Extra Color Info: %s", format_hex(block_data, 16).c_str());
break;
}

if (block != 0 && block != 1 && block !=2 && block != 3 && block != 7 && block != 11 && block != 15) {
ESP_LOGV("bambu", "Block %d Data: %s", block, format_hex(block_data, block_size).c_str());
}
}
return info;
}

}
30 changes: 30 additions & 0 deletions firmware/components/nfc/nfc_helpers.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "nfc_helpers.h"
#include "mbedtls/hkdf.h"
#include "mbedtls/md.h"


namespace esphome {
namespace nfc {
@@ -43,5 +46,32 @@ std::string get_random_ha_tag_ndef() {
return uri;
}

// TODO: should this use unique_ptr for better memory management?
std::array<std::array<uint8_t, 6>, 16> generate_keys(const std::vector<uint8_t>& uid) {

// Output buffer
static uint8_t output[96];

// Context
const unsigned char context[] = {'R', 'F', 'I', 'D', '-', 'A', '\0'};

// Perform HKDF
mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
nfc::BAMBU_SALT.data(), nfc::BAMBU_SALT.size(),
uid.data(), uid.size(),
context, sizeof(context),
output, sizeof(output));

//TODO: should this use std::unique_ptr for better memory management?
std::array<std::array<uint8_t, 6>, 16> result;
for (int i = 0; i < 16; i++) {
std::copy_n(output + i*6, 6, result[i].begin());
ESP_LOGD("bambu", "Key %d: %02x%02x%02x%02x%02x%02x", i,
result[i][0], result[i][1], result[i][2],
result[i][3], result[i][4], result[i][5]);
}
return result;
}

} // namespace nfc
} // namespace esphome
5 changes: 5 additions & 0 deletions firmware/components/nfc/nfc_helpers.h
Original file line number Diff line number Diff line change
@@ -8,10 +8,15 @@ namespace nfc {
static const char HA_TAG_ID_EXT_RECORD_TYPE[] = "android.com:pkg";
static const char HA_TAG_ID_EXT_RECORD_PAYLOAD[] = "io.homeassistant.companion.android";
static const char HA_TAG_ID_PREFIX[] = "https://www.home-assistant.io/tag/";
static const std::vector<uint8_t> BAMBU_SALT = {
0x9a, 0x75, 0x9c, 0xf2, 0xc4, 0xf7, 0xca, 0xff,
0x22, 0x2c, 0xb9, 0x76, 0x9b, 0x41, 0xbc, 0x96
};

std::string get_ha_tag_ndef(NfcTag &tag);
std::string get_random_ha_tag_ndef();
bool has_ha_tag_ndef(NfcTag &tag);
std::array<std::array<uint8_t, 6>, 16> generate_keys(const std::vector<uint8_t> &uid);

} // namespace nfc
} // namespace esphome
16 changes: 16 additions & 0 deletions firmware/components/nfc/nfc_tag.h
Original file line number Diff line number Diff line change
@@ -34,23 +34,39 @@ class NfcTag {
this->tag_type_ = tag_type;
this->ndef_message_ = make_unique<NdefMessage>(ndef_data);
};

NfcTag(std::vector<uint8_t> &uid, const std::string &tag_type, std::vector<uint8_t> &raw_data, bool is_raw_data) {
//TODO: this probably could be merged with `std::vector<uint8_t> &uid, const std::string &tag_type, std::vector<uint8_t> &ndef_data`
// but instead of making an ndef_message we just store the raw data
this->uid_ = uid;
this->tag_type_ = tag_type;
this->raw_data_ = raw_data;
this->is_raw_data_ = is_raw_data;
}
NfcTag(const NfcTag &rhs) {
uid_ = rhs.uid_;
tag_type_ = rhs.tag_type_;
if (rhs.ndef_message_ != nullptr)
ndef_message_ = make_unique<NdefMessage>(*rhs.ndef_message_);
if (!rhs.raw_data_.empty())
raw_data_ = rhs.raw_data_;
is_raw_data_ = rhs.is_raw_data_;
}

std::vector<uint8_t> &get_uid() { return this->uid_; };
const std::string &get_tag_type() { return this->tag_type_; };
bool has_ndef_message() { return this->ndef_message_ != nullptr; };
const std::shared_ptr<NdefMessage> &get_ndef_message() { return this->ndef_message_; };
void set_ndef_message(std::unique_ptr<NdefMessage> ndef_message) { this->ndef_message_ = std::move(ndef_message); };
bool has_raw_data() { return this->is_raw_data_; };
const std::vector<uint8_t> &get_raw_data() { return this->raw_data_; };

protected:
std::vector<uint8_t> uid_;
std::string tag_type_;
std::shared_ptr<NdefMessage> ndef_message_;
std::vector<uint8_t> raw_data_;
bool is_raw_data_ = false;
};

} // namespace nfc
4 changes: 3 additions & 1 deletion firmware/components/pn532/pn532.cpp
Original file line number Diff line number Diff line change
@@ -205,7 +205,7 @@ void PN532::loop() {
for (const auto &record : records) {
ESP_LOGD(TAG, " %s - %s", record->get_type().c_str(), record->get_payload().c_str());
}
}
}//TODO: elseif not ndef, but has raw data
}
} else if (next_task_ == CLEAN) {
ESP_LOGD(TAG, " Tag cleaning...");
@@ -363,6 +363,8 @@ std::unique_ptr<nfc::NfcTag> PN532::read_tag_(std::vector<uint8_t> &uid) {
if (type == nfc::TAG_TYPE_MIFARE_CLASSIC) {
ESP_LOGD(TAG, "Mifare classic");
return this->read_mifare_classic_tag_(uid);
//TODO: figure out how to preserve backwards compatiblilyt with ndef tags without keys
// return this->read_mifare_classic_tag_(uid, nfc::KEYS); //TODO: should this be pointer?
} else if (type == nfc::TAG_TYPE_2) {
ESP_LOGD(TAG, "Mifare ultralight");
return this->read_mifare_ultralight_tag_(uid);
2 changes: 2 additions & 0 deletions firmware/components/pn532/pn532.h
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#include "esphome/components/nfc/nfc_tag.h"
#include "esphome/components/nfc/nfc.h"
#include "esphome/components/nfc/automation.h"
#include "esphome/components/nfc/nfc_helpers.h" //TODO: is this the best way to add generaet_keys() dep?

#include <cinttypes>
#include <vector>
@@ -76,6 +77,7 @@ class PN532 : public PollingComponent {
bool write_tag_(std::vector<uint8_t> &uid, nfc::NdefMessage *message);

std::unique_ptr<nfc::NfcTag> read_mifare_classic_tag_(std::vector<uint8_t> &uid);
std::unique_ptr<nfc::NfcTag> read_mifare_classic_tag_(std::vector<uint8_t> &uid, std::array<const uint8_t*, 16> keys); //todo should this be *keys
bool read_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
bool write_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
bool auth_mifare_classic_block_(std::vector<uint8_t> &uid, uint8_t block_num, uint8_t key_num, const uint8_t *key);
152 changes: 117 additions & 35 deletions firmware/components/pn532/pn532_mifare_classic.cpp
Original file line number Diff line number Diff line change
@@ -12,56 +12,138 @@ std::unique_ptr<nfc::NfcTag> PN532::read_mifare_classic_tag_(std::vector<uint8_t
uint8_t current_block = 4;
uint8_t message_start_index = 0;
uint32_t message_length = 0;

if (this->auth_mifare_classic_block_(uid, current_block, nfc::MIFARE_CMD_AUTH_A, nfc::NDEF_KEY)) {
std::vector<uint8_t> data;
if (this->read_mifare_classic_block_(current_block, data)) {
if (!nfc::decode_mifare_classic_tlv(data, message_length, message_start_index)) {
return make_unique<nfc::NfcTag>(uid, nfc::ERROR);
bool is_ndef = true;
// std::array<const uint8_t*, 16> KEYS = esphome::nfc::generate_keys();
// std::vector<std::vector<uint8_t>> KEYS = esphome::nfc::generate_keys(uid);
std::array<std::array<uint8_t, 6>, 16> KEYS = esphome::nfc::generate_keys(uid);

// TODO: For some reason if using nfc::NDEF_KEY fails, all future reads also fail
// temporarially commenting out the NDEF check until I can figure out why
// if (this->auth_mifare_classic_block_(uid, current_block, nfc::MIFARE_CMD_AUTH_A, nfc::NDEF_KEY)) {
// std::vector<uint8_t> data;
// if (this->read_mifare_classic_block_(current_block, data)) {
// if (!nfc::decode_mifare_classic_tlv(data, message_length, message_start_index)) {
// return make_unique<nfc::NfcTag>(uid, nfc::ERROR);
// }
// } else {
// ESP_LOGE(TAG, "Failed to read block %d", current_block);
// return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
// }
// } else {
// ESP_LOGV(TAG, "Tag is not NDEF formatted");
// is_ndef = false;
// //return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
// }
is_ndef = false;

if (is_ndef) {
uint32_t index = 0;
uint32_t buffer_size = nfc::get_mifare_classic_buffer_size(message_length);
std::vector<uint8_t> buffer;

while (index < buffer_size) {
if (nfc::mifare_classic_is_first_block(current_block)) {
if (!this->auth_mifare_classic_block_(uid, current_block, nfc::MIFARE_CMD_AUTH_A, nfc::NDEF_KEY)) {
ESP_LOGE(TAG, "Error, Block authentication failed for %d", current_block);
}
}
std::vector<uint8_t> block_data;
if (this->read_mifare_classic_block_(current_block, block_data)) {
buffer.insert(buffer.end(), block_data.begin(), block_data.end());
} else {
ESP_LOGE(TAG, "Error reading block %d", current_block);
}
} else {
ESP_LOGE(TAG, "Failed to read block %d", current_block);
return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
}
} else {
ESP_LOGV(TAG, "Tag is not NDEF formatted");
return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
}

uint32_t index = 0;
uint32_t buffer_size = nfc::get_mifare_classic_buffer_size(message_length);
std::vector<uint8_t> buffer;
index += nfc::MIFARE_CLASSIC_BLOCK_SIZE;
current_block++;

while (index < buffer_size) {
if (nfc::mifare_classic_is_first_block(current_block)) {
if (!this->auth_mifare_classic_block_(uid, current_block, nfc::MIFARE_CMD_AUTH_A, nfc::NDEF_KEY)) {
ESP_LOGE(TAG, "Error, Block authentication failed for %d", current_block);
if (nfc::mifare_classic_is_trailer_block(current_block)) {
current_block++;
}
}
std::vector<uint8_t> block_data;
if (this->read_mifare_classic_block_(current_block, block_data)) {
buffer.insert(buffer.end(), block_data.begin(), block_data.end());

if (buffer.begin() + message_start_index < buffer.end()) {
buffer.erase(buffer.begin(), buffer.begin() + message_start_index);
} else {
ESP_LOGE(TAG, "Error reading block %d", current_block);
return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
}

index += nfc::MIFARE_CLASSIC_BLOCK_SIZE;
current_block++;
return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC, buffer);
} else {
std::vector<uint8_t> tag_data;
bool read_success = true;
int current_sector = -1;
int current_block = 0; // Start from block 0

while (current_block < 64 && read_success) { // TODO: add support for mifare 4k
int new_sector = current_block / 4;

if (new_sector != current_sector) {
// Authenticate when entering a new sector, including sector 0
if (!this->auth_mifare_classic_block_(uid, current_block, nfc::MIFARE_CMD_AUTH_A, KEYS[new_sector].data())) {
ESP_LOGW(TAG, "Warning: Sector authentication failed for sector %d", new_sector);
// Continue reading even if authentication fails
} else {
ESP_LOGVV(TAG, "Sector authentication succeeded for sector %d", new_sector);
}
current_sector = new_sector;
}

std::vector<uint8_t> block_data;
if (this->read_mifare_classic_block_(current_block, block_data)) {
tag_data.insert(tag_data.end(), block_data.begin(), block_data.end());
ESP_LOGVV(TAG, "Read block %d: %s", current_block, esphome::format_hex_pretty(block_data).c_str());
} else {
ESP_LOGE(TAG, "Error reading block %d", current_block);
read_success = false;
break;
}

if (nfc::mifare_classic_is_trailer_block(current_block)) {
current_block++;
}
}

if (buffer.begin() + message_start_index < buffer.end()) {
buffer.erase(buffer.begin(), buffer.begin() + message_start_index);
} else {
return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
if (read_success) {
ESP_LOGV(TAG, "Creating tag with raw data");
return std::make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC, tag_data, true);
} else {
ESP_LOGE(TAG, "Tag reading aborted due to errors");
return std::make_unique<nfc::NfcTag>(uid, nfc::ERROR);
}
}

return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC, buffer);
}

// std::unique_ptr<nfc::NfcTag> PN532::read_mifare_classic_tag_(std::vector<uint8_t> &uid, std::array<const uint8_t*, 16> keys) {
// uint8_t current_block = 4;
// uint8_t message_start_index = 0;
// uint32_t message_length = 0;
// std::vector<uint8_t> tag_data;

// while (current_block < 64) { //TODO: add support for mifare 4k
// uint8_t current_sector = current_block / 4;

// if (nfc::mifare_classic_is_first_block(current_block)) {
// if (!this->auth_mifare_classic_block_(uid, current_block, nfc::MIFARE_CMD_AUTH_A, nfc::KEYS[current_sector])) {
// ESP_LOGE(TAG, "Error, Block authentication failed for %d", current_block);
// } else {
// ESP_LOGVV(TAG, "Block authentication succeeded for %d", current_block);
// }
// }

// std::vector<uint8_t> block_data;
// if (this->read_mifare_classic_block_(current_block, block_data)) {
// tag_data.insert(tag_data.end(), block_data.begin(), block_data.end());
// } else {
// ESP_LOGE(TAG, "Error reading block %d", current_block);
// }

// current_block++;
// }

// // Use the new constructor, specifying that this is raw data
// ESP_LOGV(TAG, "Creating tag with raw data");
// return std::make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC, tag_data, true);
// }

bool PN532::read_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data) {
if (!this->write_command_({
PN532_COMMAND_INDATAEXCHANGE,
2 changes: 1 addition & 1 deletion firmware/conf.d/logger.yaml
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@ logger:
pn532: DEBUG
pn532_spi: DEBUG
spi: INFO
nfc: DEBUG
i2c: INFO
mqtt: DEBUG
mqtt.component: DEBUG
@@ -39,4 +38,5 @@ logger:
pn532.mifare_classic: VERBOSE
TAG: VERBOSE
NFC: VERBOSE
nfc: VERBOSE
"": ERROR
20 changes: 20 additions & 0 deletions firmware/conf.d/pn532_rfid-solo.yaml
Original file line number Diff line number Diff line change
@@ -43,6 +43,26 @@ pn532_spi:
- binary_sensor.template.publish:
id: nfc_tag_present0
state: ON
- lambda: |-
ESP_LOGV("NFC", "Checking tag for raw data");
if (tag.has_raw_data()) {
ESP_LOGV("NFC", "Tag has raw data flag set");
const auto& data = tag.get_raw_data();
if (!data.empty()) {
std::string hex_data = format_hex_pretty(data);
ESP_LOGV("NFC", "Raw data: %s", hex_data.c_str());
//TODO: how to determine if bambu labs tag (see permissions block 87-87-87-69)
auto bambu_tag = bambulabs::parse_tag_data(data);
auto color = bambu_tag.color_code.substr(0, 6); // Only publish first 6 characters, drop FF
id(filament_color_hex).publish_state(color);
id(filament_type).state = bambu_tag.type;
} else {
ESP_LOGV("NFC", "Raw data vector is empty");
}
} else {
ESP_LOGV("NFC", "Tag has no raw data flag set");
}
- lambda: |-
bool is_valid_openspool = false;
std::string payload;
56 changes: 56 additions & 0 deletions firmware/conf.d/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
esp32:
framework:
sdkconfig_options:
CONFIG_MBEDTLS_HKDF_C: y
CONFIG_MBEDTLS_MD_C: y

esphome:
libraries:
#- mbedtls
# - limits
# - kochcodes/mbedtls@3.6.2
# - armmbed/mbedtls@2.23.0
includes:
- bambu.h
# - mbedtls/hkdf.h
# - mbedtls/md.h
platformio_options:
build_flags:
#- -lmbedtls
#- -lmbedcrypto
# - -lmbedx509
#- -DCHAR_BIT=8
#- -DUSE_ESP_IDF
#- -DESP_PLATFORM
# - -DMBEDTLS_HKDF_C
# - -DMBEDTLS_MD_C
- -DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"
# - -UCONFIG_MBEDTLS_HKDF_C
# - -UCONFIG_MBEDTLS_MD_C

# external_components:
# - source: github://espressif/esp-idf
# components: [mbedtls]

external_components:
- source:
type: local
path: components
components: [pn532, nfc]

# text_sensor:
# - platform: template
# name: "HKDF Output"
# id: hkdf_output
# state_topic:
# update_interval: 60s
# lambda: |-
# auto keys = bambulabs::generate_keys();
# std::string result = "[";
# for (size_t i = 0; i < keys.size(); ++i) {
# if (i > 0) result += ", ";
# result += std::to_string(keys[i]);
# }
# result += "]";
# return result;

1 change: 1 addition & 0 deletions firmware/esp32-s3-devkitc-1.yaml
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@ packages:
#improv-bluetooth: !include conf.d/improv-bluetooth.yaml
led-internal: !include conf.d/led-internal.yaml
extra: !include conf.d/extra.yaml
test: !include conf.d/test.yaml # TODO: move to a proper file

dashboard_import:
package_import_url: github://spuder/openspool/firmware/esp32-s3-devkitc-1.yaml@main
103 changes: 103 additions & 0 deletions firmware/host.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Host.yaml is a dummy file that allows for quick compiling and testing without an esp32

# Setup
# brew install mbedtls

esphome:
name: host_device
friendly_name: Host Device
includes:
- bambu.h
platformio_options:
lib_deps:
- bblanchon/ArduinoJson @ ^6.21.5
build_flags:
# - -DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"
- "-I/opt/homebrew/include"
- "-L/opt/homebrew/lib"
- "-lmbedtls"
- "-lmbedcrypto"
- "-lmbedx509"
- "-DMBEDTLS_CONFIG_FILE=\\\"mbedtls/mbedtls_config.h\\\""

external_components:
- source:
type: local
path: components
components: [pn532, nfc]
#components: [nfc]

host:
mac_address: "DE:AD:BE:EF:c0:FE"

logger:
level: DEBUG

# Text sensor to say hello world
text_sensor:
- platform: template
name: "Hello World"
id: hello_world
lambda: |-
return {"Hello World"};
on_value:
then:
- logger.log:
format: "Hello World sensor value: %s"
args: ["x.c_str()"]

- platform: template
name: "keys"
id: generate_keys
lambda: |-
return {"Hello World 2"};
on_value:
then:
- lambda: |-
//bambulabs::generate_keys();
//TODO: refactor so genreate_keys takes a string
ESP_LOGD("host", "--------");
bambulabs::generate_keys("5a-c9-00-a6");
ESP_LOGD("host", "--------");
bambulabs::generate_keys("75-88-6B-1D");
ESP_LOGD("host", "--------");
//std::vector<uint8_t> uid = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11};
//esphome::nfc::NfcTag new_tag(uid, "Mifare Classic");
//bambulabs::generate_keys(new_tag.get_uid());
# calling bambulabs::generate_keys() with the hard coded uid 5a-c9-00-a6
# should return the following keys
# 63e5af2c1d75
# 40d146ce6e01
# 6a66957dcc91
# 15e7041f68d9
# 7ee1ac7fa75f
# 55cbbad18673
# ce5901af9416
# a223a193e6a3
# 24f4d022f402
# 7df999dd836b
# b0dac4a48903
# b026ab566f11
# 8b495d5a0b44
# 7ebef1cb3e94
# 4685790c6e01
# 3f00144c7b4a

# 75-88-6B-1D should return this
# 6e5b0ec6ef7c
# 4ce96076285f
# 0b0373be835b
# 906b2736c958
# 0a7c3aa6e3cb
# 9c357ba6842b
# 6712858e9196
# 4b3199aea656
# 6637239e0019
# b440e6ca11c0
# 89914a92bdf8
# 9cb8e022d296
# e82816da2cf9
# d48fed336320
# 5e6ca668ccc5
# d9805eec7045
2 changes: 1 addition & 1 deletion firmware/openspool-ams.yaml
Original file line number Diff line number Diff line change
@@ -2,4 +2,4 @@
packages:
base: !include common.yaml
psram: !include conf.d/psram-esp32s3.yaml
pn_532_rfid-ams: !include conf.d/pn532_rfid-ams.yaml
pn_532_rfid-ams: !include conf.d/pn532_rfid-ams.yaml