ROHC compression/decompression library
|
00001 /* 00002 * Copyright 2014 Didier Barvaux 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 00019 /** 00020 * @file common/rohc_buf.h 00021 * @brief Define a network buffer for the ROHC library 00022 * @author Didier Barvaux <didier@barvaux.org> 00023 */ 00024 00025 #ifndef ROHC_BUF_H 00026 #define ROHC_BUF_H 00027 00028 #ifdef __cplusplus 00029 extern "C" 00030 { 00031 #endif 00032 00033 /** Macro that handles DLL export declarations gracefully */ 00034 #ifdef DLL_EXPORT /* passed by autotools on command line */ 00035 #define ROHC_EXPORT __declspec(dllexport) 00036 #else 00037 #define ROHC_EXPORT 00038 #endif 00039 00040 #include "rohc_time.h" /* for struct rohc_ts */ 00041 00042 #include <stdbool.h> 00043 #include <stdlib.h> 00044 00045 00046 /** 00047 * @brief A network buffer for the ROHC library 00048 * 00049 * May represent one uncompressed packet, one ROHC packet, or a ROHC feedback. 00050 * 00051 * The network buffer does not contain the packet data itself. It only has 00052 * a pointer on it. This is designed this way for performance reasons: no copy 00053 * required to initialize a network buffer, the struct is small and may be 00054 * passed as copy to function. 00055 * 00056 * The network buffer is able to keep some free space at its beginning. The 00057 * unused space at the beginning of the buffer may be used to prepend a 00058 * network header at the very end of the packet handling. 00059 * 00060 * The beginning of the network buffer may also be shifted forward with the 00061 * \ref rohc_buf_pull function or shifted backward with the \ref rohc_buf_push 00062 * function. This is useful when parsing a network packet (once bytes are 00063 * read, shift them forward) for example. 00064 * 00065 * The network buffer may be initialized manually (see below) or with the 00066 * helper functions \ref rohc_buf_init_empty or \ref rohc_buf_init_full. 00067 * \code 00068 struct rohc_buf packet; 00069 ... 00070 packet.time.sec = 0; 00071 packet.time.nsec = 0; 00072 packet.max_len = 100; 00073 packet.data = malloc(packet.max_len); 00074 packet.offset = 2; 00075 packet.len = 2; 00076 packet[packet.offset] = 0x01; 00077 packet[packet.offset + 1] = 0x02; 00078 ... 00079 \endcode 00080 * 00081 * or as below: 00082 * \code 00083 struct rohc_buf packet; 00084 unsigned char input[100]; 00085 ... 00086 input[2] = 0x01; 00087 input[3] = 0x02; 00088 ... 00089 packet.time.sec = 0; 00090 packet.time.nsec = 0; 00091 packet.max_len = 100; 00092 packet.data = input; 00093 packet.offset = 2; 00094 packet.len = 2; 00095 ... 00096 \endcode 00097 * 00098 * @ingroup rohc 00099 */ 00100 struct rohc_buf 00101 { 00102 struct rohc_ts time; /**< The timestamp associated to the data */ 00103 uint8_t *data; /**< The buffer data */ 00104 size_t max_len; /**< The maximum length of the buffer */ 00105 size_t offset; /**< The offset for the beginning of the data */ 00106 size_t len; /**< The data length (in bytes) */ 00107 }; 00108 00109 00110 /** 00111 * @brief Initialize the given network buffer with no data 00112 * 00113 * This method is used to initialize an empty network buffer that will be used 00114 * to create a packet. For example, the ROHC packet for a compression 00115 * operation, or the uncompressed packet for a decompression operation. 00116 * 00117 * @param __data The packet data to point to 00118 * @param __max_len The maxmimum length (in bytes) of the packet data 00119 * 00120 * \par Example: 00121 * \code 00122 #define PKT_DATA_LEN 145U 00123 uint8_t pkt_data[PKT_DATA_LEN]; 00124 struct rohc_buf packet = rohc_buf_init_empty(pkt_data, PKT_DATA_LEN); 00125 \endcode 00126 * 00127 * @ingroup rohc 00128 */ 00129 #define rohc_buf_init_empty(__data, __max_len) \ 00130 { \ 00131 .time = { .sec = 0, .nsec = 0, }, \ 00132 .data = (__data), \ 00133 .max_len = (__max_len), \ 00134 .offset = 0, \ 00135 .len = 0, \ 00136 } 00137 00138 00139 /** 00140 * @brief Initialize the given network buffer with all its data 00141 * 00142 * This method is used to initialize a network buffer that will be used for 00143 * parsing only. For example, the uncompressed packet for a compression 00144 * operation, or the ROHC packet for a decompression operation. 00145 * 00146 * @param __data The packet data to point to 00147 * @param __len The maxmimum length (in bytes) of the packet data 00148 * @param __time The timestamp at which the packet was received/handled 00149 * 00150 * \par Example: 00151 * \code 00152 #define PKT_DATA_LEN 145U 00153 const uint8_t pkt_data[PKT_DATA_LEN]; 00154 const struct rohc_ts arrival_time = { .sec = 1399745625, .nsec = 42 }; 00155 const struct rohc_buf packet = 00156 rohc_buf_init_full(pkt_data, PKT_DATA_LEN, arrival_time); 00157 \endcode 00158 * 00159 * @ingroup rohc 00160 */ 00161 #define rohc_buf_init_full(__data, __len, __time) \ 00162 { \ 00163 .time = (__time), \ 00164 .data = (__data), \ 00165 .max_len = (__len), \ 00166 .offset = 0, \ 00167 .len = (__len), \ 00168 } 00169 00170 00171 /** 00172 * @brief Get the byte at the given offset in the given network buffer 00173 * 00174 * @param __buf The network buffer to get a byte from 00175 * @param __offset The offset to get bytes at 00176 * @return The byte stored in the network buffer at the offset 00177 * 00178 * @ingroup rohc 00179 */ 00180 #define rohc_buf_byte_at(__buf, __offset) \ 00181 ((__buf).data)[(__buf).offset + (__offset)] 00182 00183 00184 /** 00185 * @brief Get the next byte in the given network buffer 00186 * 00187 * @param __buf The network buffer to get the next byte from 00188 * @return The next byte stored in the network buffer 00189 * 00190 * @ingroup rohc 00191 */ 00192 #define rohc_buf_byte(__buf) \ 00193 rohc_buf_byte_at((__buf), 0) 00194 00195 00196 00197 bool rohc_buf_is_malformed(const struct rohc_buf buf) 00198 __attribute__((warn_unused_result)); 00199 00200 bool rohc_buf_is_empty(const struct rohc_buf buf) 00201 __attribute__((warn_unused_result)); 00202 00203 void rohc_buf_pull(struct rohc_buf *const buf, const size_t offset) 00204 __attribute__((nonnull(1))); 00205 void rohc_buf_push(struct rohc_buf *const buf, const size_t offset) 00206 __attribute__((nonnull(1))); 00207 00208 size_t rohc_buf_avail_len(const struct rohc_buf buf) 00209 __attribute__((warn_unused_result)); 00210 00211 uint8_t * rohc_buf_data_at(const struct rohc_buf buf, const size_t offset) 00212 __attribute__((warn_unused_result)); 00213 uint8_t * rohc_buf_data(const struct rohc_buf buf) 00214 __attribute__((warn_unused_result)); 00215 00216 void rohc_buf_prepend(struct rohc_buf *const buf, 00217 const uint8_t *const data, 00218 const size_t len) 00219 __attribute__((nonnull(1, 2))); 00220 void rohc_buf_append(struct rohc_buf *const buf, 00221 const uint8_t *const data, 00222 const size_t len) 00223 __attribute__((nonnull(1, 2))); 00224 void rohc_buf_append_buf(struct rohc_buf *const dst, 00225 const struct rohc_buf src) 00226 __attribute__((nonnull(1))); 00227 00228 void rohc_buf_reset(struct rohc_buf *const buf) 00229 __attribute__((nonnull(1))); 00230 00231 00232 #undef ROHC_EXPORT /* do not pollute outside this header */ 00233 00234 #ifdef __cplusplus 00235 } 00236 #endif 00237 00238 #endif /* ROHC_BUF_H */ 00239