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