This repository has been archived by the owner on Mar 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathtcoap_helpers.c
171 lines (132 loc) · 3.47 KB
/
tcoap_helpers.c
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
/**
* tcoap_helpers.c
*
* Author: Serge Maslyakov, [email protected]
* Copyright 2017 Serge Maslyakov. All rights reserved.
*
*/
#include "tcoap_helpers.h"
/**
* @brief See description in the header file.
*
*/
uint16_t tcoap_decode_szx_to_size(const uint8_t szx)
{
switch (szx)
{
case 0:
return TCOAP_BLOCK_SZX_VAL_0;
case 1:
return TCOAP_BLOCK_SZX_VAL_1;
case 2:
return TCOAP_BLOCK_SZX_VAL_2;
case 3:
return TCOAP_BLOCK_SZX_VAL_3;
case 4:
return TCOAP_BLOCK_SZX_VAL_4;
case 5:
return TCOAP_BLOCK_SZX_VAL_5;
case 6:
return TCOAP_BLOCK_SZX_VAL_6;
default:
return TCOAP_BLOCK_SZX_VAL_7;
}
}
/**
* @brief See description in the header file.
*
*/
void tcoap_fill_block2_opt(tcoap_option_data * const option, const tcoap_blockwise_data * const bw, uint8_t * const value)
{
/*
* Block Option Value
*
* 0
* 0 1 2 3 4 5 6 7
* +-+-+-+-+-+-+-+-+
* | NUM |M| SZX |
* +-+-+-+-+-+-+-+-+
*
* 0 1
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | NUM |M| SZX |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* 0 1 2
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | NUM |M| SZX |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
option->num = TCOAP_BLOCK2_OPT;
option->value = value;
option->len = 1;
option->next = NULL;
value[0] = (bw->arr[0] & 0x0F);
value[0] <<= 4;
value[0] |= bw->fld.block_szx;
value[0] |= bw->fld.more ? 8 : 0;
if (bw->fld.num > 15) {
option->len = 2;
value[1] = value[0];
value[0] = (bw->arr[0] >> 4);
value[0] |= (bw->arr[1] & 0x0F);
}
if (bw->fld.num > 4095) {
option->len = 3;
value[2] = value[1];
value[1] = value[0];
value[0] = (bw->arr[1] >> 4);
value[0] |= (bw->arr[2] & 0x0F);
}
}
/**
* @brief See description in the header file.
*
*/
void tcoap_extract_block2_from_opt(const tcoap_option_data * const block2, tcoap_blockwise_data * const bw)
{
bw->fld.num = 0;
bw->fld.block_szx = 0;
bw->fld.more = 0;
switch (block2->len) {
case 0:
break;
case 1:
bw->fld.num = (block2->value[0] >> 4);
bw->arr[3] = (block2->value[0] & 0x0F);
break;
case 2:
bw->arr[1] = (block2->value[0] >> 4);
bw->arr[0] = (block2->value[0] << 4) | (block2->value[1] >> 4);
bw->arr[3] = (block2->value[1] & 0x0F);
break;
case 3:
bw->arr[2] = (block2->value[0] >> 4);
bw->arr[1] = (block2->value[0] << 4) | (block2->value[1] >> 4);
bw->arr[0] = (block2->value[1] << 4) | (block2->value[2] >> 4);
bw->arr[3] = (block2->value[2] & 0x0F);
break;
default:
break;
}
}
/**
* @brief See description in the header file.
*
*/
const tcoap_option_data * tcoap_find_option_by_number(const tcoap_option_data * options, const uint16_t opt_num)
{
do {
if (options->num > opt_num) {
break;
}
if (options->num == opt_num) {
return options;
}
options = options->next;
} while (options != NULL);
return NULL;
}