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