xref: /btstack/src/classic/obex_parser.h (revision af7c3ae6cd1e2bcfd24e6d0654508ecf775c9e5d)
1 /*
2  * Copyright (C) 2021 BlueKitchen GmbH
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 BLUEKITCHEN GMBH 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 BLUEKITCHEN
24  * GMBH 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
34  * [email protected]
35  *
36  */
37 
38 /**
39  * OBEX Parser
40  * Parser incoming arbitrarily chunked OBEX object
41  */
42 
43 #ifndef OBEX_PARSER_H
44 #define OBEX_PARSER_H
45 
46 #if defined __cplusplus
47 extern "C" {
48 #endif
49 
50 #include <stdint.h>
51 
52 typedef enum {
53     OBEX_PARSER_STATE_W4_OPCODE,
54     OBEX_PARSER_STATE_W4_RESPONSE_CODE,
55     OBEX_PARSER_STATE_W4_PACKET_LEN,
56     OBEX_PARSER_STATE_W4_PARAMS,
57     OBEX_PARSER_STATE_W4_HEADER_ID,
58     OBEX_PARSER_STATE_W4_HEADER_LEN_FIRST,
59     OBEX_PARSER_STATE_W4_HEADER_LEN_SECOND,
60     OBEX_PARSER_STATE_W4_HEADER_VALUE,
61     OBEX_PARSER_STATE_COMPLETE,
62     OBEX_PARSER_STATE_OVERRUN,
63     OBEX_PARSER_STATE_INVALID,
64 } obex_parser_state_t;
65 
66 /* API_START */
67 
68 /**
69  * Callback to process chunked data
70  * @param user_data provided in obex_parser_init
71  * @param header_id current OBEX header ID
72  * @param total_len of header
73  * @param data_offset
74  * @param data_len
75  * @param data_buffer
76  */
77 typedef void (*obex_parser_callback_t)(void * user_data, uint8_t header_id, uint16_t total_len, uint16_t data_offset, const uint8_t * data_buffer, uint16_t data_len);
78 
79 typedef enum {
80     OBEX_PARSER_OBJECT_STATE_INCOMPLETE,
81     OBEX_PARSER_OBJECT_STATE_COMPLETE,
82     OBEX_PARSER_OBJECT_STATE_OVERRUN,
83     OBEX_PARSER_OBJECT_STATE_INVALID,
84 } obex_parser_object_state_t;
85 
86 typedef enum {
87     OBEX_PARSER_HEADER_INCOMPLETE,
88     OBEX_PARSER_HEADER_COMPLETE,
89     OBEX_PARSER_HEADER_OVERRUN,
90 } obex_parser_header_state_t;
91 
92 typedef struct {
93     uint8_t  opcode;
94     uint8_t  response_code;
95     // Connect only
96     uint8_t  obex_version_number;
97     uint16_t max_packet_length;
98     // Connect + Set Path only
99     uint8_t  flags;
100 } obex_parser_operation_info_t;
101 
102 typedef struct {
103     obex_parser_callback_t callback;
104     void * user_data;
105     uint16_t packet_size;
106     uint16_t packet_pos;
107     obex_parser_state_t state;
108     uint8_t  opcode;
109     uint8_t  response_code;
110     uint16_t item_len;
111     uint16_t item_pos;
112     uint8_t  params[6]; // for connect and set path
113     uint8_t  header_id;
114 } obex_parser_t;
115 
116 /**
117  * Initialize OBEX Parser for next OBEX request
118  * @param obex_parser
119  * @param function to call for fields that are not registered
120  * @param user_data provided to callback function
121  */
122 void obex_parser_init_for_request(obex_parser_t * obex_parser, obex_parser_callback_t obex_parser_callback, void * user_data);
123 
124 /**
125  * Initialize OBEX Parser for next OBEX response
126  * @param obex_parser
127  * @param opcode of request - needed as responses with additional fields like connect and set path
128  * @param function to call for fields that are not registered
129  * @param user_data provided to callback function
130  */
131 void obex_parser_init_for_response(obex_parser_t * obex_parser, uint8_t opcode, obex_parser_callback_t obex_parser_callback, void * user_data);
132 
133 /**
134  * Process OBEX data
135  * @param obex_parser
136  * @param data_len
137  * @param data_buffer
138  * @return OBEX_PARSER_OBJECT_STATE_COMPLETE if packet has been completely parsed
139  */
140 obex_parser_object_state_t obex_parser_process_data(obex_parser_t *obex_parser, const uint8_t *data_buffer, uint16_t data_len);
141 
142 /**
143  * Get operation info for request/response packets
144  * @param obex_parser
145  * @return
146  */
147 void obex_parser_get_operation_info(obex_parser_t * obex_parser, obex_parser_operation_info_t * obex_operation_info);
148 
149 /**
150  * Helper to collect header chunks in fixed-size header buffer
151  * @param header_buffer
152  * @param buffer_size of header_buffer
153  * @param total_len of header value
154  * @param data_offset of chunkc to store
155  * @param data_buffer
156  * @param data_len chunk length
157  * @return OBEX_PARSER_HEADER_COMPLETE when header value complete
158  */
159 obex_parser_header_state_t obex_parser_header_store(uint8_t * header_buffer, uint16_t buffer_size, uint16_t total_len,
160                                                     uint16_t data_offset, const uint8_t * data_buffer, uint16_t data_len);
161 
162 
163 /* API_END */
164 
165 #if defined __cplusplus
166 }
167 #endif
168 #endif
169