Skip to content

Commit

Permalink
feat: add NdefExternalTypeRecord
Browse files Browse the repository at this point in the history
  • Loading branch information
pmuller committed Jan 30, 2024
1 parent 67928bd commit cf09015
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 127 deletions.
1 change: 1 addition & 0 deletions src/MFRC522v2-NDEF.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "MFRC522v2-NDEF/constants.hpp"
#include "MFRC522v2-NDEF/message.hpp"
#include "MFRC522v2-NDEF/record.hpp"
#include "MFRC522v2-NDEF/record/external_type.hpp"
#include "MFRC522v2-NDEF/record/mime_media.hpp"
#include "MFRC522v2-NDEF/record/text.hpp"
#include "MFRC522v2-NDEF/record/uri.hpp"
34 changes: 0 additions & 34 deletions src/MFRC522v2-NDEF/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,40 +61,6 @@ int8_t NdefMessage::add_record(NdefRecord *record)
return NDEF_SUCCESS;
}

int8_t NdefMessage::add_external_type_record(
const char *domain,
const char *external_type,
uint8_t *payload,
uint32_t payload_length
)
{
auto record = NdefRecord::create_external_type_record(
domain,
external_type,
payload,
payload_length
);

if (record == nullptr)
{
PRINTLN(
F("NdefMessage::add_external_type_record failed to create external type record")
);
return NDEF_ERROR_EXTERNAL_TYPE_RECORD_CREATION_FAILED;
}

int8_t error = add_record(record);

if (error != NDEF_SUCCESS)
{
delete record;
PRINTLN(F("NdefMessage::add_external_type_record failed to add record"));
return error;
}

return NDEF_SUCCESS;
}

int8_t NdefMessage::add_empty_record() { return add_record(new NdefRecord()); }

uint32_t NdefMessage::get_encoded_size()
Expand Down
16 changes: 0 additions & 16 deletions src/MFRC522v2-NDEF/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,6 @@ class NdefMessage
*/
int8_t add_record(NdefRecord *record);

/**
* @brief Add an external type record to the message
*
* @param domain The domain
* @param external_type The external type
* @param payload The payload
* @param payload_length The payload length
* @return int8_t NDEF_SUCCESS or NDEF_ERROR_MALLOC_FAILED
*/
int8_t add_external_type_record(
const char *domain,
const char *external_type,
uint8_t *payload,
uint32_t payload_length
);

/**
* @brief Add an empty record to the message
*
Expand Down
54 changes: 1 addition & 53 deletions src/MFRC522v2-NDEF/record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,56 +191,4 @@ NdefRecord *NdefRecord::decode(const uint8_t &data, uint32_t data_length)
is_message_end,
*id
);
}

#define NDEF_RECORD_EXTERNAL_TYPE_PREFIX "urn:nfc:ext:"
#define NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH 12

NdefRecord *NdefRecord::create_external_type_record(
const char *domain,
const char *external_type,
uint8_t *payload,
uint32_t payload_length
)
{
if (domain == nullptr || external_type == nullptr || payload == nullptr)
return nullptr;

auto domain_length = strlen(domain);
auto external_type_length = strlen(external_type);
auto type_length = NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH + domain_length +
1 // ':' separator
+ external_type_length;

if (domain_length == 0 || external_type_length == 0 || type_length > 0xff)
return nullptr;

auto type = new uint8_t[type_length];
auto pointer = type;
if (type == nullptr)
return nullptr;

// Build type field
// 1. Add prefix
memcpy(
pointer,
NDEF_RECORD_EXTERNAL_TYPE_PREFIX,
NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH
);
pointer += NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH;
// 2. Add domain
memcpy(pointer, domain, domain_length);
pointer += domain_length;
// 3. Add ':' separator
*pointer = ':';
pointer++;
// 4. Add external type
memcpy(pointer, external_type, external_type_length);

return new NdefRecord(
TNF_EXTERNAL_TYPE,
*(new NdefRecordType(type, type_length, NdefRecordType::OwnershipUnique)),
*(new NdefRecordPayload(payload, payload_length, NdefRecordPayload::OwnershipCopy)
)
);
}
}
16 changes: 0 additions & 16 deletions src/MFRC522v2-NDEF/record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,6 @@ class NdefRecord
*/
static NdefRecord *decode(const uint8_t &data, uint32_t data_length);

/**
* @brief Create an external type NDEF record
*
* @param domain The domain
* @param external_type The type
* @param payload The payload
* @param payload_length The payload length
* @return NdefRecord* The NDEF record
*/
static NdefRecord *create_external_type_record(
const char *domain,
const char *external_type,
uint8_t *payload,
uint32_t payload_length
);

const NdefRecordType &type() const { return _type; };
const NdefRecordId &id() const { return _id; };
const NdefRecordPayload &payload() const { return _payload; };
Expand Down
173 changes: 173 additions & 0 deletions src/MFRC522v2-NDEF/record/external_type.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#include "external_type.hpp"

#define NDEF_RECORD_EXTERNAL_TYPE_PREFIX "urn:nfc:ext:"
#define NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH 12

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const uint8_t *payload,
uint32_t payload_length,
bool is_message_begin,
bool is_message_end,
const NdefRecordId &id
)
{
if (domain == nullptr || external_type == nullptr || payload == nullptr ||
payload_length == 0)
return nullptr;

auto domain_length = strlen(domain);
auto external_type_length = strlen(external_type);
auto type_length = NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH + domain_length +
1 // ':' separator
+ external_type_length;

if (domain_length == 0 || external_type_length == 0 || type_length > 0xff)
return nullptr;

auto type = new uint8_t[type_length];
auto pointer = type;
if (type == nullptr)
return nullptr;

// Build type field
// 1. Add prefix
memcpy(
pointer,
NDEF_RECORD_EXTERNAL_TYPE_PREFIX,
NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH
);
pointer += NDEF_RECORD_EXTERNAL_TYPE_PREFIX_LENGTH;
// 2. Add domain
memcpy(pointer, domain, domain_length);
pointer += domain_length;
// 3. Add ':' separator
*pointer = ':';
pointer++;
// 4. Add external type
memcpy(pointer, external_type, external_type_length);

const NdefRecordType *type_field =
new NdefRecordType(type, type_length, NdefRecordType::OwnershipUnique);
const NdefRecordPayload *payload_field =
new NdefRecordPayload(payload, payload_length, NdefRecordPayload::OwnershipCopy);

if (type_field == nullptr || payload_field == nullptr)
{
delete type_field;
delete payload_field;
delete[] type;
return nullptr;
}

return new NdefExternalTypeRecord(
*type_field,
*payload_field,
is_message_begin,
is_message_end,
id
);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const uint8_t *payload,
uint32_t payload_length,
bool is_message_begin,
bool is_message_end
)
{
auto id = new NdefRecordId();

if (id == nullptr)
return nullptr;

return create(
domain,
external_type,
payload,
payload_length,
is_message_begin,
is_message_end,
*id
);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const uint8_t *payload,
uint32_t payload_length,
const NdefRecordId &id
)
{
return create(domain, external_type, payload, payload_length, false, false, id);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const uint8_t *payload,
uint32_t payload_length
)
{
return create(domain, external_type, payload, payload_length, false, false);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const char *payload,
bool is_message_begin,
bool is_message_end,
const NdefRecordId &id
)
{
if (domain == nullptr || external_type == nullptr || payload == nullptr)
return nullptr;

return create(
domain,
external_type,
reinterpret_cast<const uint8_t *>(payload),
strlen(payload),
is_message_begin,
is_message_end,
id
);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const char *payload,
bool is_message_begin,
bool is_message_end
)
{
auto id = new NdefRecordId();

if (id == nullptr)
return nullptr;

return create(domain, external_type, payload, is_message_begin, is_message_end, *id);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain,
const char *external_type,
const char *payload,
const NdefRecordId &id
)
{
return create(domain, external_type, payload, false, false, id);
}

NdefExternalTypeRecord *NdefExternalTypeRecord::create(
const char *domain, const char *external_type, const char *payload
)
{
return create(domain, external_type, payload, false, false);
}
Loading

0 comments on commit cf09015

Please sign in to comment.