-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathfragmenter.h
executable file
·200 lines (174 loc) · 6.13 KB
/
fragmenter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* (c) 2018 - idlab - UGent - imec
*
* Bart Moons
*
* This file is part of the SCHC stack implementation
*
*/
#ifndef __SCHC_FRAGMENTER_H__
#define __SCHC_FRAGMENTER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "schc.h"
/**
* Return code: Indicator. Generic indication that a fragment was received
*/
#define SCHC_FRAG_INPUT 2
/**
* Return code: Indicator. Generic indication that an acknowledgment was received
*/
#define SCHC_ACK_INPUT 1
/**
* Return code: No error. Indicates successful completion of an SCHC
* operation.
*/
#define SCHC_SUCCESS 0
/**
* Return code: End of fragmentation cycle. Indicates successful completion of an SCHC
* fragmentation cycle.
*/
#define SCHC_END 3
/**
* Return code: Error. Generic indication that an SCHC operation went wrong
*/
#define SCHC_FAILURE -1
/**
* Return code: Error. Generic indication that no fragmentation was needed
*/
#define SCHC_NO_FRAGMENTATION -2
/**
* Return code: Error. Generic indication that connection is in initialization state
*/
#define SCHC_INIT -3
typedef enum {
INIT_TX = 0, SEND = 1, RESEND = 2, WAIT_BITMAP = 3, END_TX = 4, ERR = 5
} tx_state;
typedef enum {
RECV_WINDOW = 0, WAIT_NEXT_WINDOW = 1, WAIT_MISSING_FRAG = 2, WAIT_END = 3, END_RX = 4, ABORT = 5
} rx_state;
typedef struct schc_mbuf_t {
/* start of memory block */
uint8_t* ptr;
/* length of the fragment */
uint16_t len;
/* the fragment to which the mbuf belongs to */
uint8_t frag_cnt;
/* the bit offset when formatted */
uint8_t offset;
/* pointer to the next fragment*/
struct schc_mbuf_t *next;
} schc_mbuf_t;
typedef struct schc_fragmentation_ack_t {
/* the rule id included in the ack */
uint8_t rule_id[RULE_SIZE_BYTES];
/* the encoded bitmap included in the ack */
uint8_t bitmap[BITMAP_SIZE_BYTES];
/* the window included in the ack */
uint8_t window[1];
/* the DTAG received in the ack */
uint8_t dtag[1];
/* the MIC bit received in the ack */
uint8_t mic;
/* the fcn value this ack belongs to */
uint8_t fcn;
} schc_fragmentation_ack_t;
typedef struct schc_fragmentation_t schc_fragmentation_t;
struct schc_fragmentation_t {
#if DYNAMIC_MEMORY
schc_fragmentation_t *next;
/* this callback is called upon freeing the connections that were allocated */
void (*free_conn_cb)(struct schc_fragmentation_t *conn);
#endif
/* the device id of the connection */
uint32_t device_id;
/* a pointer to the start of the unfragmented, compressed packet in a bit array */
schc_bitarray_t* bit_arr;
/* the start of the packet + the total length */
uint8_t* tail_ptr;
/* the duty cycle in ms */
uint32_t dc;
/* the reassembly check sequence over the full, compressed packet */
uint8_t rcs[MAX_RCS_SIZE_BYTES];
/* the RCS algorithm */
uint32_t (*reassembly_check_sequence)(struct schc_fragmentation_t *conn);
/* the fragment counter in the current window
* ToDo: we only support fixed FCN length
* */
uint8_t fcn;
/* the current window */
uint8_t window;
/* the current DTAG */
int16_t dtag;
/* fragment index counter */
uint8_t frag_cnt;
/* the bitmap of the fragments sent */
uint8_t bitmap[MAX_WINDOWS][BITMAP_SIZE_BYTES];
/* the number of transmission attempts */
uint8_t attempts;
/* the Ack-On-Error sync counter */
uint8_t sync;
/* the current state for the sending device */
tx_state TX_STATE;
/* the current state for the receiving device */
rx_state RX_STATE;
/* the function to call when the fragmenter has something to send */
uint8_t (*send)(uint8_t* data, uint16_t length, uint32_t device_id);
/* the timer task */
void (*post_timer_task)(struct schc_fragmentation_t *conn,
void (*timer_task)(void* arg), uint32_t time_ms, void *arg);
/* this function is called when the last rx timer expires */
void (*end_rx)(struct schc_fragmentation_t *conn);
/* this function is called once the device reaches the END_TX state */
void (*end_tx)(struct schc_fragmentation_t *conn);
/* this callback may be used to remove a timer entry */
void (*remove_timer_entry)(struct schc_fragmentation_t *conn);
/* callback function when the duty cycle timer expires */
void (*duty_cycle_cb)(struct schc_fragmentation_t *conn);
/* timer context for the application */
void *timer_ctx;
/* indicates whether a timer has expired */
uint8_t timer_flag;
/* indicates if a fragment is received or this is a callback */
uint8_t input;
/* the last received ack */
schc_fragmentation_ack_t ack;
/* the start of the mbuf chain */
schc_mbuf_t *head;
/* the rule in use */
struct schc_fragmentation_rule_t* fragmentation_rule;
/* the rule id */
uint8_t rule_id[4];
/* the tile size in bytes */
uint16_t tile_size;
/* keep track of the tiles per window */
uint16_t window_tiles[MAX_WINDOW_SIZE];
/* the window an all-1 belongs to */
uint8_t all1_window;
/* the total number of transmissions */
uint8_t total_transmissions;
/* the device the connection belongs to */
struct schc_device* device;
};
schc_fragmentation_t* schc_get_tx_connection(struct schc_device* device, int16_t dtag);
schc_fragmentation_t* schc_set_tx_connection(struct schc_device* device, int16_t dtag);
schc_fragmentation_t* schc_alloc_tx_connection(struct schc_device* device);
void schc_free_connection(schc_fragmentation_t *conn);
void schc_reset(schc_fragmentation_t* conn);
int8_t schc_fragment(schc_fragmentation_t *tx_conn);
int8_t schc_reassemble(schc_fragmentation_t* rx_conn);
int8_t schc_fragmenter_init(struct schc_fragmentation_t* cb_conn);
schc_fragmentation_t* schc_input(uint8_t* data, uint16_t len, struct schc_device* device);
void schc_ack_input(uint8_t* data, schc_fragmentation_t* tx_conn);
schc_fragmentation_t* schc_fragment_input(uint8_t* data, uint16_t len, struct schc_device* device);
int8_t schc_set_tile_size(schc_fragmentation_t* conn, uint16_t tile_size);
int8_t schc_sender_abort(schc_fragmentation_t* conn);
int8_t schc_receiver_abort(schc_fragmentation_t* conn);
schc_fragmentation_t* schc_get_connection(uint32_t device_id);
struct schc_fragmentation_rule_t* get_fragmentation_rule_by_reliability_mode(reliability_mode mode, uint32_t device_id);
uint16_t get_mbuf_len(schc_fragmentation_t *conn);
void mbuf_copy(schc_fragmentation_t *conn, uint8_t* ptr);
#ifdef __cplusplus
}
#endif
#endif