ROHC compression/decompression library
|
00001 /* 00002 * Copyright 2010,2011,2012,2013,2014 Didier Barvaux 00003 * Copyright 2007,2008 Thales Alenia Space 00004 * Copyright 2007,2008,2009,2010,2012,2014 Viveris Technologies 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /** 00022 * @file c_generic.h 00023 * @brief ROHC generic compression context for IP-only, UDP and UDP Lite 00024 * profiles. 00025 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00026 * @author Didier Barvaux <didier@barvaux.org> 00027 */ 00028 00029 #ifndef ROHC_COMP_GENERIC_H 00030 #define ROHC_COMP_GENERIC_H 00031 00032 #include "rohc_comp_internals.h" 00033 #include "rohc_packets.h" 00034 #include "schemes/list.h" 00035 #include "ip.h" 00036 #include "crc.h" 00037 00038 #include <stdlib.h> 00039 00040 00041 /** 00042 * @brief Store information about an IPv4 header between the different 00043 * compressions of IP packets. 00044 * 00045 * Defines an object that contains counters, flags and structures related to an 00046 * IPv4 header and that need to be saved between the different compressions of 00047 * packets. A compression context owns objects like this for the two first 00048 * IPv4 headers. 00049 */ 00050 struct ipv4_header_info 00051 { 00052 /// A window to store the IP-ID 00053 struct c_wlsb *ip_id_window; 00054 00055 /// The previous IP header 00056 struct ipv4_hdr old_ip; 00057 00058 /// The number of times the DF field was added to the compressed header 00059 int df_count; 00060 /// @brief The number of times the IP-ID is specified as random in the 00061 /// compressed header 00062 int rnd_count; 00063 /// @brief The number of times the IP-ID is specified as coded in Network 00064 /// Byte Order (NBO) in the compressed header 00065 int nbo_count; 00066 /// @brief The number of times the IP-ID is specified as static in the 00067 /// compressed header 00068 int sid_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 /// Whether the IP-ID is considered as static or not 00075 int sid; 00076 /// @brief Whether the IP-ID of the previous IP header was considered as 00077 /// random or not 00078 int old_rnd; 00079 /// @brief Whether the IP-ID of the previous IP header was considered as 00080 /// coded in NBO or not 00081 int old_nbo; 00082 /// @brief Whether the IP-ID of the previous IP header was considered as 00083 /// static or not 00084 int old_sid; 00085 00086 /// The delta between the IP-ID and the current Sequence Number (SN) 00087 /// (overflow over 16 bits is expected when SN > IP-ID) 00088 uint16_t id_delta; 00089 }; 00090 00091 00092 /** 00093 * @brief Store information about an IPv6 header between the different 00094 * compressions of IP packets. 00095 * 00096 * Defines an object that contains counters, flags and structures related to an 00097 * IPv6 header and that need to be saved between the different compressions of 00098 * packets. A compression context owns objects like this for the two first 00099 * IPv6 headers. 00100 */ 00101 struct ipv6_header_info 00102 { 00103 /// The previous IPv6 header 00104 struct ipv6_hdr old_ip; 00105 /// The extension compressor 00106 struct list_comp ext_comp; 00107 }; 00108 00109 00110 /** 00111 * @brief Store information about an IP (IPv4 or IPv6) header between the 00112 * different compressions of IP packets. 00113 */ 00114 struct ip_header_info 00115 { 00116 ip_version version; ///< The version of the IP header 00117 00118 /// The number of times the TOS/TC field was added to the compressed header 00119 int tos_count; 00120 /// The number of times the TTL/HL field was added to the compressed header 00121 int ttl_count; 00122 /// @brief The number of times the Protocol/Next Header field was added to 00123 /// the compressed header 00124 int protocol_count; 00125 00126 /** Whether the old_* members of the struct and in its children are 00127 * initialized or not */ 00128 bool is_first_header; 00129 00130 union 00131 { 00132 struct ipv4_header_info v4; ///< The IPv4-specific header info 00133 struct ipv6_header_info v6; ///< The IPv6-specific header info 00134 } info; ///< The version specific header info 00135 }; 00136 00137 00138 /** 00139 * @brief Structure that contains variables that are used during one single 00140 * compression of packet. 00141 * 00142 * Structure that contains variables that are temporary, i.e. variables that 00143 * will only be used for the compression of the current packet. These variables 00144 * must be reinitialized every time a new packet arrive. 00145 * 00146 * @see c_init_tmp_variables 00147 */ 00148 struct generic_tmp_vars 00149 { 00150 /// The number of fields that changed in the outer IP header 00151 unsigned short changed_fields; 00152 /// The number of fields that changed in the inner IP header 00153 unsigned short changed_fields2; 00154 /// The number of static fields that changed in the two IP headers 00155 int send_static; 00156 /// The number of dynamic fields that changed in the two IP headers 00157 int send_dynamic; 00158 00159 /// The number of bits needed to encode the Sequence Number (SN) 00160 size_t nr_sn_bits; 00161 /// The number of bits needed to encode the IP-ID of the outer IP header 00162 size_t nr_ip_id_bits; 00163 /// The number of bits needed to encode the IP-ID of the inner IP header 00164 size_t nr_ip_id_bits2; 00165 00166 /// The type of packet the compressor must send: IR, IR-DYN, UO* 00167 rohc_packet_t packet_type; 00168 }; 00169 00170 00171 /** 00172 * @brief The generic compression context 00173 * 00174 * The object defines the generic context that manages IP(/nextheader) and 00175 * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific 00176 * part of the context. 00177 */ 00178 struct c_generic_context 00179 { 00180 /// The Sequence Number (SN), may be 16-bit or 32-bit long 00181 uint32_t sn; 00182 /// A window used to encode the SN 00183 struct c_wlsb *sn_window; 00184 00185 /// The number of packets sent while in Initialization & Refresh (IR) state 00186 int ir_count; 00187 /// The number of packets sent while in First Order (FO) state 00188 int fo_count; 00189 /// The number of packets sent while in Second Order (SO) state 00190 int so_count; 00191 00192 /// @brief The number of packet sent while in SO state, used for the periodic 00193 /// refreshes of the context 00194 /// @see periodic_down_transition 00195 size_t go_back_fo_count; 00196 /// @brief The number of packet sent while in FO or SO state, used for the 00197 /// periodic refreshes of the context 00198 /// @see periodic_down_transition 00199 size_t go_back_ir_count; 00200 00201 /** The number of IP headers */ 00202 size_t ip_hdr_nr; 00203 /// Information about the outer IP header 00204 struct ip_header_info outer_ip_flags; 00205 /// Information about the inner IP header 00206 struct ip_header_info inner_ip_flags; 00207 00208 /// Temporary variables that are used during one single compression of packet 00209 struct generic_tmp_vars tmp; 00210 00211 /* below are some information and handlers to manage the next header 00212 * (if any) located just after the IP headers (1 or 2 IP headers) */ 00213 00214 /// The protocol number registered by IANA for the next header protocol 00215 unsigned int next_header_proto; 00216 /// The length of the next header 00217 unsigned int next_header_len; 00218 00219 /** The handler for encoding profile-specific uncompressed header fields */ 00220 bool (*encode_uncomp_fields)(struct rohc_comp_ctxt *const context, 00221 const struct net_pkt *const uncomp_pkt) 00222 __attribute__((warn_unused_result, nonnull(1, 2))); 00223 00224 /// @brief The handler used to decide the state that should be used for the 00225 /// next packet 00226 void (*decide_state)(struct rohc_comp_ctxt *const context); 00227 /** @brief The handler used to decide which packet to send in FO state */ 00228 rohc_packet_t (*decide_FO_packet)(const struct rohc_comp_ctxt *context); 00229 /** @brief The handler used to decide which packet to send in SO state */ 00230 rohc_packet_t (*decide_SO_packet)(const struct rohc_comp_ctxt *context); 00231 /** The handler used to decide which extension to send */ 00232 rohc_ext_t (*decide_extension)(const struct rohc_comp_ctxt *context); 00233 00234 /// The handler used to initialize some data just before the IR packet build 00235 void (*init_at_IR)(const struct rohc_comp_ctxt *context, 00236 const unsigned char *next_header); 00237 00238 /** Determine the next SN value */ 00239 uint32_t (*get_next_sn)(const struct rohc_comp_ctxt *const context, 00240 const struct net_pkt *const uncomp_pkt) 00241 __attribute__((warn_unused_result, nonnull(1, 2))); 00242 00243 /// @brief The handler used to add the static part of the next header to the 00244 /// ROHC packet 00245 size_t (*code_static_part)(const struct rohc_comp_ctxt *const context, 00246 const unsigned char *const next_header, 00247 unsigned char *const dest, 00248 const size_t counter) 00249 __attribute__((warn_unused_result, nonnull(1, 2, 3))); 00250 00251 /// @brief The handler used to add the dynamic part of the next header to the 00252 /// ROHC pachet 00253 size_t (*code_dynamic_part)(const struct rohc_comp_ctxt *const context, 00254 const unsigned char *const next_header, 00255 unsigned char *const dest, 00256 const size_t counter) 00257 __attribute__((warn_unused_result, nonnull(1, 2, 3))); 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 rohc_comp_ctxt *const context, 00262 unsigned char *const dest, 00263 const size_t dest_max_len, 00264 const size_t counter) 00265 __attribute__((warn_unused_result, nonnull(1, 2))); 00266 00267 /// @brief The handler used to add an additional header in the head of the 00268 /// UO-0, UO-1 and UO-2 packets 00269 size_t (*code_UO_packet_head)(const struct rohc_comp_ctxt *const context, 00270 const unsigned char *const next_header, 00271 unsigned char *const dest, 00272 const size_t counter, 00273 size_t *const first_position) 00274 __attribute__((warn_unused_result, nonnull(1,2, 3, 5))); 00275 00276 /// @brief The handler used to add an additional header in the tail of the 00277 /// UO-0, UO-1 and UO-2 packets 00278 size_t (*code_uo_remainder)(const struct rohc_comp_ctxt *const context, 00279 const unsigned char *const next_header, 00280 unsigned char *const dest, 00281 const size_t counter) 00282 __attribute__((warn_unused_result, nonnull(1, 2, 3))); 00283 00284 /// @brief The handler used to compute the CRC-STATIC value 00285 uint8_t (*compute_crc_static)(const uint8_t *const ip, 00286 const uint8_t *const ip2, 00287 const uint8_t *const next_header, 00288 const rohc_crc_type_t crc_type, 00289 const uint8_t init_val, 00290 const uint8_t *const crc_table) 00291 __attribute__((nonnull(1, 3, 6), warn_unused_result)); 00292 00293 /// @brief The handler used to compute the CRC-DYNAMIC value 00294 uint8_t (*compute_crc_dynamic)(const uint8_t *const ip, 00295 const uint8_t *const ip2, 00296 const uint8_t *const next_header, 00297 const rohc_crc_type_t crc_type, 00298 const uint8_t init_val, 00299 const uint8_t *const crc_table) 00300 __attribute__((nonnull(1, 3, 6), warn_unused_result)); 00301 00302 /// Profile-specific data 00303 void *specific; 00304 }; 00305 00306 00307 /* 00308 * Function prototypes. 00309 */ 00310 00311 bool c_generic_create(struct rohc_comp_ctxt *const context, 00312 const rohc_lsb_shift_t sn_shift, 00313 const struct net_pkt *const packet) 00314 __attribute__((warn_unused_result, nonnull(1, 3))); 00315 void c_generic_destroy(struct rohc_comp_ctxt *const context) 00316 __attribute__((nonnull(1))); 00317 00318 bool c_generic_check_profile(const struct rohc_comp *const comp, 00319 const struct net_pkt *const packet) 00320 __attribute__((warn_unused_result, nonnull(1, 2))); 00321 00322 void change_state(struct rohc_comp_ctxt *const context, 00323 const rohc_comp_state_t new_state) 00324 __attribute__((nonnull(1))); 00325 00326 rohc_ext_t decide_extension(const struct rohc_comp_ctxt *const context) 00327 __attribute__((warn_unused_result, nonnull(1))); 00328 00329 int c_generic_encode(struct rohc_comp_ctxt *const context, 00330 const struct net_pkt *const uncomp_pkt, 00331 unsigned char *const rohc_pkt, 00332 const size_t rohc_pkt_max_len, 00333 rohc_packet_t *const packet_type, 00334 size_t *const payload_offset) 00335 __attribute__((warn_unused_result, nonnull(1, 2, 3, 5, 6))); 00336 00337 bool c_generic_reinit_context(struct rohc_comp_ctxt *const context); 00338 00339 bool c_generic_feedback(struct rohc_comp_ctxt *const context, 00340 const struct c_feedback *const feedback) 00341 __attribute__((warn_unused_result, nonnull(1, 2))); 00342 00343 bool c_generic_use_udp_port(const struct rohc_comp_ctxt *const context, 00344 const unsigned int port); 00345 00346 void decide_state(struct rohc_comp_ctxt *const context); 00347 00348 void rohc_get_ipid_bits(const struct rohc_comp_ctxt *const context, 00349 size_t *const nr_innermost_bits, 00350 size_t *const nr_outermost_bits) 00351 __attribute__((nonnull(1, 2, 3))); 00352 00353 #endif 00354