fw: robust HTTP body reads, CORS preflight, LED off at boot; update docs

- app_net.c: replace bare httpd_req_recv with recv_body_capped/alloc
  helpers (TCP-safe, full-body reads); add OPTIONS/* CORS preflight
  handler; bump WS broadcast buffer to 2048; add CORS Allow-Methods
- CMakeLists (net_service): add http_parser dep for HTTP_OPTIONS
- nfc_engine/pn532_core: add nfc_access_lock/unlock mutex, board-RGB
  quiet helper, UL type detection, general-status improvements
- pn532_transport: minor cleanup
- main.c: call board_rgb_led_quiet() at boot to kill onboard LED
- sdkconfig.defaults: add board RGB Kconfig defaults
- README, docs/LIMITATIONS, docs/PINOUT: expand and correct

Made-with: Cursor
This commit is contained in:
drjones
2026-04-07 21:23:04 -07:00
parent ad814c6a12
commit 63db10d400
13 changed files with 1070 additions and 16 deletions

View File

@@ -18,7 +18,12 @@ static void hint_type(nfc_tag_info_t *t)
t->type_hint = 1;
break;
case 0x00:
t->type_hint = 2;
/* Typical Type 2 inventory tuple is ATQA 0x0044 and 7-byte UID. */
if ((t->atqa == 0x4400 || t->atqa == 0x0044) && t->uid_len == 7) {
t->type_hint = 2;
} else {
t->type_hint = 0;
}
break;
default:
t->type_hint = 0;
@@ -41,6 +46,45 @@ bool nfc_tag_is_type2(const nfc_tag_info_t *tag)
return tag && tag->type_hint == 2;
}
int nfc_mifare_sector_count(const nfc_tag_info_t *tag)
{
if (!nfc_tag_is_mifare_classic(tag)) {
return 0;
}
return nfc_tag_is_mifare_classic_4k(tag) ? 40 : 16;
}
bool nfc_mifare_sector_layout(const nfc_tag_info_t *tag, int sector, int *first_block, int *num_blocks,
uint8_t *trailer_block)
{
if (!nfc_tag_is_mifare_classic(tag) || !first_block || !num_blocks || !trailer_block) {
return false;
}
if (!nfc_tag_is_mifare_classic_4k(tag)) {
if (sector < 0 || sector > 15) {
return false;
}
*first_block = sector * 4;
*num_blocks = 4;
*trailer_block = (uint8_t)(sector * 4 + 3);
return true;
}
if (sector < 0 || sector > 39) {
return false;
}
if (sector <= 31) {
*first_block = sector * 4;
*num_blocks = 4;
*trailer_block = (uint8_t)(sector * 4 + 3);
} else {
int r = sector - 32;
*first_block = 128 + r * 16;
*num_blocks = 16;
*trailer_block = (uint8_t)(128 + r * 16 + 15);
}
return true;
}
esp_err_t nfc_engine_init(void)
{
esp_err_t e = pn532_core_init();
@@ -248,6 +292,25 @@ esp_err_t nfc_ul_fast_read(uint8_t start_page, uint8_t *out, size_t out_max, siz
return ESP_OK;
}
esp_err_t nfc_type2_get_version(uint8_t version[8])
{
if (!version) {
return ESP_ERR_INVALID_ARG;
}
uint8_t d[] = {0x60};
uint8_t resp[32];
size_t rlen = 0;
esp_err_t e = in_data_tg(d, sizeof(d), resp, sizeof(resp), &rlen);
if (e != ESP_OK) {
return e;
}
if (rlen < 2 + 8 || resp[0] != (uint8_t)(PN532_CMD_INDATAEXCHANGE + 1) || resp[1] != 0x00) {
return ESP_ERR_INVALID_RESPONSE;
}
memcpy(version, resp + 2, 8);
return ESP_OK;
}
cJSON *nfc_tag_to_json(const nfc_tag_info_t *tag)
{
if (!tag || tag->uid_len > NFC_MAX_UID_LEN) {