Demonstration of possible usage of the the NFCController class.

NFC SmartPoster example

Demonstration of possible usage of the the NFCController class.

The application creates a smart poster record and sends it when a connected peer requests it. The smart poster record generated contains:

  • A URI: https://www.mbed.com
  • A title: "mbed website"
  • An action: EXECUTE which asks the peer to open the URI.

Running the application

Verification of the sample application can be seen on any a smartphone with an NFC reader. After running you will be able to read the tag with an NFC tag reader application.

Information about activity is also printed over the serial connection - please have a client open. You may use:

Tera Term - https://ttssh2.osdn.jp/index.html.en

This example is known to work on boards connected to a PN512 shield.

Committer:
mbed_official
Date:
Fri Nov 29 13:01:40 2019 +0000
Revision:
6:52cd72e84703
Parent:
0:9a16c3f036b0
Merge pull request #50 from jamesbeyond/update

Update readme with PN512 shield info
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-nfc

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:9a16c3f036b0 1 /* mbed Microcontroller Library
mbed_official 0:9a16c3f036b0 2 * Copyright (c) 2018-2018 ARM Limited
mbed_official 0:9a16c3f036b0 3 *
mbed_official 0:9a16c3f036b0 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 0:9a16c3f036b0 5 * you may not use this file except in compliance with the License.
mbed_official 0:9a16c3f036b0 6 * You may obtain a copy of the License at
mbed_official 0:9a16c3f036b0 7 *
mbed_official 0:9a16c3f036b0 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 0:9a16c3f036b0 9 *
mbed_official 0:9a16c3f036b0 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 0:9a16c3f036b0 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 0:9a16c3f036b0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 0:9a16c3f036b0 13 * See the License for the specific language governing permissions and
mbed_official 0:9a16c3f036b0 14 * limitations under the License.
mbed_official 0:9a16c3f036b0 15 */
mbed_official 0:9a16c3f036b0 16
mbed_official 0:9a16c3f036b0 17 #include "SmartPoster.h"
mbed_official 0:9a16c3f036b0 18
mbed_official 0:9a16c3f036b0 19 #include "nfc/ndef/common/Text.h"
mbed_official 0:9a16c3f036b0 20 #include "nfc/ndef/common/URI.h"
mbed_official 0:9a16c3f036b0 21 #include "nfc/ndef/common/Mime.h"
mbed_official 0:9a16c3f036b0 22 #include "nfc/ndef/MessageBuilder.h"
mbed_official 0:9a16c3f036b0 23 #include "nfc/ndef/common/util.h"
mbed_official 0:9a16c3f036b0 24
mbed_official 0:9a16c3f036b0 25 using mbed::Span;
mbed_official 0:9a16c3f036b0 26
mbed_official 0:9a16c3f036b0 27 using mbed::nfc::ndef::MessageBuilder;
mbed_official 0:9a16c3f036b0 28 using mbed::nfc::ndef::RecordType;
mbed_official 0:9a16c3f036b0 29 using mbed::nfc::ndef::Record;
mbed_official 0:9a16c3f036b0 30 using mbed::nfc::ndef::RecordID;
mbed_official 0:9a16c3f036b0 31 using mbed::nfc::ndef::RecordPayload;
mbed_official 0:9a16c3f036b0 32 using mbed::nfc::ndef::common::span_from_cstr;
mbed_official 0:9a16c3f036b0 33 using mbed::nfc::ndef::common::Mime;
mbed_official 0:9a16c3f036b0 34 using mbed::nfc::ndef::common::Text;
mbed_official 0:9a16c3f036b0 35 using mbed::nfc::ndef::common::URI;
mbed_official 0:9a16c3f036b0 36
mbed_official 0:9a16c3f036b0 37 namespace {
mbed_official 0:9a16c3f036b0 38 static RecordType smart_poster_record_type()
mbed_official 0:9a16c3f036b0 39 {
mbed_official 0:9a16c3f036b0 40 return RecordType(
mbed_official 0:9a16c3f036b0 41 RecordType::well_known_type,
mbed_official 0:9a16c3f036b0 42 span_from_cstr("Sp")
mbed_official 0:9a16c3f036b0 43 );
mbed_official 0:9a16c3f036b0 44 }
mbed_official 0:9a16c3f036b0 45
mbed_official 0:9a16c3f036b0 46 static RecordType action_record_type() {
mbed_official 0:9a16c3f036b0 47 return RecordType(
mbed_official 0:9a16c3f036b0 48 RecordType::well_known_type,
mbed_official 0:9a16c3f036b0 49 span_from_cstr("act")
mbed_official 0:9a16c3f036b0 50 );
mbed_official 0:9a16c3f036b0 51 }
mbed_official 0:9a16c3f036b0 52
mbed_official 0:9a16c3f036b0 53 static RecordType size_record_type() {
mbed_official 0:9a16c3f036b0 54 return RecordType(
mbed_official 0:9a16c3f036b0 55 RecordType::well_known_type,
mbed_official 0:9a16c3f036b0 56 span_from_cstr("s")
mbed_official 0:9a16c3f036b0 57 );
mbed_official 0:9a16c3f036b0 58 }
mbed_official 0:9a16c3f036b0 59
mbed_official 0:9a16c3f036b0 60 static RecordType type_record_type() {
mbed_official 0:9a16c3f036b0 61 return RecordType(
mbed_official 0:9a16c3f036b0 62 RecordType::well_known_type,
mbed_official 0:9a16c3f036b0 63 span_from_cstr("T")
mbed_official 0:9a16c3f036b0 64 );
mbed_official 0:9a16c3f036b0 65 }
mbed_official 0:9a16c3f036b0 66
mbed_official 0:9a16c3f036b0 67 static size_t compute_record_size(const RecordType& type, const RecordPayload& payload)
mbed_official 0:9a16c3f036b0 68 {
mbed_official 0:9a16c3f036b0 69 return MessageBuilder::compute_record_size(
mbed_official 0:9a16c3f036b0 70 Record(
mbed_official 0:9a16c3f036b0 71 type,
mbed_official 0:9a16c3f036b0 72 payload,
mbed_official 0:9a16c3f036b0 73 RecordID(),
mbed_official 0:9a16c3f036b0 74 false,
mbed_official 0:9a16c3f036b0 75 false
mbed_official 0:9a16c3f036b0 76 )
mbed_official 0:9a16c3f036b0 77 );
mbed_official 0:9a16c3f036b0 78 }
mbed_official 0:9a16c3f036b0 79
mbed_official 0:9a16c3f036b0 80 } // end of anonymous namespace
mbed_official 0:9a16c3f036b0 81
mbed_official 0:9a16c3f036b0 82
mbed_official 0:9a16c3f036b0 83 SmartPoster::SmartPoster(const URI &uri) :
mbed_official 0:9a16c3f036b0 84 _uri(uri),
mbed_official 0:9a16c3f036b0 85 _action(),
mbed_official 0:9a16c3f036b0 86 _resource_size(0),
mbed_official 0:9a16c3f036b0 87 _action_set(false),
mbed_official 0:9a16c3f036b0 88 _resource_size_set(false)
mbed_official 0:9a16c3f036b0 89 { }
mbed_official 0:9a16c3f036b0 90
mbed_official 0:9a16c3f036b0 91 void SmartPoster::set_title(const Text &text)
mbed_official 0:9a16c3f036b0 92 {
mbed_official 0:9a16c3f036b0 93 _title = text;
mbed_official 0:9a16c3f036b0 94 }
mbed_official 0:9a16c3f036b0 95
mbed_official 0:9a16c3f036b0 96 void SmartPoster::set_icon(const Mime &icon)
mbed_official 0:9a16c3f036b0 97 {
mbed_official 0:9a16c3f036b0 98 _icon = icon;
mbed_official 0:9a16c3f036b0 99 }
mbed_official 0:9a16c3f036b0 100
mbed_official 0:9a16c3f036b0 101 void SmartPoster::set_action(action_t action)
mbed_official 0:9a16c3f036b0 102 {
mbed_official 0:9a16c3f036b0 103 _action = action;
mbed_official 0:9a16c3f036b0 104 _action_set = true;
mbed_official 0:9a16c3f036b0 105 }
mbed_official 0:9a16c3f036b0 106
mbed_official 0:9a16c3f036b0 107 void SmartPoster::set_resource_size(uint32_t size)
mbed_official 0:9a16c3f036b0 108 {
mbed_official 0:9a16c3f036b0 109 _resource_size = size;
mbed_official 0:9a16c3f036b0 110 _resource_size_set = true;
mbed_official 0:9a16c3f036b0 111 }
mbed_official 0:9a16c3f036b0 112
mbed_official 0:9a16c3f036b0 113 void SmartPoster::set_resource_type(Span<const uint8_t> &type)
mbed_official 0:9a16c3f036b0 114 {
mbed_official 0:9a16c3f036b0 115 _type.set_text(Text::UTF8, Span<const uint8_t>(), type);
mbed_official 0:9a16c3f036b0 116 }
mbed_official 0:9a16c3f036b0 117
mbed_official 0:9a16c3f036b0 118 bool SmartPoster::append_record(MessageBuilder &ndef_builder, bool is_last_record) const
mbed_official 0:9a16c3f036b0 119 {
mbed_official 0:9a16c3f036b0 120 if (_uri.get_uri_field().empty()) {
mbed_official 0:9a16c3f036b0 121 return false;
mbed_official 0:9a16c3f036b0 122 }
mbed_official 0:9a16c3f036b0 123
mbed_official 0:9a16c3f036b0 124 struct PayloadBuilder : MessageBuilder::PayloadBuilder {
mbed_official 0:9a16c3f036b0 125 PayloadBuilder(const SmartPoster &sp) : sp(sp) { }
mbed_official 0:9a16c3f036b0 126
mbed_official 0:9a16c3f036b0 127 virtual size_t size() const
mbed_official 0:9a16c3f036b0 128 {
mbed_official 0:9a16c3f036b0 129 return sp.get_uri_record_size() +
mbed_official 0:9a16c3f036b0 130 sp.get_title_record_size() +
mbed_official 0:9a16c3f036b0 131 sp.get_icon_record_size() +
mbed_official 0:9a16c3f036b0 132 sp.get_action_record_size() +
mbed_official 0:9a16c3f036b0 133 sp.get_resource_size_record_size() +
mbed_official 0:9a16c3f036b0 134 sp.get_type_record_size();
mbed_official 0:9a16c3f036b0 135 }
mbed_official 0:9a16c3f036b0 136
mbed_official 0:9a16c3f036b0 137 virtual void build(const Span<uint8_t> &buffer) const
mbed_official 0:9a16c3f036b0 138 {
mbed_official 0:9a16c3f036b0 139 MessageBuilder smart_poster_builder(buffer);
mbed_official 0:9a16c3f036b0 140 sp.append_title(smart_poster_builder);
mbed_official 0:9a16c3f036b0 141 sp.append_icon(smart_poster_builder);
mbed_official 0:9a16c3f036b0 142 sp.append_resource_size(smart_poster_builder);
mbed_official 0:9a16c3f036b0 143 sp.append_type(smart_poster_builder);
mbed_official 0:9a16c3f036b0 144 sp.append_action(smart_poster_builder);
mbed_official 0:9a16c3f036b0 145 sp.append_uri(smart_poster_builder);
mbed_official 0:9a16c3f036b0 146 }
mbed_official 0:9a16c3f036b0 147
mbed_official 0:9a16c3f036b0 148 const SmartPoster &sp;
mbed_official 0:9a16c3f036b0 149 };
mbed_official 0:9a16c3f036b0 150
mbed_official 0:9a16c3f036b0 151 bool result = ndef_builder.append_record(
mbed_official 0:9a16c3f036b0 152 smart_poster_record_type(),
mbed_official 0:9a16c3f036b0 153 PayloadBuilder(*this),
mbed_official 0:9a16c3f036b0 154 is_last_record
mbed_official 0:9a16c3f036b0 155 );
mbed_official 0:9a16c3f036b0 156 return result;
mbed_official 0:9a16c3f036b0 157 }
mbed_official 0:9a16c3f036b0 158
mbed_official 0:9a16c3f036b0 159 void SmartPoster::append_uri(MessageBuilder& builder) const
mbed_official 0:9a16c3f036b0 160 {
mbed_official 0:9a16c3f036b0 161 _uri.append_as_record(builder, true);
mbed_official 0:9a16c3f036b0 162 }
mbed_official 0:9a16c3f036b0 163
mbed_official 0:9a16c3f036b0 164 size_t SmartPoster::get_uri_record_size() const
mbed_official 0:9a16c3f036b0 165 {
mbed_official 0:9a16c3f036b0 166 return _uri.get_record_size();
mbed_official 0:9a16c3f036b0 167 }
mbed_official 0:9a16c3f036b0 168
mbed_official 0:9a16c3f036b0 169 void SmartPoster::append_title(MessageBuilder& builder) const
mbed_official 0:9a16c3f036b0 170 {
mbed_official 0:9a16c3f036b0 171 if (_title.get_text().empty()) {
mbed_official 0:9a16c3f036b0 172 return;
mbed_official 0:9a16c3f036b0 173 }
mbed_official 0:9a16c3f036b0 174 _title.append_as_record(builder);
mbed_official 0:9a16c3f036b0 175 }
mbed_official 0:9a16c3f036b0 176
mbed_official 0:9a16c3f036b0 177 size_t SmartPoster::get_title_record_size() const
mbed_official 0:9a16c3f036b0 178 {
mbed_official 0:9a16c3f036b0 179 if (_title.get_text().empty()) {
mbed_official 0:9a16c3f036b0 180 return 0;
mbed_official 0:9a16c3f036b0 181 }
mbed_official 0:9a16c3f036b0 182
mbed_official 0:9a16c3f036b0 183 return _title.get_record_size();
mbed_official 0:9a16c3f036b0 184 }
mbed_official 0:9a16c3f036b0 185
mbed_official 0:9a16c3f036b0 186 void SmartPoster::append_icon(MessageBuilder& builder) const
mbed_official 0:9a16c3f036b0 187 {
mbed_official 0:9a16c3f036b0 188 if (_icon.get_mime_content().empty()) {
mbed_official 0:9a16c3f036b0 189 return;
mbed_official 0:9a16c3f036b0 190 }
mbed_official 0:9a16c3f036b0 191 _icon.append_as_record(builder);
mbed_official 0:9a16c3f036b0 192 }
mbed_official 0:9a16c3f036b0 193
mbed_official 0:9a16c3f036b0 194 size_t SmartPoster::get_icon_record_size() const
mbed_official 0:9a16c3f036b0 195 {
mbed_official 0:9a16c3f036b0 196 if (_icon.get_mime_content().empty()) {
mbed_official 0:9a16c3f036b0 197 return 0;
mbed_official 0:9a16c3f036b0 198 }
mbed_official 0:9a16c3f036b0 199
mbed_official 0:9a16c3f036b0 200 return _icon.get_record_size();
mbed_official 0:9a16c3f036b0 201 }
mbed_official 0:9a16c3f036b0 202
mbed_official 0:9a16c3f036b0 203 void SmartPoster::append_action(MessageBuilder& builder) const
mbed_official 0:9a16c3f036b0 204 {
mbed_official 0:9a16c3f036b0 205 if (!_action_set) {
mbed_official 0:9a16c3f036b0 206 return;
mbed_official 0:9a16c3f036b0 207 }
mbed_official 0:9a16c3f036b0 208
mbed_official 0:9a16c3f036b0 209 const uint8_t action_value[1] = { _action };
mbed_official 0:9a16c3f036b0 210 builder.append_record(
mbed_official 0:9a16c3f036b0 211 action_record_type(),
mbed_official 0:9a16c3f036b0 212 action_value
mbed_official 0:9a16c3f036b0 213 );
mbed_official 0:9a16c3f036b0 214 }
mbed_official 0:9a16c3f036b0 215
mbed_official 0:9a16c3f036b0 216 size_t SmartPoster::get_action_record_size() const
mbed_official 0:9a16c3f036b0 217 {
mbed_official 0:9a16c3f036b0 218 if (!_action_set) {
mbed_official 0:9a16c3f036b0 219 return 0;
mbed_official 0:9a16c3f036b0 220 }
mbed_official 0:9a16c3f036b0 221
mbed_official 0:9a16c3f036b0 222 const uint8_t action_value[1] = { _action };
mbed_official 0:9a16c3f036b0 223
mbed_official 0:9a16c3f036b0 224 return compute_record_size(
mbed_official 0:9a16c3f036b0 225 action_record_type(),
mbed_official 0:9a16c3f036b0 226 action_value
mbed_official 0:9a16c3f036b0 227 );
mbed_official 0:9a16c3f036b0 228 }
mbed_official 0:9a16c3f036b0 229
mbed_official 0:9a16c3f036b0 230 void SmartPoster::append_resource_size(MessageBuilder& builder) const
mbed_official 0:9a16c3f036b0 231 {
mbed_official 0:9a16c3f036b0 232 if (!_resource_size_set) {
mbed_official 0:9a16c3f036b0 233 return;
mbed_official 0:9a16c3f036b0 234 }
mbed_official 0:9a16c3f036b0 235
mbed_official 0:9a16c3f036b0 236 uint8_t value[4];
mbed_official 0:9a16c3f036b0 237 std::reverse_copy(&_resource_size, &_resource_size + 4, value);
mbed_official 0:9a16c3f036b0 238
mbed_official 0:9a16c3f036b0 239 builder.append_record(
mbed_official 0:9a16c3f036b0 240 size_record_type(),
mbed_official 0:9a16c3f036b0 241 value
mbed_official 0:9a16c3f036b0 242 );
mbed_official 0:9a16c3f036b0 243 }
mbed_official 0:9a16c3f036b0 244
mbed_official 0:9a16c3f036b0 245 size_t SmartPoster::get_resource_size_record_size() const
mbed_official 0:9a16c3f036b0 246 {
mbed_official 0:9a16c3f036b0 247 if (!_resource_size_set) {
mbed_official 0:9a16c3f036b0 248 return 0;
mbed_official 0:9a16c3f036b0 249 }
mbed_official 0:9a16c3f036b0 250
mbed_official 0:9a16c3f036b0 251 uint8_t value[4];
mbed_official 0:9a16c3f036b0 252
mbed_official 0:9a16c3f036b0 253 return compute_record_size(
mbed_official 0:9a16c3f036b0 254 size_record_type(),
mbed_official 0:9a16c3f036b0 255 value
mbed_official 0:9a16c3f036b0 256 );
mbed_official 0:9a16c3f036b0 257 }
mbed_official 0:9a16c3f036b0 258
mbed_official 0:9a16c3f036b0 259 void SmartPoster::append_type(MessageBuilder& builder) const
mbed_official 0:9a16c3f036b0 260 {
mbed_official 0:9a16c3f036b0 261 if (_type.get_text().empty()) {
mbed_official 0:9a16c3f036b0 262 return;
mbed_official 0:9a16c3f036b0 263 }
mbed_official 0:9a16c3f036b0 264
mbed_official 0:9a16c3f036b0 265 builder.append_record(
mbed_official 0:9a16c3f036b0 266 type_record_type(),
mbed_official 0:9a16c3f036b0 267 _type.get_text()
mbed_official 0:9a16c3f036b0 268 );
mbed_official 0:9a16c3f036b0 269 }
mbed_official 0:9a16c3f036b0 270
mbed_official 0:9a16c3f036b0 271 size_t SmartPoster::get_type_record_size() const
mbed_official 0:9a16c3f036b0 272 {
mbed_official 0:9a16c3f036b0 273 if (_type.get_text().empty()) {
mbed_official 0:9a16c3f036b0 274 return 0;
mbed_official 0:9a16c3f036b0 275 }
mbed_official 0:9a16c3f036b0 276
mbed_official 0:9a16c3f036b0 277 return compute_record_size(
mbed_official 0:9a16c3f036b0 278 type_record_type(),
mbed_official 0:9a16c3f036b0 279 _type.get_text()
mbed_official 0:9a16c3f036b0 280 );
mbed_official 0:9a16c3f036b0 281 }
mbed_official 0:9a16c3f036b0 282