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