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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 Jul 12 2022 13:54:35 by
