Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
NFCController.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "NFCController.h" 00018 #include "NFCControllerDriver.h" 00019 #include "Type4RemoteInitiator.h" 00020 00021 #include "stack/transceiver/transceiver.h" 00022 00023 using namespace mbed; 00024 using namespace mbed::nfc; 00025 00026 NFCController::NFCController(NFCControllerDriver *driver, events::EventQueue *queue, const Span<uint8_t> &ndef_buffer) : 00027 _driver(driver), _queue(queue), _transceiver(NULL), _scheduler(NULL), _delegate(NULL), _discovery_running(false), _ndef_buffer(ndef_buffer) 00028 { 00029 _driver->set_delegate(this); 00030 } 00031 00032 nfc_err_t NFCController::initialize() 00033 { 00034 MBED_ASSERT(_transceiver == NULL); // Initialize should only be called once 00035 _transceiver = _driver->initialize((nfc_scheduler_timer_t *)&_timer); // See implementation below 00036 00037 if (_transceiver == NULL) { 00038 // Initialization error 00039 return NFC_ERR_CONTROLLER; // Controller error 00040 } 00041 00042 // Recover scheduler 00043 _scheduler = transceiver_get_scheduler(_transceiver); 00044 00045 // Run scheduler for the first time 00046 _queue->call(this, &NFCController::scheduler_process, false); 00047 00048 return NFC_OK; 00049 } 00050 00051 void NFCController::set_delegate(Delegate *delegate) 00052 { 00053 _delegate = delegate; 00054 } 00055 00056 nfc_rf_protocols_bitmask_t NFCController::get_supported_rf_protocols() const 00057 { 00058 // nfc_rf_protocols_bitmask_t is mapped on NFC Forum types, nfc_tech_t is mapped on the underlying RF techs 00059 // We therefore need to convert these 00060 00061 nfc_rf_protocols_bitmask_t rf_protocols = {0}; 00062 nfc_tech_t initiator_tech; 00063 nfc_tech_t target_tech; 00064 _driver->get_supported_nfc_techs(&initiator_tech, &target_tech); 00065 00066 // Note: we only support ISO-DEP tag emulation in this release, 00067 // so mask out all other protocols 00068 00069 // rf_protocols.initiator_t1t = initiator_tech.nfc_type1; 00070 // rf_protocols.initiator_t2t = initiator_tech.nfc_type2; 00071 // rf_protocols.initiator_t3t = initiator_tech.nfc_type3; 00072 // rf_protocols.initiator_iso_dep = initiator_tech.nfc_iso_dep_a || initiator_tech.nfc_iso_dep_b; 00073 // 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; 00074 00075 // rf_protocols.target_t1t = target_tech.nfc_type1; 00076 // rf_protocols.target_t2t = target_tech.nfc_type2; 00077 // rf_protocols.target_t3t = target_tech.nfc_type3; 00078 rf_protocols.target_iso_dep = target_tech.nfc_iso_dep_a || target_tech.nfc_iso_dep_b; 00079 // 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; 00080 00081 return rf_protocols; 00082 } 00083 00084 nfc_err_t NFCController::configure_rf_protocols(nfc_rf_protocols_bitmask_t rf_protocols) 00085 { 00086 if (_discovery_running) { 00087 // Cannot configure RF protocols if discovery is running 00088 return NFC_ERR_BUSY; 00089 } 00090 00091 // Map to NFC techs 00092 nfc_tech_t initiator_tech = {0}; 00093 nfc_tech_t target_tech = {0}; 00094 00095 // Note: we only support ISO-DEP tag emulation in this release, 00096 // so mask out all other protocols 00097 00098 target_tech.nfc_iso_dep_a = target_tech.nfc_iso_dep_b = true; 00099 00100 // Configure polling options (no need to set bailing flags as we're only using target mode) 00101 polling_options_t options = {0}; 00102 options.listen_for = -1; // Listen forever 00103 00104 transceiver_set_protocols(_transceiver, initiator_tech, target_tech, options); 00105 00106 return NFC_OK; 00107 } 00108 00109 nfc_err_t NFCController::start_discovery() 00110 { 00111 if (_discovery_running) { 00112 // Cannot start discovery if it's already running 00113 return NFC_ERR_BUSY; 00114 } 00115 00116 transceiver_poll(_transceiver, &NFCController::s_polling_callback, this /* use this as callback argument */); 00117 00118 return NFC_OK; 00119 } 00120 00121 nfc_err_t NFCController::cancel_discovery() 00122 { 00123 if (!_discovery_running) { 00124 return NFC_OK; 00125 } 00126 00127 transceiver_abort(_transceiver); 00128 00129 return NFC_OK; 00130 } 00131 00132 nfc_transceiver_t *NFCController::transceiver() const 00133 { 00134 return _transceiver; 00135 } 00136 00137 void NFCController::polling_callback(nfc_err_t ret) 00138 { 00139 // Polling has completed 00140 _discovery_running = false; 00141 00142 NFC_DBG("Polling finished with result %u", ret); 00143 00144 if (ret == NFC_OK) { 00145 // Check if a remote initiator was detected and if so, instantiate it 00146 if (!transceiver_is_initiator_mode(_transceiver)) { 00147 nfc_tech_t active_tech = transceiver_get_active_techs(_transceiver); 00148 if ((active_tech.nfc_iso_dep_a || active_tech.nfc_iso_dep_b) && (_delegate != NULL)) { 00149 Type4RemoteInitiator *type4_remote_initiator_ptr = new (std::nothrow) Type4RemoteInitiator(this, _ndef_buffer); 00150 if (type4_remote_initiator_ptr != NULL) { 00151 SharedPtr<NFCRemoteInitiator> type4_remote_initiator(type4_remote_initiator_ptr); 00152 _delegate->on_nfc_initiator_discovered(type4_remote_initiator); 00153 } 00154 } 00155 } 00156 } 00157 00158 if (_delegate != NULL) { 00159 Delegate::nfc_discovery_terminated_reason_t reason; 00160 00161 // Map reason 00162 switch (ret) { 00163 case NFC_OK: 00164 reason = Delegate::nfc_discovery_terminated_completed; 00165 break; 00166 case NFC_ERR_ABORTED: 00167 reason = Delegate::nfc_discovery_terminated_canceled; 00168 break; 00169 default: 00170 // Any other error code means there was an error during the discovery process 00171 reason = Delegate::nfc_discovery_terminated_rf_error; 00172 break; 00173 } 00174 00175 _delegate->on_discovery_terminated(reason); 00176 } 00177 } 00178 00179 void NFCController::scheduler_process(bool hw_interrupt) 00180 { 00181 _timeout.detach(); // Cancel timeout - if it triggers, it's ok as we'll have an "early" iteration which will likely be a no-op 00182 00183 // Process stack events 00184 uint32_t timeout = nfc_scheduler_iteration(_scheduler, hw_interrupt ? EVENT_HW_INTERRUPT : EVENT_NONE); 00185 00186 _timeout.attach(callback(this, &NFCController::on_timeout), timeout); 00187 } 00188 00189 void NFCController::on_hw_interrupt() 00190 { 00191 // Run scheduler - this is called in interrupt context 00192 _timeout.detach(); // Cancel timeout - if it triggers anyways, it's ok 00193 _queue->call(this, &NFCController::scheduler_process, true); 00194 } 00195 00196 void NFCController::on_timeout() 00197 { 00198 // Run scheduler - this is called in interrupt context 00199 _queue->call(this, &NFCController::scheduler_process, false); 00200 } 00201 00202 void NFCController::s_polling_callback(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData) 00203 { 00204 NFCController *self = (NFCController *) pUserData; 00205 self->polling_callback(ret); 00206 } 00207 00208 // Implementation nfc_scheduler_timer_t 00209 void nfc_scheduler_timer_init(nfc_scheduler_timer_t *timer) 00210 { 00211 (void)timer; // This is a no-op 00212 } 00213 00214 void nfc_scheduler_timer_start(nfc_scheduler_timer_t *timer) 00215 { 00216 Timer *mbed_timer = (Timer *)timer; 00217 mbed_timer->start(); 00218 } 00219 00220 uint32_t nfc_scheduler_timer_get(nfc_scheduler_timer_t *timer) 00221 { 00222 Timer *mbed_timer = (Timer *)timer; 00223 return (uint32_t)mbed_timer->read_ms(); 00224 } 00225 00226 void nfc_scheduler_timer_stop(nfc_scheduler_timer_t *timer) 00227 { 00228 Timer *mbed_timer = (Timer *)timer; 00229 mbed_timer->stop(); 00230 } 00231 00232 void nfc_scheduler_timer_reset(nfc_scheduler_timer_t *timer) 00233 { 00234 Timer *mbed_timer = (Timer *)timer; 00235 mbed_timer->reset(); 00236 }
Generated on Tue Aug 9 2022 00:37:16 by
1.7.2