00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef ROHC_COMP_RFC3095_H
00030 #define ROHC_COMP_RFC3095_H
00031
00032 #include "rohc_comp_internals.h"
00033 #include "rohc_packets.h"
00034 #include "schemes/comp_list.h"
00035 #include "ip.h"
00036 #include "crc.h"
00037
00038 #include <stdlib.h>
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 struct ipv4_header_info
00051 {
00052
00053 struct c_wlsb *ip_id_window;
00054
00055
00056 struct ipv4_hdr old_ip;
00057
00058
00059 size_t df_count;
00060
00061
00062 size_t rnd_count;
00063
00064
00065 size_t nbo_count;
00066
00067
00068 size_t sid_count;
00069
00070
00071 int rnd;
00072
00073 int nbo;
00074
00075 int sid;
00076
00077
00078 int old_rnd;
00079
00080
00081 int old_nbo;
00082
00083
00084 int old_sid;
00085
00086
00087
00088 uint16_t id_delta;
00089 };
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 struct ipv6_header_info
00102 {
00103
00104 struct ipv6_hdr old_ip;
00105
00106 struct list_comp ext_comp;
00107 };
00108
00109
00110
00111
00112
00113
00114 struct ip_header_info
00115 {
00116 ip_version version;
00117
00118
00119 size_t tos_count;
00120
00121 size_t ttl_count;
00122
00123
00124 size_t protocol_count;
00125
00126
00127
00128 bool is_first_header;
00129
00130 union
00131 {
00132 struct ipv4_header_info v4;
00133 struct ipv6_header_info v6;
00134 } info;
00135 };
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 struct generic_tmp_vars
00149 {
00150
00151 unsigned short changed_fields;
00152
00153 unsigned short changed_fields2;
00154
00155 int send_static;
00156
00157 int send_dynamic;
00158
00159
00160 size_t nr_sn_bits_less_equal_than_4;
00161
00162 size_t nr_sn_bits_more_than_4;
00163
00164
00165 size_t nr_ip_id_bits;
00166
00167 size_t nr_ip_id_bits2;
00168
00169
00170 rohc_packet_t packet_type;
00171 };
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 struct rohc_comp_rfc3095_ctxt
00182 {
00183
00184 uint32_t sn;
00185
00186 struct c_wlsb *sn_window;
00187
00188
00189 size_t ip_hdr_nr;
00190
00191 struct ip_header_info outer_ip_flags;
00192
00193 struct ip_header_info inner_ip_flags;
00194
00195
00196 struct generic_tmp_vars tmp;
00197
00198
00199
00200
00201
00202 unsigned int next_header_proto;
00203
00204 unsigned int next_header_len;
00205
00206
00207 bool (*encode_uncomp_fields)(struct rohc_comp_ctxt *const context,
00208 const struct net_pkt *const uncomp_pkt)
00209 __attribute__((warn_unused_result, nonnull(1, 2)));
00210
00211
00212
00213 void (*decide_state)(struct rohc_comp_ctxt *const context);
00214
00215 rohc_packet_t (*decide_FO_packet)(const struct rohc_comp_ctxt *context);
00216
00217 rohc_packet_t (*decide_SO_packet)(const struct rohc_comp_ctxt *context);
00218
00219 rohc_ext_t (*decide_extension)(const struct rohc_comp_ctxt *context);
00220
00221
00222 void (*init_at_IR)(struct rohc_comp_ctxt *const context,
00223 const uint8_t *const next_header);
00224
00225
00226 uint32_t (*get_next_sn)(const struct rohc_comp_ctxt *const context,
00227 const struct net_pkt *const uncomp_pkt)
00228 __attribute__((warn_unused_result, nonnull(1, 2)));
00229
00230
00231
00232 size_t (*code_static_part)(const struct rohc_comp_ctxt *const context,
00233 const uint8_t *const next_header,
00234 uint8_t *const dest,
00235 const size_t counter)
00236 __attribute__((warn_unused_result, nonnull(1, 2, 3)));
00237
00238
00239
00240 size_t (*code_dynamic_part)(const struct rohc_comp_ctxt *const context,
00241 const uint8_t *const next_header,
00242 uint8_t *const dest,
00243 const size_t counter)
00244 __attribute__((warn_unused_result, nonnull(1, 2, 3)));
00245
00246
00247
00248 int (*code_ir_remainder)(const struct rohc_comp_ctxt *const context,
00249 uint8_t *const dest,
00250 const size_t dest_max_len,
00251 const size_t counter)
00252 __attribute__((warn_unused_result, nonnull(1, 2)));
00253
00254
00255
00256 size_t (*code_UO_packet_head)(const struct rohc_comp_ctxt *const context,
00257 const uint8_t *const next_header,
00258 uint8_t *const dest,
00259 const size_t counter,
00260 size_t *const first_position)
00261 __attribute__((warn_unused_result, nonnull(1,2, 3, 5)));
00262
00263
00264
00265 size_t (*code_uo_remainder)(const struct rohc_comp_ctxt *const context,
00266 const uint8_t *const next_header,
00267 uint8_t *const dest,
00268 const size_t counter)
00269 __attribute__((warn_unused_result, nonnull(1, 2, 3)));
00270
00271
00272 uint8_t (*compute_crc_static)(const uint8_t *const ip,
00273 const uint8_t *const ip2,
00274 const uint8_t *const next_header,
00275 const rohc_crc_type_t crc_type,
00276 const uint8_t init_val,
00277 const uint8_t *const crc_table)
00278 __attribute__((nonnull(1, 3, 6), warn_unused_result));
00279
00280
00281 uint8_t (*compute_crc_dynamic)(const uint8_t *const ip,
00282 const uint8_t *const ip2,
00283 const uint8_t *const next_header,
00284 const rohc_crc_type_t crc_type,
00285 const uint8_t init_val,
00286 const uint8_t *const crc_table)
00287 __attribute__((nonnull(1, 3, 6), warn_unused_result));
00288
00289
00290 void *specific;
00291 };
00292
00293
00294
00295
00296
00297
00298 bool rohc_comp_rfc3095_create(struct rohc_comp_ctxt *const context,
00299 const rohc_lsb_shift_t sn_shift,
00300 const struct net_pkt *const packet)
00301 __attribute__((warn_unused_result, nonnull(1, 3)));
00302
00303 void rohc_comp_rfc3095_destroy(struct rohc_comp_ctxt *const context)
00304 __attribute__((nonnull(1)));
00305
00306 bool rohc_comp_rfc3095_check_profile(const struct rohc_comp *const comp,
00307 const struct net_pkt *const packet)
00308 __attribute__((warn_unused_result, nonnull(1, 2)));
00309
00310 rohc_ext_t decide_extension(const struct rohc_comp_ctxt *const context)
00311 __attribute__((warn_unused_result, nonnull(1)));
00312
00313 int rohc_comp_rfc3095_encode(struct rohc_comp_ctxt *const context,
00314 const struct net_pkt *const uncomp_pkt,
00315 uint8_t *const rohc_pkt,
00316 const size_t rohc_pkt_max_len,
00317 rohc_packet_t *const packet_type,
00318 size_t *const payload_offset)
00319 __attribute__((warn_unused_result, nonnull(1, 2, 3, 5, 6)));
00320
00321 bool rohc_comp_rfc3095_feedback(struct rohc_comp_ctxt *const context,
00322 const enum rohc_feedback_type feedback_type,
00323 const uint8_t *const packet,
00324 const size_t packet_len,
00325 const uint8_t *const feedback_data,
00326 const size_t feedback_data_len)
00327 __attribute__((warn_unused_result, nonnull(1, 3, 5)));
00328
00329 void rohc_comp_rfc3095_decide_state(struct rohc_comp_ctxt *const context)
00330 __attribute__((nonnull(1)));
00331
00332 void rohc_get_ipid_bits(const struct rohc_comp_ctxt *const context,
00333 size_t *const nr_innermost_bits,
00334 size_t *const nr_outermost_bits)
00335 __attribute__((nonnull(1, 2, 3)));
00336
00337 bool rohc_comp_rfc3095_is_sn_possible(const struct rohc_comp_rfc3095_ctxt *const rfc3095_ctxt,
00338 const size_t bits_nr,
00339 const size_t add_bits_nr)
00340 __attribute__((warn_unused_result, nonnull(1), pure));
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 static inline bool no_outer_ip_id_bits_required(const struct rohc_comp_rfc3095_ctxt *const ctxt)
00351 {
00352 return (ctxt->outer_ip_flags.version != IPV4 ||
00353 ctxt->outer_ip_flags.info.v4.rnd == 1 ||
00354 ctxt->tmp.nr_ip_id_bits == 0);
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 static inline bool is_outer_ip_id_bits_possible(const struct rohc_comp_rfc3095_ctxt *const ctxt,
00367 const size_t max_ip_id_bits_nr)
00368 {
00369 return (ctxt->outer_ip_flags.version == IPV4 &&
00370 ctxt->outer_ip_flags.info.v4.rnd != 1 &&
00371 ctxt->tmp.nr_ip_id_bits <= max_ip_id_bits_nr);
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 static inline bool no_inner_ip_id_bits_required(const struct rohc_comp_rfc3095_ctxt *const ctxt)
00383 {
00384 return (ctxt->inner_ip_flags.version != IPV4 ||
00385 ctxt->inner_ip_flags.info.v4.rnd == 1 ||
00386 ctxt->tmp.nr_ip_id_bits2 == 0);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 static inline bool is_inner_ip_id_bits_possible(const struct rohc_comp_rfc3095_ctxt *const ctxt,
00399 const size_t max_ip_id_bits_nr)
00400 {
00401 return (ctxt->inner_ip_flags.version == IPV4 &&
00402 ctxt->inner_ip_flags.info.v4.rnd != 1 &&
00403 ctxt->tmp.nr_ip_id_bits2 <= max_ip_id_bits_nr);
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 static inline size_t get_nr_ipv4_non_rnd(const struct rohc_comp_rfc3095_ctxt *const ctxt)
00414 {
00415 size_t nr_ipv4_non_rnd = 0;
00416
00417
00418 if(ctxt->outer_ip_flags.version == IPV4 && ctxt->outer_ip_flags.info.v4.rnd != 1)
00419 {
00420 nr_ipv4_non_rnd++;
00421 }
00422
00423
00424 if(ctxt->ip_hdr_nr >= 1 &&
00425 ctxt->inner_ip_flags.version == IPV4 &&
00426 ctxt->inner_ip_flags.info.v4.rnd != 1)
00427 {
00428 nr_ipv4_non_rnd++;
00429 }
00430
00431 return nr_ipv4_non_rnd;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 static inline size_t get_nr_ipv4_non_rnd_with_bits(const struct rohc_comp_rfc3095_ctxt *const ctxt)
00444 {
00445 size_t nr_ipv4_non_rnd_with_bits = 0;
00446
00447
00448 if(ctxt->outer_ip_flags.version == IPV4 &&
00449 ctxt->outer_ip_flags.info.v4.rnd != 1 &&
00450 ctxt->tmp.nr_ip_id_bits > 0)
00451 {
00452 nr_ipv4_non_rnd_with_bits++;
00453 }
00454
00455
00456 if(ctxt->ip_hdr_nr >= 1 &&
00457 ctxt->inner_ip_flags.version == IPV4 &&
00458 ctxt->inner_ip_flags.info.v4.rnd != 1 &&
00459 ctxt->tmp.nr_ip_id_bits2 > 0)
00460 {
00461 nr_ipv4_non_rnd_with_bits++;
00462 }
00463
00464 return nr_ipv4_non_rnd_with_bits;
00465 }
00466
00467
00468 #endif
00469