From d5201f00e4ee16297168c982cdb7bbc840160ec3 Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Tue, 14 Aug 2018 11:41:29 +0100 Subject: [PATCH] Add basis for NFC Controller implementation --- features/nfc/controllers/PN512Driver.h | 4 +- features/nfc/nfc/NFCController.h | 16 ++ features/nfc/nfc/NFCControllerDriver.h | 4 +- features/nfc/source/controllers/PN512Driver.c | 0 features/nfc/source/nfc/NFCController.cpp | 151 ++++++++++++++++++ features/nfc/stack/transceiver/transceiver.h | 1 - 6 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 features/nfc/source/controllers/PN512Driver.c create mode 100644 features/nfc/source/nfc/NFCController.cpp diff --git a/features/nfc/controllers/PN512Driver.h b/features/nfc/controllers/PN512Driver.h index 23454a414a..216b8cfe5b 100644 --- a/features/nfc/controllers/PN512Driver.h +++ b/features/nfc/controllers/PN512Driver.h @@ -30,8 +30,8 @@ namespace nfc { PN512Driver(PN512TransportDriver* transport_driver); private: - virtual void initialize(scheduler_timer_t* pTimer) = 0; - virtual transceiver_t* get_transceiver() const; + virtual void initialize(nfc_scheduler_timer_t* pTimer) = 0; + virtual nfc_transceiver_t* get_transceiver() const; pn512_t _pn512; }; diff --git a/features/nfc/nfc/NFCController.h b/features/nfc/nfc/NFCController.h index 8cafebd275..7b0fbc95f2 100644 --- a/features/nfc/nfc/NFCController.h +++ b/features/nfc/nfc/NFCController.h @@ -88,6 +88,13 @@ namespace nfc { */ NFCController(NFCControllerDriver* driver, events::EventQueue* queue); + /** + * Initialize the NFC controller + * + * This method must be called before any other method call. + */ + void initialize(); + /** * Set the delegate that will receive events generated by this controller. * @@ -130,8 +137,17 @@ namespace nfc { nfc_err_t cancel_discovery(); private: + void polling_callback(nfc_err_t ret); + + // Callbacks from NFC stack + static void s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData); + NFCControllerDriver* _driver; + events::EventQueue* _queue; + nfc_transceiver_t* _transceiver; + Timer _timer; Delegate* _delegate; + bool _discovery_running; }; /** diff --git a/features/nfc/nfc/NFCControllerDriver.h b/features/nfc/nfc/NFCControllerDriver.h index 9629e32364..27e64b1dda 100644 --- a/features/nfc/nfc/NFCControllerDriver.h +++ b/features/nfc/nfc/NFCControllerDriver.h @@ -41,9 +41,9 @@ namespace nfc { * Initialize the driver and retrieve the interface to the controller. * * @param[in] pTimer The MicroNFC timer instance for the scheduler to use - * @return an initialized MicroNFC transceiver_t instance + * @return an initialized MicroNFC nfc_transceiver_t instance */ - virtual transceiver_t* initialize(scheduler_timer_t* timer) = 0; + virtual nfc_transceiver_t* initialize(nfc_scheduler_timer_t* timer) = 0; /** * Retrieve list of technologies supported by the controller diff --git a/features/nfc/source/controllers/PN512Driver.c b/features/nfc/source/controllers/PN512Driver.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/features/nfc/source/nfc/NFCController.cpp b/features/nfc/source/nfc/NFCController.cpp new file mode 100644 index 0000000000..5d3d9a78f1 --- /dev/null +++ b/features/nfc/source/nfc/NFCController.cpp @@ -0,0 +1,151 @@ +/* mbed Microcontroller Library + * Copyright (c) 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 "NFCController.h" +#include "NFCControllerDriver.h" + +#include "stack/transceiver/transceiver.h" + +using namespace mbed; +using namespace mbed::nfc; + +NFCController::NFCController(NFCControllerDriver* driver, events::EventQueue* queue) : + _driver(driver), _queue(queue), _transceiver(NULL), _delegate(NULL), _discovery_running(false) +{ + +} + +void NFCController::initialize() +{ + MBED_ASSERT(_transceiver == NULL); // Initialize should only be called once + _transceiver = _driver->initialize((nfc_scheduler_timer_t*)&_timer); +} + +void NFCController::set_delegate(Delegate* delegate) +{ + _delegate = delegate; +} + +nfc_rf_protocols_bitmask_t NFCController::get_supported_rf_protocols() const +{ + // nfc_rf_protocols_bitmask_t is mapped on NFC Forum types, nfc_tech_t is mapped on the underlying RF techs + // We therefore need to convert these + + nfc_rf_protocols_bitmask_t rf_protocols = {0}; + nfc_tech_t initiator_tech; + nfc_tech_t target_tech; + _driver->get_supported_nfc_techs(&initiator_tech, &target_tech); + + // Note: we only support ISO-DEP tag emulation in this release, + // so mask out all other protocols + + // rf_protocols.initiator_t1t = initiator_tech.nfc_type1; + // rf_protocols.initiator_t2t = initiator_tech.nfc_type2; + // rf_protocols.initiator_t3t = initiator_tech.nfc_type3; + // rf_protocols.initiator_iso_dep = initiator_tech.nfc_iso_dep_a || initiator_tech.nfc_iso_dep_b; + // rf_protocols.initiator_nfc_dep = initiator_tech.nfc_nfc_dep_a || initiator_tech.nfc_nfc_dep_f_212 || initiator_tech.nfc_nfc_dep_f_424; + + // rf_protocols.target_t1t = target_tech.nfc_type1; + // rf_protocols.target_t2t = target_tech.nfc_type2; + // rf_protocols.target_t3t = target_tech.nfc_type3; + rf_protocols.target_iso_dep = target_tech.nfc_iso_dep_a || target_tech.nfc_iso_dep_b; + // rf_protocols.target_nfc_dep = target_tech.nfc_nfc_dep_a || target_tech.nfc_nfc_dep_f_212 || target_tech.nfc_nfc_dep_f_424; + + return rf_protocols; +} + +nfc_err_t NFCController::configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_protocols) +{ + if( _discovery_running ) { + // Cannot configure RF protocols if discovery is running + return NFC_ERR_BUSY; + } + + // Map to NFC techs + nfc_tech_t initiator_tech = {0}; + nfc_tech_t target_tech = {0}; + + // Note: we only support ISO-DEP tag emulation in this release, + // so mask out all other protocols + + target_tech.nfc_iso_dep_a = target_tech.nfc_iso_dep_b = true; + + // Configure polling options (no need to set bailing flags as we're only using target mode) + polling_options_t options = {0}; + + transceiver_set_protocols(_transceiver, initiator_tech, target_tech, options); +} + +nfc_err_t NFCController::start_discovery() +{ + if( _discovery_running ) { + // Cannot start discovery if it's already running + return NFC_ERR_BUSY; + } + + transceiver_poll(_transceiver, &NFCController::s_polling_callback, this /* use this as callback argument */); +} + +nfc_err_t NFCController::cancel_discovery() +{ + if( !_discovery_running ) { + return NFC_OK; + } + + transceiver_abort(_transceiver); +} + +void NFCController::polling_callback(nfc_err_t ret) +{ + // Polling has completed + _discovery_running = false; + + if( ret == NFC_OK ) { + // Check if a remote initiator was detected and if so, instantiate it + if( !transceiver_is_initiator_mode(_transceiver) ) { + nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver); + if( active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b ) { + SharedPtr ptr = + } + } + } + + if(_delegate != NULL) { + nfc_discovery_terminated_reason_t reason; + + // Map reason + switch(ret) { + case NFC_OK: + reason = nfc_discovery_terminated_completed; + break; + case NFC_ERR_ABORTED: + reason = nfc_discovery_terminated_canceled; + break; + default: + // Any other error code means there was an error during the discovery process + reason = nfc_discovery_terminated_rf_error; + break; + } + + _delegate->on_discovery_terminated(reason); + } +} + +static void NFCController::s_polling_callback(nfc_transceiver_t* pTransceiver, nfc_err_t ret, void* pUserData) +{ + NFCController* self = (NFCController*) pUserData; + self->polling_callback(ret); +} \ No newline at end of file diff --git a/features/nfc/stack/transceiver/transceiver.h b/features/nfc/stack/transceiver/transceiver.h index 70660b625b..3884d34acf 100644 --- a/features/nfc/stack/transceiver/transceiver.h +++ b/features/nfc/stack/transceiver/transceiver.h @@ -63,7 +63,6 @@ typedef struct __nfc_tech unsigned int nfc_nfc_dep_f_424 : 1; } nfc_tech_t; - typedef struct __polling_options polling_options_t; struct __polling_options {