1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef DEVICE_NFC_NFC_NDEF_RECORD_H_
6#define DEVICE_NFC_NFC_NDEF_RECORD_H_
7
8#include <string>
9#include <vector>
10
11#include "base/values.h"
12
13namespace device {
14
15// NfcNdefRecord represents an NDEF (NFC Data Exchange Format) record. NDEF is
16// a light-weight binary format specified by the NFC Forum for transmission and
17// storage of typed data over NFC. NDEF defines two constructs: NDEF records and
18// messages. An NDEF record contains typed data, such as MIME-type media, a URI,
19// or a custom application payload, whereas an NDEF message is a container for
20// one or more NDEF records.
21class NfcNdefRecord {
22 public:
23  // NDEF record types that define the payload of the NDEF record.
24  enum Type {
25    kTypeHandoverCarrier,
26    kTypeHandoverRequest,
27    kTypeHandoverSelect,
28    kTypeSmartPoster,
29    kTypeText,
30    kTypeURI,
31    kTypeUnknown
32  };
33
34  // The following are strings that define a possible field of an NDEF record.
35  // These strings are used as the keys in the dictionary returned by |data|.
36  // Not all fields are always present in an NDEF record, where the presence
37  // of a field depends on the type of the record. While some fields are
38  // required for a specific record type, others can be optional and won't
39  // always be present.
40
41  // Fields for type "Text".
42
43  // The character encoding. When present, the value is one of |kEncodingUtf8|
44  // and |kEncodingUtf16|. Otherwise, this field is optional.
45  static const char kFieldEncoding[];
46
47  // The ISO/IANA language code (e.g. "en" or "jp"). This field is optional.
48  static const char kFieldLanguageCode[];
49
50  // The human readable representation of a text. This field is mandatory.
51  static const char kFieldText[];
52
53  // Fields for type "URI".
54
55  // The complete URI, including the scheme and the resource. This field is
56  // required.
57  static const char kFieldURI[];
58
59  // The URI object MIME type. This is a description of the MIME type of the
60  // object the URI points at. This field is optional.
61  static const char kFieldMimeType[];
62
63  // The size of the object the URI points at. This field is optional.
64  // If present, the value is an unsigned integer. Since base/values.h does not
65  // define an unsigned integer type, use a base::DoubleValue to store this.
66  static const char kFieldTargetSize[];
67
68  // Fields for type "SmartPoster". A SmartPoster can contain all possible
69  // fields of a "URI" record, in addition to the following:
70
71  // The "title" of the SmartPoster. This is an optional field. If present, the
72  // value of this field is a list of dictionaries, where each dictionary
73  // contains the possible fields of a "Text" record. If the list contains
74  // more than one element, each element usually represents the same "title"
75  // text in a different language.
76  static const char kFieldTitles[];
77
78  // The suggested course of action. The value of this field is one of
79  // |kSmartPosterAction*|. This field is optional.
80  static const char kFieldAction[];
81
82  // Possible values for character encoding.
83  static const char kEncodingUtf8[];
84  static const char kEncodingUtf16[];
85
86  // Possible actions defined by the NFC forum SmartPoster record type. Each
87  // action is a suggestion to the application indicating the action it should
88  // take with the contents of the record.
89
90  // Do the action. e.g. open a URI, send an SMS, dial a phone number.
91  static const char kSmartPosterActionDo[];
92
93  // Store data, e.g. store an SMS, bookmark a URI, etc.
94  static const char kSmartPosterActionSave[];
95
96  // Open the data for editing.
97  static const char kSmartPosterActionOpen[];
98
99  NfcNdefRecord();
100  virtual ~NfcNdefRecord();
101
102  // Returns the type that defines the payload of this NDEF record.
103  Type type() const { return type_; }
104
105  // Returns the contents of this record in the form of a mapping from keys
106  // declared above to their stored values.
107  const base::DictionaryValue& data() const { return data_; }
108
109  // Returns true, if this record has been populated via a call to "Populate".
110  bool IsPopulated() const;
111
112  // Populates the record with the contents of |data| and sets its type to
113  // |type|. Returns true, if the record was successfully populated. If a
114  // failure occurs, e.g. |data| contains values that are not allowed in
115  // records of type |type| or if |data| does not contain mandatory fields of
116  // |type|, this method returns false. Populating an instance of an
117  // NfcNdefRecord is allowed only once and after a successful call to this
118  // method, all subsequent calls to this method will fail. Use IsPopulated()
119  // to determine if this record can be populated.
120  bool Populate(Type type, const base::DictionaryValue* data);
121
122 private:
123  // The type of this record.
124  Type type_;
125
126  // The contents of the record.
127  base::DictionaryValue data_;
128
129  DISALLOW_COPY_AND_ASSIGN(NfcNdefRecord);
130};
131
132// NfcNdefMessage represent an NDEF message. An NDEF message, contains one or
133// more NDEF records and the order in which the records are stored dictates the
134// order in which applications are meant to interpret them. For example, a
135// client may decide to dispatch to applications based on the first record in
136// the sequence.
137class NfcNdefMessage {
138 public:
139  // Typedef for a list of NDEF records.
140  typedef std::vector<NfcNdefRecord*> RecordList;
141
142  NfcNdefMessage();
143  virtual ~NfcNdefMessage();
144
145  // The NDEF records that are contained in this message.
146  const RecordList& records() const { return records_; }
147
148  // Adds the NDEF record |record| to the sequence of records that this
149  // NfcNdefMessage contains. This method simply adds the record to this message
150  // and does NOT take ownership of it.
151  void AddRecord(NfcNdefRecord* record);
152
153  // Removes the NDEF record |record| from this message. Returns true, if the
154  // record was removed, otherwise returns false if |record| was not contained
155  // in this message.
156  bool RemoveRecord(NfcNdefRecord* record);
157
158 private:
159  // The NDEF records that are contained by this message.
160  RecordList records_;
161
162  DISALLOW_COPY_AND_ASSIGN(NfcNdefMessage);
163};
164
165}  // namespace device
166
167#endif  // DEVICE_NFC_NFC_NDEF_RECORD_H_
168