rules.h
1 /*
2  * Copyright (C) 2018 imec IDLab
3  * Copyright (C) 2022 Freie Universität Berlin
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
24 #ifndef RULES_RULES_H
25 #define RULES_RULES_H
26 
27 #include "kernel_defines.h"
28 
29 #include "schc.h"
30 #ifdef USE_COAP
31 #include "net/coap.h"
32 #endif
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #if USE_IP6
39 static const struct schc_ipv6_rule_t ipv6_rule1 = {
40  .up = 10, .down = 10, .length = 11,
41  {
42  /* field, ML, len, pos, dir, val, MO, CDA */
43  { IP6_V, 0, 4, 1, BI, {6}, &mo_equal, NOTSENT },
44  { IP6_TC, 0, 8, 1, BI, {0}, &mo_ignore, NOTSENT },
45  { IP6_FL, 0, 20, 1, BI, {0, 0, 0}, &mo_ignore, NOTSENT },
46  { IP6_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
47  { IP6_NH, 0, 8, 1, BI, {17}, &mo_equal, NOTSENT },
48  { IP6_HL, 0, 8, 1, UP, {64}, &mo_equal, NOTSENT },
49  { IP6_HL, 0, 8, 1, DOWN, {0}, &mo_ignore, VALUESENT },
50  { IP6_DEVPRE, 0, 64, 1, BI, {
51  0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00
52  }, &mo_equal, NOTSENT },
53  { IP6_DEVIID, 0, 64, 1, BI, {
54  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
55  }, &mo_equal, NOTSENT },
56  { IP6_APPPRE, 4, 64, 1, BI, {
57  /* you can store as many IPs as (MAX_FIELD_LENGTH / 8) */
58  0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
59  0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
60  0x20, 0x01, 0x0d, 0xb8, 0x00, 0x03, 0x00, 0x00,
61  0x20, 0x01, 0x0d, 0xb8, 0x00, 0x04, 0x00, 0x00
62  }, &mo_matchmap, MAPPINGSENT },
63  { IP6_APPIID, 0, 64, 1, BI, {
64  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
65  }, &mo_equal, NOTSENT },
66  }
67 };
68 
69 /* link local test rule */
70 static const struct schc_ipv6_rule_t ipv6_rule2 = {
71  .up = 10, .down = 10, .length = 10,
72  {
73  /* field, ML, len, pos, dir, val, MO, CDA */
74  { IP6_V, 0, 4, 1, BI, {6}, &mo_equal, NOTSENT },
75  { IP6_TC, 0, 8, 1, BI, {0}, &mo_ignore, NOTSENT },
76  { IP6_FL, 0, 20, 1, BI, {0, 0, 0}, &mo_ignore, NOTSENT },
77  { IP6_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
78  { IP6_NH, 2, 8, 1, BI, {17, 58}, &mo_matchmap, MAPPINGSENT },
79  { IP6_HL, 2, 8, 1, BI, {64, 255}, &mo_matchmap, NOTSENT },
80  { IP6_DEVPRE, 0, 64, 1, BI, {
81  0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
82  }, &mo_equal, NOTSENT },
83  { IP6_DEVIID, 62, 64, 1, BI, {
84  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
85  }, &mo_MSB, LSB },
86  { IP6_APPPRE, 0, 64, 1, BI, {
87  0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
88  }, &mo_equal, NOTSENT },
89  { IP6_APPIID, 62, 64, 1, BI, {
90  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
91  }, &mo_MSB, LSB },
92  }
93 };
94 #endif
95 
96 #if USE_UDP
97 static const struct schc_udp_rule_t udp_rule1 = {
98  .up = 4, .down = 4, .length = 4,
99  {
100  /* field, ML, len, pos, dir, val, MO, CDA */
101  /* set field length to 16 to indicate 16 bit values
102  * MO param length to 2 to indicate 2 indices */
103  { UDP_DEV, 2, 16, 1, BI, {
104  0x33, 0x16, /* 5683 or */
105  0x33, 0x17 /* 5684 */
106  }, &mo_matchmap, MAPPINGSENT },
107  { UDP_APP, 2, 16, 1, BI, {
108  0x33, 0x16, /* 5683 or */
109  0x33, 0x17 /* 5684 */
110  }, &mo_matchmap, MAPPINGSENT },
111  { UDP_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
112  { UDP_CHK, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPCHK },
113  }
114 };
115 
116 static const struct schc_udp_rule_t udp_rule2 = {
117  .up = 4, .down = 4, .length = 4,
118  {
119  /* field, ML, len, pos, dir, val, MO, CDA */
120  { UDP_DEV, 12, 16, 1, BI, {0x1F, 0x40}, &mo_MSB, LSB },
121  { UDP_APP, 12, 16, 1, BI, {0x1F, 0x40}, &mo_MSB, LSB },
122  { UDP_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
123  { UDP_CHK, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPCHK },
124  }
125 };
126 
127 static const struct schc_udp_rule_t udp_rule3 = {
128  .up = 4, .down = 4, .length = 4,
129  {
130  /* field, ML, len, pos, dir, val, MO, CDA */
131  { UDP_DEV, 0, 16, 1, BI, {0x13, 0x89}, &mo_equal, NOTSENT },
132  { UDP_APP, 0, 16, 1, BI, {0x13, 0x88}, &mo_equal, NOTSENT },
133  { UDP_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
134  { UDP_CHK, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPCHK },
135  }
136 };
137 #endif
138 
139 #if USE_COAP
140 /* It is important to use strings, identical to the ones defined in coap.h for the options. */
141 
142 /* GET /usage */
143 static const struct schc_coap_rule_t coap_rule1 = {
144  .up = 9, .down = 7, .length = 9,
145  {
146  /* field, ML, len, pos, dir, val, MO, CDA */
147  { COAP_V, 0, 2, 1, BI, {COAP_V1}, &mo_equal, NOTSENT },
148  /* the MO_param_length (ML) is used to indicate the true length of the list */
149  { COAP_T, 4, 2, 1, BI, {
150  COAP_TYPE_CON, COAP_TYPE_NON, COAP_TYPE_ACK, COAP_TYPE_RST
151  }, &mo_matchmap, MAPPINGSENT },
152  { COAP_TKL, 0, 4, 1, BI, {4}, &mo_equal, NOTSENT },
153  { COAP_C, 0, 8, 1, BI, {COAP_METHOD_PUT}, &mo_equal, NOTSENT },
154  { COAP_MID, 0, 16, 1, BI, {0x23, 0xBB}, &mo_equal, NOTSENT },
155  { COAP_TKN, 24, 32, 1, BI, {
156  0x21, 0xFA, 0x01, 0x00
157  }, &mo_MSB, LSB },
158  { COAP_URIPATH, 0, 40, 1, BI, "usage", &mo_equal, NOTSENT },
159  { COAP_NORESP, 0, 8, 1, BI, {0x1A}, &mo_equal, NOTSENT },
160  { COAP_PAYLOAD, 0, 8, 1, BI, {0xFF}, &mo_equal, NOTSENT }
161  }
162 };
163 
164 /* POST temperature value */
165 static const struct schc_coap_rule_t coap_rule2 = {
166  .up = 7, .down = 7, .length = 10,
167  {
168  /* field, ML, len, pos, dir, val, MO, CDA */
169  { COAP_V, 0, 2, 1, BI, {COAP_V1}, &mo_equal, NOTSENT },
170  { COAP_T, 0, 2, 1, BI, {0}, &mo_ignore, VALUESENT },
171  { COAP_TKL, 0, 4, 1, BI, {4}, &mo_equal, NOTSENT },
172  { COAP_C, 0, 8, 1, UP, {COAP_CODE_CONTENT}, &mo_equal, NOTSENT },
173  { COAP_C, 0, 8, 1, DOWN, {COAP_METHOD_GET}, &mo_equal, NOTSENT },
174  /* match the first 12 bits */
175  { COAP_MID, 12, 16, 1, UP, {0x23, 0xBB}, &mo_MSB, LSB },
176  { COAP_MID, 0, 16, 1, DOWN, {0, 0}, &mo_ignore, VALUESENT },
177  { COAP_TKN, 0, 32, 1, BI, {0, 0, 0, 0}, &mo_ignore, VALUESENT },
178  { COAP_URIPATH, 0, 32, 1, DOWN, "temp", &mo_equal, NOTSENT },
179  /* respond with CONTENT */
180  { COAP_PAYLOAD, 0, 8, 1, UP, {0xFF}, &mo_equal, NOTSENT }
181  }
182 };
183 
184 static const struct schc_coap_rule_t coap_rule3 = {
185  .up = 1, .down = 1, .length = 1,
186  {
187  /* field, ML, len, pos, dir, val, MO, CDA */
188  { COAP_V, 0, 2, 1, BI, {COAP_V1}, &mo_equal, NOTSENT },
189  }
190 };
191 
192 static const struct schc_coap_rule_t coap_rule4 = {
193  .up = 12, .down = 12, .length = 12,
194  {
195  /* field, ML, len, pos, dir, val, MO, CDA */
196  { COAP_V, 0, 2, 1, BI, {COAP_V1}, &mo_equal, NOTSENT },
197  { COAP_T, 0, 2, 1, BI, {COAP_TYPE_CON}, &mo_equal, NOTSENT },
198  { COAP_TKL, 0, 4, 1, BI, {8}, &mo_equal, NOTSENT },
199  { COAP_C, 0, 8, 1, BI, {COAP_METHOD_POST}, &mo_equal, NOTSENT },
200  { COAP_MID, 0, 16, 1, BI, {0x23, 0xBB}, &mo_ignore, VALUESENT },
201  /* match the 24 first bits, send the last 8 */
202  { COAP_TKN, 24, 32, 1, BI, {
203  0x21, 0xFA, 0x01, 0x00
204  }, &mo_MSB, LSB },
205  { COAP_URIPATH, 0, 16, 1, BI, "rd", &mo_equal, NOTSENT },
206  { COAP_CONTENTF, 0, 8, 1, BI, {0x28}, &mo_equal, NOTSENT },
207  { COAP_URIQUERY, 0, 72, 1, BI, "lwm2m=1.0", &mo_equal, NOTSENT },
208  { COAP_URIQUERY, 0, 88, 1, BI, "ep=magician", &mo_equal, NOTSENT },
209  { COAP_URIQUERY, 0, 48, 1, BI, "lt=121", &mo_equal, NOTSENT },
210  /* respond with CONTENT */
211  { COAP_PAYLOAD, 0, 8, 1, BI, {0xff}, &mo_equal, NOTSENT }
212  }
213 };
214 #endif
215 
216 static const struct schc_compression_rule_t comp_rule_1 = {
217  .rule_id = 0x01,
218  .rule_id_size_bits = 8U,
219 #if USE_IP6
220  &ipv6_rule1,
221 #endif
222 #if USE_UDP
223  &udp_rule1,
224 #endif
225 #if USE_COAP
226  &coap_rule1,
227 #endif
228 };
229 
230 static const struct schc_compression_rule_t comp_rule_2 = {
231  .rule_id = 0x02,
232  .rule_id_size_bits = 8U,
233 #if USE_IP6
234  &ipv6_rule1,
235 #endif
236 #if USE_UDP
237  &udp_rule3,
238 #endif
239 #if USE_COAP
240  &coap_rule2,
241 #endif
242 };
243 
244 static const struct schc_compression_rule_t comp_rule_3 = {
245  .rule_id = 0x03,
246  .rule_id_size_bits = 8U,
247 #if USE_IP6
248  &ipv6_rule2,
249 #endif
250 #if USE_UDP
251  &udp_rule2,
252 #endif
253 #if USE_COAP
254  &coap_rule3,
255 #endif
256 };
257 
258 static const struct schc_compression_rule_t comp_rule_4 = {
259  .rule_id = 0x04,
260  .rule_id_size_bits = 8U,
261 #if USE_IP6
262  &ipv6_rule2,
263 #endif
264 #if USE_UDP
265  &udp_rule2,
266 #endif
267 #if USE_COAP
268  &coap_rule4,
269 #endif
270 };
271 
272 static const struct schc_fragmentation_rule_t frag_rule_21 = {
273  .rule_id = 21,
274  .rule_id_size_bits = 8,
275  .mode = NO_ACK,
276  .dir = BI,
277  .FCN_SIZE = 1, /* FCN size */
278  .MAX_WND_FCN = 0, /* Maximum fragments per window */
279  .WINDOW_SIZE = 0, /* Window size */
280  .DTAG_SIZE = 0, /* DTAG size */
281 };
282 
283 static const struct schc_fragmentation_rule_t frag_rule_22 = {
284  .rule_id = 22,
285  .rule_id_size_bits = 8,
286  .mode = ACK_ON_ERROR,
287  .dir = BI,
288  .FCN_SIZE = 3, /* FCN size */
289  .MAX_WND_FCN = 6, /* Maximum fragments per window */
290  .WINDOW_SIZE = 1, /* Window size */
291  .DTAG_SIZE = 0, /* DTAG size */
292 };
293 
294 static const struct schc_fragmentation_rule_t frag_rule_23 = {
295  .rule_id = 23,
296  .rule_id_size_bits = 8,
297  .mode = ACK_ALWAYS,
298  .dir = BI,
299  .FCN_SIZE = 3, /* FCN size */
300  .MAX_WND_FCN = 6, /* Maximum fragments per window */
301  .WINDOW_SIZE = 1, /* Window size */
302  .DTAG_SIZE = 0, /* DTAG size */
303 };
304 
305 /* save compression rules in flash */
306 static const struct schc_compression_rule_t* node1_compression_rules[] = {
307  &comp_rule_1, &comp_rule_2, &comp_rule_3, &comp_rule_4
308 };
309 
310 /* save fragmentation rules in flash */
311 static const struct schc_fragmentation_rule_t* node1_fragmentation_rules[] = {
312  &frag_rule_21, &frag_rule_22, &frag_rule_23,
313 };
314 
315 /* rules for a particular device */
316 static const struct schc_device node1 = {
317  .device_id = 1,
318  .uncomp_rule_id = 0,
319  .uncomp_rule_id_size_bits = 8,
320  .compression_rule_count = ARRAY_SIZE(node1_compression_rules),
321  .compression_context = &node1_compression_rules,
322  .fragmentation_rule_count = ARRAY_SIZE(node1_fragmentation_rules),
323  .fragmentation_context = &node1_fragmentation_rules
324 };
325 static const struct schc_device node2 = {
326  .device_id = 2,
327  .uncomp_rule_id = 0,
328  .uncomp_rule_id_size_bits = 8,
329  .compression_rule_count = ARRAY_SIZE(node1_compression_rules),
330  .compression_context = &node1_compression_rules,
331  .fragmentation_rule_count = ARRAY_SIZE(node1_fragmentation_rules),
332  .fragmentation_context = &node1_fragmentation_rules
333 };
334 
335 /* server keeps track of multiple devices: add devices to device list */
336 static const struct schc_device* devices[] = { &node1, &node2 };
337 
338 #define DEVICE_COUNT ((int)ARRAY_SIZE(devices))
339 
340 #ifdef __cplusplus
341 }
342 #endif
343 
344 #endif /* RULES_RULES_H */
#define ARRAY_SIZE(a)
Calculate the number of elements in a static array.
Definition: container.h:83
#define COAP_V1
Identifier for CoAP version 1 (RFC 7252)
Definition: coap.h:39
@ COAP_METHOD_GET
GET request (no paylod)
Definition: coap.h:172
@ COAP_METHOD_PUT
PUT request (update resource with payload)
Definition: coap.h:174
@ COAP_METHOD_POST
POST request (resource processes payload)
Definition: coap.h:173
Common macros and compiler attributes/pragmas configuration.
Generic CoAP values as defined by RFC7252.