source: asp3_tinet_ecnl_arm/trunk/btstack/src/sdp_parser.c@ 374

Last change on this file since 374 was 374, checked in by coas-nagasima, 5 years ago

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.3 KB
Line 
1/*
2 * Copyright (C) 2009-2013 by Matthias Ringwald
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at btstack@ringwald.ch
34 *
35 */
36
37/*
38 * sdp_parser.c
39 */
40#include <btstack/hci_cmds.h>
41#include "sdp_parser.h"
42#include "debug.h"
43
44typedef enum {
45 GET_LIST_LENGTH = 1,
46 GET_RECORD_LENGTH,
47 GET_ATTRIBUTE_ID_HEADER_LENGTH,
48 GET_ATTRIBUTE_ID,
49 GET_ATTRIBUTE_VALUE_LENGTH,
50 GET_ATTRIBUTE_VALUE
51} state_t;
52
53static state_t state = GET_LIST_LENGTH;
54static uint16_t attribute_id = 0;
55static uint16_t attribute_bytes_received = 0;
56static uint16_t attribute_bytes_delivered = 0;
57static uint16_t list_offset = 0;
58static uint16_t list_size;
59static uint16_t record_offset = 0;
60static uint16_t record_size;
61static uint16_t attribute_value_size;
62static int record_counter = 0;
63
64#ifdef HAVE_SDP_EXTRA_QUERIES
65static uint32_t record_handle;
66#endif
67
68static void (*sdp_query_callback)(sdp_query_event_t * event);
69
70// Low level parser
71static de_state_t de_header_state;
72
73
74void de_state_init(de_state_t * state){
75 state->in_state_GET_DE_HEADER_LENGTH = 1;
76 state->addon_header_bytes = 0;
77 state->de_size = 0;
78 state->de_offset = 0;
79}
80
81int de_state_size(uint8_t eventByte, de_state_t *de_state){
82 if (de_state->in_state_GET_DE_HEADER_LENGTH){
83 de_state->addon_header_bytes = de_get_header_size(&eventByte) - 1;
84 de_state->de_size = 0;
85 de_state->de_offset = 0;
86
87 if (de_state->addon_header_bytes == 0){
88 de_state->de_size = de_get_data_size(&eventByte);
89 if (de_state->de_size == 0) {
90 log_error(" ERROR: ID size is zero");
91 }
92 // log_info("Data element payload is %d bytes.", de_state->de_size);
93 return 1;
94 }
95 de_state->in_state_GET_DE_HEADER_LENGTH = 0;
96 return 0;
97 }
98
99 if (de_state->addon_header_bytes > 0){
100 de_state->de_size = (de_state->de_size << 8) | eventByte;
101 de_state->addon_header_bytes--;
102 }
103 if (de_state->addon_header_bytes > 0) return 0;
104 // log_info("Data element payload is %d bytes.", de_state->de_size);
105 de_state->in_state_GET_DE_HEADER_LENGTH = 1;
106 return 1;
107}
108
109void dummy_notify(sdp_query_event_t* event){}
110
111void sdp_parser_register_callback(void (*sdp_callback)(sdp_query_event_t* event)){
112 sdp_query_callback = dummy_notify;
113 if (sdp_callback != NULL){
114 sdp_query_callback = sdp_callback;
115 }
116}
117
118void parse(uint8_t eventByte){
119 // count all bytes
120 list_offset++;
121 record_offset++;
122
123 // log_info(" parse BYTE_RECEIVED %02x", eventByte);
124 switch(state){
125 case GET_LIST_LENGTH:
126 if (!de_state_size(eventByte, &de_header_state)) break;
127 list_offset = de_header_state.de_offset;
128 list_size = de_header_state.de_size;
129 // log_info("parser: List offset %u, list size %u", list_offset, list_size);
130
131 record_counter = 0;
132 state = GET_RECORD_LENGTH;
133 break;
134
135 case GET_RECORD_LENGTH:
136 // check size
137 if (!de_state_size(eventByte, &de_header_state)) break;
138 // log_info("parser: Record payload is %d bytes.", de_header_state.de_size);
139 record_offset = de_header_state.de_offset;
140 record_size = de_header_state.de_size;
141 state = GET_ATTRIBUTE_ID_HEADER_LENGTH;
142 break;
143
144 case GET_ATTRIBUTE_ID_HEADER_LENGTH:
145 if (!de_state_size(eventByte, &de_header_state)) break;
146 attribute_id = 0;
147 // log_info("ID data is stored in %d bytes.", de_header_state.de_size);
148 state = GET_ATTRIBUTE_ID;
149 break;
150
151 case GET_ATTRIBUTE_ID:
152 attribute_id = (attribute_id << 8) | eventByte;
153 de_header_state.de_size--;
154 if (de_header_state.de_size > 0) break;
155 // log_info("parser: Attribute ID: %04x.", attribute_id);
156
157 state = GET_ATTRIBUTE_VALUE_LENGTH;
158 attribute_bytes_received = 0;
159 attribute_bytes_delivered = 0;
160 attribute_value_size = 0;
161 de_state_init(&de_header_state);
162 break;
163
164 case GET_ATTRIBUTE_VALUE_LENGTH:
165 attribute_bytes_received++;
166 {
167 sdp_query_attribute_value_event_t attribute_value_event = {
168 SDP_EVENT_QUERY_ATTRIBUTE_VALUE,
169 record_counter,
170 attribute_id,
171 attribute_value_size,
172 attribute_bytes_delivered++,
173 eventByte
174 };
175 (*sdp_query_callback)((sdp_query_event_t*)&attribute_value_event);
176 }
177 if (!de_state_size(eventByte, &de_header_state)) break;
178
179 attribute_value_size = de_header_state.de_size + attribute_bytes_received;
180
181 state = GET_ATTRIBUTE_VALUE;
182 break;
183
184 case GET_ATTRIBUTE_VALUE:
185 attribute_bytes_received++;
186 {
187 sdp_query_attribute_value_event_t attribute_value_event = {
188 SDP_EVENT_QUERY_ATTRIBUTE_VALUE,
189 record_counter,
190 attribute_id,
191 attribute_value_size,
192 attribute_bytes_delivered++,
193 eventByte
194 };
195
196 (*sdp_query_callback)((sdp_query_event_t*)&attribute_value_event);
197 }
198 // log_info("paser: attribute_bytes_received %u, attribute_value_size %u", attribute_bytes_received, attribute_value_size);
199
200 if (attribute_bytes_received < attribute_value_size) break;
201 // log_info("parser: Record offset %u, record size %u", record_offset, record_size);
202 if (record_offset != record_size){
203 state = GET_ATTRIBUTE_ID_HEADER_LENGTH;
204 // log_info("Get next attribute");
205 break;
206 }
207 record_offset = 0;
208 // log_info("parser: List offset %u, list size %u", list_offset, list_size);
209
210 if (list_size > 0 && list_offset != list_size){
211 record_counter++;
212 state = GET_RECORD_LENGTH;
213 // log_info("parser: END_OF_RECORD");
214 break;
215 }
216 list_offset = 0;
217 de_state_init(&de_header_state);
218 state = GET_LIST_LENGTH;
219 record_counter = 0;
220 // log_info("parser: END_OF_RECORD & DONE");
221 break;
222 default:
223 break;
224 }
225}
226
227void sdp_parser_init(void){
228 // init
229 de_state_init(&de_header_state);
230 state = GET_LIST_LENGTH;
231 list_offset = 0;
232 record_offset = 0;
233 record_counter = 0;
234}
235
236void sdp_parser_handle_chunk(uint8_t * data, uint16_t size){
237 int i;
238 for (i=0;i<size;i++){
239 parse(data[i]);
240 }
241}
242
243#ifdef HAVE_SDP_EXTRA_QUERIES
244void sdp_parser_init_service_attribute_search(void){
245 // init
246 de_state_init(&de_header_state);
247 state = GET_RECORD_LENGTH;
248 list_offset = 0;
249 record_offset = 0;
250 record_counter = 0;
251}
252
253void sdp_parser_init_service_search(void){
254 record_offset = 0;
255}
256
257void sdp_parser_handle_service_search(uint8_t * data, uint16_t total_count, uint16_t record_handle_count){
258 int i;
259 for (i=0;i<record_handle_count;i++){
260 record_handle = big_endian_read_32(data, i*4);
261 record_counter++;
262 {
263 sdp_query_service_record_handle_event_t service_record_handle_event = {
264 SDP_QUERY_SERVICE_RECORD_HANDLE,
265 total_count,
266 record_counter,
267 record_handle
268 };
269 (*sdp_query_callback)((sdp_query_event_t*)&service_record_handle_event);
270 }
271 }
272}
273#endif
274
275void sdp_parser_handle_done(uint8_t status){
276 sdp_query_complete_event_t complete_event = {
277 SDP_EVENT_QUERY_COMPLETE,
278 status
279 };
280 (*sdp_query_callback)((sdp_query_event_t*)&complete_event);
281}
Note: See TracBrowser for help on using the repository browser.