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.
MessageParser.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 <string.h> 00018 00019 #include "nfc/ndef/MessageParser.h" 00020 #include "nfc/ndef/Record.h" 00021 00022 namespace { 00023 struct buffer_iterator_t { 00024 buffer_iterator_t(const mbed::Span<const uint8_t> &buffer) : 00025 buffer(buffer), 00026 position(0) 00027 { } 00028 00029 uint8_t operator*() 00030 { 00031 return buffer[position]; 00032 } 00033 00034 buffer_iterator_t &operator++() 00035 { 00036 ++position; 00037 return *this; 00038 } 00039 00040 buffer_iterator_t operator++(int) 00041 { 00042 buffer_iterator_t previous = *this; 00043 ++*this; 00044 return previous; 00045 } 00046 00047 buffer_iterator_t &operator+=(size_t increment) 00048 { 00049 position += increment; 00050 return *this; 00051 } 00052 00053 operator bool() const 00054 { 00055 return (position >= buffer.size()) ? false : true; 00056 } 00057 00058 size_t remaining_size() const 00059 { 00060 return buffer.size() - position; 00061 } 00062 00063 void read_le(uint8_t *dest, size_t size) 00064 { 00065 memcpy(dest, buffer.data() + position, size); 00066 position += size; 00067 } 00068 00069 void read_be(uint8_t *dest, size_t size) 00070 { 00071 // TODO: Needs proper network to host function 00072 std::reverse_copy( 00073 buffer.data() + position, 00074 buffer.data() + position + size, 00075 dest 00076 ); 00077 position += size; 00078 } 00079 00080 mbed::Span<const uint8_t> get_underlying_buffer() const 00081 { 00082 return buffer.last(buffer.size() - position); 00083 } 00084 00085 private: 00086 mbed::Span<const uint8_t> buffer; 00087 mbed::Span<const uint8_t>::index_type position; 00088 }; 00089 00090 } // end of anonymous namespace 00091 00092 namespace mbed { 00093 namespace nfc { 00094 namespace ndef { 00095 00096 struct MessageParser::parsing_state_t { 00097 parsing_state_t(const Span<const uint8_t> &data_buffer) : 00098 it(data_buffer), 00099 first_record_parsed(false), 00100 last_record_parsed(false), 00101 error(false) 00102 { } 00103 00104 buffer_iterator_t it; 00105 bool first_record_parsed: 1; 00106 bool last_record_parsed: 1; 00107 bool error: 1; 00108 }; 00109 00110 MessageParser::MessageParser() : 00111 _delegate(NULL) 00112 { } 00113 00114 void MessageParser::set_delegate(Delegate *delegate) 00115 { 00116 _delegate = delegate; 00117 } 00118 00119 void MessageParser::parse(const Span<const uint8_t> &data_buffer) 00120 { 00121 parsing_state_t parsing_state(data_buffer); 00122 report_parsing_started(); 00123 while (parsing_state.it && parse_record(parsing_state)); 00124 if (!parsing_state.error && !parsing_state.last_record_parsed) { 00125 report_parsing_error(MISSING_MESSAGE_END, parsing_state); 00126 } 00127 report_parsing_terminated(); 00128 } 00129 00130 bool MessageParser::parse_record(parsing_state_t &s) 00131 { 00132 if (s.error || s.last_record_parsed) { 00133 return false; 00134 } 00135 00136 // ensure that the header can be extracted 00137 if (s.it.remaining_size() < 1) { 00138 report_parsing_error(INSUFICIENT_DATA, s); 00139 return false; 00140 } 00141 00142 uint8_t header = *s.it++; 00143 00144 // NOTE: report an error until the chunk parsing design is sorted out 00145 if (header & Header::chunk_flag_bit) { 00146 report_parsing_error(CHUNK_RECORD_NOT_SUPPORTED, s); 00147 return false; 00148 } 00149 00150 // handle first record cases 00151 if (s.first_record_parsed == false) { 00152 if (header & Header::message_begin_bit) { 00153 s.first_record_parsed = true; 00154 } else { 00155 report_parsing_error(INVALID_MESSAGE_START, s); 00156 return false; 00157 } 00158 } else if (header & Header::message_begin_bit) { 00159 report_parsing_error(INVALID_MESSAGE_START, s); 00160 return false; 00161 } 00162 00163 // handle last record 00164 if (header & Header::message_end_bit) { 00165 s.last_record_parsed = true; 00166 } 00167 00168 // ensure their is enough space to contain the type length, payload 00169 // length and id length 00170 uint8_t lengths_size = compute_lengths_size(header); 00171 if (s.it.remaining_size() < lengths_size) { 00172 report_parsing_error(INSUFICIENT_DATA, s); 00173 return false; 00174 } 00175 00176 // extract the various length from the message 00177 uint8_t type_length = extract_type_length(s); 00178 uint32_t payload_length = extract_payload_length(s, header); 00179 uint8_t id_length = extract_id_length(s, header); 00180 00181 // there should be enough bytes left in the buffer 00182 if (s.it.remaining_size() < (type_length + id_length + payload_length)) { 00183 report_parsing_error(INSUFICIENT_DATA, s); 00184 return false; 00185 } 00186 00187 // validate the Type Name Format of the header 00188 switch (header & Header::tnf_bits) { 00189 case RecordType::empty: 00190 if (type_length || payload_length || id_length) { 00191 report_parsing_error(INVALID_EMPTY_RECORD, s); 00192 return false; 00193 } 00194 break; 00195 case RecordType::well_known_type: 00196 case RecordType::media_type: 00197 case RecordType::absolute_uri: 00198 case RecordType::external_type: 00199 if (!type_length) { 00200 report_parsing_error(MISSING_TYPE_VALUE, s); 00201 return false; 00202 } 00203 break; 00204 case RecordType::unknown: 00205 if (type_length) { 00206 report_parsing_error(INVALID_UNKNOWN_TYPE_LENGTH, s); 00207 return false; 00208 } 00209 break; 00210 case RecordType::unchanged: 00211 // shouldn't be handled outside of chunk handling 00212 report_parsing_error(INVALID_UNCHANGED_TYPE, s); 00213 return false; 00214 default: 00215 report_parsing_error(INVALID_TYPE_NAME_FORMAT, s); 00216 return false; 00217 } 00218 00219 // build the record 00220 Record record; 00221 00222 // flags 00223 record.last_record = header & Header::message_end_bit; 00224 00225 // type 00226 record.type.tnf = static_cast<RecordType::tnf_t>(header & Header::tnf_bits); 00227 if (type_length) { 00228 record.type.value = s.it.get_underlying_buffer().first(type_length); 00229 s.it += type_length; 00230 } 00231 00232 // id 00233 if (id_length) { 00234 record.id = s.it.get_underlying_buffer().first(id_length); 00235 s.it += id_length; 00236 } 00237 00238 // payload 00239 if (payload_length) { 00240 record.payload = s.it.get_underlying_buffer().first(payload_length); 00241 s.it += payload_length; 00242 } 00243 00244 s.it += payload_length; 00245 00246 report_record_parsed(record); 00247 00248 return true; 00249 } 00250 00251 uint8_t MessageParser::compute_lengths_size(uint8_t header) 00252 { 00253 return 1 /* type_length size */ + 00254 ((header & Header::short_record_bit) ? 1 : 4) /* payload length */ + 00255 ((header & Header::id_length_bit) ? 1 : 0); 00256 } 00257 00258 uint8_t MessageParser::extract_type_length(parsing_state_t &s) 00259 { 00260 return *s.it++; 00261 } 00262 00263 uint32_t MessageParser::extract_payload_length(parsing_state_t &s, uint8_t header) 00264 { 00265 uint32_t payload_length = 0; 00266 if (header & Header::short_record_bit) { 00267 payload_length = *s.it++; 00268 } else { 00269 s.it.read_be( 00270 reinterpret_cast<uint8_t *>(&payload_length), 00271 sizeof(payload_length) 00272 ); 00273 } 00274 return payload_length; 00275 } 00276 00277 uint8_t MessageParser::extract_id_length(parsing_state_t &s, uint8_t header) 00278 { 00279 return (header & Header::id_length_bit) ? *s.it++ : 0; 00280 } 00281 00282 void MessageParser::report_parsing_started() 00283 { 00284 if (_delegate) { 00285 _delegate->on_parsing_started(); 00286 } 00287 } 00288 00289 void MessageParser::report_record_parsed(const Record &record) 00290 { 00291 if (_delegate) { 00292 _delegate->on_record_parsed(record); 00293 } 00294 } 00295 00296 void MessageParser::report_parsing_terminated() 00297 { 00298 if (_delegate) { 00299 _delegate->on_parsing_terminated(); 00300 } 00301 } 00302 00303 void MessageParser::report_parsing_error(error_t error, parsing_state_t &parsing_state) 00304 { 00305 parsing_state.error = true; 00306 if (_delegate) { 00307 _delegate->on_parsing_error(error); 00308 } 00309 } 00310 00311 } // namespace ndef 00312 } // namespace nfc 00313 } // namespace mbed 00314
Generated on Tue Aug 9 2022 00:37:15 by
1.7.2