ROHC compression/decompression library
d_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,2013 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 d_generic.h
00023  * @brief ROHC generic decompression 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  * @author David Moreau from TAS
00028  */
00029 
00030 #ifndef ROHC_DECOMP_GENERIC_H
00031 #define ROHC_DECOMP_GENERIC_H
00032 
00033 #include "rohc_decomp.h"
00034 #include "rohc_decomp_internals.h"
00035 #include "rohc_packets.h"
00036 #include "comp_list.h"
00037 #include "schemes/wlsb.h"
00038 #include "schemes/ip_id_offset.h"
00039 #include "schemes/list.h"
00040 #include "ip.h"
00041 #include "crc.h"
00042 
00043 #include <stddef.h>
00044 #ifdef __KERNEL__
00045 #       include <linux/types.h>
00046 #else
00047 #       include <stdbool.h>
00048 #endif
00049 
00050 
00051 /** The outer or inner IP bits extracted from ROHC headers */
00052 struct rohc_extr_ip_bits
00053 {
00054         uint8_t version:4;  /**< The version bits found in static chain of IR
00055                                  header */
00056 
00057         uint8_t tos;     /**< The TOS/TC bits found in dynamic chain of IR/IR-DYN
00058                               header or in extension header */
00059         size_t tos_nr;   /**< The number of TOS/TC bits found */
00060 
00061         uint16_t id;     /**< The IP-ID bits found in dynamic chain of IR/IR-DYN
00062                               header, in UO* base header, in extension header and
00063                               in remainder of UO* header */
00064         size_t id_nr;    /**< The number of IP-ID bits found */
00065         bool is_id_enc;  /**< Whether value(IP-ID) is encoded or not */
00066 
00067         uint8_t df:1;    /**< The DF bits found in dynamic chain of IR/IR-DYN
00068                               header or in extension header */
00069         size_t df_nr;    /**< The number of DF bits found */
00070 
00071         uint8_t ttl;     /**< The TTL/HL bits found in dynamic chain of IR/IR-DYN
00072                               header or in extension header */
00073         size_t ttl_nr;   /**< The number of TTL/HL bits found */
00074 
00075         uint8_t proto;   /**< The protocol/next header bits found static chain
00076                               of IR header or in extension header */
00077         size_t proto_nr; /**< The number of protocol/next header bits */
00078 
00079         uint8_t nbo:1;   /**< The NBO bits found in dynamic chain of IR/IR-DYN
00080                               header or in extension header */
00081         size_t nbo_nr;   /**< The number of NBO bits found */
00082 
00083         uint8_t rnd:1;   /**< The RND bits found in dynamic chain of IR/IR-DYN
00084                               header or in extension header */
00085         size_t rnd_nr;   /**< The number of RND bits found */
00086 
00087         uint8_t sid:1;   /**< The SID bits found in dynamic chain of IR/IR-DYN
00088                               header or in extension header */
00089         size_t sid_nr;   /**< The number of SID bits found */
00090 
00091         uint32_t flowid:20;  /**< The IPv6 flow ID bits found in static chain of
00092                                   IR header */
00093         size_t flowid_nr;    /**< The number of flow label bits */
00094 
00095         uint8_t saddr[16];   /**< The source address bits found in static chain of
00096                                   IR header */
00097         size_t saddr_nr;     /**< The number of source address bits */
00098 
00099         uint8_t daddr[16];   /**< The destination address bits found in static
00100                                   chain of IR header */
00101         size_t daddr_nr;     /**< The number of source address bits */
00102 };
00103 
00104 
00105 /**
00106  * @brief The bits extracted from ROHC UO* base headers
00107  *
00108  * @see parse_uo0
00109  * @see parse_uo1
00110  * @see parse_uor2
00111  */
00112 struct rohc_extr_bits
00113 {
00114         bool is_context_reused; /**< Whether the context is re-used or not */
00115 
00116         /* SN */
00117         uint32_t sn;         /**< The SN bits found in ROHC header */
00118         size_t sn_nr;        /**< The number of SN bits found in ROHC header */
00119         bool is_sn_enc;      /**< Whether value(SN) is encoded with W-LSB or not */
00120         rohc_lsb_ref_t sn_ref_type; /**< The SN reference to use for LSB decoding
00121                                          (used for context repair after CRC failure) */
00122         bool sn_ref_offset;         /**< Optional offset to add to the reference SN
00123                                          (used for context repair after CRC failure) */
00124 
00125         /** bits related to outer IP header */
00126         struct rohc_extr_ip_bits outer_ip;
00127 
00128         /** bits related to inner IP header */
00129         struct rohc_extr_ip_bits inner_ip;
00130 
00131         /* CRC */
00132         rohc_crc_type_t crc_type; /**< The type of CRC that protect the ROHC header */
00133         uint8_t crc;              /**< The CRC bits found in ROHC header */
00134         size_t crc_nr;            /**< The number of CRC bits found in ROHC header */
00135 
00136         /* X (extension) flag */
00137         uint8_t ext_flag:1;     /**< X (extension) flag */
00138 
00139         /* Mode bits */
00140         uint8_t mode:2;         /**< The Mode bits found in ROHC header */
00141         size_t mode_nr;         /**< The number of Mode bits found in ROHC header */
00142 
00143 
00144         /* bits below are for UDP-based profiles only
00145            @todo TODO should be moved in d_udp.c */
00146 
00147         uint16_t udp_src;     /**< The UDP source port bits found in static chain
00148                                    of IR header */
00149         size_t udp_src_nr;    /**< The number of UDP source port bits */
00150 
00151         uint16_t udp_dst;     /**< The UDP destination port bits in static chain
00152                                    of IR header */
00153         size_t udp_dst_nr;    /**< The number of UDP destination port bits */
00154 
00155         uint16_t udp_check;   /**< The UDP checksum bits found in dynamic chain
00156                                    of IR/IR-DYN header or in remainder of UO*
00157                                    header */
00158         size_t udp_check_nr;  /**< The number of UDP checksum bits */
00159 
00160 
00161         /* bits below are for UDP-Lite-based profiles only
00162            @todo TODO should be moved in d_udp_lite.c */
00163 
00164         uint16_t udp_lite_cc;     /**< The UDP-Lite CC bits found in dynamic
00165                                        chain of IR/IR-DYN header or in remainder
00166                                        of UO* header */
00167         size_t udp_lite_cc_nr;    /**< The number of UDP-Lite CC bits */
00168 
00169 
00170         /* bits below are for RTP profile only
00171            @todo TODO should be moved in d_rtp.c */
00172 
00173         /* RTP version */
00174         uint8_t rtp_version:2;  /**< The RTP version bits found in dynamic chain
00175                                      of IR/IR-DYN header */
00176         size_t rtp_version_nr;  /**< The number of RTP version bits */
00177 
00178         /* RTP Padding (R-P) flag */
00179         uint8_t rtp_p:1;        /**< The RTP Padding bits found in dynamic chain
00180                                      of IR/IR-DYN header or in extension header */
00181         size_t rtp_p_nr;        /**< The number of RTP Padding bits */
00182 
00183         /* RTP eXtension (R-X) flag */
00184         uint8_t rtp_x:1;        /**< The RTP eXtension (R-X) bits found in
00185                                      extension header */
00186         size_t rtp_x_nr;        /**< The number of RTP X bits */
00187 
00188         /* RTP CSRC Count (CC) */
00189         uint8_t rtp_cc:4;       /**< The RTP CSRC Count bits found in dynamic
00190                                      chain of IR/IR-DYN header */
00191         size_t rtp_cc_nr;       /**< The number of the RTP CSRC Count bits */
00192 
00193         /* RTP Marker (M) flag */
00194         uint8_t rtp_m:1;        /**< The RTP Marker (M) bits found in dynamic chain
00195                                      of IR/IR-DYN header, UO* base header and
00196                                      extension header */
00197         size_t rtp_m_nr;        /**< The number of the RTP Marker (M) bits */
00198 
00199         /* RTP Payload Type (RTP-PT) */
00200         uint8_t rtp_pt:7;       /**< The RTP Payload Type (PT) bits found in
00201                                      dynamic chain of IR/IR-DYN header or in
00202                                      extension header */
00203         size_t rtp_pt_nr;       /**< The number of RTP PT bits found in header */
00204 
00205         /* RTP TimeStamp (TS) */
00206         uint32_t ts;            /**< The TS bits found in dynamic chain of
00207                                      IR/IR-DYN header, in UO* base header or in
00208                                      extension header */
00209         size_t ts_nr;           /**< The number of TS bits found in ROHC header */
00210         bool is_ts_scaled;      /**< Whether TS is transmitted scaled or not */
00211 
00212         /* RTP Synchronization SouRCe (SSRC)  identifier */
00213         uint32_t rtp_ssrc;      /**< The SSRC bits found in static chain of
00214                                      IR header */
00215         size_t rtp_ssrc_nr;     /**< The number of SSRC bits found in header */
00216 
00217 
00218         /* bits below are for ESP profile only
00219            @todo TODO should be moved in d_esp.c */
00220 
00221         /* ESP Security Parameters Index (SPI) */
00222         uint32_t esp_spi;      /**< The SPI bits found in static chain of
00223                                      IR header */
00224         size_t esp_spi_nr;     /**< The number of SPI bits found in header */
00225 };
00226 
00227 
00228 /** The outer or inner IP values decoded from the extracted ROHC bits */
00229 struct rohc_decoded_ip_values
00230 {
00231         uint8_t version:4;   /**< The decoded version field */
00232         uint8_t tos;         /**< The decoded TOS/TC field */
00233         uint16_t id;         /**< The decoded IP-ID field (IPv4 only) */
00234         uint8_t df:1;        /**< The decoded DF field (IPv4 only) */
00235         uint8_t ttl;         /**< The decoded TTL/HL field */
00236         uint8_t proto;       /**< The decoded protocol/NH field */
00237         uint8_t nbo:1;       /**< The decoded NBO field (IPv4 only) */
00238         uint8_t rnd:1;       /**< The decoded RND field (IPv4 only) */
00239         uint8_t sid:1;       /**< The decoded SID field (IPv4 only) */
00240         uint32_t flowid:20;  /**< The decoded flow ID field (IPv6 only) */
00241         uint8_t saddr[16];   /**< The decoded source address field */
00242         uint8_t daddr[16];   /**< The decoded destination address field */
00243 };
00244 
00245 
00246 /**
00247  * @brief The values decoded from the bits extracted from ROHC header
00248  *
00249  * @see decode_uo0
00250  * @see decode_uo1
00251  * @see decode_uor2
00252  * @see decode_values_from_bits
00253  * @see rtp_decode_values_from_bits
00254  */
00255 struct rohc_decoded_values
00256 {
00257         uint32_t sn;  /**< The decoded SN value */
00258 
00259         /** The decoded values for the outer IP header */
00260         struct rohc_decoded_ip_values outer_ip;
00261         /** The decoded values for the inner IP header */
00262         struct rohc_decoded_ip_values inner_ip;
00263 
00264         /* bits below are for UDP-based profile only
00265            @todo TODO should be moved in d_udp.c */
00266         uint16_t udp_src;   /**< The decoded UDP source port */
00267         uint16_t udp_dst;   /**< The decoded UDP destination port bits */
00268         uint16_t udp_check; /**< The decoded UDP checksum */
00269 
00270         /* bits below are for UDP-Lite-based profile only
00271            @todo TODO should be moved in d_udp_lite.c */
00272         uint16_t udp_lite_cc;   /**< The decoded UDP-Lite CC */
00273 
00274         /* bits below are for RTP profile only
00275            @todo TODO should be moved in d_rtp.c */
00276         uint8_t rtp_version:2;  /**< The decoded RTP version */
00277         uint8_t rtp_p:1;        /**< The decoded RTP Padding (R-P) flag */
00278         uint8_t rtp_x:1;        /**< The decoded RTP eXtension (R-X) flag */
00279         uint8_t rtp_cc:4;       /**< The decoded RTP CSRC Count */
00280         uint8_t rtp_m:1;        /**< The decoded RTP Marker (M) flag */
00281         uint8_t rtp_pt:7;       /**< The decoded RTP Payload Type (RTP-PT) */
00282         uint32_t ts;            /**< The decoded RTP TimeStamp (TS) value */
00283         uint32_t rtp_ssrc;      /**< The decoded SSRC value */
00284 
00285         /* bits below are for ESP profile only
00286            @todo TODO should be moved in d_esp.c */
00287         uint32_t esp_spi;       /**< The decoded ESP SPI */
00288 };
00289 
00290 
00291 /**
00292  * @brief Store information about an IP header between the different
00293  *        decompressions of IP packets.
00294  *
00295  * Defines an object that contains flags and structures related to an IP header
00296  * and that need to be saved between the different decompressions of packets. A
00297  * decompression context owns objects like this for the two first IP headers.
00298  */
00299 struct d_generic_changes
00300 {
00301         /// The IP header
00302         struct ip_packet ip;
00303 
00304         /// Whether the IP-ID is considered as random or not (IPv4 only)
00305         int rnd;
00306         /// Whether the IP-ID is considered as coded in NBO or not (IPv4 only)
00307         int nbo;
00308         /// Whether the IP-ID is considered as static or not (IPv4 only)
00309         int sid;
00310 
00311         /// The next header located after the IP header(s)
00312         void *next_header;
00313         /// The length of the next header
00314         unsigned int next_header_len;
00315 };
00316 
00317 
00318 /**
00319  * @brief The different correction algorithms available in case of CRC failure
00320  */
00321 typedef enum
00322 {
00323         ROHC_DECOMP_CRC_CORR_SN_NONE    = 0, /**< No correction */
00324         ROHC_DECOMP_CRC_CORR_SN_WRAP    = 1, /**< Correction of SN wraparound */
00325         ROHC_DECOMP_CRC_CORR_SN_UPDATES = 2, /**< Correction of incorrect SN updates */
00326 
00327 } rohc_decomp_crc_corr_t;
00328 
00329 
00330 /**
00331  * @brief The generic decompression context
00332  *
00333  * The object defines the generic context that manages IP(/nextheader) and
00334  * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific
00335  * part of the context.
00336  */
00337 struct d_generic_context
00338 {
00339         /// Information about the outer IP header
00340         struct d_generic_changes *outer_ip_changes;
00341         /// Information about the inner IP header
00342         struct d_generic_changes *inner_ip_changes;
00343 
00344         /// The LSB decoding context for the Sequence Number (SN)
00345         struct rohc_lsb_decode *sn_lsb_ctxt;
00346         /// The IP-ID of the outer IP header
00347         struct ip_id_offset_decode *outer_ip_id_offset_ctxt;
00348         /// The IP-ID of the inner IP header
00349         struct ip_id_offset_decode *inner_ip_id_offset_ctxt;
00350 
00351         /// The list decompressor of the outer IP header
00352         struct list_decomp list_decomp1;
00353         /// The list decompressor of the inner IP header
00354         struct list_decomp list_decomp2;
00355 
00356         /// Whether the decompressed packet contains a 2nd IP header
00357         int multiple_ip;
00358 
00359         /* below are some information and handlers to manage the next header
00360          * (if any) located just after the IP headers (1 or 2 IP headers) */
00361 
00362         /// The IP protocol ID of the protocol the context is able to decompress
00363         unsigned short next_header_proto;
00364 
00365         /// The length of the next header
00366         unsigned int next_header_len;
00367 
00368         /// @brief The handler used to parse the static part of the next header
00369         ///        in the ROHC packet
00370         int (*parse_static_next_hdr)(const struct rohc_decomp_ctxt *const context,
00371                                      const unsigned char *packet,
00372                                      size_t length,
00373                                      struct rohc_extr_bits *const bits);
00374 
00375         /// @brief The handler used to parse the dynamic part of the next header
00376         ///        in the ROHC packet
00377         int (*parse_dyn_next_hdr)(const struct rohc_decomp_ctxt *const context,
00378                                   const uint8_t *packet,
00379                                   const size_t length,
00380                                   struct rohc_extr_bits *const bits);
00381 
00382         /**
00383          * @brief The handler used to parse the extension 3 of the UO* ROHC packet
00384          *
00385          * @param context           The decompression context
00386          * @param rohc_data         The ROHC data to parse
00387          * @param rohc_data_len     The length of the ROHC data to parse
00388          * @param packet_type       The type of ROHC packet to parse
00389          * @param bits              IN: the bits already found in base header
00390          *                          OUT: the bits found in the extension header 3
00391          * @return                  The data length read from the ROHC packet,
00392          *                          -2 in case packet must be reparsed,
00393          *                          -1 in case of error
00394          */
00395         int (*parse_ext3)(const struct rohc_decomp_ctxt *const context,
00396                           const unsigned char *const rohc_data,
00397                           const size_t rohc_data_len,
00398                           const rohc_packet_t packet_type,
00399                           struct rohc_extr_bits *const bits)
00400                 __attribute__((warn_unused_result, nonnull(1, 2, 5)));
00401 
00402         /// The handler used to parse the tail of the UO* ROHC packet
00403         int (*parse_uo_remainder)(const struct rohc_decomp_ctxt *const context,
00404                                   const unsigned char *packet,
00405                                   unsigned int length,
00406                                   struct rohc_extr_bits *const bits);
00407 
00408         /** The handler used to decode extracted for next header */
00409         bool (*decode_values_from_bits)(const struct rohc_decomp_ctxt *context,
00410                                         const struct rohc_extr_bits bits,
00411                                         struct rohc_decoded_values *const decoded);
00412 
00413         /** The handler used to build the uncompressed next header */
00414         int (*build_next_header)(const struct rohc_decomp_ctxt *const context,
00415                                  const struct rohc_decoded_values decoded,
00416                                  unsigned char *dest,
00417                                  const unsigned int payload_len);
00418 
00419         /// @brief The handler used to compute the CRC-STATIC value
00420         uint8_t (*compute_crc_static)(const uint8_t *const ip,
00421                                       const uint8_t *const ip2,
00422                                       const uint8_t *const next_header,
00423                                       const rohc_crc_type_t crc_type,
00424                                       const uint8_t init_val,
00425                                       const uint8_t *const crc_table);
00426 
00427         /// @brief The handler used to compute the CRC-DYNAMIC value
00428         uint8_t (*compute_crc_dynamic)(const uint8_t *const ip,
00429                                        const uint8_t *const ip2,
00430                                        const uint8_t *const next_header,
00431                                        const rohc_crc_type_t crc_type,
00432                                        const uint8_t init_val,
00433                                        const uint8_t *const crc_table);
00434 
00435         /** The handler used to update context with decoded next header fields */
00436         void (*update_context)(const struct rohc_decomp_ctxt *context,
00437                                const struct rohc_decoded_values decoded);
00438 
00439         /// Profile-specific data
00440         void *specific;
00441 
00442 
00443         /*
00444          * for correction upon CRC failure
00445          */
00446 
00447         /** The algorithm being used for correction CRC failure */
00448         rohc_decomp_crc_corr_t crc_corr;
00449         /** Correction counter (see e and f in 5.3.2.2.4 of the RFC 3095) */
00450         size_t correction_counter;
00451 /** The number of last packets to record arrival times for */
00452 #define ROHC_MAX_ARRIVAL_TIMES  10U
00453         /** The arrival times for the last packets */
00454         struct rohc_ts arrival_times[ROHC_MAX_ARRIVAL_TIMES];
00455         /** The number of arrival times in arrival_times */
00456         size_t arrival_times_nr;
00457         /** The index for the arrival time of the next packet */
00458         size_t arrival_times_index;
00459         /** The arrival time of the current packet */
00460         struct rohc_ts cur_arrival_time;
00461 };
00462 
00463 
00464 /*
00465  * Public function prototypes.
00466  */
00467 
00468 void * d_generic_create(const struct rohc_decomp_ctxt *const context,
00469 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00470                         rohc_trace_callback_t trace_cb,
00471 #endif
00472                         rohc_trace_callback2_t trace_cb2,
00473                         void *const trace_cb_priv,
00474                         const int profile_id)
00475         __attribute__((nonnull(1), warn_unused_result));
00476 
00477 void d_generic_destroy(void *const context)
00478         __attribute__((nonnull(1)));
00479 
00480 rohc_status_t d_generic_decode(struct rohc_decomp *const decomp,
00481                                struct rohc_decomp_ctxt *const context,
00482                                const struct rohc_buf rohc_packet,
00483                                const size_t add_cid_len,
00484                                const size_t large_cid_len,
00485                                struct rohc_buf *const uncomp_packet,
00486                                rohc_packet_t *const packet_type)
00487         __attribute__((warn_unused_result, nonnull(1, 2, 6, 7)));
00488 
00489 uint32_t d_generic_get_sn(const struct rohc_decomp_ctxt *const context);
00490 
00491 
00492 
00493 /*
00494  * Helper functions
00495  */
00496 
00497 
00498 static inline bool is_ipv4_pkt(const struct rohc_extr_ip_bits bits)
00499         __attribute__((warn_unused_result, const));
00500 
00501 static inline bool is_ipv4_rnd_pkt(const struct rohc_extr_ip_bits bits)
00502         __attribute__((warn_unused_result, const));
00503 
00504 static inline bool is_ipv4_non_rnd_pkt(const struct rohc_extr_ip_bits bits)
00505         __attribute__((warn_unused_result, const));
00506 
00507 
00508 /**
00509  * @brief Is the given IP header IPV4 wrt packet?
00510  *
00511  * @param bits  The bits extracted from packet
00512  * @return      true if IPv4, false if IPv6
00513  */
00514 static inline bool is_ipv4_pkt(const struct rohc_extr_ip_bits bits)
00515 {
00516         return (bits.version == IPV4);
00517 }
00518 
00519 
00520 /**
00521  * @brief Is the given IP header IPv4 and its IP-ID random wrt packet?
00522  *
00523  * @param bits  The bits extracted from packet
00524  * @return      true if IPv4 and random, false otherwise
00525  */
00526 static inline bool is_ipv4_rnd_pkt(const struct rohc_extr_ip_bits bits)
00527 {
00528         return (is_ipv4_pkt(bits) && bits.rnd == 1);
00529 }
00530 
00531 
00532 /**
00533  * @brief Is the given IP header IPv4 and its IP-ID non-random wrt packet?
00534  *
00535  * @param bits  The bits extracted from packet
00536  * @return      true if IPv4 and non-random, false otherwise
00537  */
00538 static inline bool is_ipv4_non_rnd_pkt(const struct rohc_extr_ip_bits bits)
00539 {
00540         return (is_ipv4_pkt(bits) && bits.rnd == 0);
00541 }
00542 
00543 
00544 #endif
00545