diff --git a/VERSION b/VERSION
index 0ea3a94..0c62199 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.0
+0.2.1
diff --git a/vendor/github.com/hsanjuan/go-ndef/LICENSE b/vendor/github.com/hsanjuan/go-ndef/LICENSE
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vendor/github.com/hsanjuan/go-ndef/byte_utils.go b/vendor/github.com/hsanjuan/go-ndef/byte_utils.go
new file mode 100644
index 0000000..2de485e
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/byte_utils.go
@@ -0,0 +1,96 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+package ndef
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+)
+
+// BytesToUint64 parses a byte slice to an uint64 (BigEndian). If the slice
+// is longer than 8 bytes, it's truncated. If it's shorter, they are considered
+// the less significant bits of the uint64.
+func bytesToUint64(b []byte) uint64 {
+ // Make sure we are not parsing more than 8 bytes (uint64 size)
+ byte8 := make([]byte, 8)
+ if len(b) > 8 {
+ copy(byte8, b[len(b)-8:]) // use the last 8 bytes
+ } else {
+ copy(byte8[8-len(b):], b) // copy to last positions of byte8
+ }
+ return binary.BigEndian.Uint64(byte8)
+}
+
+// Uint64ToBytes converts a BigEndian uint64 into a byte slice of
+// desiredLen. For lengths under 8 bytes, the 8 byte result is
+// truncated (the most significant bytes are discarded
+func uint64ToBytes(n uint64, desiredLen int) []byte {
+ buf := new(bytes.Buffer)
+ binary.Write(buf, binary.BigEndian, n)
+ if desiredLen >= 8 {
+ slice := make([]byte, desiredLen)
+ copy(slice[desiredLen-8:], buf.Bytes())
+ return slice
+ }
+
+ return buf.Bytes()[8-desiredLen:]
+}
+
+// func PrintBytes(bytes []byte, length int) {
+// for i := 0; i < length; i++ {
+// fmt.Printf("%02x ", bytes[i])
+// }
+// fmt.Println()
+// }
+
+// FmtBytes receives a byte slice and a n value and returns
+// a string with first n hex-formatted values of the slice
+func fmtBytes(bytes []byte, n int) (str string) {
+ if n > len(bytes) {
+ n = len(bytes)
+ }
+ for i := 0; i < n; i++ {
+ str += fmt.Sprintf("%02x ", bytes[i])
+ }
+ return str
+}
+
+// Reads from the bytes buffer and panics with an error
+// if the buffer does not have the bytes to read that we want
+// This is meant as a replacement for byteslice[3:3+x] where
+// I don't have to constantly check the array length
+// but instead I throw a custom panic
+func getBytes(b *bytes.Buffer, n int) []byte {
+ slice := make([]byte, n)
+ nread, err := b.Read(slice)
+ if err != nil || nread != n {
+ panic(errors.New("unexpected end of data"))
+ }
+ return slice
+}
+
+// Same as above bug for a single byte
+func getByte(b *bytes.Buffer) byte {
+ byte, err := b.ReadByte()
+ if err != nil {
+ panic(errors.New("unexpected end of data"))
+ }
+ return byte
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/message.go b/vendor/github.com/hsanjuan/go-ndef/message.go
new file mode 100644
index 0000000..9c910ce
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/message.go
@@ -0,0 +1,235 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+package ndef
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strings"
+)
+
+// Message represents an NDEF Message, which is a collection of one or
+// more NDEF Records.
+//
+// Most common types of NDEF Messages (URI, Media) only have a single
+// record. However, others, like Smart Posters, have multiple ones.
+type Message struct {
+ Records []*Record
+}
+
+// NewMessage returns a new Message initialized with a single Record
+// with the TNF, Type, ID and Payload values.
+func NewMessage(tnf byte, rtype string, id string, payload RecordPayload) *Message {
+ return &Message{
+ Records: []*Record{NewRecord(tnf, rtype, id, payload)},
+ }
+}
+
+// NewMessageFromRecords returns a new Message containing several NDEF
+// Records. The MB and ME flags for the records are adjusted to
+// create a valid message.
+func NewMessageFromRecords(records ...*Record) *Message {
+ n := len(records)
+ if n == 0 {
+ return &Message{}
+ }
+
+ last := n - 1
+
+ for _, r := range records {
+ r.SetMB(false)
+ r.SetME(false)
+ }
+
+ records[0].SetMB(true)
+ records[last].SetME(true)
+
+ return &Message{
+ Records: records,
+ }
+}
+
+// NewTextMessage returns a new Message with a single Record
+// of WellKnownType T[ext].
+func NewTextMessage(textVal, language string) *Message {
+ return &Message{
+ []*Record{NewTextRecord(textVal, language)},
+ }
+}
+
+// NewURIMessage returns a new Message with a single Record
+// of WellKnownType U[RI].
+func NewURIMessage(uriVal string) *Message {
+ return &Message{
+ []*Record{NewURIRecord(uriVal)},
+ }
+}
+
+// NewSmartPosterMessage returns a new Message with a single Record
+// of WellKnownType Sp (Smart Poster).
+func NewSmartPosterMessage(msgPayload *Message) *Message {
+ return &Message{
+ []*Record{NewSmartPosterRecord(msgPayload)},
+ }
+}
+
+// NewMediaMessage returns a new Message with a single Record
+// of Media (RFC-2046) type.
+//
+// mimeType is something like "text/json" or "image/jpeg".
+func NewMediaMessage(mimeType string, payload []byte) *Message {
+ return &Message{
+ []*Record{NewMediaRecord(mimeType, payload)},
+ }
+}
+
+// NewAbsoluteURIMessage returns a new Message with a single Record
+// of AbsoluteURI type.
+//
+// AbsoluteURI means that the type of the payload for this record is
+// defined by an URI resource. It is not supposed to be used to
+// describe an URI. For that, use NewURIRecord().
+func NewAbsoluteURIMessage(typeURI string, payload []byte) *Message {
+ return &Message{
+ []*Record{NewAbsoluteURIRecord(typeURI, payload)},
+ }
+}
+
+// NewExternalMessage returns a new Message with a single Record
+// of NFC Forum External type.
+func NewExternalMessage(extType string, payload []byte) *Message {
+ return &Message{
+ []*Record{NewExternalRecord(extType, payload)},
+ }
+}
+
+// Returns the string representation of each of the records in the message.
+func (m *Message) String() string {
+ str := ""
+ last := len(m.Records) - 1
+ for i, r := range m.Records {
+ str += r.String()
+ if i != last {
+ str += "\n"
+ }
+ }
+ return str
+}
+
+// Inspect returns a string with information about the message and its records.
+func (m *Message) Inspect() string {
+ str := fmt.Sprintf("NDEF Message with %d records.", len(m.Records))
+ if len(m.Records) > 0 {
+ str += "\n"
+ for i, r := range m.Records {
+ str += fmt.Sprintf("Record %d:\n", i)
+ rIns := r.Inspect()
+ rInsLines := strings.Split(rIns, "\n")
+ for _, l := range rInsLines {
+ str += " " + l + "\n"
+ }
+ }
+ }
+ return str
+}
+
+// Unmarshal parses a byte slice into a Message. This is done by
+// parsing all Records in the slice, until there are no more to parse.
+//
+// Returns the number of bytes processed (message length), or an error
+// if something looks wrong with the message or its records.
+func (m *Message) Unmarshal(buf []byte) (rLen int, err error) {
+ m.Records = []*Record{}
+ rLen = 0
+ for rLen < len(buf) {
+ r := new(Record)
+ recordLen, err := r.Unmarshal(buf[rLen:])
+ rLen += recordLen
+ if err != nil {
+ return rLen, err
+ }
+ m.Records = append(m.Records, r)
+ if r.ME() { // last record in message
+ break
+ }
+ }
+
+ err = m.check()
+ return rLen, err
+}
+
+// Marshal provides the byte slice representation of a Message,
+// which is the concatenation of the Marshaling of each of its records.
+//
+// Returns an error if something goes wrong.
+func (m *Message) Marshal() ([]byte, error) {
+ err := m.check()
+ if err != nil {
+ return nil, err
+ }
+
+ var buffer bytes.Buffer
+ for _, r := range m.Records {
+ rBytes, err := r.Marshal()
+ if err != nil {
+ return nil, err
+ }
+ _, err = buffer.Write(rBytes)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return buffer.Bytes(), nil
+}
+
+func (m *Message) check() error {
+ last := len(m.Records) - 1
+
+ if last < 0 {
+ return errors.New(eNORECORDS)
+ }
+
+ if !m.Records[0].MB() {
+ return errors.New(eNOMB)
+ }
+
+ if !m.Records[last].ME() {
+ return errors.New(eNOME)
+ }
+
+ for i, r := range m.Records {
+ if i > 0 && r.MB() {
+ return errors.New(eBADMB)
+ }
+ if i < last && r.ME() {
+ return errors.New(eBADME)
+ }
+ }
+
+ return nil
+}
+
+// Check errors
+const (
+ eNORECORDS = "NDEF Message Check: No records"
+ eNOMB = "NDEF Message Check: first record has not the MessageBegin flag set"
+ eNOME = "NDEF Message Check: last record has not the MessageEnd flag set"
+ eBADMB = "NDEF Message Check: middle record has the MessageBegin flag set"
+ eBADME = "NDEF Message Check: middle record has the MessageEnd flag set"
+)
diff --git a/vendor/github.com/hsanjuan/go-ndef/ndef.go b/vendor/github.com/hsanjuan/go-ndef/ndef.go
new file mode 100644
index 0000000..2b5224c
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/ndef.go
@@ -0,0 +1,36 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// Package ndef provides an implementation of the NFC Data Exchange
+// Format (NDEF) specification:
+// - NFCForum-TS-NDEF_1.0
+// - NFCForum-TS-RTD_1.0
+// It allows to parse byte slices into a structured Message type,
+// as well as to turn an Message into a bytes again.
+package ndef
+
+// Possible values for the TNF Field as defined in the specification.
+const (
+ Empty = byte(iota)
+ NFCForumWellKnownType
+ MediaType
+ AbsoluteURI
+ NFCForumExternalType
+ Unknown
+ Unchanged
+ Reserved
+)
diff --git a/vendor/github.com/hsanjuan/go-ndef/record.go b/vendor/github.com/hsanjuan/go-ndef/record.go
new file mode 100644
index 0000000..77b7c2d
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/record.go
@@ -0,0 +1,342 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+package ndef
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+
+ "github.com/hsanjuan/go-ndef/types/absoluteuri"
+ "github.com/hsanjuan/go-ndef/types/ext"
+ "github.com/hsanjuan/go-ndef/types/media"
+ "github.com/hsanjuan/go-ndef/types/wkt/text"
+ "github.com/hsanjuan/go-ndef/types/wkt/uri"
+)
+
+// A Record is an NDEF Record. Multiple records can be
+// part of a single NDEF Message.
+type Record struct {
+ chunks []*recordChunk
+}
+
+// NewRecord returns a single-chunked record with the given options.
+// Use a generic.Payload if you want to use a custom byte-slice for payload.
+func NewRecord(tnf byte, typ string, id string, payload RecordPayload) *Record {
+ var payloadBytes []byte
+ if payload != nil {
+ payloadBytes = payload.Marshal()
+ }
+
+ chunk := newChunk(
+ tnf,
+ typ,
+ id,
+ payloadBytes,
+ )
+ return &Record{
+ chunks: []*recordChunk{chunk},
+ }
+}
+
+// TNF returns the Type Name Format (3 bits) associated to this Record.
+func (r *Record) TNF() byte {
+ if r.Empty() {
+ return 0
+ }
+ return r.chunks[0].TNF
+}
+
+// Type returns the declared Type for this record.
+func (r *Record) Type() string {
+ if r.Empty() {
+ return ""
+ }
+ return r.chunks[0].Type
+}
+
+// ID returns the declared record ID for this record.
+func (r *Record) ID() string {
+ if r.Empty() {
+ return ""
+ }
+ return r.chunks[0].ID
+}
+
+// Payload returns the RecordPayload for this record. It will use
+// one of the supported types, or otherwise a generic.Payload.
+func (r *Record) Payload() (RecordPayload, error) {
+ if r.Empty() {
+ return nil, errors.New("empty record")
+ }
+
+ var buf bytes.Buffer
+ for _, chunk := range r.chunks {
+ _, err := buf.Write(chunk.Payload)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return makeRecordPayload(r.TNF(), r.Type(), buf.Bytes()), nil
+}
+
+// Empty returns true if this record has no chunks.
+func (r *Record) Empty() bool {
+ return len(r.chunks) == 0
+}
+
+// MB returns the value of the MessageBegin bit of the first chunk of this
+// record, signaling that this is the first record in an NDEF Message.
+// a NDEF Message.
+func (r *Record) MB() bool {
+ if r.Empty() {
+ return false
+ }
+ return r.chunks[0].MB
+}
+
+// SetMB sets the MessageBegin bit of the first chunk of this Record.
+func (r *Record) SetMB(b bool) {
+ if r.Empty() {
+ return
+ }
+ r.chunks[0].MB = b
+}
+
+// ME returns the value of the MessageEnd bit of the last chunk of this Record,
+// signaling that this is the last record in an NDEF Message.
+func (r *Record) ME() bool {
+ if r.Empty() {
+ return false
+ }
+ return r.chunks[len(r.chunks)-1].ME
+}
+
+// SetME sets the MessageEnd bit of the last chunk of this record.
+func (r *Record) SetME(b bool) {
+ if r.Empty() {
+ return
+ }
+ r.chunks[len(r.chunks)-1].ME = b
+}
+
+// NewTextRecord returns a new Record with a
+// Payload of Text [Well-Known] Type.
+func NewTextRecord(textVal, language string) *Record {
+ pl := text.New(textVal, language)
+ return NewRecord(NFCForumWellKnownType, "T", "", pl)
+}
+
+// NewURIRecord returns a new Record with a
+// Payload of URI [Well-Known] Type.
+func NewURIRecord(uriVal string) *Record {
+ pl := uri.New(uriVal)
+ return NewRecord(NFCForumWellKnownType, "U", "", pl)
+}
+
+// NewSmartPosterRecord creates a new Record representing a Smart Poster.
+// The Payload of a Smart Poster is an NDEF Message.
+func NewSmartPosterRecord(msg *Message) *Record {
+ pl := NewSmartPosterPayload(msg)
+ return NewRecord(NFCForumWellKnownType, "Sp", "", pl)
+}
+
+// NewMediaRecord returns a new Record with a
+// Media type (per RFC-2046) as payload.
+//
+// mimeType is something like "text/json" or "image/jpeg".
+func NewMediaRecord(mimeType string, payload []byte) *Record {
+ pl := media.New(mimeType, payload)
+ return NewRecord(MediaType, mimeType, "", pl)
+}
+
+// NewAbsoluteURIRecord returns a new Record with a
+// Payload of Absolute URI type.
+//
+// AbsoluteURI means that the type of the payload for this record is
+// defined by an URI resource. It is not supposed to be used to
+// describe an URI. For that, use NewURIRecord().
+func NewAbsoluteURIRecord(typeURI string, payload []byte) *Record {
+ pl := absoluteuri.New(typeURI, payload)
+ return NewRecord(AbsoluteURI, typeURI, "", pl)
+}
+
+// NewExternalRecord returns a new Record with a
+// Payload of NFC Forum external type.
+func NewExternalRecord(extType string, payload []byte) *Record {
+ pl := ext.New(extType, payload)
+ return NewRecord(NFCForumExternalType, extType, "", pl)
+}
+
+// String a string representation of the payload of the record, prefixed
+// by the URN of the resource.
+//
+// Note that not all NDEF Payloads are supported, and that custom types/payloads
+// are considered not printable. In those cases, a generic RecordPayload is
+// used and an explanatory message is returned instead.
+// See submodules under "types/" for a list of supported types.
+func (r *Record) String() string {
+ pl, err := r.Payload()
+ if err != nil {
+ return err.Error()
+ }
+ return pl.Type() + ":" + pl.String()
+}
+
+// Inspect provides a string with information about this record.
+// For a String representation of the contents use String().
+func (r *Record) Inspect() string {
+ if r.Empty() {
+ return "Empty record"
+ }
+
+ pl, err := r.Payload()
+ if err != nil {
+ return err.Error()
+ }
+
+ var str string
+ str += fmt.Sprintf("TNF: %d\n", r.TNF())
+ str += fmt.Sprintf("Type: %s\n", r.Type())
+ str += fmt.Sprintf("ID: %s\n", r.ID())
+ str += fmt.Sprintf("MB: %t\n", r.MB())
+ str += fmt.Sprintf("ME: %t\n", r.ME())
+ str += fmt.Sprintf("Payload Length: %d", pl.Len())
+ return str
+}
+
+// Unmarshal parses a byte slice into a Record struct (the slice can
+// have extra bytes which are ignored). The Record is always reset before
+// parsing.
+//
+// It does this by parsing every record chunk until a chunk with the CF flag
+// cleared is read is read.
+//
+// Returns how many bytes were parsed from the slice (record length) or
+// an error if something went wrong.
+func (r *Record) Unmarshal(buf []byte) (rLen int, err error) {
+ rLen = 0
+ var chunks []*recordChunk
+ for rLen < len(buf) {
+ chunk := &recordChunk{}
+ chunkSize, err := chunk.Unmarshal(buf[rLen:])
+ rLen += chunkSize
+ if err != nil {
+ return rLen, err
+ }
+ chunks = append(chunks, chunk)
+
+ // the last chunk record of a chunked record
+ // has the CF flag cleared.
+ if !chunk.CF {
+ break
+ }
+ }
+
+ r.chunks = chunks
+ err = r.check()
+ return rLen, err
+}
+
+// Marshal returns the byte representation of a Record. It does this
+// by producing a single record chunk.
+//
+// Note that if the original Record was unmarshaled from many chunks,
+// the recovery is not possible anymore.
+func (r *Record) Marshal() ([]byte, error) {
+ err := r.check()
+ if err != nil {
+ return nil, err
+ }
+
+ var buf bytes.Buffer
+ for _, chunk := range r.chunks {
+ chunkBytes, err := chunk.Marshal()
+ if err != nil {
+ return buf.Bytes(), err
+ }
+ _, err = buf.Write(chunkBytes)
+ if err != nil {
+ return buf.Bytes(), err
+ }
+ }
+ return buf.Bytes(), nil
+}
+
+func (r *Record) check() error {
+ chunksLen := len(r.chunks)
+ last := chunksLen - 1
+ if chunksLen == 0 {
+ return errors.New(eNOCHUNKS)
+ }
+ if chunksLen == 1 && r.chunks[0].CF {
+ return errors.New(eFIRSTCHUNKED)
+ }
+ if r.chunks[0].CF && r.chunks[last].CF {
+ return errors.New(eLASTCHUNKED)
+ }
+
+ if chunksLen > 1 {
+ chunksWithoutCF := 0
+ chunksWithIL := 0
+ chunksWithTypeLength := 0
+ chunksWithoutUnchangedType := 0
+ for i, r := range r.chunks {
+ // Check CF in all but the last
+ if !r.CF && i != last {
+ chunksWithoutCF++
+ }
+ // Check IL in all but first
+ if r.IL && i != 0 {
+ chunksWithIL++
+ }
+ // TypeLength should be zero except in the first
+ if r.TypeLength > 0 && i != 0 {
+ chunksWithTypeLength++
+ }
+ // All but first chunk should have TNF to 0x06
+ if r.TNF != Unchanged && i != 0 {
+ chunksWithoutUnchangedType++
+ }
+ }
+ if chunksWithoutCF > 0 {
+ return errors.New(eCFMISSING)
+ }
+ if chunksWithIL > 0 {
+ return errors.New(eBADIL)
+ }
+ if chunksWithTypeLength > 0 {
+ return errors.New(eBADTYPELENGTH)
+ }
+ if chunksWithoutUnchangedType > 0 {
+ return errors.New(eBADTNF)
+ }
+ }
+ return nil
+}
+
+// Set some short-hands for the errors that can happen on check().
+const (
+ eNOCHUNKS = "NDEF Record Check: No chunks"
+ eFIRSTCHUNKED = "NDEF Record Check: A single record cannot have the Chunk flag set"
+ eLASTCHUNKED = "NDEF Record Check: Last record cannot have the Chunk flag set"
+ eCFMISSING = "NDEF Record Check: Chunk Flag missing from some records"
+ eBADIL = "NDEF Record Check: IL flag is set on a middle or final chunk"
+ eBADTYPELENGTH = "NDEF Record Check: A middle or last chunk has TypeLength != 0"
+ eBADTNF = "NDEF Record Check: A middle or last chunk TNF is not UNCHANGED"
+)
diff --git a/vendor/github.com/hsanjuan/go-ndef/record_chunk.go b/vendor/github.com/hsanjuan/go-ndef/record_chunk.go
new file mode 100644
index 0000000..28cd289
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/record_chunk.go
@@ -0,0 +1,269 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+package ndef
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "runtime"
+)
+
+// RecordChunk represents how a Record is actually stored
+// We need this for parsing and checking the validity of a Record
+// before assembling them.
+type recordChunk struct {
+ // First byte
+ MB bool // Message begin
+ ME bool // Message end
+ CF bool // Chunk Flag
+ SR bool // Short record
+ IL bool // ID length field present
+ TNF byte // Type name format (3 bits)
+ TypeLength byte // Type Length
+ IDLength byte // Length of the ID field
+ PayloadLength uint64 // Length of the Payload.
+ Type string // Type of the payload. Must follow TNF
+ ID string // An URI (per RFC 3986)
+ Payload []byte // Payload
+}
+
+// Reset clears up all the fields of the Record and sets them to their
+// default values.
+func (r *recordChunk) Reset() {
+ r.MB = false
+ r.ME = false
+ r.CF = false
+ r.SR = false
+ r.IL = false
+ r.TNF = 0
+ r.TypeLength = 0
+ r.IDLength = 0
+ r.PayloadLength = 0
+ r.Type = ""
+ r.ID = ""
+ r.Payload = []byte{}
+}
+
+// New returns a single RecordChunk with the given options. This chunk can be
+// used directly to make a single-chunk NDEF Record on a single-record NDEF
+// message: the MB and ME fields are set to true.
+func newChunk(tnf byte, typ string, id string, payload []byte) *recordChunk {
+ chunk := &recordChunk{}
+ chunk.Reset()
+ chunk.MB = true // Message-begin
+ chunk.ME = true // Message-end
+ chunk.CF = false // not chunked
+ chunk.IL = len(id) > 0 // only if ID field present
+ chunk.TNF = tnf
+ chunk.TypeLength = byte(len([]byte(typ)))
+ chunk.Type = typ
+ chunk.IDLength = byte(len([]byte(id)))
+ chunk.ID = id
+
+ payloadLen := uint64(len(payload))
+ if payloadLen > 4294967295 { //2^32-1. 4GB message max.
+ payloadLen = 4294967295
+ }
+ chunk.SR = payloadLen < 256 // Short record vs. Long
+ chunk.PayloadLength = payloadLen
+
+ // FIXME: If payload is greater than 2^32 - 1
+ // we'll truncate without warning.
+ chunk.Payload = payload[:payloadLen]
+ return chunk
+}
+
+// Provide a string with information about this record chunk.
+// Records' payload do not make sense without having compiled a whole Record
+// so they are not dealed with here.
+func (r *recordChunk) String() string {
+ var str string
+ str += fmt.Sprintf("MB: %t | ME: %t | CF: %t | SR: %t | IL: %t | TNF: %d\n",
+ r.MB, r.ME, r.CF, r.SR, r.IL, r.TNF)
+ str += fmt.Sprintf("TypeLength: %d", r.TypeLength)
+ str += fmt.Sprintf(" | Type: %s\n", r.Type)
+ str += fmt.Sprintf("Record Payload Length: %d",
+ r.PayloadLength)
+ if r.IL {
+ str += fmt.Sprintf(" | IDLength: %d", r.IDLength)
+ str += fmt.Sprintf(" | ID: %s", r.ID)
+ }
+ str += fmt.Sprintf("\n")
+ return str
+}
+
+// Unmarshal parses a byte slice into a single Record chunk struct (the slice
+// can have extra bytes which are ignored). The Record is always reset before
+// parsing.
+//
+// Returns how many bytes were parsed from the slice (record length) or
+// an error if something went wrong.
+func (r *recordChunk) Unmarshal(buf []byte) (rLen int, err error) {
+ // Handle errors that are produced by getByte() and getBytes()
+ defer func() {
+ if r := recover(); r != nil {
+ if _, ok := r.(runtime.Error); ok {
+ panic(r)
+ }
+ err = r.(error)
+ err = errors.New("Record.Unmarshal: " + err.Error())
+ }
+ }()
+ r.Reset()
+ bytesBuf := bytes.NewBuffer(buf)
+
+ firstByte := getByte(bytesBuf)
+ r.MB = (firstByte >> 7 & 0x1) == 1
+ r.ME = (firstByte >> 6 & 0x1) == 1
+ r.CF = (firstByte >> 5 & 0x1) == 1
+ r.SR = (firstByte >> 4 & 0x1) == 1
+ r.IL = (firstByte >> 3 & 0x1) == 1
+ r.TNF = firstByte & 0x7
+
+ r.TypeLength = getByte(bytesBuf)
+
+ if r.SR { //This is a short record
+ r.PayloadLength = uint64(getByte(bytesBuf))
+ } else { // Regular record
+ r.PayloadLength = bytesToUint64(getBytes(bytesBuf, 4))
+ }
+ if r.IL {
+ r.IDLength = getByte(bytesBuf)
+ }
+ r.Type = string(getBytes(bytesBuf, int(r.TypeLength)))
+ if r.IL {
+ r.ID = string(getBytes(bytesBuf, int(r.IDLength)))
+ }
+ r.Payload = getBytes(bytesBuf, int(r.PayloadLength))
+
+ rLen = len(buf) - bytesBuf.Len()
+ err = r.Check()
+ if err != nil {
+ return rLen, err
+ }
+ return rLen, nil
+}
+
+// Marshal returns the byte representation of a Record, or an error
+// if something went wrong
+func (r *recordChunk) Marshal() ([]byte, error) {
+ err := r.Check()
+ if err != nil {
+ return nil, err
+ }
+ var buffer bytes.Buffer
+ firstByte := byte(0)
+ if r.MB {
+ firstByte |= 0x1 << 7
+ }
+ if r.ME {
+ firstByte |= 0x1 << 6
+ }
+ if r.CF {
+ firstByte |= 0x1 << 5
+ }
+ if r.SR {
+ firstByte |= 0x1 << 4
+ }
+ if r.IL {
+ firstByte |= 0x1 << 3
+ }
+ firstByte |= (r.TNF & 0x7) //Last 3 bits are from TNF
+ buffer.WriteByte(firstByte)
+ // TypeLength byte
+ buffer.WriteByte(r.TypeLength)
+
+ // Payload Length byte (for SR) or 4 bytes for the regular case
+ if r.SR {
+ buffer.WriteByte(byte(r.PayloadLength))
+ } else {
+ buffer.Write(uint64ToBytes(r.PayloadLength, 4))
+ }
+
+ // ID Length byte if we are meant to have it
+ if r.IL {
+ buffer.WriteByte(r.IDLength)
+ }
+
+ // Write the type bytes if we have something
+ if r.TypeLength > 0 {
+ buffer.Write([]byte(r.Type))
+ }
+
+ // Write the ID bytes if we have something
+ if r.IL && r.IDLength > 0 {
+ buffer.Write([]byte(r.ID))
+ }
+
+ buffer.Write(r.Payload)
+ return buffer.Bytes(), nil
+}
+
+// Check verifies that fields in this chunk are not in violation of the spec.
+func (r *recordChunk) Check() error {
+ // If the TNF value is 0x00, the TYPE_LENGTH, ID_LENGTH,
+ // and PAYLOAD_LENGTH fields MUST be zero and the TYPE, ID,
+ // and PAYLOAD fields MUST be omitted from the record.
+ if r.TNF == Empty && (r.TypeLength > 0 ||
+ r.IDLength > 0 || r.PayloadLength > 0) {
+ return errors.New("Record.check: " +
+ "Empty record TNF but not empty fields")
+ }
+ // If the TNF value is 0x05 or 0x06 (Unknown/Unchanged),
+ // the TYPE_LENGTH field MUST be 0 and the TYPE
+ // field MUST be omitted from the NDEF record.
+ if (r.TNF == Unknown || r.TNF == Unchanged) && r.TypeLength > 0 {
+ return errors.New("Record.check: " +
+ "This TNF does not support a Type field")
+ }
+
+ // The TNF value MUST NOT be 0x07.
+ if r.TNF == Reserved {
+ return errors.New("Record.check: " +
+ "The TNF cannot be Reserved, that value is reserved.")
+ }
+
+ // NFC Record Type Definition 3.4:
+ // The binary encoding of Well Known Types
+ // (including Global and Local Names) and External
+ // Type names MUST be done according to the
+ // ASCII chart in Appendix A.
+ if r.TNF == NFCForumWellKnownType ||
+ r.TNF == NFCForumExternalType {
+ typeString := string(r.Type)
+ for _, rune := range typeString {
+ if rune < 32 || rune > 126 {
+ return errors.New("Record.check(): " +
+ "Record type names SHALL " +
+ "be formed of characters from of the " +
+ "US ASCII [ASCII] character set")
+ }
+ }
+ }
+
+ if r.IL && r.IDLength > 0 {
+ for _, rune := range r.ID {
+ if rune < 32 || rune > 126 {
+ return errors.New("Record.check(): " +
+ "ID must use ASCII characters")
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/record_payload.go b/vendor/github.com/hsanjuan/go-ndef/record_payload.go
new file mode 100644
index 0000000..8d63f6d
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/record_payload.go
@@ -0,0 +1,71 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+package ndef
+
+import (
+ "github.com/hsanjuan/go-ndef/types/absoluteuri"
+ "github.com/hsanjuan/go-ndef/types/ext"
+ "github.com/hsanjuan/go-ndef/types/generic"
+ "github.com/hsanjuan/go-ndef/types/media"
+ "github.com/hsanjuan/go-ndef/types/wkt/text"
+ "github.com/hsanjuan/go-ndef/types/wkt/uri"
+)
+
+// The RecordPayload interface should be implemented by supported
+// NDEF Record types. It ensures that we have a way to interpret payloads
+// into printable information and to produce NDEF Record payloads for a given
+// type.
+type RecordPayload interface {
+ // Returns a string representation of the Payload
+ String() string
+ // Provides serialization for the Payload
+ Marshal() []byte
+ // Provides de-serialization for the Payload
+ Unmarshal(buf []byte)
+ // Returns a string indetifying the type of this payload
+ Type() string
+ // Returns the length of the Payload (serialized)
+ Len() int
+}
+
+func makeRecordPayload(tnf byte, rtype string, payload []byte) RecordPayload {
+ var r RecordPayload
+ switch tnf {
+ case NFCForumWellKnownType:
+ switch rtype {
+ case "U":
+ r = new(uri.Payload)
+ case "T":
+ r = new(text.Payload)
+ case "Sp":
+ r = new(SmartPosterPayload)
+ default:
+ r = new(generic.Payload)
+ }
+ case MediaType:
+ r = media.New(rtype, nil)
+ case NFCForumExternalType:
+ r = ext.New(rtype, nil)
+ case AbsoluteURI:
+ r = absoluteuri.New(rtype, nil)
+ default:
+ r = new(generic.Payload)
+ }
+ r.Unmarshal(payload)
+ return r
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/sp.go b/vendor/github.com/hsanjuan/go-ndef/sp.go
new file mode 100644
index 0000000..6158b4d
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/sp.go
@@ -0,0 +1,64 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+package ndef
+
+// Unfortunately splitting this to its own package causes a hard to break cycle.
+
+// SmartPosterPayload represents the Payload of a Smart Poster, which is
+// an NDEF Message with one or multiple records.
+type SmartPosterPayload struct {
+ Message *Message
+}
+
+// NewSmartPosterPayload returns a new Smart Poster payload.
+func NewSmartPosterPayload(msg *Message) *SmartPosterPayload {
+ return &SmartPosterPayload{
+ Message: msg,
+ }
+}
+
+// String returns the contents of the message contained in the Smart Poster.
+func (sp *SmartPosterPayload) String() string {
+ str := "\n"
+ str += sp.Message.String()
+ return str
+}
+
+// Type returns the URN for the Smart Poster type
+func (sp *SmartPosterPayload) Type() string {
+ return "urn:nfc:wkt:Sp"
+}
+
+// Marshal returns the bytes representing the payload of a Smart Poster.
+// The payload is the contained NDEF Message.
+func (sp *SmartPosterPayload) Marshal() []byte {
+ bs, _ := sp.Message.Marshal()
+ return bs
+}
+
+// Unmarshal parses the SmartPosterPayload from a Smart Poster.
+func (sp *SmartPosterPayload) Unmarshal(buf []byte) {
+ msg := &Message{}
+ msg.Unmarshal(buf)
+ sp.Message = msg
+}
+
+// Len returns the length of this payload in bytes.
+func (sp *SmartPosterPayload) Len() int {
+ return len(sp.Marshal())
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/types/absoluteuri/absolute_uri.go b/vendor/github.com/hsanjuan/go-ndef/types/absoluteuri/absolute_uri.go
new file mode 100644
index 0000000..d8207f5
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/types/absoluteuri/absolute_uri.go
@@ -0,0 +1,65 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// Package absoluteuri provides an implementation for NDEF Payloads
+// of Absolute URI type.
+package absoluteuri
+
+// Payload is a wrapper to store a Payload
+type Payload struct {
+ URIType string
+ Payload []byte
+}
+
+// New returns a pointer to a Payload type holding the given payload with the
+// given type.
+func New(uriType string, payload []byte) *Payload {
+ return &Payload{
+ URIType: uriType,
+ Payload: payload,
+ }
+}
+
+// String returns a string explaining that we are not sure how to print
+// this type.
+func (absu *Payload) String() string {
+ if absu.Len() > 0 {
+ return ""
+ }
+ return ""
+}
+
+// Type returns the URI defining the type for this payload
+func (absu *Payload) Type() string {
+ return absu.URIType
+}
+
+// Marshal returns the bytes representing the payload
+func (absu *Payload) Marshal() []byte {
+ return absu.Payload
+}
+
+// Unmarshal parses a generic payload
+func (absu *Payload) Unmarshal(buf []byte) {
+ absu.Payload = buf
+}
+
+// Len is the length of the byte slice resulting of Marshaling
+// this Payload.
+func (absu *Payload) Len() int {
+ return len(absu.Marshal())
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/types/ext/ext.go b/vendor/github.com/hsanjuan/go-ndef/types/ext/ext.go
new file mode 100644
index 0000000..bdc5462
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/types/ext/ext.go
@@ -0,0 +1,65 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// Package ext provides an implementation for NDEF Payloads of NFC Forum
+// External Type.
+package ext
+
+// Payload is a wrapper to store a Payload
+type Payload struct {
+ ExtType string
+ Payload []byte
+}
+
+// New returns a pointer to a Payload type holding the given payload with the
+// given type.
+func New(extType string, payload []byte) *Payload {
+ return &Payload{
+ ExtType: extType,
+ Payload: payload,
+ }
+}
+
+// String returns a string explaining that we are not sure how to print
+// this type.
+func (extT *Payload) String() string {
+ if extT.Len() > 0 {
+ return ""
+ }
+ return ""
+}
+
+// Type returns a readable type name for this payload.
+func (extT *Payload) Type() string {
+ return "urn:nfc:ext:" + extT.ExtType
+}
+
+// Marshal returns the bytes representing the payload
+func (extT *Payload) Marshal() []byte {
+ return extT.Payload
+}
+
+// Unmarshal parses a generic payload
+func (extT *Payload) Unmarshal(buf []byte) {
+ extT.Payload = buf
+}
+
+// Len is the length of the byte slice resulting of Marshaling
+// this Payload.
+func (extT *Payload) Len() int {
+ return len(extT.Marshal())
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/types/generic/generic.go b/vendor/github.com/hsanjuan/go-ndef/types/generic/generic.go
new file mode 100644
index 0000000..e1842f2
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/types/generic/generic.go
@@ -0,0 +1,62 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// Package generic provides a generic implementation for NDEF Payloads which are
+// either custom or not supported yet.
+package generic
+
+// Payload is a wrapper to store a Payload.
+type Payload struct {
+ Payload []byte
+}
+
+// New returns a pointer to a Payload type holding the given payload.
+func New(payload []byte) *Payload {
+ return &Payload{
+ Payload: payload,
+ }
+}
+
+// String returns a string explaining that we are not sure how to print
+// this type.
+func (g *Payload) String() string {
+ if g.Len() > 0 {
+ return ""
+ }
+ return ""
+}
+
+// Type returns the name of the payload type. In this case, it's generic.
+func (g *Payload) Type() string {
+ return "go-ndef-generic"
+}
+
+// Marshal returns the bytes representing the payload of a Record of
+// generic type.
+func (g *Payload) Marshal() []byte {
+ return g.Payload
+}
+
+// Unmarshal parses a generic payload.
+func (g *Payload) Unmarshal(buf []byte) {
+ g.Payload = buf
+}
+
+// Len is the length of the byte slice resulting of Marshaling.
+func (g *Payload) Len() int {
+ return len(g.Marshal())
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/types/media/media.go b/vendor/github.com/hsanjuan/go-ndef/types/media/media.go
new file mode 100644
index 0000000..4ec2d28
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/types/media/media.go
@@ -0,0 +1,65 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// Package media provides an implementation for NDEF Payloads for media
+// types.
+package media
+
+// Payload is a wrapper to store a Payload
+type Payload struct {
+ MimeType string
+ Payload []byte
+}
+
+// New returns a pointer to a Payload type holding the given payload with the
+// given type.
+func New(mimeType string, payload []byte) *Payload {
+ return &Payload{
+ MimeType: mimeType,
+ Payload: payload,
+ }
+}
+
+// String returns a string explaining that we are not sure how to print
+// this type.
+func (media *Payload) String() string {
+ if media.Len() > 0 {
+ return ""
+ }
+ return ""
+}
+
+// Type returns the mime type of this payload.
+func (media *Payload) Type() string {
+ return media.MimeType
+}
+
+// Marshal returns the bytes representing the payload
+func (media *Payload) Marshal() []byte {
+ return media.Payload
+}
+
+// Unmarshal parses a generic payload
+func (media *Payload) Unmarshal(buf []byte) {
+ media.Payload = buf
+}
+
+// Len is the length of the byte slice resulting of Marshaling
+// this Payload.
+func (media *Payload) Len() int {
+ return len(media.Marshal())
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/types/wkt/text/text.go b/vendor/github.com/hsanjuan/go-ndef/types/wkt/text/text.go
new file mode 100644
index 0000000..0916db4
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/types/wkt/text/text.go
@@ -0,0 +1,119 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// BUG(hector): The implementation ignores the guidelines about displaying the
+// text and removing the control characters.
+
+// BUG(hector): UTF-16 with different byte order, with/without BOM is not tested.
+
+// Package text provides support for NDEF Payloads of Text type.
+// It follows the NFC Forum Text Record Type Definition specification
+// (NFCForum-TS-RTD_Text_1.0).
+//
+// The Payload type implements the RecordPayload interface from ndef,
+// so it can be used as ndef.Record.Payload.
+package text
+
+import (
+ "bytes"
+ "strings"
+ "unicode/utf16"
+)
+
+// Payload represents a NDEF Record Payload of type "T", which
+// holds a text field and IANA-formatted language information.
+type Payload struct {
+ Language string
+ Text string
+}
+
+// New returns a pointer to a Payload.
+//
+// The language parameter must be compliant to RFC 3066 (i.e. "en_US"),
+// but no check is performed.
+func New(text, language string) *Payload {
+ return &Payload{
+ Language: language,
+ Text: text,
+ }
+}
+
+// String returns the actual text. Language information is ommited.
+func (t *Payload) String() string {
+ return t.Text
+}
+
+// Type returns the URN for Text types.
+func (t *Payload) Type() string {
+ return "urn:nfc:wkt:T"
+}
+
+// Marshal returns the bytes representing the payload of a text Record.
+func (t *Payload) Marshal() []byte {
+ var buf bytes.Buffer
+ ianaLen := byte(len(t.Language))
+ buf.WriteByte(ianaLen)
+ buf.Write([]byte(t.Language))
+ buf.Write([]byte(t.Text))
+ return buf.Bytes()
+}
+
+// Unmarshal parses the Payload from a text Record.
+func (t *Payload) Unmarshal(buf []byte) {
+ t.Language = ""
+ t.Text = ""
+ i := byte(0)
+ if len(buf) < 1 {
+ return
+ }
+ firstByte := buf[i]
+ i++
+ isUtf16 := firstByte>>7 == 1
+ // firstByte>>6 must be set to 0
+ ianaLen := 0x3F & firstByte // last 5 bytes
+ if len(buf) < int(i+ianaLen) {
+ return
+ }
+ t.Language = string(buf[i : i+ianaLen])
+ i += ianaLen
+ if len(buf) < int(i) {
+ return
+ }
+ if isUtf16 {
+ //Convert buf to []uint16
+ bytesBuf := bytes.NewBuffer(buf[i:])
+ var finished bool
+ var uint16buf []uint16
+ for !finished {
+ b1, err := bytesBuf.ReadByte()
+ b2, err := bytesBuf.ReadByte()
+ uint16buf = append(uint16buf,
+ uint16(b1<<8)|uint16(b2))
+ finished = err != nil
+ }
+ runes := utf16.Decode(uint16buf)
+ // It appears we get an extra trailing char at the end
+ t.Text = strings.TrimSuffix(string(runes), "\x00")
+ } else {
+ t.Text = string(buf[i:])
+ }
+}
+
+// Len is the length of the byte slice resulting of Marshaling..
+func (t *Payload) Len() int {
+ return len(t.Marshal())
+}
diff --git a/vendor/github.com/hsanjuan/go-ndef/types/wkt/uri/uri.go b/vendor/github.com/hsanjuan/go-ndef/types/wkt/uri/uri.go
new file mode 100644
index 0000000..2b66fd2
--- /dev/null
+++ b/vendor/github.com/hsanjuan/go-ndef/types/wkt/uri/uri.go
@@ -0,0 +1,127 @@
+/***
+ Copyright (c) 2018, Hector Sanjuan
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+***/
+
+// Package uri provides support for NDEF Payloads of URI type.
+// It follows the NFC Forum URI Record Type Definition specification
+// (NFCForum-TS-RTD_URI_1.0).
+//
+// The Payload type implements the RecordPayload interface from ndef,
+// so it can be used as ndef.Record.Payload.
+package uri
+
+import (
+ "regexp"
+ "strings"
+)
+
+// URIProtocols provides a mapping between the first byte if a NDEF Payload of
+// type "U" (URI) and the string value for the protocol.
+var URIProtocols = map[byte]string{
+ 0: "",
+ 1: "http://www.",
+ 2: "https://www.",
+ 3: "http://",
+ 4: "https://",
+ 5: "tel:",
+ 6: "mailto:",
+ 7: "ftp://anonymous:anonymous@",
+ 8: "ftp://ftp.",
+ 9: "ftps://",
+ 10: "sftp://",
+ 11: "smb://",
+ 12: "nfs://",
+ 13: "ftp://",
+ 14: "dev://",
+ 15: "news:",
+ 16: "telnet://",
+ 17: "imap:",
+ 18: "rtsp://",
+ 19: "urn:",
+ 20: "pop:",
+ 21: "sip:",
+ 22: "sips:",
+ 23: "tftp:",
+ 24: "btspp://",
+ 25: "btl2cap://",
+ 26: "btgoep://",
+ 27: "tcpobex://",
+ 28: "irdaobex://",
+ 29: "file://",
+ 30: "urn:epc:id:",
+ 31: "urn:epc:tag:",
+ 32: "urn:epc:pat:",
+ 33: "urn:epc:raw:",
+ 34: "urn:epc:",
+ 35: "urn:nfc:",
+}
+
+// Payload represents a NDEF Record Payload of Type "U".
+type Payload struct {
+ IdentCode byte
+ URIField string
+}
+
+// New returns a pointer to an Payload object.
+// The Identifier code is automatically
+// set based on the provided string.
+func New(uriStr string) *Payload {
+ u := new(Payload)
+ u.URIField = uriStr
+ for i := byte(1); i < 36; i++ {
+ m, _ := regexp.MatchString("^"+URIProtocols[i], uriStr)
+ if m {
+ u.IdentCode = i
+ u.URIField = strings.Replace(uriStr,
+ URIProtocols[i], "", 1)
+ break
+ }
+ }
+ return u
+}
+
+// String returns the URI string.
+func (u *Payload) String() string {
+ return URIProtocols[u.IdentCode] + u.URIField
+}
+
+// Type returns the Uniform Resource Name for URIs.
+func (u *Payload) Type() string {
+ return "urn:nfc:wkt:U"
+}
+
+// Marshal returns the bytes representing the payload of a Record of URI type.
+func (u *Payload) Marshal() []byte {
+ p := []byte{u.IdentCode}
+ return append(p, []byte(u.URIField)...)
+}
+
+// Unmarshal parses the payload of a URI type record.
+func (u *Payload) Unmarshal(buf []byte) {
+ u.IdentCode = 0
+ u.URIField = ""
+ if len(buf) > 0 {
+ u.IdentCode = buf[0]
+ }
+ if len(buf) > 1 {
+ u.URIField = string(buf[1:])
+ }
+}
+
+// Len is the length of the byte slice resulting of Marshaling.
+func (u *Payload) Len() int {
+ return len(u.Marshal())
+}