ROHC compression/decompression library
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 2 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * This program is distributed in the hope that it will be useful, 00008 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 * GNU General Public License for more details. 00011 * 00012 * You should have received a copy of the GNU General Public License 00013 * along with this program; if not, write to the Free Software 00014 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00015 */ 00016 00017 /** 00018 * @file c_generic.h 00019 * @brief ROHC generic compression context for IP-only, UDP and UDP Lite 00020 * profiles. 00021 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00022 * @author Didier Barvaux <didier@barvaux.org> 00023 * @author The hackers from ROHC for Linux 00024 */ 00025 00026 #ifndef C_GENERIC_H 00027 #define C_GENERIC_H 00028 00029 #include "rohc_comp_internals.h" 00030 #include "rohc_packets.h" 00031 #include "comp_list.h" 00032 #include "ip.h" 00033 #include "crc.h" 00034 00035 #include <stdlib.h> 00036 00037 00038 /// The number of compression list items 00039 #define MAX_ITEM 15 00040 00041 /// The number of compressed list to send to make the reference list 00042 /// L is the name specified in the RFC 00043 #define L 5 00044 00045 /** 00046 * @brief Store information about an IPv4 header between the different 00047 * compressions of IP packets. 00048 * 00049 * Defines an object that contains counters, flags and structures related to an 00050 * IPv4 header and that need to be saved between the different compressions of 00051 * packets. A compression context owns objects like this for the two first 00052 * IPv4 headers. 00053 */ 00054 struct ipv4_header_info 00055 { 00056 /// A window to store the IP-ID 00057 struct c_wlsb *ip_id_window; 00058 00059 /// The previous IP header 00060 struct ipv4_hdr old_ip; 00061 00062 /// The number of times the DF field was added to the compressed header 00063 int df_count; 00064 /// @brief The number of times the IP-ID is specified as random in the 00065 /// compressed header 00066 int rnd_count; 00067 /// @brief The number of times the IP-ID is specified as coded in Network 00068 /// Byte Order (NBO) in the compressed header 00069 int nbo_count; 00070 /// @brief The number of times the IP-ID is specified as static in the 00071 /// compressed header 00072 int sid_count; 00073 00074 /// Whether the IP-ID is considered as random or not 00075 int rnd; 00076 /// Whether the IP-ID is considered as coded in NBO or not 00077 int nbo; 00078 /// Whether the IP-ID is considered as static or not 00079 int sid; 00080 /// @brief Whether the IP-ID of the previous IP header was considered as 00081 /// random or not 00082 int old_rnd; 00083 /// @brief Whether the IP-ID of the previous IP header was considered as 00084 /// coded in NBO or not 00085 int old_nbo; 00086 /// @brief Whether the IP-ID of the previous IP header was considered as 00087 /// static or not 00088 int old_sid; 00089 00090 /// The delta between the IP-ID and the current Sequence Number (SN) 00091 /// (overflow over 16 bits is expected when SN > IP-ID) 00092 uint16_t id_delta; 00093 }; 00094 00095 00096 /** 00097 * @brief Store information about an IPv6 header between the different 00098 * compressions of IP packets. 00099 * 00100 * Defines an object that contains counters, flags and structures related to an 00101 * IPv6 header and that need to be saved between the different compressions of 00102 * packets. A compression context owns objects like this for the two first 00103 * IPv6 headers. 00104 */ 00105 struct ipv6_header_info 00106 { 00107 /// The previous IPv6 header 00108 struct ipv6_hdr old_ip; 00109 /// The extension compressor 00110 struct list_comp *ext_comp; 00111 }; 00112 00113 00114 /** 00115 * @brief Store information about an IP (IPv4 or IPv6) header between the 00116 * different compressions of IP packets. 00117 */ 00118 struct ip_header_info 00119 { 00120 ip_version version; ///< The version of the IP header 00121 00122 /// The number of times the TOS/TC field was added to the compressed header 00123 int tos_count; 00124 /// The number of times the TTL/HL field was added to the compressed header 00125 int ttl_count; 00126 /// @brief The number of times the Protocol/Next Header field was added to 00127 /// the compressed header 00128 int protocol_count; 00129 00130 /** Whether the old_* members of the struct and in its children are 00131 * initialized or not */ 00132 bool is_first_header; 00133 00134 union 00135 { 00136 struct ipv4_header_info v4; ///< The IPv4-specific header info 00137 struct ipv6_header_info v6; ///< The IPv6-specific header info 00138 } info; ///< The version specific header info 00139 }; 00140 00141 00142 /** 00143 * @brief Structure that contains variables that are used during one single 00144 * compression of packet. 00145 * 00146 * Structure that contains variables that are temporary, i.e. variables that 00147 * will only be used for the compression of the current packet. These variables 00148 * must be reinitialized every time a new packet arrive. 00149 * 00150 * @see c_init_tmp_variables 00151 */ 00152 struct generic_tmp_vars 00153 { 00154 /// The number of IP headers in the packet to compress (1 or 2 only) 00155 int nr_of_ip_hdr; 00156 00157 /// The number of fields that changed in the outer IP header 00158 unsigned short changed_fields; 00159 /// The number of fields that changed in the inner IP header 00160 unsigned short changed_fields2; 00161 /// The number of static fields that changed in the two IP headers 00162 int send_static; 00163 /// The number of dynamic fields that changed in the two IP headers 00164 int send_dynamic; 00165 00166 /// The number of bits needed to encode the Sequence Number (SN) 00167 size_t nr_sn_bits; 00168 /// The number of bits needed to encode the IP-ID of the outer IP header 00169 size_t nr_ip_id_bits; 00170 /// The number of bits needed to encode the IP-ID of the inner IP header 00171 size_t nr_ip_id_bits2; 00172 00173 /// The type of packet the compressor must send: IR, IR-DYN, UO* 00174 rohc_packet_t packet_type; 00175 00176 /// The maximal size of the compressed packet 00177 size_t max_size; 00178 }; 00179 00180 00181 /** 00182 * @brief The generic compression context 00183 * 00184 * The object defines the generic context that manages IP(/nextheader) and 00185 * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific 00186 * part of the context. 00187 */ 00188 struct c_generic_context 00189 { 00190 /// The Sequence Number (SN), may be 16-bit or 32-bit long 00191 uint32_t sn; 00192 /// A window used to encode the SN 00193 struct c_wlsb *sn_window; 00194 00195 /// The number of packets sent while in Initialization & Refresh (IR) state 00196 int ir_count; 00197 /// The number of packets sent while in First Order (FO) state 00198 int fo_count; 00199 /// The number of packets sent while in Second Order (SO) state 00200 int so_count; 00201 00202 /// @brief The number of packet sent while in SO state, used for the periodic 00203 /// refreshes of the context 00204 /// @see periodic_down_transition 00205 int go_back_fo_count; 00206 /// @brief The number of packet sent while in FO or SO state, used for the 00207 /// periodic refreshes of the context 00208 /// @see periodic_down_transition 00209 int go_back_ir_count; 00210 00211 /// Information about the outer IP header 00212 struct ip_header_info ip_flags; 00213 /// Information about the inner IP header 00214 struct ip_header_info ip2_flags; 00215 /// Whether the ip2_flags object is initialized or not 00216 int is_ip2_initialized; 00217 00218 /// Temporary variables that are used during one single compression of packet 00219 struct generic_tmp_vars tmp; 00220 00221 /* below are some information and handlers to manage the next header 00222 * (if any) located just after the IP headers (1 or 2 IP headers) */ 00223 00224 /// The protocol number registered by IANA for the next header protocol 00225 unsigned int next_header_proto; 00226 /// The length of the next header 00227 unsigned int next_header_len; 00228 00229 /** The handler for encoding profile-specific uncompressed header fields */ 00230 int (*encode_uncomp_fields)(struct c_context *const context, 00231 const struct ip_packet *const ip, 00232 const struct ip_packet *const ip2, 00233 const unsigned char *const next_header); 00234 00235 /// @brief The handler used to decide the state that should be used for the 00236 /// next packet 00237 void (*decide_state)(struct c_context *const context); 00238 /** @brief The handler used to decide which packet to send in FO state */ 00239 rohc_packet_t (*decide_FO_packet)(const struct c_context *context); 00240 /** @brief The handler used to decide which packet to send in SO state */ 00241 rohc_packet_t (*decide_SO_packet)(const struct c_context *context); 00242 /** The handler used to decide which extension to send */ 00243 rohc_ext_t (*decide_extension)(const struct c_context *context); 00244 00245 /// The handler used to initialize some data just before the IR packet build 00246 void (*init_at_IR)(const struct c_context *context, 00247 const unsigned char *next_header); 00248 00249 /** Determine the next SN value */ 00250 uint32_t (*get_next_sn)(const struct c_context *context, 00251 const struct ip_packet *outer_ip, 00252 const struct ip_packet *inner_ip); 00253 00254 /// @brief The handler used to add the static part of the next header to the 00255 /// ROHC packet 00256 int (*code_static_part)(const struct c_context *context, 00257 const unsigned char *next_header, 00258 unsigned char *const dest, 00259 int counter); 00260 00261 /// @brief The handler used to add the dynamic part of the next header to the 00262 /// ROHC pachet 00263 int (*code_dynamic_part)(const struct c_context *context, 00264 const unsigned char *next_header, 00265 unsigned char *const dest, 00266 int counter); 00267 00268 /// @brief The handler used to add the IR/IR-DYN remainder header to the 00269 /// ROHC pachet 00270 int (*code_ir_remainder)(const struct c_context *context, 00271 unsigned char *const dest, 00272 int counter); 00273 00274 /// @brief The handler used to add an additional header in the head of the 00275 /// UO-0, UO-1 and UO-2 packets 00276 int (*code_UO_packet_head)(const struct c_context *context, 00277 const unsigned char *next_header, 00278 unsigned char *const dest, 00279 int counter, 00280 int *const first_position); 00281 00282 /// @brief The handler used to add an additional header in the tail of the 00283 /// UO-0, UO-1 and UO-2 packets 00284 int (*code_uo_remainder)(const struct c_context *context, 00285 const unsigned char *next_header, 00286 unsigned char *const dest, 00287 int counter); 00288 00289 /// @brief The handler used to compute the CRC-STATIC value 00290 unsigned int (*compute_crc_static)(const unsigned char *const ip, 00291 const unsigned char *const ip2, 00292 const unsigned char *const next_header, 00293 const rohc_crc_type_t crc_type, 00294 const unsigned int init_val, 00295 const unsigned char *const crc_table); 00296 00297 /// @brief The handler used to compute the CRC-DYNAMIC value 00298 unsigned int (*compute_crc_dynamic)(const unsigned char *const ip, 00299 const unsigned char *const ip2, 00300 const unsigned char *const next_header, 00301 const rohc_crc_type_t crc_type, 00302 const unsigned int init_val, 00303 const unsigned char *const crc_table); 00304 00305 /// Profile-specific data 00306 void *specific; 00307 }; 00308 00309 00310 /** 00311 * @brief The list compressor 00312 */ 00313 struct list_comp 00314 { 00315 /** Whether the extension list is present in IP header or not */ 00316 bool is_present; 00317 /** Whether the extension list changed in the last IP header or not */ 00318 bool changed; 00319 00320 /// The reference list 00321 struct c_list *ref_list; 00322 /// The current list 00323 struct c_list *curr_list; 00324 /// counter which indicates if ref_list is reference list 00325 int counter; 00326 /// The compression based table 00327 struct rohc_list_item based_table[MAX_ITEM]; 00328 /// The translation table 00329 struct c_translation trans_table[MAX_ITEM]; 00330 00331 00332 /* Functions for handling the data to compress */ 00333 00334 /// @brief the handler used to get the extension in the IP packet 00335 unsigned char * (*get_extension)(const struct ip_packet *ip, 00336 const int index); 00337 00338 /// @brief the handler used to get the index in based table for the corresponding item 00339 int (*get_index_table)(const struct ip_packet *ip, const int index); 00340 00341 /// @brief the handler used to get the size of an extension 00342 unsigned short (*get_size)(const unsigned char *ext); 00343 00344 /// @brief the handler used to compare two extension of the same type 00345 int (*compare)(const struct list_comp *const comp, 00346 const unsigned char *const ext, 00347 const int size, 00348 const int index_table); 00349 00350 /// @brief the handler used to create the item with the corresponding 00351 /// type of the extension 00352 void (*create_item)(struct list_comp *const comp, 00353 const unsigned int index_table, 00354 const unsigned char *ext_data, 00355 const size_t ext_size); 00356 00357 /// @brief the handler used to free the based table element 00358 void (*free_table)(struct list_comp *const comp); 00359 00360 00361 /* Traces */ 00362 00363 /** The callback function used to manage traces */ 00364 rohc_trace_callback_t trace_callback; 00365 /** The profile ID the compression list was created for */ 00366 int profile_id; 00367 }; 00368 00369 00370 /* 00371 * Function prototypes. 00372 */ 00373 00374 int c_generic_create(struct c_context *const context, 00375 const rohc_lsb_shift_t sn_shift, 00376 const struct ip_packet *ip); 00377 void c_generic_destroy(struct c_context *const context); 00378 00379 bool c_generic_check_profile(const struct rohc_comp *const comp, 00380 const struct ip_packet *const outer_ip, 00381 const struct ip_packet *const inner_ip, 00382 const uint8_t protocol, 00383 rohc_ctxt_key_t *const ctxt_key); 00384 00385 void change_mode(struct c_context *const context, const rohc_mode new_mode); 00386 void change_state(struct c_context *const context, const rohc_c_state new_state); 00387 00388 rohc_ext_t decide_extension(const struct c_context *context); 00389 00390 int c_generic_encode(struct c_context *const context, 00391 const struct ip_packet *ip, 00392 const size_t packet_size, 00393 unsigned char *const dest, 00394 const size_t dest_size, 00395 rohc_packet_t *const packet_type, 00396 int *const payload_offset); 00397 00398 bool c_generic_reinit_context(struct c_context *const context); 00399 00400 void c_generic_feedback(struct c_context *const context, 00401 const struct c_feedback *feedback); 00402 00403 bool c_generic_use_udp_port(const struct c_context *const context, 00404 const unsigned int port); 00405 00406 void decide_state(struct c_context *const context); 00407 00408 void rohc_get_ipid_bits(const struct c_context *context, 00409 size_t *const nr_innermost_bits, 00410 size_t *const nr_outermost_bits); 00411 00412 #endif 00413