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