ndn-lite
fragmentation-support.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 Zhiyi Zhang, Tianyuan Yu
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v3.0. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
9 #ifndef NDN_ENCODING_FRAGMENTATION_SUPPORT_H
10 #define NDN_ENCODING_FRAGMENTATION_SUPPORT_H
11 
12 #include "../ndn-constants.h"
13 #include "../ndn-error-code.h"
14 #include <inttypes.h>
15 #include <string.h>
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
40 typedef struct ndn_fragmenter {
44  const uint8_t* original;
48  uint32_t original_size;
57  uint16_t frag_identifier;
61  uint32_t total_frag_num;
65  uint32_t offset;
69  uint32_t counter;
71 
72 
83 static inline void
84 ndn_fragmenter_init(ndn_fragmenter_t* fragmenter, const uint8_t* original, uint32_t original_size,
85  uint32_t fragment_max_size, uint16_t frag_identifier)
86 {
87  fragmenter->original = original;
88  fragmenter->original_size = original_size;
89  fragmenter->fragment_max_size = fragment_max_size;
90  fragmenter->frag_identifier = frag_identifier;
91 
92  fragmenter->total_frag_num = fragmenter->original_size / (fragment_max_size - 3);
93  int rem = fragmenter->original_size % (fragment_max_size - 3);
94  if (rem != 0)
95  fragmenter->total_frag_num += 1;
96  fragmenter->offset = 0;
97  fragmenter->counter = 0;
98 }
99 
107 static inline int
108 ndn_fragmenter_fragment(ndn_fragmenter_t* fragmenter, uint8_t* fragmented)
109 {
110  if (fragmenter->counter == fragmenter->total_frag_num)
111  return NDN_FRAG_NO_MORE_FRAGS;
112 
113  memset(fragmented, 0, fragmenter->fragment_max_size);
114 
115  uint8_t is_last = (fragmenter->counter == fragmenter->total_frag_num - 1)? 1 : 0;
116  uint8_t seq = fragmenter->counter % (NDN_FRAG_MAX_SEQ_NUM + 1);
117 
118  // header
119  fragmented[0] = seq;
120  if (is_last)
121  fragmented[0] |= NDN_FRAG_MF_MASK;
122  fragmented[0] |= NDN_FRAG_HB_MASK;
123  fragmented[1] = (fragmenter->frag_identifier >> 8) & 0xFF;
124  fragmented[2] = fragmenter->frag_identifier & 0xFF;
125 
126  // payload
127  int size = (is_last)?
128  fragmenter->original_size - fragmenter->offset: fragmenter->fragment_max_size - 3;
129  memcpy(&fragmented[3], &fragmenter->original[fragmenter->offset], size);
130 
131  // update state
132  fragmenter->counter++;
133  fragmenter->offset += size;
134  return 0;
135 }
136 
140 typedef struct ndn_frag_assembler {
144  uint8_t* original;
152  uint16_t frag_identifier;
156  uint32_t offset;
160  uint8_t seq;
164  uint8_t is_finished;
166 
173 static inline void
174 ndn_frag_assembler_init(ndn_frag_assembler_t* assembler, uint8_t* original, uint32_t original_max_size)
175 {
176  assembler->original = original;
177  assembler->original_max_size = original_max_size;
178  assembler->frag_identifier = 0;
179  assembler->offset = 0;
180  assembler->seq = 0;
181  assembler->is_finished = 0;
182 }
183 
191 static inline int
192 ndn_frag_assembler_assemble_frag(ndn_frag_assembler_t* assembler, uint8_t* frag, uint32_t fra_size)
193 {
194  int first_time = (assembler->offset == 0)? 1 : 0;
195  // get seq
196  uint8_t seq = frag[0] & NDN_FRAG_SEQ_MASK;
197  if (seq != assembler->seq)
198  return NDN_FRAG_OUT_OF_ORDER;
199  assembler->seq += 1;
200  if (assembler->seq == NDN_FRAG_MAX_SEQ_NUM + 1)
201  assembler->seq = 0;
202 
203  // get identifier
204  uint16_t id = ((uint16_t)frag[1] << 8) + (uint16_t)frag[2];
205  if (assembler->frag_identifier != id && first_time == 0)
207  if (first_time)
208  assembler->frag_identifier = id;
209 
210  if (assembler->original_max_size < assembler->offset + fra_size - 3)
211  return NDN_OVERSIZE;
212 
213  memcpy(&assembler->original[assembler->offset], &frag[3], fra_size - 3);
214  assembler->offset += fra_size - 3;
215 
216  // get MF bit
217  uint8_t mf = frag[0] & NDN_FRAG_MF_MASK;
218  if (mf == NDN_FRAG_MF_MASK) {
219  // no more frags
220  assembler->is_finished = 1;
221  }
222  return 0;
223 }
224 
225 #ifdef __cplusplus
226 }
227 #endif
228 
229 #endif // NDN_ENCODING_FRAGMENTATION_SUPPORT_H
uint16_t frag_identifier
The identifier of the fragments.
Definition: fragmentation-support.h:152
The structure to keep the state when assembling fragments.
Definition: fragmentation-support.h:140
uint32_t offset
The offset before which the original packet has been assembled.
Definition: fragmentation-support.h:156
struct ndn_frag_assembler ndn_frag_assembler_t
The structure to keep the state when assembling fragments.
uint32_t counter
The counter indicating how many frags have been generated.
Definition: fragmentation-support.h:69
#define NDN_FRAG_OUT_OF_ORDER
Definition: ndn-error-code.h:107
uint8_t * original
The buffer to keep the original packet.
Definition: fragmentation-support.h:144
struct ndn_fragmenter ndn_fragmenter_t
NDN-Lite reuses the ndn-riot fragmentation header (3 bytes header)
#define NDN_FRAG_NO_MORE_FRAGS
Definition: ndn-error-code.h:106
uint32_t total_frag_num
The total number of frags to be generated.
Definition: fragmentation-support.h:61
uint16_t frag_identifier
The identifier of the fragments.
Definition: fragmentation-support.h:57
static int ndn_fragmenter_fragment(ndn_fragmenter_t *fragmenter, uint8_t *fragmented)
Generate one fragmented packet.
Definition: fragmentation-support.h:108
NDN-Lite reuses the ndn-riot fragmentation header (3 bytes header)
Definition: fragmentation-support.h:40
uint8_t seq
Next sequence number of the fragment to be received.
Definition: fragmentation-support.h:160
static void ndn_frag_assembler_init(ndn_frag_assembler_t *assembler, uint8_t *original, uint32_t original_max_size)
Init an assembler.
Definition: fragmentation-support.h:174
uint32_t offset
The offset before which the original packet has been fragmented.
Definition: fragmentation-support.h:65
#define NDN_FRAG_MF_MASK
Definition: ndn-constants.h:54
#define NDN_FRAG_HB_MASK
Definition: ndn-constants.h:53
uint32_t original_size
The size of the original packet.
Definition: fragmentation-support.h:48
#define NDN_FRAG_SEQ_MASK
Definition: ndn-constants.h:55
uint8_t is_finished
A flag used to check whether the assembling is finished.
Definition: fragmentation-support.h:164
const uint8_t * original
The buffer to keep the original packet.
Definition: fragmentation-support.h:44
#define NDN_OVERSIZE
The object given is larger than expected.
Definition: ndn-error-code.h:33
static int ndn_frag_assembler_assemble_frag(ndn_frag_assembler_t *assembler, uint8_t *frag, uint32_t fra_size)
Assemble a fragment into the assembler.
Definition: fragmentation-support.h:192
#define NDN_FRAG_WRONG_IDENTIFIER
Definition: ndn-error-code.h:109
uint32_t original_max_size
The size of the buffer to keep the original packet.s.
Definition: fragmentation-support.h:148
#define NDN_FRAG_MAX_SEQ_NUM
Definition: ndn-constants.h:56
uint32_t fragment_max_size
The max size of each fragment.
Definition: fragmentation-support.h:53
static void ndn_fragmenter_init(ndn_fragmenter_t *fragmenter, const uint8_t *original, uint32_t original_size, uint32_t fragment_max_size, uint16_t frag_identifier)
Init a fragmenter.
Definition: fragmentation-support.h:84