Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
RIOT
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cm-projects
RIOT
Commits
4897222e
Commit
4897222e
authored
7 years ago
by
Kaspar Schleiser
Browse files
Options
Downloads
Patches
Plain Diff
nanocoap: add server-side block1 support
parent
012c016b
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
sys/include/net/nanocoap.h
+100
-0
100 additions, 0 deletions
sys/include/net/nanocoap.h
sys/net/application_layer/nanocoap/nanocoap.c
+102
-11
102 additions, 11 deletions
sys/net/application_layer/nanocoap/nanocoap.c
with
202 additions
and
11 deletions
sys/include/net/nanocoap.h
+
100
−
0
View file @
4897222e
...
...
@@ -65,6 +65,8 @@ extern "C" {
#define COAP_OPT_URI_PATH (11)
#define COAP_OPT_CONTENT_FORMAT (12)
#define COAP_OPT_URI_QUERY (15)
#define COAP_OPT_BLOCK2 (23)
#define COAP_OPT_BLOCK1 (27)
/** @} */
/**
...
...
@@ -211,6 +213,16 @@ extern "C" {
#define COAP_DEFAULT_LEISURE (5)
/** @} */
/**
* @name Blockwise transfer (RFC7959)
* @{
*/
#define COAP_BLOCKWISE_NUM_OFF (4)
#define COAP_BLOCKWISE_MORE_OFF (3)
#define COAP_BLOCKWISE_SZX_MASK (0x07)
#define COAP_BLOCKWISE_SZX_MAX (7)
/** @} */
/**
* @brief Raw CoAP PDU header structure
*/
...
...
@@ -262,6 +274,17 @@ typedef struct {
void
*
context
;
/**< ptr to user defined context data */
}
coap_resource_t
;
/**
* @brief Block1 helper struct
*/
typedef
struct
{
size_t
offset
;
/**< offset of received data */
uint32_t
blknum
;
/**< block number */
unsigned
szx
;
/**< szx value */
int
more
;
/**< -1 for no option, 0 for last block,
1 for more blocks coming */
}
coap_block1_t
;
/**
* @brief Global CoAP resource list
*/
...
...
@@ -409,6 +432,71 @@ size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type
*/
size_t
coap_put_option_uri
(
uint8_t
*
buf
,
uint16_t
lastonum
,
const
char
*
uri
,
uint16_t
optnum
);
/**
* @brief Generic block option getter
*
* @param[in] pkt pkt to work on
* @param[in] option actual block option number to get
* @param[out] blknum block number
* @param[out] szx SZX value
*
* @returns -1 if option not found
* @returns 0 if more flag is not set
* @returns 1 if more flag is set
*/
int
coap_get_blockopt
(
coap_pkt_t
*
pkt
,
uint16_t
option
,
uint32_t
*
blknum
,
unsigned
*
szx
);
/**
* @brief Block1 option getter
*
* This function gets a CoAP packet's block1 option and parses it into a helper
* structure.
*
* If no block1 option is present in @p pkt, the values in @p block1 will be
* initialized with zero. That implies both block1->offset and block1->more are
* also valid in that case, as packet with offset==0 and more==0 means it contains
* all the payload for the corresponding request.
*
* @param[in] pkt pkt to work on
* @param[out] block1 ptr to preallocated coap_block1_t structure
*
* @returns 0 if block1 option not present
* @returns 1 if structure has been filled
*/
int
coap_get_block1
(
coap_pkt_t
*
pkt
,
coap_block1_t
*
block1
);
/**
* @brief Insert block1 option into buffer
*
* @param[out] buf buffer to write to
* @param[in] lastonum number of previous option (for delta calculation),
* must be < 27
* @param[in] blknum block number
* @param[in] szx SXZ value
* @param[in] more more flag (1 or 0)
*
* @returns amount of bytes written to @p buf
*/
size_t
coap_put_option_block1
(
uint8_t
*
buf
,
uint16_t
lastonum
,
unsigned
blknum
,
unsigned
szx
,
int
more
);
/**
* @brief Insert block1 option into buffer (from coap_block1_t)
*
* This function is wrapper around @ref coap_put_option_block1(),
* taking its arguments from a coap_block1_t struct.
*
* It will write option Nr. 27 (COAP_OPT_BLOCK1).
*
* It is safe to be called when @p block1 was generated for a non-blockwise
* request.
*
* @param[in] pkt_pos buffer to write to
* @param[in] block1 ptr to block1 struct (created by coap_get_block1())
* @param[in] lastonum last option number (must be < 27)
*
* @returns amount of bytes written to @p pkt_pos
*/
size_t
coap_put_block1_ok
(
uint8_t
*
pkt_pos
,
coap_block1_t
*
block1
,
uint16_t
lastonum
);
/**
* @brief Get content type from packet
...
...
@@ -436,6 +524,18 @@ unsigned coap_get_content_type(coap_pkt_t *pkt);
*/
int
coap_get_uri
(
coap_pkt_t
*
pkt
,
uint8_t
*
target
);
/**
* @brief Helper to decode SZX value to size in bytes
*
* @param[in] szx SZX value to decode
*
* @returns SZX value decoded to bytes
*/
static
inline
unsigned
coap_szx2size
(
unsigned
szx
)
{
return
(
1
<<
(
szx
+
4
));
}
/**
* @brief Get the CoAP version number
*
...
...
This diff is collapsed.
Click to expand it.
sys/net/application_layer/nanocoap/nanocoap.c
+
102
−
11
View file @
4897222e
...
...
@@ -30,6 +30,8 @@
static
int
_decode_value
(
unsigned
val
,
uint8_t
**
pkt_pos_ptr
,
uint8_t
*
pkt_end
);
int
coap_get_option_uint
(
coap_pkt_t
*
pkt
,
unsigned
opt_num
,
uint32_t
*
target
);
static
uint32_t
_decode_uint
(
uint8_t
*
pkt_pos
,
unsigned
nbytes
);
static
size_t
_encode_uint
(
uint32_t
*
val
);
/* http://tools.ietf.org/html/rfc7252#section-3
* 0 1 2 3
...
...
@@ -161,17 +163,6 @@ static uint8_t *_parse_option(coap_pkt_t *pkt, uint8_t *pkt_pos, uint16_t *delta
return
pkt_pos
;
}
static
uint32_t
_decode_uint
(
uint8_t
*
pkt_pos
,
unsigned
nbytes
)
{
assert
(
nbytes
<=
4
);
uint32_t
res
=
0
;
if
(
nbytes
)
{
memcpy
(((
uint8_t
*
)
&
res
)
+
(
4
-
nbytes
),
pkt_pos
,
nbytes
);
}
return
ntohl
(
res
);
}
int
coap_get_option_uint
(
coap_pkt_t
*
pkt
,
unsigned
opt_num
,
uint32_t
*
target
)
{
assert
(
target
);
...
...
@@ -265,6 +256,29 @@ int coap_get_uri(coap_pkt_t *pkt, uint8_t *target)
return
NANOCOAP_URI_MAX
-
left
;
}
int
coap_get_blockopt
(
coap_pkt_t
*
pkt
,
uint16_t
option
,
uint32_t
*
blknum
,
unsigned
*
szx
)
{
uint8_t
*
optpos
=
coap_find_option
(
pkt
,
option
);
if
(
!
optpos
)
{
*
blknum
=
0
;
*
szx
=
0
;
return
-
1
;
}
int
option_len
;
uint16_t
delta
;
uint8_t
*
data_start
=
_parse_option
(
pkt
,
optpos
,
&
delta
,
&
option_len
);
uint32_t
blkopt
=
_decode_uint
(
data_start
,
option_len
);
DEBUG
(
"nanocoap: blkopt len: %i
\n
"
,
option_len
);
DEBUG
(
"nanocoap: blkopt: 0x%08x
\n
"
,
(
unsigned
)
blkopt
);
*
blknum
=
blkopt
>>
COAP_BLOCKWISE_NUM_OFF
;
*
szx
=
blkopt
&
COAP_BLOCKWISE_SZX_MASK
;
return
(
blkopt
&
0x8
)
?
1
:
0
;
}
ssize_t
coap_handle_req
(
coap_pkt_t
*
pkt
,
uint8_t
*
resp_buf
,
unsigned
resp_buf_len
)
{
if
(
coap_get_code_class
(
pkt
)
!=
COAP_REQ
)
{
...
...
@@ -416,6 +430,43 @@ static int _decode_value(unsigned val, uint8_t **pkt_pos_ptr, uint8_t *pkt_end)
return
res
;
}
static
uint32_t
_decode_uint
(
uint8_t
*
pkt_pos
,
unsigned
nbytes
)
{
assert
(
nbytes
<=
4
);
uint32_t
res
=
0
;
if
(
nbytes
)
{
memcpy
(((
uint8_t
*
)
&
res
)
+
(
4
-
nbytes
),
pkt_pos
,
nbytes
);
}
return
ntohl
(
res
);
}
static
size_t
_encode_uint
(
uint32_t
*
val
)
{
uint8_t
*
tgt
=
(
uint8_t
*
)
val
;
size_t
size
=
0
;
/* count number of used bytes */
uint32_t
tmp
=
*
val
;
while
(
tmp
)
{
size
++
;
tmp
>>=
8
;
}
/* convert to network byte order */
tmp
=
htonl
(
*
val
);
/* copy bytewise, starting with first actually used byte */
*
val
=
0
;
uint8_t
*
tmp_u8
=
(
uint8_t
*
)
&
tmp
;
tmp_u8
+=
(
4
-
size
);
for
(
unsigned
n
=
0
;
n
<
size
;
n
++
)
{
*
tgt
++
=
*
tmp_u8
++
;
}
return
size
;
}
static
unsigned
_put_delta_optlen
(
uint8_t
*
buf
,
unsigned
offset
,
unsigned
shift
,
unsigned
val
)
{
if
(
val
<
13
)
{
...
...
@@ -469,6 +520,46 @@ size_t coap_put_option_ct(uint8_t *buf, uint16_t lastonum, uint16_t content_type
}
}
static
size_t
coap_put_option_block
(
uint8_t
*
buf
,
uint16_t
lastonum
,
unsigned
blknum
,
unsigned
szx
,
int
more
,
uint16_t
option
)
{
uint32_t
blkopt
=
(
blknum
<<
4
)
|
szx
|
(
more
?
0x8
:
0
);
size_t
olen
=
_encode_uint
(
&
blkopt
);
return
coap_put_option
(
buf
,
lastonum
,
option
,
(
uint8_t
*
)
&
blkopt
,
olen
);
}
size_t
coap_put_option_block1
(
uint8_t
*
buf
,
uint16_t
lastonum
,
unsigned
blknum
,
unsigned
szx
,
int
more
)
{
return
coap_put_option_block
(
buf
,
lastonum
,
blknum
,
szx
,
more
,
COAP_OPT_BLOCK1
);
}
int
coap_get_block1
(
coap_pkt_t
*
pkt
,
coap_block1_t
*
block1
)
{
uint32_t
blknum
;
unsigned
szx
;
block1
->
more
=
coap_get_blockopt
(
pkt
,
COAP_OPT_BLOCK1
,
&
blknum
,
&
szx
);
if
(
block1
->
more
>=
0
)
{
block1
->
offset
=
blknum
<<
(
szx
+
4
);
}
else
{
block1
->
offset
=
0
;
}
block1
->
blknum
=
blknum
;
block1
->
szx
=
szx
;
return
(
block1
->
more
>=
0
);
}
size_t
coap_put_block1_ok
(
uint8_t
*
pkt_pos
,
coap_block1_t
*
block1
,
uint16_t
lastonum
)
{
if
(
block1
->
more
>=
1
)
{
return
coap_put_option_block1
(
pkt_pos
,
lastonum
,
block1
->
blknum
,
block1
->
szx
,
block1
->
more
);
}
else
{
return
0
;
}
}
size_t
coap_put_option_uri
(
uint8_t
*
buf
,
uint16_t
lastonum
,
const
char
*
uri
,
uint16_t
optnum
)
{
char
separator
=
(
optnum
==
COAP_OPT_URI_PATH
)
?
'/'
:
'&'
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment