Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Geithner, Thomas
desk-control
Commits
0b4d690f
Commit
0b4d690f
authored
Oct 09, 2017
by
Anon Mall
Browse files
finished coap frontend
parent
d4b168ae
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/coap-frontend.cpp
View file @
0b4d690f
...
...
@@ -3,26 +3,364 @@
*
* Created on: 13.09.2017
* Author: geith
* Author: mall
*/
#include <iostream>
#include <unistd.h>
#include <cassert>
extern
"C"
{
#include <netdb.h>
}
#include "coap-frontend.h"
#include "desk-controller.h"
#include <iostream>
#ifdef __GNUC__
#define UNUSED_PARAM __attribute__((unused))
#else
/* not a GCC */
#define UNUSED_PARAM
#endif
/* GCC */
#
include <unistd.h>
#
define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
#define INDEX "Index...\n" \
"...\n\n"
using
namespace
std
;
using
namespace
desk
;
CoapFrontend
::
CoapFrontend
(
Controller
&
controller
,
uint16_t
port
)
:
Frontend
(
controller
),
AvahiService
(
"desk"
,
"_coap._udp"
,
port
),
thread
(
&
CoapFrontend
::
run
,
this
),
m_port
(
port
)
map
<
coap_resource_t
*
,
CoapFrontend
*>
CoapFrontend
::
s_callbackMap
;
CoapFrontend
::
CoapFrontend
(
Controller
&
controller
,
uint16_t
port
)
:
Frontend
(
controller
),
m_controller
(
controller
),
AvahiService
(
"desk"
,
"_coap._udp"
,
port
),
thread
(
&
CoapFrontend
::
run
,
this
),
m_port
(
port
),
m_async
(
NULL
)
{
m_ccontext
=
get_context
(
"::"
,
port
);
if
(
!
m_ccontext
)
throw
CoapException
(
"Context could not be initialized"
);
init_resources
(
m_ccontext
);
}
void
CoapFrontend
::
s_get_index
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
UNUSED_PARAM
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
CoapFrontend
*
cf
=
s_callbackMap
.
at
(
resource
);
cf
->
hnd_get_index
(
ctx
,
resource
,
local_interface
,
peer
,
request
,
token
,
response
);
}
void
CoapFrontend
::
hnd_get_index
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
UNUSED_PARAM
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
unsigned
char
buf
[
3
];
printf
(
"%s: #1
\n
"
,
__func__
);
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
205
);
coap_add_option
(
response
,
COAP_OPTION_CONTENT_TYPE
,
coap_encode_var_bytes
(
buf
,
COAP_MEDIATYPE_TEXT_PLAIN
),
buf
);
coap_add_option
(
response
,
COAP_OPTION_MAXAGE
,
coap_encode_var_bytes
(
buf
,
0x2ffff
),
buf
);
coap_add_data
(
response
,
strlen
(
INDEX
),
(
unsigned
char
*
)
INDEX
);
}
void
CoapFrontend
::
s_get_height
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
UNUSED_PARAM
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
CoapFrontend
*
cf
=
s_callbackMap
.
at
(
resource
);
cf
->
hnd_get_height
(
ctx
,
resource
,
local_interface
,
peer
,
request
,
token
,
response
);
}
void
CoapFrontend
::
hnd_get_height
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
)
{
coap_opt_iterator_t
opt_iter
;
coap_opt_t
*
option
;
unsigned
char
buf
[
40
];
size_t
len
;
time_t
now
;
coap_tick_t
t
;
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
205
);
if
(
coap_find_observer
(
resource
,
peer
,
token
))
{
coap_add_option
(
response
,
COAP_OPTION_OBSERVE
,
coap_encode_var_bytes
(
buf
,
ctx
->
observe
),
buf
);
}
coap_add_option
(
response
,
COAP_OPTION_CONTENT_FORMAT
,
coap_encode_var_bytes
(
buf
,
COAP_MEDIATYPE_TEXT_PLAIN
),
buf
);
len
=
snprintf
((
char
*
)
buf
,
sizeof
(
buf
),
"%d"
,
m_controller
.
getHeight
());
coap_add_data
(
response
,
len
,
buf
);
}
void
CoapFrontend
::
s_put_height
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
UNUSED_PARAM
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
CoapFrontend
*
cf
=
s_callbackMap
.
at
(
resource
);
cf
->
hnd_put_height
(
ctx
,
resource
,
local_interface
,
peer
,
request
,
token
,
response
);
}
void
CoapFrontend
::
hnd_put_height
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
coap_tick_t
t
;
size_t
size
;
unsigned
char
*
data
;
int
val
;
unsigned
char
buf
[
20
];
resource
->
dirty
=
1
;
coap_get_data
(
request
,
&
size
,
&
data
);
strncpy
((
char
*
)
buf
,
(
const
char
*
)
data
,
MIN
(
size
,
sizeof
(
buf
)));
if
(
size
!=
0
)
{
char
*
endptr
;
val
=
strtol
((
const
char
*
)
buf
,
&
endptr
,
10
);
if
((
char
*
)
buf
==
endptr
)
{
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
415
);
}
else
{
m_controller
.
setHeight
(
val
);
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
204
);
}
}
else
{
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
400
);
}
}
void
CoapFrontend
::
s_get_offset
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
UNUSED_PARAM
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
CoapFrontend
*
cf
=
s_callbackMap
.
at
(
resource
);
cf
->
hnd_get_offset
(
ctx
,
resource
,
local_interface
,
peer
,
request
,
token
,
response
);
}
void
CoapFrontend
::
hnd_get_offset
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
)
{
coap_opt_iterator_t
opt_iter
;
coap_opt_t
*
option
;
unsigned
char
buf
[
40
];
size_t
len
;
time_t
now
;
coap_tick_t
t
;
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
205
);
if
(
coap_find_observer
(
resource
,
peer
,
token
))
{
coap_add_option
(
response
,
COAP_OPTION_OBSERVE
,
coap_encode_var_bytes
(
buf
,
ctx
->
observe
),
buf
);
}
coap_add_option
(
response
,
COAP_OPTION_CONTENT_FORMAT
,
coap_encode_var_bytes
(
buf
,
COAP_MEDIATYPE_TEXT_PLAIN
),
buf
);
len
=
snprintf
((
char
*
)
buf
,
sizeof
(
buf
),
"%d"
,
m_controller
.
getOffset
());
cout
<<
"offset: "
<<
m_controller
.
getOffset
()
<<
endl
;
coap_add_data
(
response
,
len
,
buf
);
}
void
CoapFrontend
::
s_put_offset
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
UNUSED_PARAM
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
CoapFrontend
*
cf
=
s_callbackMap
.
at
(
resource
);
cf
->
hnd_put_offset
(
ctx
,
resource
,
local_interface
,
peer
,
request
,
token
,
response
);
}
void
CoapFrontend
::
hnd_put_offset
(
coap_context_t
*
ctx
UNUSED_PARAM
,
struct
coap_resource_t
*
resource
UNUSED_PARAM
,
const
coap_endpoint_t
*
local_interface
UNUSED_PARAM
,
coap_address_t
*
peer
UNUSED_PARAM
,
coap_pdu_t
*
request
,
str
*
token
UNUSED_PARAM
,
coap_pdu_t
*
response
)
{
coap_tick_t
t
;
size_t
size
;
unsigned
char
*
data
;
int
val
;
unsigned
char
buf
[
20
];
resource
->
dirty
=
1
;
coap_get_data
(
request
,
&
size
,
&
data
);
strncpy
((
char
*
)
buf
,
(
const
char
*
)
data
,
MIN
(
size
,
sizeof
(
buf
)));
if
(
size
!=
0
)
{
char
*
endptr
;
val
=
strtol
((
const
char
*
)
buf
,
&
endptr
,
10
);
if
((
char
*
)
buf
==
endptr
)
{
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
415
);
}
else
{
m_controller
.
setOffset
(
val
);
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
204
);
}
}
else
{
response
->
hdr
->
code
=
COAP_RESPONSE_CODE
(
400
);
}
}
void
CoapFrontend
::
init_resources
(
coap_context_t
*
ctx
)
{
coap_resource_t
*
root
;
coap_resource_t
*
height
;
coap_resource_t
*
offset
;
// root
root
=
coap_resource_init
(
NULL
,
0
,
0
);
s_callbackMap
.
emplace
(
root
,
this
);
coap_register_handler
(
root
,
COAP_REQUEST_GET
,
s_get_index
);
coap_add_attr
(
root
,
(
unsigned
char
*
)
"ct"
,
2
,
(
unsigned
char
*
)
"0"
,
1
,
0
);
coap_add_attr
(
root
,
(
unsigned
char
*
)
"title"
,
5
,
(
unsigned
char
*
)
"
\"
General Info
\"
"
,
14
,
0
);
coap_add_resource
(
ctx
,
root
);
// height
height
=
coap_resource_init
((
unsigned
char
*
)
"height"
,
6
,
COAP_RESOURCE_FLAGS_NOTIFY_CON
);
s_callbackMap
.
emplace
(
height
,
this
);
coap_register_handler
(
height
,
COAP_REQUEST_GET
,
s_get_height
);
coap_register_handler
(
height
,
COAP_REQUEST_PUT
,
s_put_height
);
// attributes...
height
->
observable
=
1
;
coap_add_resource
(
ctx
,
height
);
m_res_height
=
height
;
// offset
offset
=
coap_resource_init
((
unsigned
char
*
)
"offset"
,
6
,
COAP_RESOURCE_FLAGS_NOTIFY_CON
);
s_callbackMap
.
emplace
(
offset
,
this
);
coap_register_handler
(
offset
,
COAP_REQUEST_GET
,
s_get_offset
);
coap_register_handler
(
offset
,
COAP_REQUEST_PUT
,
s_put_offset
);
// attributes...
offset
->
observable
=
1
;
coap_add_resource
(
ctx
,
offset
);
m_res_offset
=
offset
;
}
coap_context_t
*
CoapFrontend
::
get_context
(
const
char
*
node
,
int
port
)
{
coap_context_t
*
ctx
=
NULL
;
int
s
;
struct
addrinfo
hints
;
struct
addrinfo
*
result
,
*
rp
;
memset
(
&
hints
,
0
,
sizeof
(
struct
addrinfo
));
hints
.
ai_family
=
AF_UNSPEC
;
/* Allow IPv4 or IPv6 */
hints
.
ai_socktype
=
SOCK_DGRAM
;
/* Coap uses UDP */
hints
.
ai_flags
=
AI_PASSIVE
|
AI_NUMERICHOST
;
s
=
getaddrinfo
(
node
,
to_string
(
port
).
c_str
(),
&
hints
,
&
result
);
if
(
s
!=
0
)
{
fprintf
(
stderr
,
"getaddrinfo: %s
\n
"
,
gai_strerror
(
s
));
return
NULL
;
}
/* iterate through results until success */
for
(
rp
=
result
;
rp
!=
NULL
;
rp
=
rp
->
ai_next
)
{
coap_address_t
addr
;
if
(
rp
->
ai_addrlen
<=
sizeof
(
addr
.
addr
))
{
coap_address_init
(
&
addr
);
addr
.
size
=
rp
->
ai_addrlen
;
memcpy
(
&
addr
.
addr
,
rp
->
ai_addr
,
rp
->
ai_addrlen
);
ctx
=
coap_new_context
(
&
addr
);
if
(
ctx
)
{
/* TODO: output address:port for successful binding */
goto
finish
;
}
}
}
fprintf
(
stderr
,
"no context available for interface '%s'
\n
"
,
node
);
finish:
freeaddrinfo
(
result
);
return
ctx
;
}
CoapFrontend
::~
CoapFrontend
()
...
...
@@ -36,10 +374,10 @@ CoapFrontend::~CoapFrontend()
*/
}
void
CoapFrontend
::
notify
(
DeskNotification
&
notification
)
void
CoapFrontend
::
notify
(
DeskNotification
&
notification
)
{
switch
(
notification
.
type
){
switch
(
notification
.
type
)
{
case
DeskNotification
::
Type
::
current_height
:
cout
<<
__PRETTY_FUNCTION__
<<
": height="
<<
notification
.
value
<<
endl
;
break
;
...
...
@@ -52,13 +390,97 @@ CoapFrontend::notify(DeskNotification& notification)
}
}
void
CoapFrontend
::
run
()
void
CoapFrontend
::
check_async
(
coap_context_t
*
ctx
,
const
coap_endpoint_t
*
local_if
,
coap_tick_t
now
)
{
coap_pdu_t
*
response
;
coap_async_state_t
*
tmp
;
size_t
size
=
sizeof
(
coap_hdr_t
)
+
13
;
if
(
!
m_async
||
now
<
m_async
->
created
+
(
unsigned
long
)
m_async
->
appdata
)
return
;
response
=
coap_pdu_init
(
m_async
->
flags
&
COAP_ASYNC_CONFIRM
?
COAP_MESSAGE_CON
:
COAP_MESSAGE_NON
,
COAP_RESPONSE_CODE
(
205
),
0
,
size
);
if
(
!
response
)
{
debug
(
"check_async: insufficient memory, we'll try later
\n
"
);
m_async
->
appdata
=
(
void
*
)((
unsigned
long
)
m_async
->
appdata
+
15
*
COAP_TICKS_PER_SECOND
);
return
;
}
response
->
hdr
->
id
=
coap_new_message_id
(
ctx
);
if
(
m_async
->
tokenlen
)
coap_add_token
(
response
,
m_async
->
tokenlen
,
m_async
->
token
);
coap_add_data
(
response
,
4
,
(
unsigned
char
*
)
"done"
);
if
(
coap_send
(
ctx
,
local_if
,
&
m_async
->
peer
,
response
)
==
COAP_INVALID_TID
)
{
debug
(
"check_async: cannot send response for message %d
\n
"
,
response
->
hdr
->
id
);
}
coap_delete_pdu
(
response
);
coap_remove_async
(
ctx
,
m_async
->
id
,
&
tmp
);
coap_free_async
(
m_async
);
m_async
=
NULL
;
}
void
CoapFrontend
::
run
()
{
while
(
true
){
cout
<<
__PRETTY_FUNCTION__
<<
": tbd..."
<<
endl
;
cout
<<
"Starting CoapFrontend thread"
<<
endl
;
coap_queue_t
*
nextpdu
;
coap_tick_t
now
;
struct
timeval
tv
,
*
timeout
;
int
result
;
struct
coap_resource_t
*
time_resource
=
NULL
;
sleep
(
1
);
while
(
true
)
{
FD_ZERO
(
&
m_readfds
);
FD_SET
(
m_ccontext
->
sockfd
,
&
m_readfds
);
nextpdu
=
coap_peek_next
(
m_ccontext
);
coap_ticks
(
&
now
);
while
(
nextpdu
&&
nextpdu
->
t
<=
now
-
m_ccontext
->
sendqueue_basetime
)
{
coap_retransmit
(
m_ccontext
,
coap_pop_next
(
m_ccontext
)
);
nextpdu
=
coap_peek_next
(
m_ccontext
);
}
if
(
nextpdu
&&
nextpdu
->
t
<=
COAP_RESOURCE_CHECK_TIME
)
{
/* set timeout if there is a pdu to send before our automatic timeout occurs */
tv
.
tv_usec
=
((
nextpdu
->
t
)
%
COAP_TICKS_PER_SECOND
)
*
1000000
/
COAP_TICKS_PER_SECOND
;
tv
.
tv_sec
=
(
nextpdu
->
t
)
/
COAP_TICKS_PER_SECOND
;
timeout
=
&
tv
;
}
else
{
tv
.
tv_usec
=
0
;
tv
.
tv_sec
=
COAP_RESOURCE_CHECK_TIME
;
timeout
=
&
tv
;
}
result
=
select
(
FD_SETSIZE
,
&
m_readfds
,
0
,
0
,
timeout
);
if
(
result
<
0
)
{
/* error */
if
(
errno
!=
EINTR
)
perror
(
"select"
);
}
else
if
(
result
>
0
)
{
/* read from socket */
if
(
FD_ISSET
(
m_ccontext
->
sockfd
,
&
m_readfds
)
)
{
coap_read
(
m_ccontext
);
/* read received data */
/* coap_dispatch( ctx ); /\* and dispatch PDUs from receivequeue *\/ */
}
}
else
{
/* timeout */
if
(
time_resource
)
{
time_resource
->
dirty
=
1
;
}
}
check_async
(
m_ccontext
,
m_ccontext
->
endpoint
,
now
);
coap_check_notify
(
m_ccontext
);
//cout << __PRETTY_FUNCTION__ << ": tbd..." << endl;
sleep
(
1
);
}
}
src/coap-frontend.h
View file @
0b4d690f
...
...
@@ -11,7 +11,13 @@
#include "desk-frontend.h"
#include "avahi-service.h"
#define WITH_POSIX
#include "coap.h"
#include <thread>
#include <exception>
#include <map>
#include <utility>
#include <avahi-client/client.h>
#include <avahi-client/publish.h>
...
...
@@ -19,6 +25,21 @@
namespace
desk
{
class
CoapException
:
public
std
::
exception
{
public:
CoapException
(
std
::
string
msg
)
_GLIBCXX_USE_NOEXCEPT
:
m_msg
(
msg
){
}
virtual
const
char
*
what
()
const
_GLIBCXX_USE_NOEXCEPT
{
return
m_msg
.
c_str
();
}
protected:
std
::
string
m_msg
;
};
class
CoapFrontend
:
public
Frontend
,
public
AvahiService
,
public
std
::
thread
{
public:
...
...
@@ -26,12 +47,107 @@ public:
virtual
~
CoapFrontend
();
protected:
uint16_t
m_port
;
static
void
s_get_index
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
static
void
s_get_height
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
static
void
s_put_height
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
static
void
s_get_offset
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
static
void
s_put_offset
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
coap_context_t
*
get_context
(
const
char
*
node
,
int
port
);
void
init_resources
(
coap_context_t
*
ctx
);
void
hnd_get_index
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
void
hnd_get_height
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
void
hnd_put_height
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
void
hnd_get_offset
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
void
hnd_put_offset
(
coap_context_t
*
ctx
,
struct
coap_resource_t
*
resource
,
const
coap_endpoint_t
*
local_interface
,
coap_address_t
*
peer
,
coap_pdu_t
*
request
,
str
*
token
,
coap_pdu_t
*
response
);
virtual
void
notify
(
DeskNotification
&
height
);
void
check_async
(
coap_context_t
*
ctx
,
const
coap_endpoint_t
*
local_if
,
coap_tick_t
now
);
void
run
(
void
);