ROHC compression/decompression library
rohc_comp_internals.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010,2011,2012,2013,2014 Didier Barvaux
00003  * Copyright 2012,2013,2014 Viveris Technologies
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 /**
00021  * @file    rohc_comp_internals.h
00022  * @brief   Internal structures for ROHC compression
00023  * @author  Didier Barvaux <didier.barvaux@toulouse.viveris.com>
00024  * @author  Didier Barvaux <didier@barvaux.org>
00025  */
00026 
00027 #ifndef ROHC_COMP_INTERNALS_H
00028 #define ROHC_COMP_INTERNALS_H
00029 
00030 #include "rohc_internal.h"
00031 #include "rohc_traces_internal.h"
00032 #include "rohc_packets.h"
00033 #include "rohc_comp.h"
00034 #include "schemes/wlsb.h"
00035 #include "net_pkt.h"
00036 #include "rohc_stats.h"
00037 
00038 #ifdef __KERNEL__
00039 #       include <linux/types.h>
00040 #else
00041 #       include <stdbool.h>
00042 #endif
00043 
00044 
00045 /*
00046  * Constants and macros
00047  */
00048 
00049 /** The number of ROHC profiles ready to be used */
00050 #define C_NUM_PROFILES 7U
00051 
00052 /** The maximal number of outgoing feedbacks that can be queued */
00053 #define FEEDBACK_RING_SIZE 1000U
00054 
00055 /** The default maximal number of packets sent in > IR states (= FO and SO
00056  *  states) before changing back the state to IR (periodic refreshes) */
00057 #define CHANGE_TO_IR_COUNT  1700
00058 
00059 /** The default maximal number of packets sent in > FO states (= SO state)
00060  *  before changing back the state to FO (periodic refreshes) */
00061 #define CHANGE_TO_FO_COUNT  700
00062 
00063 /** The minimal number of packets that must be sent while in IR state before
00064  *  being able to switch to the FO state */
00065 #define MAX_IR_COUNT  3
00066 
00067 /** The minimal number of packets that must be sent while in FO state before
00068  *  being able to switch to the SO state */
00069 #define MAX_FO_COUNT  3
00070 
00071 /** The minimal number of packets that must be sent while in INIT_STRIDE
00072  *  state before being able to switch to the SEND_SCALED state */
00073 #define ROHC_INIT_TS_STRIDE_MIN  3U
00074 
00075 /**
00076  * @brief Default number of transmission for lists to become a reference list
00077  *
00078  * The minimal number of times of compressed list shall be sent to become
00079  * a reference list. L is the name specified in the RFC.
00080  */
00081 #define ROHC_LIST_DEFAULT_L  5U
00082 
00083 
00084 /** Print a warning trace for the given compression context */
00085 #define rohc_comp_warn(context, format, ...) \
00086         rohc_warning((context)->compressor, ROHC_TRACE_COMP, \
00087                      (context)->profile->id, \
00088                      format, ##__VA_ARGS__)
00089 
00090 /** Print a debug trace for the given compression context */
00091 #define rohc_comp_debug(context, format, ...) \
00092         rohc_debug((context)->compressor, ROHC_TRACE_COMP, \
00093                    (context)->profile->id, \
00094                    format, ##__VA_ARGS__)
00095 
00096 
00097 /*
00098  * Declare ROHC compression structures that are defined at the end of this
00099  * file but used by other structures at the beginning of the file.
00100  */
00101 
00102 struct c_feedback;
00103 struct rohc_comp_ctxt;
00104 
00105 
00106 /*
00107  * Definitions of ROHC compression structures
00108  */
00109 
00110 
00111 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00112 /**
00113  * @brief Information on ROHC feedback data
00114  */
00115 struct rohc_feedback
00116 {
00117         /** The feedback data */
00118         unsigned char *data;
00119         /** The length (in bytes) of the feedback data */
00120         size_t length;
00121         /** Whether the feedback data was locked during packet build? */
00122         bool is_locked;
00123 };
00124 #endif /* !ROHC_ENABLE_DEPRECATED_API */
00125 
00126 
00127 /**
00128  * @brief The ROHC compressor
00129  */
00130 struct rohc_comp
00131 {
00132 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00133         /**
00134          * @brief Whether the compressor is enabled or not
00135          *
00136          * The compressor is enabled by default and may be disabled by user.
00137          */
00138         int enabled;
00139 #endif /* !ROHC_ENABLE_DEPRECATED_API */
00140 
00141         /** The medium associated with the decompressor */
00142         struct rohc_medium medium;
00143 
00144         /** Enabled/disabled features for the compressor */
00145         rohc_comp_features_t features;
00146 
00147         /** The array of compression contexts that use the compressor */
00148         struct rohc_comp_ctxt *contexts;
00149         /** The number of compression contexts in use in the array */
00150         size_t num_contexts_used;
00151 
00152         /** Which profiles are enabled and with one are not? */
00153         bool enabled_profiles[C_NUM_PROFILES];
00154 
00155 
00156         /* CRC-related variables: */
00157 
00158         /** The table to enable fast CRC-3 computation */
00159         unsigned char crc_table_3[256];
00160         /** The table to enable fast CRC-7 computation */
00161         unsigned char crc_table_7[256];
00162         /** The table to enable fast CRC-8 computation */
00163         unsigned char crc_table_8[256];
00164 
00165 
00166 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00167         /* feedback-related variables: */
00168 
00169         /** The ring of outgoing feedbacks */
00170         struct rohc_feedback feedbacks[FEEDBACK_RING_SIZE];
00171         /** The index of the oldest feedback in the feedback ring */
00172         size_t feedbacks_first;
00173         /** The index of the oldest unlocked feedback in the feedback ring */
00174         size_t feedbacks_first_unlocked;
00175         /** @brief The index of the next empty location in the feedback ring */
00176         size_t feedbacks_next;
00177 #endif /* !ROHC_ENABLE_DEPRECATED_API */
00178 
00179 
00180         /* segment-related variables */
00181 
00182 /** The maximal value for MRRU */
00183 #define ROHC_MAX_MRRU 65535
00184         /** The remaining bytes of the Reconstructed Reception Unit (RRU) waiting
00185          *  to be split into segments */
00186         unsigned char rru[ROHC_MAX_MRRU];
00187         /** The offset of the remaining bytes in the RRU buffer */
00188         size_t rru_off;
00189         /** The number of the remaining bytes in the RRU buffer */
00190         size_t rru_len;
00191 
00192 
00193         /* variables related to RTP detection */
00194 
00195 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00196 /** The maximal number of RTP ports (shall be > 2) */
00197 #define MAX_RTP_PORTS 15U
00198         /** The RTP ports table */
00199         unsigned int rtp_ports[MAX_RTP_PORTS];
00200 #endif /* !ROHC_ENABLE_DEPRECATED_API */
00201 
00202         /** The callback function used to detect RTP packet */
00203         rohc_rtp_detection_callback_t rtp_callback;
00204         /** Pointer to an external memory area provided/used by the callback user */
00205         void *rtp_private;
00206 
00207 
00208         /* some statistics about the compression process: */
00209 
00210         /** The number of sent packets */
00211         int num_packets;
00212         /** The size of all the received uncompressed IP packets */
00213         int total_uncompressed_size;
00214         /** The size of all the sent compressed ROHC packets */
00215         int total_compressed_size;
00216 
00217         /** The last context used by the compressor */
00218         struct rohc_comp_ctxt *last_context;
00219 
00220 
00221         /* random callback */
00222 
00223         /** The user-defined callback for random numbers */
00224         rohc_comp_random_cb_t random_cb;
00225         /** Private data that will be given to the callback for random numbers */
00226         void *random_cb_ctxt;
00227 
00228 
00229         /* user interaction variables: */
00230 
00231         /** The width of the W-LSB sliding window */
00232         size_t wlsb_window_width;
00233         /** The maximal number of packets sent in > IR states (= FO and SO
00234          *  states) before changing back the state to IR (periodic refreshes) */
00235         size_t periodic_refreshes_ir_timeout;
00236         /** The maximal number of packets sent in > FO states (= SO state)
00237          *  before changing back the state to FO (periodic refreshes) */
00238         size_t periodic_refreshes_fo_timeout;
00239         /** Maximum Reconstructed Reception Unit */
00240         size_t mrru;
00241         /** The connection type (currently not used) */
00242         int connection_type;
00243         /** The number of uncompressed transmissions for list compression (L) */
00244         size_t list_trans_nr;
00245 
00246 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00247         /** The old callback function used to manage traces */
00248         rohc_trace_callback_t trace_callback;
00249 #endif
00250         /** The new callback function used to manage traces */
00251         rohc_trace_callback2_t trace_callback2;
00252         /** The private context of the callback function used to manage traces */
00253         void *trace_callback_priv;
00254 };
00255 
00256 
00257 /**
00258  * @brief The ROHC compression profile
00259  *
00260  * The object defines a ROHC profile. Each field must be filled in
00261  * for each new profile.
00262  */
00263 struct rohc_comp_profile
00264 {
00265         /** The profile ID as reserved by IANA */
00266         const rohc_profile_t id;
00267 
00268         /**
00269          * @brief The IP protocol ID used to find out which profile is able to
00270          *        compress an IP packet
00271          */
00272         const unsigned short protocol;
00273 
00274         /**
00275          * @brief The handler used to create the profile-specific part of the
00276          *        compression context
00277          */
00278         bool (*create)(struct rohc_comp_ctxt *const context,
00279                        const struct net_pkt *const packet)
00280                 __attribute__((warn_unused_result, nonnull(1, 2)));
00281 
00282         /**
00283          * @brief The handler used to destroy the profile-specific part of the
00284          *        compression context
00285          */
00286         void (*destroy)(struct rohc_comp_ctxt *const context)
00287                 __attribute__((nonnull(1)));
00288 
00289         /**
00290          * @brief The handler used to check whether an uncompressed IP packet
00291          *        fits the current profile or not
00292          */
00293         bool (*check_profile)(const struct rohc_comp *const comp,
00294                               const struct net_pkt *const packet)
00295                 __attribute__((warn_unused_result, nonnull(1, 2)));
00296 
00297         /**
00298          * @brief The handler used to check whether an uncompressed IP packet
00299          *        belongs to a context or not
00300          */
00301         bool (*check_context)(const struct rohc_comp_ctxt *const context,
00302                               const struct net_pkt *const packet)
00303                 __attribute__((warn_unused_result, nonnull(1, 2)));
00304 
00305         /**
00306          * @brief The handler used to encode uncompressed IP packets
00307          *
00308          * @param context            The compression context
00309          * @param ip                 The IP packet to encode
00310          * @param packet_size        The length of the IP packet to encode
00311          * @param rohc_pkt           OUT: The ROHC packet
00312          * @param rohc_pkt_max_len   The maximum length of the ROHC packet
00313          * @param packet_type        OUT: The type of ROHC packet that is created
00314          * @param payload_offset     OUT: The offset for the payload in the IP packet
00315          * @return                   The length of the ROHC packet if successful,
00316          *                           -1 otherwise
00317          */
00318         int (*encode)(struct rohc_comp_ctxt *const context,
00319                       const struct net_pkt *const uncomp_pkt,
00320                       unsigned char *const rohc_pkt,
00321                       const size_t rohc_pkt_max_len,
00322                       rohc_packet_t *const packet_type,
00323                       size_t *const payload_offset)
00324                 __attribute__((warn_unused_result, nonnull(1, 2, 3, 5, 6)));
00325 
00326         /**
00327          * @brief The handler used to re-initialize a context
00328          */
00329         bool (*reinit_context)(struct rohc_comp_ctxt *const context)
00330                 __attribute__((nonnull(1), warn_unused_result));
00331 
00332         /**
00333          * @brief The handler used to warn the profile-specific part of the
00334          *        context about the arrival of feedback data
00335          */
00336         bool (*feedback)(struct rohc_comp_ctxt *const context,
00337                          const struct c_feedback *const feedback)
00338                 __attribute__((warn_unused_result, nonnull(1, 2)));
00339 
00340         /**
00341          * @brief The handler used to detect if a UDP port is used by the profile
00342          */
00343         bool (*use_udp_port)(const struct rohc_comp_ctxt *const context,
00344                              const unsigned int port);
00345 };
00346 
00347 
00348 /**
00349  * @brief The ROHC compression context
00350  */
00351 struct rohc_comp_ctxt
00352 {
00353         /** Whether the context is in use or not */
00354         int used;
00355         /** The time when the context was created (in seconds) */
00356         uint64_t latest_used;
00357         /** The time when the context was last used (in seconds) */
00358         uint64_t first_used;
00359 
00360         /** The context unique ID (CID) */
00361         rohc_cid_t cid;
00362 
00363         /** The key to help finding the context associated with a packet */
00364         rohc_ctxt_key_t key; /* may not be unique */
00365 
00366         /** The associated compressor */
00367         struct rohc_comp *compressor;
00368 
00369         /** The associated profile */
00370         const struct rohc_comp_profile *profile;
00371         /** Profile-specific data, defined by the profiles */
00372         void *specific;
00373 
00374         /** The operation mode in which the context operates among:
00375          *  ROHC_U_MODE, ROHC_O_MODE, ROHC_R_MODE */
00376         rohc_mode_t mode;
00377         /** The operation state in which the context operates: IR, FO, SO */
00378         rohc_comp_state_t state;
00379 
00380         /* below are some statistics */
00381 
00382         /* The type of ROHC packet created for the last compressed packet */
00383         rohc_packet_t packet_type;
00384 
00385         /** The average size of the uncompressed packets */
00386         int total_uncompressed_size;
00387         /** The average size of the compressed packets */
00388         int total_compressed_size;
00389         /** The average size of the uncompressed headers */
00390         int header_uncompressed_size;
00391         /** The average size of the compressed headers */
00392         int header_compressed_size;
00393 
00394         /** The total size of the last uncompressed packet */
00395         int total_last_uncompressed_size;
00396         /** The total size of the last compressed packet */
00397         int total_last_compressed_size;
00398         /** The header size of the last uncompressed packet */
00399         int header_last_uncompressed_size;
00400         /** The header size of the last compressed packet */
00401         int header_last_compressed_size;
00402 
00403         /** The number of sent packets */
00404         int num_sent_packets;
00405 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00406         /** The number of sent IR packets */
00407         int num_sent_ir;
00408         /** The number of sent IR-DYN packets */
00409         int num_sent_ir_dyn;
00410         /** The number of received feedbacks */
00411         int num_recv_feedbacks;
00412 #endif
00413 
00414 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1
00415         /** The size of the last 16 uncompressed packets */
00416         struct rohc_stats total_16_uncompressed;
00417         /** The size of the last 16 compressed packets */
00418         struct rohc_stats total_16_compressed;
00419         /** The size of the last 16 uncompressed headers */
00420         struct rohc_stats header_16_uncompressed;
00421         /** The size of the last 16 compressed headers */
00422         struct rohc_stats header_16_compressed;
00423 #endif
00424 };
00425 
00426 
00427 /**
00428  * @brief The feedback packet
00429  */
00430 struct c_feedback
00431 {
00432         /** The Context ID to which the feedback packet is related */
00433         rohc_cid_t cid;
00434 
00435         /**
00436          * @brief The type of feedback packet
00437          *
00438          * A value of 1 means FEEDBACK-1, value 2 means FEEDBACK-2.
00439          */
00440         int type;
00441 
00442         /** The feedback data (ie. the packet excluding the first type octet) */
00443         unsigned char *data;
00444         /** The size of the feedback data */
00445         size_t size;
00446 
00447         /**
00448          * @brief The offset that indicates the beginning of the profile-specific
00449          *        data in the feedback data
00450          */
00451         int specific_offset;
00452         /** The size of the profile-specific data */
00453         int specific_size;
00454 
00455         /** The type of acknowledgement (FEEDBACK-2 only) */
00456         enum
00457         {
00458                 /** The classical ACKnowledgement */
00459                 ACK,
00460                 /** The Negative ACKnowledgement */
00461                 NACK,
00462                 /** The Negative STATIC ACKnowledgement */
00463                 STATIC_NACK,
00464                 /** Currently unused acknowledgement type */
00465                 RESERVED
00466         } acktype;
00467 };
00468 
00469 #endif
00470