Refactor NFC Maker with proper NDEF logic

Also fixes wifi not working in some cases
This commit is contained in:
Willy-JL
2023-07-12 01:53:27 +02:00
parent 0e1b3f2d84
commit 6e9e6262c6

View File

@@ -61,221 +61,168 @@ void nfc_maker_scene_result_on_enter(void* context) {
buf[i++] = 0x48; // Internal buf[i++] = 0x48; // Internal
buf[i++] = 0x00; // Lock bytes buf[i++] = 0x00; // Lock bytes
buf[i++] = 0x00; // ... buf[i++] = 0x00; // ...
buf[i++] = 0xE1; // Capability container buf[i++] = 0xE1; // Capability container
buf[i++] = 0x10; // ... buf[i++] = 0x10; // ...
buf[i++] = 0x3E; // ... buf[i++] = 0x3E; // ...
buf[i++] = 0x00; // ... buf[i++] = 0x00; // ...
buf[i++] = 0x03; // Message flags
size_t start = i++;
buf[i++] = 0x03; // Container flags
// NDEF Docs: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/protocols/nfc/index.html#nfc-data-exchange-format-ndef
uint8_t tnf = 0x00;
const char* type = "";
uint8_t* payload = NULL;
size_t payload_len = 0;
size_t data_len = 0;
size_t j = 0;
switch(scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneMenu)) { switch(scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneMenu)) {
case NfcMakerSceneBluetooth: { case NfcMakerSceneBluetooth: {
buf[i++] = 0xD2; tnf = 0x02; // Media-type [RFC 2046]
buf[i++] = 0x20; type = "application/vnd.bluetooth.ep.oob";
buf[i++] = 0x08;
buf[i++] = 0x61;
buf[i++] = 0x70;
buf[i++] = 0x70; data_len = GAP_MAC_ADDR_SIZE;
buf[i++] = 0x6C; payload_len = data_len + 2;
buf[i++] = 0x69; payload = malloc(payload_len);
buf[i++] = 0x63;
buf[i++] = 0x61; payload[j++] = 0x08;
buf[i++] = 0x74; payload[j++] = 0x00;
buf[i++] = 0x69; memcpy(&payload[j], app->mac_buf, data_len);
buf[i++] = 0x6F; j += data_len;
buf[i++] = 0x6E;
buf[i++] = 0x2F;
buf[i++] = 0x76;
buf[i++] = 0x6E;
buf[i++] = 0x64;
buf[i++] = 0x2E;
buf[i++] = 0x62;
buf[i++] = 0x6C;
buf[i++] = 0x75;
buf[i++] = 0x65;
buf[i++] = 0x74;
buf[i++] = 0x6F;
buf[i++] = 0x6F;
buf[i++] = 0x74;
buf[i++] = 0x68;
buf[i++] = 0x2E;
buf[i++] = 0x65;
buf[i++] = 0x70;
buf[i++] = 0x2E;
buf[i++] = 0x6F;
buf[i++] = 0x6F;
buf[i++] = 0x62;
buf[i++] = 0x08;
buf[i++] = 0x00;
memcpy(&buf[i], app->mac_buf, GAP_MAC_ADDR_SIZE);
i += GAP_MAC_ADDR_SIZE;
break; break;
} }
case NfcMakerSceneHttps: { case NfcMakerSceneHttps: {
uint8_t data_len = strnlen(app->text_buf, TEXT_INPUT_LEN); tnf = 0x01; // NFC Forum well-known type [NFC RTD]
type = "\x55";
buf[i++] = 0xD1; data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
buf[i++] = 0x01; payload_len = data_len + 1;
buf[i++] = data_len + 1; payload = malloc(payload_len);
buf[i++] = 0x55;
buf[i++] = 0x04; // Prepend "https://" payload[j++] = 0x04; // Prepend "https://"
memcpy(&buf[i], app->text_buf, data_len); memcpy(&payload[j], app->text_buf, data_len);
i += data_len; j += data_len;
break; break;
} }
case NfcMakerSceneMail: { case NfcMakerSceneMail: {
uint8_t data_len = strnlen(app->text_buf, TEXT_INPUT_LEN); tnf = 0x01; // NFC Forum well-known type [NFC RTD]
type = "\x55";
buf[i++] = 0xD1; data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
buf[i++] = 0x01; payload_len = data_len + 1;
buf[i++] = data_len + 1; payload = malloc(payload_len);
buf[i++] = 0x55;
buf[i++] = 0x06; // Prepend "mailto:" payload[j++] = 0x06; // Prepend "mailto:"
memcpy(&buf[i], app->text_buf, data_len); memcpy(&payload[j], app->text_buf, data_len);
i += data_len; j += data_len;
break; break;
} }
case NfcMakerScenePhone: { case NfcMakerScenePhone: {
uint8_t data_len = strnlen(app->text_buf, TEXT_INPUT_LEN); tnf = 0x01; // NFC Forum well-known type [NFC RTD]
type = "\x55";
buf[i++] = 0xD1; data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
buf[i++] = 0x01; payload_len = data_len + 1;
buf[i++] = data_len + 1; payload = malloc(payload_len);
buf[i++] = 0x55;
buf[i++] = 0x05; // Prepend "tel:" payload[j++] = 0x05; // Prepend "tel:"
memcpy(&buf[i], app->text_buf, data_len); memcpy(&payload[j], app->text_buf, data_len);
i += data_len; j += data_len;
break; break;
} }
case NfcMakerSceneText: { case NfcMakerSceneText: {
uint8_t data_len = strnlen(app->text_buf, TEXT_INPUT_LEN); tnf = 0x01; // NFC Forum well-known type [NFC RTD]
type = "\x54";
buf[i++] = 0xD1; data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
buf[i++] = 0x01; payload_len = data_len + 3;
buf[i++] = data_len + 3; payload = malloc(payload_len);
buf[i++] = 0x54;
buf[i++] = 0x02; payload[j++] = 0x02;
buf[i++] = 0x65; // e payload[j++] = 0x65; // e
buf[i++] = 0x6E; // n payload[j++] = 0x6E; // n
memcpy(&buf[i], app->text_buf, data_len); memcpy(&payload[j], app->text_buf, data_len);
i += data_len; j += data_len;
break; break;
} }
case NfcMakerSceneUrl: { case NfcMakerSceneUrl: {
uint8_t data_len = strnlen(app->text_buf, TEXT_INPUT_LEN); tnf = 0x01; // NFC Forum well-known type [NFC RTD]
type = "\x55";
buf[i++] = 0xD1; data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
buf[i++] = 0x01; payload_len = data_len + 1;
buf[i++] = data_len + 1; payload = malloc(payload_len);
buf[i++] = 0x55;
buf[i++] = 0x00; // No prepend payload[j++] = 0x00; // No prepend
memcpy(&buf[i], app->text_buf, data_len); memcpy(&payload[j], app->text_buf, data_len);
i += data_len; j += data_len;
break; break;
} }
case NfcMakerSceneWifi: { case NfcMakerSceneWifi: {
tnf = 0x02; // Media-type [RFC 2046]
type = "application/vnd.wfa.wsc";
uint8_t ssid_len = strnlen(app->text_buf, WIFI_INPUT_LEN); uint8_t ssid_len = strnlen(app->text_buf, WIFI_INPUT_LEN);
uint8_t pass_len = strnlen(app->pass_buf, WIFI_INPUT_LEN); uint8_t pass_len = strnlen(app->pass_buf, WIFI_INPUT_LEN);
uint8_t data_len = ssid_len + pass_len; uint8_t data_len = ssid_len + pass_len;
payload_len = data_len + 39;
payload = malloc(payload_len);
buf[i++] = 0xD2; payload[j++] = 0x10;
buf[i++] = 0x17; payload[j++] = 0x0E;
buf[i++] = data_len + 47; payload[j++] = 0x00;
buf[i++] = 0x61;
buf[i++] = 0x70;
buf[i++] = 0x70; payload[j++] = data_len + 43;
buf[i++] = 0x6C; payload[j++] = 0x10;
buf[i++] = 0x69; payload[j++] = 0x26;
buf[i++] = 0x63; payload[j++] = 0x00;
buf[i++] = 0x61; payload[j++] = 0x01;
buf[i++] = 0x74; payload[j++] = 0x01;
buf[i++] = 0x69; payload[j++] = 0x10;
buf[i++] = 0x6F; payload[j++] = 0x45;
buf[i++] = 0x6E; payload[j++] = 0x00;
buf[i++] = 0x2F; payload[j++] = ssid_len;
buf[i++] = 0x76; memcpy(&payload[j], app->text_buf, ssid_len);
buf[i++] = 0x6E; j += ssid_len;
payload[j++] = 0x10;
payload[j++] = 0x03;
buf[i++] = 0x64; payload[j++] = 0x00;
buf[i++] = 0x2E; payload[j++] = 0x02;
buf[i++] = 0x77; payload[j++] = 0x00;
buf[i++] = 0x66; payload[j++] =
scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneWifiAuth);
buf[i++] = 0x61; payload[j++] = 0x10;
buf[i++] = 0x2E; payload[j++] = 0x0F;
buf[i++] = 0x77; payload[j++] = 0x00;
buf[i++] = 0x73; payload[j++] = 0x02;
buf[i++] = 0x63; payload[j++] = 0x00;
buf[i++] = 0x10; payload[j++] =
buf[i++] = 0x0E; scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneWifiEncr);
buf[i++] = 0x00; payload[j++] = 0x10;
payload[j++] = 0x27;
buf[i++] = data_len + 43; payload[j++] = 0x00;
buf[i++] = 0x10; payload[j++] = pass_len;
buf[i++] = 0x26; memcpy(&payload[j], app->pass_buf, pass_len);
buf[i++] = 0x00; j += pass_len;
payload[j++] = 0x10;
payload[j++] = 0x20;
buf[i++] = 0x01; payload[j++] = 0x00;
buf[i++] = 0x01; payload[j++] = 0x06;
buf[i++] = 0x10; payload[j++] = 0xFF;
buf[i++] = 0x45; payload[j++] = 0xFF;
buf[i++] = 0x00; payload[j++] = 0xFF;
buf[i++] = ssid_len; payload[j++] = 0xFF;
memcpy(&buf[i], app->text_buf, ssid_len); payload[j++] = 0xFF;
i += ssid_len; payload[j++] = 0xFF;
buf[i++] = 0x10;
buf[i++] = 0x03;
buf[i++] = 0x00;
buf[i++] = 0x02;
buf[i++] = 0x00;
buf[i++] = scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneWifiAuth);
buf[i++] = 0x10;
buf[i++] = 0x0F;
buf[i++] = 0x00;
buf[i++] = 0x02;
buf[i++] = 0x00;
buf[i++] = scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneWifiEncr);
buf[i++] = 0x10;
buf[i++] = 0x27;
buf[i++] = 0x00;
buf[i++] = pass_len;
memcpy(&buf[i], app->pass_buf, pass_len);
i += pass_len;
buf[i++] = 0x10;
buf[i++] = 0x20;
buf[i++] = 0x00;
buf[i++] = 0x06;
buf[i++] = 0xFF;
buf[i++] = 0xFF;
buf[i++] = 0xFF;
buf[i++] = 0xFF;
buf[i++] = 0xFF;
buf[i++] = 0xFF;
break; break;
} }
@@ -283,8 +230,51 @@ void nfc_maker_scene_result_on_enter(void* context) {
break; break;
} }
// Message length and terminator // Record header
buf[start] = i - start - 1; uint8_t flags = 0;
flags |= 1 << 7; // MB (Message Begin)
flags |= 1 << 6; // ME (Message End)
flags |= tnf; // TNF (Type Name Format)
size_t type_len = strlen(type);
size_t header_len = 0;
header_len += 1; // Flags and TNF
header_len += 1; // Type length
if(payload_len < 0xFF) {
flags |= 1 << 4; // SR (Short Record)
header_len += 1; // Payload length
} else {
header_len += 4; // Payload length
}
header_len += type_len; // Payload type
size_t record_len = header_len + payload_len;
if(record_len < 0xFF) {
buf[i++] = record_len; // Record length
} else {
buf[i++] = 0xFF; // Record length
buf[i++] = record_len >> 8; // ...
buf[i++] = record_len & 0xFF; // ...
}
buf[i++] = flags; // Flags and TNF
buf[i++] = type_len; // Type length
if(flags & 1 << 4) { // SR (Short Record)
buf[i++] = payload_len; // Payload length
} else {
buf[i++] = 0x00; // Payload length
buf[i++] = 0x00; // ...
buf[i++] = payload_len >> 8; // ...
buf[i++] = payload_len & 0xFF; // ...
}
memcpy(&buf[i], type, type_len); // Payload type
i += type_len;
// Record payload
memcpy(&buf[i], payload, payload_len);
i += payload_len;
free(payload);
// Record terminator
buf[i++] = 0xFE; buf[i++] = 0xFE;
// Padding until last 5 pages // Padding until last 5 pages