ROHC compression/decompression library
feedback.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015,2016 Didier Barvaux
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file feedback.h
21  * @brief ROHC feedback definitions and formats
22  * @author Didier Barvaux <didier@barvaux.org>
23  */
24 
25 #ifndef ROHC_FEEDBACK_H
26 #define ROHC_FEEDBACK_H
27 
28 #include "rohc.h"
29 
30 #ifdef __KERNEL__
31 # include <endian.h>
32 #else
33 # include "config.h" /* for WORDS_BIGENDIAN */
34 #endif
35 
36 #include <stdbool.h>
37 #include <stdint.h>
38 #include <stddef.h>
39 
40 
41 /** The type of ROHC feedback */
43 {
44  ROHC_FEEDBACK_1 = 1, /**< ROHC FEEDBACK-1 */
45  ROHC_FEEDBACK_2 = 2, /**< ROHC FEEDBACK-2 */
46 };
47 
48 
49 /** The type of acknowledgement */
51 {
52  ROHC_FEEDBACK_ACK = 0, /**< The classical ACKnowledgement */
53  ROHC_FEEDBACK_NACK = 1, /**< The Negative ACKnowledgement */
54  ROHC_FEEDBACK_STATIC_NACK = 2, /**< The Negative STATIC ACKnowledgement */
55  ROHC_FEEDBACK_RESERVED = 3, /**< reserved (MUST NOT be used for parsability) */
56 };
57 
58 
59 /**
60  * @brief Whether the feedback is protected by a CRC or not
61  */
62 typedef enum
63 {
64  ROHC_FEEDBACK_WITH_NO_CRC = 0, /**< No CRC protects the feedback */
65  ROHC_FEEDBACK_WITH_CRC_OPT = 1, /**< A CRC option protects the feedback */
66  ROHC_FEEDBACK_WITH_CRC_BASE = 2, /**< A base header CRC protects the feedback */
67 
69 
70 
71 /** The ROHC feedback options */
73 {
74  ROHC_FEEDBACK_OPT_CRC = 1, /**< The Feedback CRC option */
75  ROHC_FEEDBACK_OPT_REJECT = 2, /**< The Feedback REJECT option */
76  ROHC_FEEDBACK_OPT_SN_NOT_VALID = 3, /**< The Feedback SN-NOT-VALID option */
77 /** The Feedback MSN-NOT-VALID option (TCP profile) */
78 #define ROHC_FEEDBACK_OPT_MSN_NOT_VALID ROHC_FEEDBACK_OPT_SN_NOT_VALID
79 /** The Feedback ACKNUMBER-NOT-VALID option (ROHCv2 profiles) */
80 #define ROHC_FEEDBACK_OPT_ACKNUMBER_NOT_VALID ROHC_FEEDBACK_OPT_SN_NOT_VALID
81  ROHC_FEEDBACK_OPT_SN = 4, /**< The Feedback SN option */
82 /** The Feedback MSN option (TCP profile) */
83 #define ROHC_FEEDBACK_OPT_MSN ROHC_FEEDBACK_OPT_SN
84  ROHC_FEEDBACK_OPT_CLOCK = 5, /**< The Feedback CLOCK option */
85  ROHC_FEEDBACK_OPT_JITTER = 6, /**< The Feedback JITTER option */
86  ROHC_FEEDBACK_OPT_LOSS = 7, /**< The Feedback LOSS option */
87  ROHC_FEEDBACK_OPT_CV_REQUEST = 8, /**< The Feedback CV-REQUEST option */
88  ROHC_FEEDBACK_OPT_CONTEXT_MEMORY = 9, /**< The Feedback CONTEXT_MEMORY option */
89  ROHC_FEEDBACK_OPT_CLOCK_RESOLUTION = 10, /**< The Feedback CLOCK_RESOLUTION option */
90  ROHC_FEEDBACK_OPT_UNKNOWN_11 = 11, /**< Unknown option with value 11 */
91  ROHC_FEEDBACK_OPT_UNKNOWN_12 = 12, /**< Unknown option with value 12 */
92  ROHC_FEEDBACK_OPT_UNKNOWN_13 = 13, /**< Unknown option with value 13 */
93  ROHC_FEEDBACK_OPT_UNKNOWN_14 = 14, /**< Unknown option with value 14 */
94  ROHC_FEEDBACK_OPT_UNKNOWN_15 = 15, /**< Unknown option with value 15 */
95  ROHC_FEEDBACK_OPT_MAX /**< The max number of feedback options */
96 };
97 
98 
99 /** The ROHC FEEDBACK-2 format as defined in RFC3095 */
101 {
102 #if WORDS_BIGENDIAN == 1
103  uint8_t ack_type:2; /**< The type of acknowledgement \see rohc_feedback_ack_type */
104  uint8_t mode:2; /**< The decompression context mode */
105  uint8_t sn1:4; /**< The 4 first LSB bits of the SN being acked */
106 #else
107  uint8_t sn1:4;
108  uint8_t mode:2;
109  uint8_t ack_type:2;
110 #endif
111  uint8_t sn2; /**< The 8 next LSB bits of the SN being acked */
112 } __attribute__((packed));
113 
114 
115 /** The ROHC FEEDBACK-2 format as defined in RFC6846 */
117 {
118 #if WORDS_BIGENDIAN == 1
119  uint8_t ack_type:2; /**< The type of acknowledgement \see rohc_feedback_ack_type */
120  uint8_t sn1:6; /**< The 6 first LSB bits of the SN being acked */
121 #else
122  uint8_t sn1:6;
123  uint8_t ack_type:2;
124 #endif
125  uint8_t sn2; /**< The 8 next LSB bits of the SN being acked */
126  uint8_t crc; /**< The feedback CRC */
127 } __attribute__((packed));
128 
129 
130 /** The characteristics of one ROHC feedback option */
132 {
133  const char *const name;
134  bool unknown;
135  bool supported;
136  size_t expected_len;
137  enum {
141  } crc_req;
143 };
144 
145 
146 /**
147  * @brief Max occurrences of a feedback option in one feedback packet
148  *
149  * Even if the standard says that some options may be present multiple times,
150  * don't allow more than a raisonable occurrences. It allows the library to
151  * protect itself against abuses.
152  */
153 #define ROHC_FEEDBACK_OPT_MAX_OCCURS 100U
154 
155 
156 /** Feedback options capacities */
157 static const struct rohc_feedback_opt_charac
159 {
160  [0] = {
161  .name = "unknown option with value 0",
162  .unknown = true,
163  },
165  .name = "CRC",
166  .unknown = false,
167  .supported = true,
168  .expected_len = 2U,
170  .max_occurs = {
171  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
172  [ROHC_PROFILE_RTP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3095 §5.7.6.3 */
173  [ROHC_PROFILE_UDP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as RTP */
174  [ROHC_PROFILE_ESP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
175  [ROHC_PROFILE_IP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
177  [ROHC_PROFILE_TCP] = 0, /* RFC6846 §8.3.2 */
180  [ROHCv2_PROFILE_IP_UDP] = 0, /* RFC5225 §6.9.2 */
181  [ROHCv2_PROFILE_IP_ESP] = 0, /* RFC5225 §6.9.2 */
182  [ROHCv2_PROFILE_IP] = 0, /* RFC5225 §6.9.2 */
183  }
184  },
186  .name = "REJECT",
187  .unknown = false,
188  .supported = true,
189  .expected_len = 1U,
190  .crc_req = ROHC_FEEDBACK_OPT_CRC_REQUIRED, /* RFC3095, §5.7.6.4 */
191  .max_occurs = {
192  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
193  [ROHC_PROFILE_RTP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3095 §5.7.6.4 */
194  [ROHC_PROFILE_UDP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as RTP */
195  [ROHC_PROFILE_ESP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
196  [ROHC_PROFILE_IP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
198  [ROHC_PROFILE_TCP] = 1, /* RFC6846 §8.3.2.1 */
201  [ROHCv2_PROFILE_IP_UDP] = 1, /* RFC5225 §6.9.2.1 */
202  [ROHCv2_PROFILE_IP_ESP] = 1, /* RFC5225 §6.9.2.1 */
203  [ROHCv2_PROFILE_IP] = 1, /* RFC5225 §6.9.2.1 */
204  }
205  },
207  .name = "(M)SN-NOT-VALID/ACKNUMBER-NOT-VALID",
208  .unknown = false,
209  .supported = true,
210  .expected_len = 1U,
212  .max_occurs = {
213  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
214  [ROHC_PROFILE_RTP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3095 §5.7.6.5 */
215  [ROHC_PROFILE_UDP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as RTP */
216  [ROHC_PROFILE_ESP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
217  [ROHC_PROFILE_IP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
219  [ROHC_PROFILE_TCP] = 1, /* RFC6846 §8.3.2.2 */
222  [ROHCv2_PROFILE_IP_UDP] = 1, /* RFC5225 §6.9.2.2 */
223  [ROHCv2_PROFILE_IP_ESP] = 1, /* RFC5225 §6.9.2.2 */
224  [ROHCv2_PROFILE_IP] = 1, /* RFC5225 §6.9.2.2 */
225  }
226  },
228  .name = "(M)SN",
229  .unknown = false,
230  .supported = true,
231  .expected_len = 2U,
233  .max_occurs = {
234  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
235  [ROHC_PROFILE_RTP] = 1, /* RFC4815 §8.5: 1 option needed for 16-bit SN */
236  [ROHC_PROFILE_UDP] = 1, /* same as RTP */
237  [ROHC_PROFILE_ESP] = 3, /* RFC4815 §8.5: 3 options needed for 32-bit SN */
238  [ROHC_PROFILE_IP] = 1, /* same as UDP */
239  [ROHC_PROFILE_RTP_LLA] = 1, /* same as RTP */
240  [ROHC_PROFILE_TCP] = 1, /* RFC6846 §8.3.2.3 */
241  [ROHC_PROFILE_UDPLITE_RTP] = 1, /* same as RTP */
242  [ROHC_PROFILE_UDPLITE] = 1, /* same as UDP */
243  [ROHCv2_PROFILE_IP_UDP] = 0, /* RFC5225 §6.9.2 */
244  [ROHCv2_PROFILE_IP_ESP] = 0, /* RFC5225 §6.9.2 */
245  [ROHCv2_PROFILE_IP] = 0, /* RFC5225 §6.9.2 */
246  }
247  },
249  .name = "CLOCK",
250  .unknown = false,
251  .supported = false,
252  .expected_len = 2U,
253  .crc_req = ROHC_FEEDBACK_OPT_CRC_SUGGESTED, /* RFC3095, §5.7.6.7 */
254  .max_occurs = {
255  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
256  [ROHC_PROFILE_RTP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3095 §5.7.6.7 */
257  [ROHC_PROFILE_UDP] = 0, /* RFC3095 §5.11.6 */
258  [ROHC_PROFILE_ESP] = 0, /* same as UDP */
259  [ROHC_PROFILE_IP] = 0, /* same as UDP */
261  [ROHC_PROFILE_TCP] = 0, /* RFC6846 §8.3.2 */
263  [ROHC_PROFILE_UDPLITE] = 0, /* same as UDP */
264  [ROHCv2_PROFILE_IP_UDP] = 0, /* RFC5225 §6.9.2 */
265  [ROHCv2_PROFILE_IP_ESP] = 0, /* RFC5225 §6.9.2 */
266  [ROHCv2_PROFILE_IP] = 0, /* RFC5225 §6.9.2 */
267  }
268  },
270  .name = "JITTER",
271  .unknown = false,
272  .supported = false,
273  .expected_len = 2U,
274  .crc_req = ROHC_FEEDBACK_OPT_CRC_SUGGESTED, /* RFC3095, §5.7.6.8 */
275  .max_occurs = {
276  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
277  [ROHC_PROFILE_RTP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3095 §5.7.6.8 */
278  [ROHC_PROFILE_UDP] = 0, /* RFC3095 §5.11.6 */
279  [ROHC_PROFILE_ESP] = 0, /* same as UDP */
280  [ROHC_PROFILE_IP] = 0, /* same as UDP */
282  [ROHC_PROFILE_TCP] = 0, /* RFC6846 §8.3.2 */
284  [ROHC_PROFILE_UDPLITE] = 0, /* same as UDP */
285  [ROHCv2_PROFILE_IP_UDP] = 0, /* RFC5225 §6.9.2 */
286  [ROHCv2_PROFILE_IP_ESP] = 0, /* RFC5225 §6.9.2 */
287  [ROHCv2_PROFILE_IP] = 0, /* RFC5225 §6.9.2 */
288  }
289  },
291  .name = "LOSS",
292  .unknown = false,
293  .supported = false,
294  .expected_len = 2U,
295  .crc_req = ROHC_FEEDBACK_OPT_CRC_SUGGESTED, /* RFC3095, §5.7.6.9 */
296  .max_occurs = {
297  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
298  [ROHC_PROFILE_RTP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3095 §5.7.6.9 */
299  [ROHC_PROFILE_UDP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as RTP */
300  [ROHC_PROFILE_ESP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
301  [ROHC_PROFILE_IP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* same as UDP */
303  [ROHC_PROFILE_TCP] = 0, /* RFC6846 §8.3.2 */
306  [ROHCv2_PROFILE_IP_UDP] = 0, /* RFC5225 §6.9.2 */
307  [ROHCv2_PROFILE_IP_ESP] = 0, /* RFC5225 §6.9.2 */
308  [ROHCv2_PROFILE_IP] = 0, /* RFC5225 §6.9.2 */
309  }
310  },
312  .name = "CV-REQUEST",
313  .unknown = false,
314  .supported = false,
315  .expected_len = 1U,
317  .max_occurs = {
318  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
319  [ROHC_PROFILE_RTP] = 0, /* RFC3095 §5.7.6.2 */
320  [ROHC_PROFILE_UDP] = 0, /* same as RTP */
321  [ROHC_PROFILE_ESP] = 0, /* same as UDP */
322  [ROHC_PROFILE_IP] = 0, /* same as UDP */
323  [ROHC_PROFILE_RTP_LLA] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC4362 §4.5 */
324  [ROHC_PROFILE_TCP] = 0, /* RFC6846 §8.3.2 */
325  [ROHC_PROFILE_UDPLITE_RTP] = 0, /* same as RTP */
326  [ROHC_PROFILE_UDPLITE] = 0, /* same as UDP */
327  [ROHCv2_PROFILE_IP_UDP] = 0, /* RFC5225 §6.9.2 */
328  [ROHCv2_PROFILE_IP_ESP] = 0, /* RFC5225 §6.9.2 */
329  [ROHCv2_PROFILE_IP] = 0, /* RFC5225 §6.9.2 */
330  }
331  },
333  .name = "CONTEXT_MEMORY",
334  .unknown = false,
335  .supported = false,
336  .expected_len = 1U,
338  .max_occurs = {
339  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
340  [ROHC_PROFILE_RTP] = 0, /* RFC3095 §5.7.6.2 */
341  [ROHC_PROFILE_UDP] = 0, /* same as RTP */
342  [ROHC_PROFILE_ESP] = 0, /* same as UDP */
343  [ROHC_PROFILE_IP] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC3843 §3.7 */
344  [ROHC_PROFILE_RTP_LLA] = 0, /* same as RTP */
345  [ROHC_PROFILE_TCP] = 1, /* RFC6846 §8.3.2.4 */
347  [ROHC_PROFILE_UDPLITE] = ROHC_FEEDBACK_OPT_MAX_OCCURS, /* RFC4019 §5.7 */
348  [ROHCv2_PROFILE_IP_UDP] = 1, /* RFC5225 §6.9.2.3 */
349  [ROHCv2_PROFILE_IP_ESP] = 1, /* RFC5225 §6.9.2.3 */
350  [ROHCv2_PROFILE_IP] = 1, /* RFC5225 §6.9.2.3 */
351  }
352  },
354  .name = "CLOCK_RESOLUTION",
355  .unknown = false,
356  .supported = false,
357  .expected_len = 2U,
359  .max_occurs = {
360  [ROHC_PROFILE_UNCOMPRESSED] = 0, /* RFC3095 §5.10.4 */
361  [ROHC_PROFILE_RTP] = 0, /* RFC3095 §5.7.6.2 */
362  [ROHC_PROFILE_UDP] = 0, /* same as RTP */
363  [ROHC_PROFILE_ESP] = 0, /* same as UDP */
364  [ROHC_PROFILE_IP] = 0, /* RFC3843 §3.7 */
365  [ROHC_PROFILE_RTP_LLA] = 0, /* same as RTP */
366  [ROHC_PROFILE_TCP] = 0, /* RFC6846 §8.3.2 */
367  [ROHC_PROFILE_UDPLITE_RTP] = 0, /* RFC4019 §5.7 */
368  [ROHC_PROFILE_UDPLITE] = 0, /* RFC4019 §5.7 */
369  [ROHCv2_PROFILE_IP_UDP] = 1, /* RFC5225 §6.9.2.4 */
370  [ROHCv2_PROFILE_IP_ESP] = 1, /* RFC5225 §6.9.2.4 */
371  [ROHCv2_PROFILE_IP] = 1, /* RFC5225 §6.9.2.4 */
372  }
373  },
375  .name = "unknown option with value 11",
376  .unknown = true,
377  },
379  .name = "unknown option with value 12",
380  .unknown = true,
381  },
383  .name = "unknown option with value 13",
384  .unknown = true,
385  },
387  .name = "unknown option with value 14",
388  .unknown = true,
389  },
391  .name = "unknown option with value 15",
392  .unknown = true,
393  },
394 };
395 
396 
397 #endif
398 
uint8_t mode
Definition: feedback.h:108
Definition: feedback.h:92
const char *const name
Definition: feedback.h:133
Definition: feedback.h:91
Definition: feedback.h:85
uint8_t sn1
Definition: feedback.h:107
uint8_t ack_type
Definition: feedback.h:109
rohc_feedback_ack_type
Definition: feedback.h:50
Definition: feedback.h:116
bool supported
Definition: feedback.h:135
Definition: rohc_profiles.h:104
Definition: feedback.h:75
rohc_feedback_opt
Definition: feedback.h:72
Definition: rohc_profiles.h:83
Definition: feedback.h:88
Definition: feedback.h:87
Definition: feedback.h:52
bool unknown
Definition: feedback.h:134
Definition: feedback.h:90
ROHC common definitions and routines.
Definition: feedback.h:84
Definition: feedback.h:45
size_t expected_len
Definition: feedback.h:136
size_t max_occurs[ROHC_PROFILE_MAX]
Definition: feedback.h:142
Definition: feedback.h:64
Definition: feedback.h:86
Definition: feedback.h:131
Definition: feedback.h:66
Definition: feedback.h:81
Definition: feedback.h:76
Definition: feedback.h:100
Definition: feedback.h:55
Definition: rohc_profiles.h:129
Definition: feedback.h:65
Definition: feedback.h:94
enum rohc_feedback_opt_charac::@0 crc_req
Definition: rohc_profiles.h:119
Definition: rohc_profiles.h:108
Definition: feedback.h:54
Definition: rohc_profiles.h:95
Definition: rohc_profiles.h:112
Definition: feedback.h:74
uint8_t sn1
Definition: feedback.h:122
Definition: rohc_profiles.h:79
uint8_t ack_type
Definition: feedback.h:123
#define ROHC_FEEDBACK_OPT_MAX_OCCURS
Max occurrences of a feedback option in one feedback packet.
Definition: feedback.h:153
Definition: feedback.h:93
uint8_t crc
Definition: feedback.h:126
uint8_t sn2
Definition: feedback.h:125
Definition: feedback.h:95
Definition: feedback.h:89
Definition: feedback.h:53
uint8_t sn2
Definition: feedback.h:111
Definition: rohc_profiles.h:100
rohc_feedback_type
Definition: feedback.h:42
Definition: rohc_profiles.h:91
Definition: rohc_profiles.h:121
Definition: feedback.h:44
Definition: rohc_profiles.h:123
Definition: rohc_profiles.h:87
rohc_feedback_crc_t
Whether the feedback is protected by a CRC or not.
Definition: feedback.h:62