Demonstration of possible usage of the NFC EEPROM class (including support for ST25DV NFC chip)

Dependencies:   eeprom_driver

Revision:
0:86f202e07059
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/target/NfcControllerToEEPROMAdapter.cpp	Mon Sep 24 17:09:39 2018 +0100
@@ -0,0 +1,203 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "NfcControllerToEEPROMAdapter.h"
+
+#include <algorithm>
+
+#include "nfc/NFCController.h"
+#include "nfc/NFCEEPROMDriver.h"
+#include "nfc/NFCRemoteInitiator.h"
+
+namespace mbed {
+namespace nfc {
+
+ControllerToEEPROMDriverAdapter::ControllerToEEPROMDriverAdapter(
+    NFCController &controller,
+    const Span<uint8_t> &buffer
+) :
+    _nfc_controller(controller),
+    _eeprom_buffer(buffer),
+    _current_eeprom_size(buffer.size()),
+    _session_opened(false)
+{
+}
+
+ControllerToEEPROMDriverAdapter::~ControllerToEEPROMDriverAdapter()
+{
+    if (_nfc_remote_initiator.get()) {
+        _nfc_remote_initiator->set_delegate(NULL);
+    }
+    _nfc_controller.set_delegate(NULL);
+    _nfc_controller.cancel_discovery();
+}
+
+void ControllerToEEPROMDriverAdapter::reset()
+{
+    _current_eeprom_size = _eeprom_buffer.size();
+    memset(_eeprom_buffer.data(), 0, _eeprom_buffer.size());
+
+    if (_nfc_remote_initiator.get()) {
+        _nfc_remote_initiator->set_delegate(NULL);
+        _nfc_remote_initiator.reset();
+    }
+
+    _nfc_controller.initialize();
+    _nfc_controller.set_delegate(this);
+
+    nfc_rf_protocols_bitmask_t protocols = { 0 };
+    protocols.target_iso_dep = 1;
+    _nfc_controller.configure_rf_protocols(protocols);
+
+    _nfc_controller.start_discovery();
+}
+
+size_t ControllerToEEPROMDriverAdapter::read_max_size()
+{
+    return _eeprom_buffer.size();
+}
+
+void ControllerToEEPROMDriverAdapter::start_session(bool force)
+{
+    _session_opened = true;
+    delegate()->on_session_started(true);
+}
+
+void ControllerToEEPROMDriverAdapter::end_session()
+{
+    _session_opened = false;
+    delegate()->on_session_ended(true);
+}
+
+void ControllerToEEPROMDriverAdapter::read_bytes(
+    uint32_t address, uint8_t *bytes, size_t count
+) {
+    if (address >= _current_eeprom_size) {
+        delegate()->on_bytes_read(0);
+        return;
+    }
+
+    size_t size = std::min(count, (size_t) (_current_eeprom_size - address));
+    memcpy(bytes, _eeprom_buffer.data() + address, size);
+    delegate()->on_bytes_read(size);
+}
+
+void ControllerToEEPROMDriverAdapter::write_bytes(
+    uint32_t address, const uint8_t *bytes, size_t count
+) {
+    if (address >= _current_eeprom_size) {
+        delegate()->on_bytes_written(0);
+        return;
+    }
+
+    size_t size = std::min(count, (size_t) (_current_eeprom_size - address));
+    memcpy(_eeprom_buffer.data() + address, bytes, size);
+    delegate()->on_bytes_written(size);
+}
+
+void ControllerToEEPROMDriverAdapter::read_size()
+{
+    delegate()->on_size_read(true, _current_eeprom_size);
+}
+
+void ControllerToEEPROMDriverAdapter::write_size(size_t count)
+{
+    if (count > (size_t) _eeprom_buffer.size()) {
+        delegate()->on_size_written(false);
+    } else {
+        _current_eeprom_size = count;
+        delegate()->on_size_written(true);
+    }
+}
+
+void ControllerToEEPROMDriverAdapter::erase_bytes(uint32_t address, size_t count)
+{
+    if (address >= _current_eeprom_size) {
+        delegate()->on_bytes_erased(0);
+        return;
+    }
+
+    size_t size = std::min(count, (size_t) (_current_eeprom_size - address));
+    memset(_eeprom_buffer.data() + address, 0, size);
+    delegate()->on_bytes_erased(size);
+}
+
+/* ------------------------------------------------------------------------
+ * Implementation of NFCRemoteInitiator::Delegate
+ */
+void ControllerToEEPROMDriverAdapter::on_connected() { }
+
+void ControllerToEEPROMDriverAdapter::on_disconnected()
+{
+    // reset the state of the remote initiator
+    _nfc_remote_initiator->set_delegate(NULL);
+    _nfc_remote_initiator.reset();
+
+    // restart peer discovery
+    _nfc_controller.start_discovery();
+}
+
+void ControllerToEEPROMDriverAdapter::parse_ndef_message(const Span<const uint8_t> &buffer)
+{
+    if (_session_opened) {
+        return;
+    }
+
+    if (buffer.size() > _eeprom_buffer.size()) {
+        return;
+    }
+
+    _current_eeprom_size = buffer.size();
+    memcpy(_eeprom_buffer.data(), buffer.data(), _current_eeprom_size);
+}
+
+size_t ControllerToEEPROMDriverAdapter::build_ndef_message(const Span<uint8_t> &buffer)
+{
+    if (_session_opened) {
+        return 0;
+    }
+
+    if ((size_t) buffer.size() < _current_eeprom_size) {
+        return 0;
+    }
+
+    memcpy(buffer.data(), _eeprom_buffer.data(), _current_eeprom_size);
+    return _current_eeprom_size;
+}
+
+/* ------------------------------------------------------------------------
+ * Implementation of NFCController::Delegate
+ */
+void ControllerToEEPROMDriverAdapter::on_discovery_terminated(
+    nfc_discovery_terminated_reason_t reason
+) {
+    if(reason != nfc_discovery_terminated_completed) {
+        _nfc_controller.start_discovery();
+    }
+}
+
+void ControllerToEEPROMDriverAdapter::on_nfc_initiator_discovered(
+    const SharedPtr<NFCRemoteInitiator> &nfc_initiator
+) {
+    // setup the local remote initiator
+    _nfc_remote_initiator = nfc_initiator;
+    _nfc_remote_initiator->set_delegate(this);
+    _nfc_remote_initiator->connect();
+}
+
+}  // namespace nfc
+}  // namespace mbed
+