3 * neard - Near Field Communication manager
5 * Copyright (C) 2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 #define RECORD_TNF_EMPTY 0x00
38 #define RECORD_TNF_WELLKNOWN 0x01
39 #define RECORD_TNF_MIME 0x02
40 #define RECORD_TNF_URI 0x03
41 #define RECORD_TNF_EXTERNAL 0x04
42 #define RECORD_TNF_UNKNOWN 0x05
43 #define RECORD_TNF_UNCHANGED 0x06
45 #define RECORD_MB(record) (((record)[0] & 0x80) >> 7)
46 #define RECORD_ME(record) (((record)[0] & 0x40) >> 6)
47 #define RECORD_CF(record) (((record)[0] & 0x20) >> 5)
48 #define RECORD_SR(record) (((record)[0] & 0x10) >> 4)
49 #define RECORD_IL(record) (((record)[0] & 0x8) >> 3)
50 #define RECORD_TNF(record) ((record)[0] & 0x7)
52 void __near_ndef_destroy(struct near_ndef *ndef)
57 static gboolean record_sp(uint8_t tnf, uint8_t *type, size_t type_length)
59 DBG("tnf 0x%x type length %zu", tnf, type_length);
61 if (tnf == RECORD_TNF_WELLKNOWN
63 && strncmp((char *)type, "Sp", 2) == 0)
70 static uint8_t record_type_offset(uint8_t *record, size_t *type_length)
75 sr = RECORD_SR(record);
76 il = RECORD_IL(record);
77 tnf = RECORD_TNF(record);
78 *type_length = record[1];
97 static uint8_t record_payload_offset(uint8_t *record, size_t *payload_length)
99 uint8_t sr, tnf, il, type_length, id_length;
102 sr = RECORD_SR(record);
103 il = RECORD_IL(record);
104 tnf = RECORD_TNF(record);
105 type_length = record[1];
114 *payload_length = record[offset];
115 /* Payload length is 1 byte */
118 *payload_length = *((uint32_t *)(record + offset));
119 /* Payload length is 4 bytes */
124 id_length = record[offset];
131 offset += type_length;
134 offset -= type_length;
138 DBG("type length %d payload length %zu id length %d offset %d", type_length, *payload_length, id_length, offset);
143 struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length)
145 struct near_ndef *ndef;
146 struct near_ndef_record *record;
147 uint8_t *raw_record, payload_offset, type_offset;
149 ndef = g_try_malloc0(sizeof(struct near_ndef));
154 raw_record = ndef_data;
157 uint8_t mb, me, sr, tnf, il;
158 size_t i, type_length;
160 mb = RECORD_MB(raw_record);
161 me = RECORD_ME(raw_record);
162 sr = RECORD_SR(raw_record);
163 il = RECORD_IL(raw_record);
164 tnf = RECORD_TNF(raw_record);
165 DBG("Record MB 0x%x ME 0x%x SR 0x%x IL 0x%x TNF 0x%x", mb, me, sr, il, tnf);
167 if (ndef->n_records == 0 && mb != 1)
170 type_offset = record_type_offset(raw_record, &type_length);
172 ndef->smart_poster = record_sp(tnf, raw_record + type_offset, type_length);
173 if (ndef->smart_poster == TRUE) {
174 size_t payload_length;
178 payload_offset = record_payload_offset(raw_record, &payload_length);
180 raw_record += payload_offset;
185 record = g_try_malloc0(sizeof(struct near_ndef_record));
186 if (record == NULL) {
187 __near_ndef_destroy(ndef);
193 payload_offset = record_payload_offset(raw_record, &record->payload_length);
194 record->payload = raw_record + payload_offset;
196 type_offset = record_type_offset(raw_record, &record->type_length);
197 record->type = raw_record + type_offset;
199 for (i = 0; i < record->payload_length; i++)
200 DBG("Payload[%d] %c 0x%x", i, record->payload[i], record->payload[i]);
202 ndef->n_records += 1;
203 ndef->records = g_list_append(ndef->records, record);
208 raw_record = record->payload + record->payload_length;