+static bool _net_nfc_util_init_data(data_s * data, uint32_t length)
+{
+ if (data == NULL || length == 0)
+ return false;
+
+ _nfc_emul_util_alloc_mem(data->buffer, length);
+ if (data->buffer == NULL)
+ return false;
+
+ data->length = length;
+
+ return true;
+}
+
+static void _net_nfc_util_clear_data(data_s * data)
+{
+ if (data == NULL)
+ return;
+
+ if (data->buffer != NULL) {
+ _nfc_emul_util_free_mem(data->buffer);
+ data->buffer = NULL;
+ }
+
+ data->length = 0;
+}
+
+static net_nfc_error_e _net_nfc_util_free_record(ndef_record_s * record)
+{
+ if (record == NULL)
+ return NET_NFC_NULL_PARAMETER;
+
+ _net_nfc_util_clear_data(&record->type_s);
+ _net_nfc_util_clear_data(&record->id_s);
+ _net_nfc_util_clear_data(&record->payload_s);
+
+ _nfc_emul_util_free_mem(record);
+
+ return NET_NFC_OK;
+}
+
+static net_nfc_error_e _net_nfc_util_free_ndef_message(ndef_message_s * msg)
+{
+ int idx = 0;
+ ndef_record_s *prev, *current;
+
+ if (msg == NULL)
+ return NET_NFC_NULL_PARAMETER;
+
+ current = msg->records;
+
+ for (idx = 0; idx < msg->recordCount; idx++) {
+ if (current == NULL)
+ break;
+
+ prev = current;
+ current = current->next;
+
+ _net_nfc_util_free_record(prev);
+ }
+
+ _nfc_emul_util_free_mem(msg);
+
+ return NET_NFC_OK;
+}
+
+static net_nfc_error_e _net_nfc_util_create_record(net_nfc_record_tnf_e recordType, data_s * typeName, data_s * id, data_s * payload, ndef_record_s ** record)
+{
+ ndef_record_s *record_temp = NULL;
+
+ if (record == NULL)
+ return NET_NFC_NULL_PARAMETER;
+
+ if (recordType < NET_NFC_RECORD_EMPTY || recordType > NET_NFC_RECORD_UNCHAGNED)
+ return NET_NFC_OUT_OF_BOUND;
+
+ /* empty_tag */
+ if (recordType == NET_NFC_RECORD_EMPTY) {
+ if ((typeName != NULL && typeName->length > 0) || (payload != NULL && payload->length > 0) || (id != NULL && id->length > 0))
+ return NET_NFC_INVALID_PARAM;
+ } else {
+ if (typeName == NULL || typeName->buffer == NULL || typeName->length == 0)
+ return NET_NFC_INVALID_PARAM;
+ }
+
+ _nfc_emul_util_alloc_mem(record_temp, sizeof(ndef_record_s));
+ if (record_temp == NULL)
+ return NET_NFC_ALLOC_FAIL;
+ // set type name and length and TNF field
+ record_temp->TNF = recordType;
+
+ if (typeName != NULL && typeName->length > 0) {
+ if (_net_nfc_util_init_data(&record_temp->type_s, typeName->length) == false) {
+ _nfc_emul_util_free_mem(record_temp);
+
+ return NET_NFC_ALLOC_FAIL;
+ }
+
+ memcpy(record_temp->type_s.buffer, typeName->buffer, record_temp->type_s.length);
+ } else {
+ record_temp->type_s.buffer = NULL;
+ record_temp->type_s.length = 0;
+ }
+
+ record_temp->SR = 1;
+
+ // set payload
+ if (payload != NULL && payload->length > 0) {
+ if (_net_nfc_util_init_data(&record_temp->payload_s, payload->length) == false) {
+ _net_nfc_util_clear_data(&record_temp->type_s);
+ _nfc_emul_util_free_mem(record_temp);
+
+ return NET_NFC_ALLOC_FAIL;
+ }
+
+ memcpy(record_temp->payload_s.buffer, payload->buffer, record_temp->payload_s.length);
+
+ if (payload->length > 255)
+ record_temp->SR = 0;
+ } else {
+ record_temp->payload_s.buffer = NULL;
+ record_temp->payload_s.length = 0;
+ }
+
+ // set id and id length and IL field
+ if (id != NULL && id->buffer != NULL && id->length > 0) {
+ if (_net_nfc_util_init_data(&record_temp->id_s, id->length) == false) {
+ _net_nfc_util_clear_data(&record_temp->payload_s);
+ _net_nfc_util_clear_data(&record_temp->type_s);
+ _nfc_emul_util_free_mem(record_temp);
+
+ return NET_NFC_ALLOC_FAIL;
+ }
+
+ memcpy(record_temp->id_s.buffer, id->buffer, record_temp->id_s.length);
+ record_temp->IL = 1;
+ } else {
+ record_temp->IL = 0;
+ record_temp->id_s.buffer = NULL;
+ record_temp->id_s.length = 0;
+ }
+
+ // this is default value
+ record_temp->MB = 1;
+ record_temp->ME = 1;
+
+ record_temp->next = NULL;
+
+ *record = record_temp;
+
+ return NET_NFC_OK;
+}
+
+static net_nfc_error_e _net_nfc_util_append_record(ndef_message_s * msg, ndef_record_s * record)
+{
+ if (msg == NULL || record == NULL)
+ return NET_NFC_NULL_PARAMETER;
+
+ if (msg->recordCount == 0) {
+ // set short message and append
+ record->MB = 1;
+ record->ME = 1;
+ record->next = NULL;
+
+ msg->records = record;
+
+ msg->recordCount++;
+
+ DEBUG_MSG("record is added to NDEF message :: count [%d]", msg->recordCount);
+ } else {
+ ndef_record_s *current = NULL;
+ ndef_record_s *prev = NULL;
+
+ // set flag :: this record is FIRST
+ current = msg->records;
+
+ if (current != NULL) {
+ // first node
+ current->MB = 1;
+ current->ME = 0;
+
+ prev = current;
+
+ // second node
+ current = current->next;
+
+ while (current != NULL) {
+ current->MB = 0;
+ current->ME = 0;
+ prev = current;
+ current = current->next;
+ }
+
+ // set flag :: this record is END
+ record->MB = 0;
+ record->ME = 1;
+
+ prev->next = record;
+ msg->recordCount++;
+ }
+ }
+
+ return NET_NFC_OK;
+}
+
+static uint32_t _net_nfc_util_get_record_length(ndef_record_s * Record)
+{
+ uint32_t RecordLength = 1;
+
+ if (Record == NULL)
+ return 0;
+
+ /* Type length is present only for following TNF
+ NET_NFC_TNF_NFCWELLKNOWN
+ NET_NFC_TNF_MEDIATYPE
+ SLP_FRINET_NFC_NDEFRECORD_TNF_ABSURI
+ SLP_FRINET_NFC_NDEFRECORD_TNF_NFCEXT
+ */
+
+ /* ++ is for the Type Length Byte */
+ RecordLength++;
+ if (Record->TNF != EMUL_NDEF_TNF_EMPTY && Record->TNF != EMUL_NDEF_TNF_UNKNOWN && Record->TNF != EMUL_NDEF_TNF_UNCHANGED)
+ RecordLength += Record->type_s.length;
+
+ /* to check if payloadlength is 8bit or 32bit */
+ if (Record->SR != 0) {
+ /* ++ is for the Payload Length Byte */
+ RecordLength++; /* for short record */
+ } else {
+ /* + NET_NFC_NDEF_NORMAL_RECORD_BYTE is for the Payload Length Byte */
+ RecordLength += 4;
+ }
+
+ /* for non empty record */
+ if (Record->TNF != EMUL_NDEF_TNF_EMPTY)
+ RecordLength += Record->payload_s.length;
+
+ /* ID and IDlength are present only if IL flag is set */
+ if (Record->IL != 0) {
+ RecordLength += Record->id_s.length;
+ /* ++ is for the ID Length Byte */
+ RecordLength++;
+ }
+
+ return RecordLength;
+}
+
+static uint32_t _net_nfc_util_get_ndef_message_length(ndef_message_s * message)
+{
+ ndef_record_s *current;
+ int total = 0;
+
+ if (message == NULL)
+ return 0;
+
+ current = message->records;
+
+ while (current != NULL) {
+ total += _net_nfc_util_get_record_length(current);
+ current = current->next;
+ }
+
+ return total;
+}
+
+static net_nfc_error_e _net_nfc_util_create_ndef_message(ndef_message_s ** ndef_message)
+{
+ if (ndef_message == NULL)
+ return NET_NFC_NULL_PARAMETER;
+
+ _nfc_emul_util_alloc_mem(*ndef_message, sizeof(ndef_message_s));
+ if (*ndef_message == NULL)
+ return NET_NFC_ALLOC_FAIL;
+
+ return NET_NFC_OK;
+}
+
+static net_nfc_error_e _net_nfc_util_convert_ndef_message_to_rawdata(ndef_message_s * ndef, data_s * rawdata)
+{
+ ndef_record_s *record = NULL;
+ uint8_t *current = NULL;
+ uint8_t ndef_header;
+
+ if (rawdata == NULL || ndef == NULL)
+ return NET_NFC_NULL_PARAMETER;
+
+ record = ndef->records;
+ current = rawdata->buffer;
+
+ while (record) {
+ ndef_header = 0x00;
+
+ if (record->MB)
+ ndef_header |= NET_NFC_NDEF_RECORD_MASK_MB;
+ if (record->ME)
+ ndef_header |= NET_NFC_NDEF_RECORD_MASK_ME;
+ if (record->CF)
+ ndef_header |= NET_NFC_NDEF_RECORD_MASK_CF;
+ if (record->SR)
+ ndef_header |= NET_NFC_NDEF_RECORD_MASK_SR;
+ if (record->IL)
+ ndef_header |= NET_NFC_NDEF_RECORD_MASK_IL;
+
+ ndef_header |= record->TNF;
+
+ *current++ = ndef_header;
+
+ /* check empty record */
+ if (record->TNF == EMUL_NDEF_TNF_EMPTY) {
+ /* set type length to zero */
+ *current++ = 0x00;
+
+ /* set payload length to zero */
+ *current++ = 0x00;
+
+ /* set ID length to zero */
+ if (record->IL)
+ *current++ = 0x00;
+
+ record = record->next;
+
+ continue;
+ }
+
+
+ /* set type length */
+ if (record->TNF == EMUL_NDEF_TNF_UNKNOWN || record->TNF == EMUL_NDEF_TNF_UNCHANGED)
+ *current++ = 0x00;
+ else
+ *current++ = record->type_s.length;
+
+ /* set payload length */
+ if (record->SR) {
+ *current++ = (uint8_t) (record->payload_s.length & 0x000000FF);
+ } else {
+ *current++ = (uint8_t) ((record->payload_s.length & 0xFF000000) >> 24);
+ *current++ = (uint8_t) ((record->payload_s.length & 0x00FF0000) >> 16);
+ *current++ = (uint8_t) ((record->payload_s.length & 0x0000FF00) >> 8);
+ *current++ = (uint8_t) (record->payload_s.length & 0x000000FF);
+ }
+
+ /* set ID length */
+ if (record->IL)
+ *current++ = record->id_s.length;
+
+ /* set type buffer */
+ if ((record->TNF != EMUL_NDEF_TNF_UNKNOWN) && (record->TNF != EMUL_NDEF_TNF_UNCHANGED)) {
+ memcpy(current, record->type_s.buffer, record->type_s.length);
+ current += record->type_s.length;
+ }
+
+ /* set ID buffer */
+ memcpy(current, record->id_s.buffer, record->id_s.length);
+ current += record->id_s.length;
+
+ /* set payload buffer */
+ memcpy(current, record->payload_s.buffer, record->payload_s.length);
+ current += record->payload_s.length;
+
+ record = record->next;
+ }
+
+ return NET_NFC_OK;
+}
+