ROHC compression/decompression library
c_generic.h
Go to the documentation of this file.
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