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 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