mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Extend nfc ndef records with Text (#2191)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
		| @@ -10,16 +10,13 @@ NdefMessage::NdefMessage(std::vector<uint8_t> &data) { | |||||||
|   uint8_t index = 0; |   uint8_t index = 0; | ||||||
|   while (index <= data.size()) { |   while (index <= data.size()) { | ||||||
|     uint8_t tnf_byte = data[index++]; |     uint8_t tnf_byte = data[index++]; | ||||||
|     bool me = tnf_byte & 0x40; |     bool me = tnf_byte & 0x40;      // Message End bit (is set if this is the last record of the message) | ||||||
|     bool sr = tnf_byte & 0x10; |     bool sr = tnf_byte & 0x10;      // Short record bit (is set if payload size is less or equal to 255 bytes) | ||||||
|     bool il = tnf_byte & 0x08; |     bool il = tnf_byte & 0x08;      // ID length bit (is set if ID Length field exists) | ||||||
|     uint8_t tnf = tnf_byte & 0x07; |     uint8_t tnf = tnf_byte & 0x07;  // Type Name Format | ||||||
|  |  | ||||||
|     ESP_LOGVV(TAG, "me=%s, sr=%s, il=%s, tnf=%d", YESNO(me), YESNO(sr), YESNO(il), tnf); |     ESP_LOGVV(TAG, "me=%s, sr=%s, il=%s, tnf=%d", YESNO(me), YESNO(sr), YESNO(il), tnf); | ||||||
|  |  | ||||||
|     auto record = make_unique<NdefRecord>(); |  | ||||||
|     record->set_tnf(tnf); |  | ||||||
|  |  | ||||||
|     uint8_t type_length = data[index++]; |     uint8_t type_length = data[index++]; | ||||||
|     uint32_t payload_length = 0; |     uint32_t payload_length = 0; | ||||||
|     if (sr) { |     if (sr) { | ||||||
| @@ -38,28 +35,34 @@ NdefMessage::NdefMessage(std::vector<uint8_t> &data) { | |||||||
|     ESP_LOGVV(TAG, "Lengths: type=%d, payload=%d, id=%d", type_length, payload_length, id_length); |     ESP_LOGVV(TAG, "Lengths: type=%d, payload=%d, id=%d", type_length, payload_length, id_length); | ||||||
|  |  | ||||||
|     std::string type_str(data.begin() + index, data.begin() + index + type_length); |     std::string type_str(data.begin() + index, data.begin() + index + type_length); | ||||||
|     record->set_type(type_str); |  | ||||||
|     index += type_length; |     index += type_length; | ||||||
|  |  | ||||||
|  |     std::string id_str = ""; | ||||||
|     if (il) { |     if (il) { | ||||||
|       std::string id_str(data.begin() + index, data.begin() + index + id_length); |       id_str = std::string(data.begin() + index, data.begin() + index + id_length); | ||||||
|       record->set_id(id_str); |  | ||||||
|       index += id_length; |       index += id_length; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     uint8_t payload_identifier = 0x00; |     std::vector<uint8_t> payload_data(data.begin() + index, data.begin() + index + payload_length); | ||||||
|     if (type_str == "U") { |  | ||||||
|       payload_identifier = data[index++]; |     std::unique_ptr<NdefRecord> record; | ||||||
|       payload_length -= 1; |  | ||||||
|  |     // Based on tnf and type, create a more specific NdefRecord object | ||||||
|  |     // constructed from the payload data | ||||||
|  |     if (tnf == TNF_WELL_KNOWN && type_str == "U") { | ||||||
|  |       record = make_unique<NdefRecordUri>(payload_data); | ||||||
|  |     } else if (tnf == TNF_WELL_KNOWN && type_str == "T") { | ||||||
|  |       record = make_unique<NdefRecordText>(payload_data); | ||||||
|  |     } else { | ||||||
|  |       // Could not recognize the record, so store as generic one. | ||||||
|  |       record = make_unique<NdefRecord>(payload_data); | ||||||
|  |       record->set_tnf(tnf); | ||||||
|  |       record->set_type(type_str); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     std::string payload_str(data.begin() + index, data.begin() + index + payload_length); |     record->set_id(id_str); | ||||||
|  |  | ||||||
|     if (payload_identifier > 0x00 && payload_identifier <= PAYLOAD_IDENTIFIERS_COUNT) { |  | ||||||
|       payload_str.insert(0, PAYLOAD_IDENTIFIERS[payload_identifier]); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     record->set_payload(payload_str); |  | ||||||
|     index += payload_length; |     index += payload_length; | ||||||
|  |  | ||||||
|     ESP_LOGV(TAG, "Adding record type %s = %s", record->get_type().c_str(), record->get_payload().c_str()); |     ESP_LOGV(TAG, "Adding record type %s = %s", record->get_type().c_str(), record->get_payload().c_str()); | ||||||
| @@ -82,13 +85,10 @@ bool NdefMessage::add_record(std::unique_ptr<NdefRecord> record) { | |||||||
| bool NdefMessage::add_text_record(const std::string &text) { return this->add_text_record(text, "en"); }; | bool NdefMessage::add_text_record(const std::string &text) { return this->add_text_record(text, "en"); }; | ||||||
|  |  | ||||||
| bool NdefMessage::add_text_record(const std::string &text, const std::string &encoding) { | bool NdefMessage::add_text_record(const std::string &text, const std::string &encoding) { | ||||||
|   std::string payload = to_string(text.length()) + encoding + text; |   return this->add_record(make_unique<NdefRecordText>(encoding, text)); | ||||||
|   return this->add_record(make_unique<NdefRecord>(TNF_WELL_KNOWN, "T", payload)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool NdefMessage::add_uri_record(const std::string &uri) { | bool NdefMessage::add_uri_record(const std::string &uri) { return this->add_record(make_unique<NdefRecordUri>(uri)); } | ||||||
|   return this->add_record(make_unique<NdefRecord>(TNF_WELL_KNOWN, "U", uri)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| std::vector<uint8_t> NdefMessage::encode() { | std::vector<uint8_t> NdefMessage::encode() { | ||||||
|   std::vector<uint8_t> data; |   std::vector<uint8_t> data; | ||||||
|   | |||||||
| @@ -5,6 +5,8 @@ | |||||||
| #include "esphome/core/helpers.h" | #include "esphome/core/helpers.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "ndef_record.h" | #include "ndef_record.h" | ||||||
|  | #include "ndef_record_text.h" | ||||||
|  | #include "ndef_record_uri.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace nfc { | namespace nfc { | ||||||
| @@ -18,7 +20,7 @@ class NdefMessage { | |||||||
|   NdefMessage(const NdefMessage &msg) { |   NdefMessage(const NdefMessage &msg) { | ||||||
|     records_.reserve(msg.records_.size()); |     records_.reserve(msg.records_.size()); | ||||||
|     for (const auto &r : msg.records_) { |     for (const auto &r : msg.records_) { | ||||||
|       records_.emplace_back(make_unique<NdefRecord>(*r)); |       records_.emplace_back(r->clone()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,40 +5,22 @@ namespace nfc { | |||||||
|  |  | ||||||
| static const char *const TAG = "nfc.ndef_record"; | static const char *const TAG = "nfc.ndef_record"; | ||||||
|  |  | ||||||
| uint32_t NdefRecord::get_encoded_size() { | NdefRecord::NdefRecord(std::vector<uint8_t> payload_data) { | ||||||
|   uint32_t size = 2; |   this->payload_ = std::string(payload_data.begin(), payload_data.end()); | ||||||
|   if (this->payload_.length() > 255) { |  | ||||||
|     size += 4; |  | ||||||
|   } else { |  | ||||||
|     size += 1; |  | ||||||
|   } |  | ||||||
|   if (this->id_.length()) { |  | ||||||
|     size += 1; |  | ||||||
|   } |  | ||||||
|   size += (this->type_.length() + this->payload_.length() + this->id_.length()); |  | ||||||
|   return size; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<uint8_t> NdefRecord::encode(bool first, bool last) { | std::vector<uint8_t> NdefRecord::encode(bool first, bool last) { | ||||||
|   std::vector<uint8_t> data; |   std::vector<uint8_t> data; | ||||||
|  |  | ||||||
|   data.push_back(this->get_tnf_byte(first, last)); |   // Get encoded payload, this is overriden by more specific record classes | ||||||
|  |   std::vector<uint8_t> payload_data = get_encoded_payload(); | ||||||
|  |  | ||||||
|  |   size_t payload_length = payload_data.size(); | ||||||
|  |  | ||||||
|  |   data.push_back(this->create_flag_byte(first, last, payload_length)); | ||||||
|  |  | ||||||
|   data.push_back(this->type_.length()); |   data.push_back(this->type_.length()); | ||||||
|  |  | ||||||
|   uint8_t payload_prefix = 0x00; |  | ||||||
|   uint8_t payload_prefix_length = 0x00; |  | ||||||
|   for (uint8_t i = 1; i < PAYLOAD_IDENTIFIERS_COUNT; i++) { |  | ||||||
|     std::string prefix = PAYLOAD_IDENTIFIERS[i]; |  | ||||||
|     if (this->payload_.substr(0, prefix.length()).find(prefix) != std::string::npos) { |  | ||||||
|       payload_prefix = i; |  | ||||||
|       payload_prefix_length = prefix.length(); |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   uint32_t payload_length = this->payload_.length() - payload_prefix_length + 1; |  | ||||||
|  |  | ||||||
|   if (payload_length <= 255) { |   if (payload_length <= 255) { | ||||||
|     data.push_back(payload_length); |     data.push_back(payload_length); | ||||||
|   } else { |   } else { | ||||||
| @@ -58,25 +40,23 @@ std::vector<uint8_t> NdefRecord::encode(bool first, bool last) { | |||||||
|     data.insert(data.end(), this->id_.begin(), this->id_.end()); |     data.insert(data.end(), this->id_.begin(), this->id_.end()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   data.push_back(payload_prefix); |   data.insert(data.end(), payload_data.begin(), payload_data.end()); | ||||||
|  |  | ||||||
|   data.insert(data.end(), this->payload_.begin() + payload_prefix_length, this->payload_.end()); |  | ||||||
|   return data; |   return data; | ||||||
| } | } | ||||||
|  |  | ||||||
| uint8_t NdefRecord::get_tnf_byte(bool first, bool last) { | uint8_t NdefRecord::create_flag_byte(bool first, bool last, size_t payload_size) { | ||||||
|   uint8_t value = this->tnf_; |   uint8_t value = this->tnf_ & 0b00000111; | ||||||
|   if (first) { |   if (first) { | ||||||
|     value = value | 0x80; |     value = value | 0x80;  // Set MB bit | ||||||
|   } |   } | ||||||
|   if (last) { |   if (last) { | ||||||
|     value = value | 0x40; |     value = value | 0x40;  // Set ME bit | ||||||
|   } |   } | ||||||
|   if (this->payload_.length() <= 255) { |   if (payload_size <= 255) { | ||||||
|     value = value | 0x10; |     value = value | 0x10;  // Set SR bit | ||||||
|   } |   } | ||||||
|   if (this->id_.length()) { |   if (this->id_.length()) { | ||||||
|     value = value | 0x08; |     value = value | 0x08;  // Set IL bit | ||||||
|   } |   } | ||||||
|   return value; |   return value; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -15,86 +15,40 @@ static const uint8_t TNF_UNKNOWN = 0x05; | |||||||
| static const uint8_t TNF_UNCHANGED = 0x06; | static const uint8_t TNF_UNCHANGED = 0x06; | ||||||
| static const uint8_t TNF_RESERVED = 0x07; | static const uint8_t TNF_RESERVED = 0x07; | ||||||
|  |  | ||||||
| static const uint8_t PAYLOAD_IDENTIFIERS_COUNT = 0x23; |  | ||||||
| static const char *const PAYLOAD_IDENTIFIERS[] = {"", |  | ||||||
|                                                   "http://www.", |  | ||||||
|                                                   "https://www.", |  | ||||||
|                                                   "http://", |  | ||||||
|                                                   "https://", |  | ||||||
|                                                   "tel:", |  | ||||||
|                                                   "mailto:", |  | ||||||
|                                                   "ftp://anonymous:anonymous@", |  | ||||||
|                                                   "ftp://ftp.", |  | ||||||
|                                                   "ftps://", |  | ||||||
|                                                   "sftp://", |  | ||||||
|                                                   "smb://", |  | ||||||
|                                                   "nfs://", |  | ||||||
|                                                   "ftp://", |  | ||||||
|                                                   "dav://", |  | ||||||
|                                                   "news:", |  | ||||||
|                                                   "telnet://", |  | ||||||
|                                                   "imap:", |  | ||||||
|                                                   "rtsp://", |  | ||||||
|                                                   "urn:", |  | ||||||
|                                                   "pop:", |  | ||||||
|                                                   "sip:", |  | ||||||
|                                                   "sips:", |  | ||||||
|                                                   "tftp:", |  | ||||||
|                                                   "btspp://", |  | ||||||
|                                                   "btl2cap://", |  | ||||||
|                                                   "btgoep://", |  | ||||||
|                                                   "tcpobex://", |  | ||||||
|                                                   "irdaobex://", |  | ||||||
|                                                   "file://", |  | ||||||
|                                                   "urn:epc:id:", |  | ||||||
|                                                   "urn:epc:tag:", |  | ||||||
|                                                   "urn:epc:pat:", |  | ||||||
|                                                   "urn:epc:raw:", |  | ||||||
|                                                   "urn:epc:", |  | ||||||
|                                                   "urn:nfc:"}; |  | ||||||
|  |  | ||||||
| class NdefRecord { | class NdefRecord { | ||||||
|  public: |  public: | ||||||
|   NdefRecord(){}; |   NdefRecord(){}; | ||||||
|   NdefRecord(uint8_t tnf, const std::string &type, const std::string &payload) { |   NdefRecord(std::vector<uint8_t> payload_data); | ||||||
|     this->tnf_ = tnf; |  | ||||||
|     this->type_ = type; |  | ||||||
|     this->set_payload(payload); |  | ||||||
|   }; |  | ||||||
|   NdefRecord(uint8_t tnf, const std::string &type, const std::string &payload, const std::string &id) { |  | ||||||
|     this->tnf_ = tnf; |  | ||||||
|     this->type_ = type; |  | ||||||
|     this->set_payload(payload); |  | ||||||
|     this->id_ = id; |  | ||||||
|   }; |  | ||||||
|   NdefRecord(const NdefRecord &rhs) { |  | ||||||
|     this->tnf_ = rhs.tnf_; |  | ||||||
|     this->type_ = rhs.type_; |  | ||||||
|     this->payload_ = rhs.payload_; |  | ||||||
|     this->payload_identifier_ = rhs.payload_identifier_; |  | ||||||
|     this->id_ = rhs.id_; |  | ||||||
|   }; |  | ||||||
|   void set_tnf(uint8_t tnf) { this->tnf_ = tnf; }; |   void set_tnf(uint8_t tnf) { this->tnf_ = tnf; }; | ||||||
|   void set_type(const std::string &type) { this->type_ = type; }; |   void set_type(const std::string &type) { this->type_ = type; }; | ||||||
|   void set_payload_identifier(uint8_t payload_identifier) { this->payload_identifier_ = payload_identifier; }; |  | ||||||
|   void set_payload(const std::string &payload) { this->payload_ = payload; }; |   void set_payload(const std::string &payload) { this->payload_ = payload; }; | ||||||
|   void set_id(const std::string &id) { this->id_ = id; }; |   void set_id(const std::string &id) { this->id_ = id; }; | ||||||
|  |   NdefRecord(const NdefRecord &) = default; | ||||||
|  |   virtual ~NdefRecord() {} | ||||||
|  |   virtual std::unique_ptr<NdefRecord> clone() const {  // To allow copying polymorphic classes | ||||||
|  |     return make_unique<NdefRecord>(*this); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|   uint32_t get_encoded_size(); |   uint32_t get_encoded_size(); | ||||||
|  |  | ||||||
|   std::vector<uint8_t> encode(bool first, bool last); |   std::vector<uint8_t> encode(bool first, bool last); | ||||||
|   uint8_t get_tnf_byte(bool first, bool last); |  | ||||||
|  |   uint8_t create_flag_byte(bool first, bool last, size_t payload_size); | ||||||
|  |  | ||||||
|   const std::string &get_type() const { return this->type_; }; |   const std::string &get_type() const { return this->type_; }; | ||||||
|   const std::string &get_id() const { return this->id_; }; |   const std::string &get_id() const { return this->id_; }; | ||||||
|   const std::string &get_payload() const { return this->payload_; }; |   virtual const std::string &get_payload() const { return this->payload_; }; | ||||||
|  |  | ||||||
|  |   virtual std::vector<uint8_t> get_encoded_payload() { | ||||||
|  |     std::vector<uint8_t> empty_payload; | ||||||
|  |     return empty_payload; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   uint8_t tnf_; |   uint8_t tnf_; | ||||||
|   std::string type_; |   std::string type_; | ||||||
|   uint8_t payload_identifier_; |  | ||||||
|   std::string payload_; |  | ||||||
|   std::string id_; |   std::string id_; | ||||||
|  |   std::string payload_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace nfc | }  // namespace nfc | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								esphome/components/nfc/ndef_record_text.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								esphome/components/nfc/ndef_record_text.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | #include "ndef_record_text.h" | ||||||
|  | #include "ndef_record.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace nfc { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "nfc.ndef_record_text"; | ||||||
|  |  | ||||||
|  | NdefRecordText::NdefRecordText(const std::vector<uint8_t> &payload) { | ||||||
|  |   if (payload.empty()) { | ||||||
|  |     ESP_LOGE(TAG, "Record payload too short"); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   uint8_t language_code_length = payload[0] & 0b00111111;  // Todo, make use of encoding bit? | ||||||
|  |  | ||||||
|  |   this->language_code_ = std::string(payload.begin() + 1, payload.begin() + 1 + language_code_length); | ||||||
|  |  | ||||||
|  |   this->text_ = std::string(payload.begin() + 1 + language_code_length, payload.end()); | ||||||
|  |  | ||||||
|  |   this->tnf_ = TNF_WELL_KNOWN; | ||||||
|  |  | ||||||
|  |   this->type_ = "T"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::vector<uint8_t> NdefRecordText::get_encoded_payload() { | ||||||
|  |   std::vector<uint8_t> data; | ||||||
|  |  | ||||||
|  |   uint8_t flag_byte = this->language_code_.length() & 0b00111111;  // UTF8 assumed | ||||||
|  |  | ||||||
|  |   data.push_back(flag_byte); | ||||||
|  |  | ||||||
|  |   data.insert(data.end(), this->language_code_.begin(), this->language_code_.end()); | ||||||
|  |  | ||||||
|  |   data.insert(data.end(), this->text_.begin(), this->text_.end()); | ||||||
|  |   return data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace nfc | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										41
									
								
								esphome/components/nfc/ndef_record_text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								esphome/components/nfc/ndef_record_text.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  | #include "ndef_record.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace nfc { | ||||||
|  |  | ||||||
|  | class NdefRecordText : public NdefRecord { | ||||||
|  |  public: | ||||||
|  |   NdefRecordText(){}; | ||||||
|  |   NdefRecordText(const std::vector<uint8_t> &payload); | ||||||
|  |   NdefRecordText(const std::string &language_code, const std::string &text) { | ||||||
|  |     this->tnf_ = TNF_WELL_KNOWN; | ||||||
|  |     this->type_ = "T"; | ||||||
|  |     this->language_code_ = language_code; | ||||||
|  |     this->text_ = text; | ||||||
|  |   }; | ||||||
|  |   NdefRecordText(const std::string &language_code, const std::string &text, const std::string &id) { | ||||||
|  |     this->tnf_ = TNF_WELL_KNOWN; | ||||||
|  |     this->type_ = "T"; | ||||||
|  |     this->language_code_ = language_code; | ||||||
|  |     this->text_ = text; | ||||||
|  |     this->id_ = id; | ||||||
|  |   }; | ||||||
|  |   NdefRecordText(const NdefRecordText &) = default; | ||||||
|  |  | ||||||
|  |   std::unique_ptr<NdefRecord> clone() const override { return make_unique<NdefRecordText>(*this); }; | ||||||
|  |  | ||||||
|  |   std::vector<uint8_t> get_encoded_payload() override; | ||||||
|  |  | ||||||
|  |   const std::string &get_payload() const override { return this->text_; }; | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   std::string text_; | ||||||
|  |   std::string language_code_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace nfc | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										48
									
								
								esphome/components/nfc/ndef_record_uri.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								esphome/components/nfc/ndef_record_uri.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | #include "ndef_record_uri.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace nfc { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "nfc.ndef_record_uri"; | ||||||
|  |  | ||||||
|  | NdefRecordUri::NdefRecordUri(const std::vector<uint8_t> &payload) { | ||||||
|  |   if (payload.empty()) { | ||||||
|  |     ESP_LOGE(TAG, "Record payload too short"); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   uint8_t payload_identifier = payload[0];  // First byte of payload is prefix code | ||||||
|  |  | ||||||
|  |   std::string uri(payload.begin() + 1, payload.end()); | ||||||
|  |  | ||||||
|  |   if (payload_identifier > 0x00 && payload_identifier <= PAYLOAD_IDENTIFIERS_COUNT) { | ||||||
|  |     uri.insert(0, PAYLOAD_IDENTIFIERS[payload_identifier]); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   this->tnf_ = TNF_WELL_KNOWN; | ||||||
|  |   this->type_ = "U"; | ||||||
|  |   this->set_URI(uri); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::vector<uint8_t> NdefRecordUri::get_encoded_payload() { | ||||||
|  |   std::vector<uint8_t> data; | ||||||
|  |  | ||||||
|  |   uint8_t payload_prefix = 0x00; | ||||||
|  |   uint8_t payload_prefix_length = 0x00; | ||||||
|  |   for (uint8_t i = 1; i < PAYLOAD_IDENTIFIERS_COUNT; i++) { | ||||||
|  |     std::string prefix = PAYLOAD_IDENTIFIERS[i]; | ||||||
|  |     if (this->URI_.substr(0, prefix.length()).find(prefix) != std::string::npos) { | ||||||
|  |       payload_prefix = i; | ||||||
|  |       payload_prefix_length = prefix.length(); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   data.push_back(payload_prefix); | ||||||
|  |  | ||||||
|  |   data.insert(data.end(), this->URI_.begin() + payload_prefix_length, this->URI_.end()); | ||||||
|  |   return data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace nfc | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										76
									
								
								esphome/components/nfc/ndef_record_uri.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								esphome/components/nfc/ndef_record_uri.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  | #include "ndef_record.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace nfc { | ||||||
|  |  | ||||||
|  | static const uint8_t PAYLOAD_IDENTIFIERS_COUNT = 0x23; | ||||||
|  | static const char *const PAYLOAD_IDENTIFIERS[] = {"", | ||||||
|  |                                                   "http://www.", | ||||||
|  |                                                   "https://www.", | ||||||
|  |                                                   "http://", | ||||||
|  |                                                   "https://", | ||||||
|  |                                                   "tel:", | ||||||
|  |                                                   "mailto:", | ||||||
|  |                                                   "ftp://anonymous:anonymous@", | ||||||
|  |                                                   "ftp://ftp.", | ||||||
|  |                                                   "ftps://", | ||||||
|  |                                                   "sftp://", | ||||||
|  |                                                   "smb://", | ||||||
|  |                                                   "nfs://", | ||||||
|  |                                                   "ftp://", | ||||||
|  |                                                   "dav://", | ||||||
|  |                                                   "news:", | ||||||
|  |                                                   "telnet://", | ||||||
|  |                                                   "imap:", | ||||||
|  |                                                   "rtsp://", | ||||||
|  |                                                   "urn:", | ||||||
|  |                                                   "pop:", | ||||||
|  |                                                   "sip:", | ||||||
|  |                                                   "sips:", | ||||||
|  |                                                   "tftp:", | ||||||
|  |                                                   "btspp://", | ||||||
|  |                                                   "btl2cap://", | ||||||
|  |                                                   "btgoep://", | ||||||
|  |                                                   "tcpobex://", | ||||||
|  |                                                   "irdaobex://", | ||||||
|  |                                                   "file://", | ||||||
|  |                                                   "urn:epc:id:", | ||||||
|  |                                                   "urn:epc:tag:", | ||||||
|  |                                                   "urn:epc:pat:", | ||||||
|  |                                                   "urn:epc:raw:", | ||||||
|  |                                                   "urn:epc:", | ||||||
|  |                                                   "urn:nfc:"}; | ||||||
|  |  | ||||||
|  | class NdefRecordUri : public NdefRecord { | ||||||
|  |  public: | ||||||
|  |   NdefRecordUri(){}; | ||||||
|  |   NdefRecordUri(const std::vector<uint8_t> &payload); | ||||||
|  |   NdefRecordUri(const std::string &URI) { | ||||||
|  |     this->tnf_ = TNF_WELL_KNOWN; | ||||||
|  |     this->type_ = "U"; | ||||||
|  |     this->URI_ = URI; | ||||||
|  |   }; | ||||||
|  |   NdefRecordUri(const std::string &URI, const std::string &id) { | ||||||
|  |     this->tnf_ = TNF_WELL_KNOWN; | ||||||
|  |     this->type_ = "U"; | ||||||
|  |     this->URI_ = URI; | ||||||
|  |     this->id_ = id; | ||||||
|  |   }; | ||||||
|  |   NdefRecordUri(const NdefRecordUri &) = default; | ||||||
|  |   std::unique_ptr<NdefRecord> clone() const override { return make_unique<NdefRecordUri>(*this); }; | ||||||
|  |  | ||||||
|  |   void set_URI(const std::string &URI) { this->URI_ = URI; }; | ||||||
|  |  | ||||||
|  |   std::vector<uint8_t> get_encoded_payload() override; | ||||||
|  |   const std::string &get_payload() const override { return this->URI_; }; | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   std::string URI_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace nfc | ||||||
|  | }  // namespace esphome | ||||||
		Reference in New Issue
	
	Block a user