Add packaging directory
[platform/upstream/neard.git] / src / tlv.c
1 /*
2  *
3  *  neard - Near Field Communication manager
4  *
5  *  Copyright (C) 2011  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "near.h"
27
28 uint16_t near_tlv_length(uint8_t *tlv)
29 {
30         uint16_t length;
31
32         if (tlv[0] == TLV_NULL || tlv[0] == TLV_END)
33                 length = 0;
34         else if (tlv[1] == 0xff)
35                 length = near_get_be16(tlv + 2);
36         else
37                 length = tlv[1];
38
39         return length;
40 }
41
42 uint8_t *near_tlv_next(uint8_t *tlv)
43 {
44         uint16_t length;
45         uint8_t l_length;
46
47         length = near_tlv_length(tlv);
48         if (length > 0xfe)
49                 l_length = 3;
50         else if (length == 0)
51                 l_length = 0;
52         else
53                 l_length = 1;
54
55         /* T (1 byte) + L (1 or 3 bytes) + V */
56         return tlv + 1 + l_length + length;
57 }
58
59 uint8_t *near_tlv_data(uint8_t *tlv)
60 {
61         uint16_t length;
62         uint8_t l_length;
63
64         length = near_tlv_length(tlv);
65         if (length > 0xfe)
66                 l_length = 3;
67         else if (length == 0)
68                 l_length = 0;
69         else
70                 l_length = 1;
71
72         /* T (1 byte) + L (1 or 3 bytes) */
73         return tlv + 1 + l_length;
74 }
75
76 GList *near_tlv_parse(uint8_t *tlv, size_t tlv_length)
77 {
78         GList *records;
79         uint8_t *data, t;
80
81         DBG("");
82
83         records = NULL;
84         data = tlv;
85
86         while (1) {
87                 t = tlv[0];
88
89                 DBG("tlv 0x%x", tlv[0]);
90
91                 switch (t) {
92                 case TLV_NDEF:
93                         DBG("NDEF found %d bytes long", near_tlv_length(tlv));
94
95                         records = near_ndef_parse_msg(near_tlv_data(tlv),
96                                                 near_tlv_length(tlv), NULL);
97
98                         break;
99                 case TLV_END:
100                         break;
101                 }
102
103                 if (t == TLV_END)
104                         break;
105
106                 tlv = near_tlv_next(tlv);
107
108                 if (tlv - data >= (uint16_t) tlv_length)
109                         break;
110         }
111
112         DBG("Done");
113
114         return records;
115 }