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++] = 0x00; // Lock bytes
buf[i++] = 0x00; // ...
buf[i++] = 0xE1; // Capability container
buf[i++] = 0x10; // ...
buf[i++] = 0x3E; // ...
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)) {
case NfcMakerSceneBluetooth: {
buf[i++] = 0xD2;
buf[i++] = 0x20;
buf[i++] = 0x08;
buf[i++] = 0x61;
buf[i++] = 0x70;
tnf = 0x02; // Media-type [RFC 2046]
type = "application/vnd.bluetooth.ep.oob";
buf[i++] = 0x70;
buf[i++] = 0x6C;
buf[i++] = 0x69;
buf[i++] = 0x63;
data_len = GAP_MAC_ADDR_SIZE;
payload_len = data_len + 2;
payload = malloc(payload_len);
buf[i++] = 0x61;
buf[i++] = 0x74;
buf[i++] = 0x69;
buf[i++] = 0x6F;
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;
payload[j++] = 0x08;
payload[j++] = 0x00;
memcpy(&payload[j], app->mac_buf, data_len);
j += data_len;
break;
}
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;
buf[i++] = 0x01;
buf[i++] = data_len + 1;
buf[i++] = 0x55;
data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
payload_len = data_len + 1;
payload = malloc(payload_len);
buf[i++] = 0x04; // Prepend "https://"
memcpy(&buf[i], app->text_buf, data_len);
i += data_len;
payload[j++] = 0x04; // Prepend "https://"
memcpy(&payload[j], app->text_buf, data_len);
j += data_len;
break;
}
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;
buf[i++] = 0x01;
buf[i++] = data_len + 1;
buf[i++] = 0x55;
data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
payload_len = data_len + 1;
payload = malloc(payload_len);
buf[i++] = 0x06; // Prepend "mailto:"
memcpy(&buf[i], app->text_buf, data_len);
i += data_len;
payload[j++] = 0x06; // Prepend "mailto:"
memcpy(&payload[j], app->text_buf, data_len);
j += data_len;
break;
}
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;
buf[i++] = 0x01;
buf[i++] = data_len + 1;
buf[i++] = 0x55;
data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
payload_len = data_len + 1;
payload = malloc(payload_len);
buf[i++] = 0x05; // Prepend "tel:"
memcpy(&buf[i], app->text_buf, data_len);
i += data_len;
payload[j++] = 0x05; // Prepend "tel:"
memcpy(&payload[j], app->text_buf, data_len);
j += data_len;
break;
}
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;
buf[i++] = 0x01;
buf[i++] = data_len + 3;
buf[i++] = 0x54;
data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
payload_len = data_len + 3;
payload = malloc(payload_len);
buf[i++] = 0x02;
buf[i++] = 0x65; // e
buf[i++] = 0x6E; // n
memcpy(&buf[i], app->text_buf, data_len);
i += data_len;
payload[j++] = 0x02;
payload[j++] = 0x65; // e
payload[j++] = 0x6E; // n
memcpy(&payload[j], app->text_buf, data_len);
j += data_len;
break;
}
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;
buf[i++] = 0x01;
buf[i++] = data_len + 1;
buf[i++] = 0x55;
data_len = strnlen(app->text_buf, TEXT_INPUT_LEN);
payload_len = data_len + 1;
payload = malloc(payload_len);
buf[i++] = 0x00; // No prepend
memcpy(&buf[i], app->text_buf, data_len);
i += data_len;
payload[j++] = 0x00; // No prepend
memcpy(&payload[j], app->text_buf, data_len);
j += data_len;
break;
}
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 pass_len = strnlen(app->pass_buf, WIFI_INPUT_LEN);
uint8_t data_len = ssid_len + pass_len;
payload_len = data_len + 39;
payload = malloc(payload_len);
buf[i++] = 0xD2;
buf[i++] = 0x17;
buf[i++] = data_len + 47;
buf[i++] = 0x61;
buf[i++] = 0x70;
payload[j++] = 0x10;
payload[j++] = 0x0E;
payload[j++] = 0x00;
buf[i++] = 0x70;
buf[i++] = 0x6C;
buf[i++] = 0x69;
buf[i++] = 0x63;
payload[j++] = data_len + 43;
payload[j++] = 0x10;
payload[j++] = 0x26;
payload[j++] = 0x00;
buf[i++] = 0x61;
buf[i++] = 0x74;
buf[i++] = 0x69;
buf[i++] = 0x6F;
payload[j++] = 0x01;
payload[j++] = 0x01;
payload[j++] = 0x10;
payload[j++] = 0x45;
buf[i++] = 0x6E;
buf[i++] = 0x2F;
buf[i++] = 0x76;
buf[i++] = 0x6E;
payload[j++] = 0x00;
payload[j++] = ssid_len;
memcpy(&payload[j], app->text_buf, ssid_len);
j += ssid_len;
payload[j++] = 0x10;
payload[j++] = 0x03;
buf[i++] = 0x64;
buf[i++] = 0x2E;
buf[i++] = 0x77;
buf[i++] = 0x66;
payload[j++] = 0x00;
payload[j++] = 0x02;
payload[j++] = 0x00;
payload[j++] =
scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneWifiAuth);
buf[i++] = 0x61;
buf[i++] = 0x2E;
buf[i++] = 0x77;
buf[i++] = 0x73;
payload[j++] = 0x10;
payload[j++] = 0x0F;
payload[j++] = 0x00;
payload[j++] = 0x02;
buf[i++] = 0x63;
buf[i++] = 0x10;
buf[i++] = 0x0E;
buf[i++] = 0x00;
payload[j++] = 0x00;
payload[j++] =
scene_manager_get_scene_state(app->scene_manager, NfcMakerSceneWifiEncr);
payload[j++] = 0x10;
payload[j++] = 0x27;
buf[i++] = data_len + 43;
buf[i++] = 0x10;
buf[i++] = 0x26;
buf[i++] = 0x00;
payload[j++] = 0x00;
payload[j++] = pass_len;
memcpy(&payload[j], app->pass_buf, pass_len);
j += pass_len;
payload[j++] = 0x10;
payload[j++] = 0x20;
buf[i++] = 0x01;
buf[i++] = 0x01;
buf[i++] = 0x10;
buf[i++] = 0x45;
payload[j++] = 0x00;
payload[j++] = 0x06;
payload[j++] = 0xFF;
payload[j++] = 0xFF;
buf[i++] = 0x00;
buf[i++] = ssid_len;
memcpy(&buf[i], app->text_buf, ssid_len);
i += ssid_len;
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;
payload[j++] = 0xFF;
payload[j++] = 0xFF;
payload[j++] = 0xFF;
payload[j++] = 0xFF;
break;
}
@@ -283,8 +230,51 @@ void nfc_maker_scene_result_on_enter(void* context) {
break;
}
// Message length and terminator
buf[start] = i - start - 1;
// Record header
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;
// Padding until last 5 pages