upload original libcoap release-4.3.4

Signed-off-by: wanghan985406 <wanghan76@huawei.com>
This commit is contained in:
wanghan985406
2023-12-21 07:02:16 +00:00
parent c3f959c04c
commit b0e2e05964
309 changed files with 101288 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
Olaf Bergmann
Carsten Schönert
Jon Shallow
Jean-Claude Michelou
Christian Amsüss
For additional contributors, see
https://github.com/obgm/libcoap/graphs/contributors
+210
View File
@@ -0,0 +1,210 @@
For Windows builds - see the Windows Section
Obtaining the Libcoap Source
============================
To get the libcoap library source, you need to do either the following
* Obtain the latest distribution package file from
https://github.com/obgm/libcoap/archive/develop.zip
[There is a stable version at
https://github.com/obgm/libcoap/archive/main.zip]
* Change to the directory that you want to install the libcoap sub-directory
into
* Unpack the distribution package file
* Change into the top level directory of the unpackaged files
or alternatively, clone the libcoap git repository from github
* Change to the directory that you want to install the libcoap sub-directory
into.
* Then clone the latest (develop) version of the code:-
git clone https://github.com/obgm/libcoap.git
* Change into the top level directory of the cloned files
* Optionally, change the branch from develop to the stable main branch:-
git checkout main
Building Libcoap Libraries and Examples
=======================================
Follow the appropriate sections below
TinyDTLS Only
=============
It is possible that you may need to execute the following two commands once to
get the TinyDTLS code into your project, so the TinyDTLS library can be used.
git submodule init
git submodule update
General Building with cmake for linux/windows/macos/android (not for RIOT, LwIP or Contiki-NG - see below)
================
cmake -E remove_directory build
cmake -E make_directory build
cd build
cmake .. -DENABLE_TESTS=ON
cmake --build .
[sudo] cmake --build . -- install
cd ..
Note: to see possible options (TLS lib, doc, tests, examples etc.):
cmake -LH build
Note: For Windows, this is supported by Visual Studio Code with CMake extension
Note: You must use cmake version >=3.10.
Note: you can use cmake's find package after installation: find_package(libcoap-3 REQUIRED),
and target_link_libraries(myTarget PRIVATE libcoap::coap-2)
Note: Shared Library support is not currently available for Windows.
General Building with autoconf (not for RIOT, LwIP or Contiki-NG - see below)
================
./autogen.sh
./configure
make
sudo make install
./autogen.sh will fail if there is a required package for buildling libcoap
that is missing. Install the missing package and try ./autogen.sh again.
It is possible that you may need to provide some options to ./configure
to customize your installation.
In particular you may need to define which (D)TLS library to use as well as
disable some building of documentation.
General configure instructions can be found in INSTALL, which is built
by ./autogen.sh
./configure --help
gives the specific options available to libcoap.
Some examples are:-
# No DTLS
./configure --enable-tests --disable-documentation --enable-examples --disable-dtls --enable-shared
# With TinyDTLS
./configure --enable-tests --disable-documentation --enable-examples --with-tinydtls --enable-shared
Note: FreeBSD requires gmake instead of make when building TinyDTLS - i.e.
gmake
sudo gmake install
# With OpenSSL
./configure --with-openssl --enable-tests --enable-shared
# With GnuTLS
./configure --with-gnutls --enable-tests --enable-shared
Note: --disable-documentation disables the building of doxygen and man page
files. If you want to only disable one of them, use --disable-doxygen or
--disable-manpages. Doxygen requires the program doxygen and man pages require
the program a2x to build the appropriate files.
If you need to rebuild the libcoap-*.{map,sym} files to update any exposed
function changes, run
make update-map-file
prior to running 'make'.
RIOT
====
./autogen.sh
./configure --disable-tests --disable-documentation --disable-examples --disable-dtls
cd examples/riot
make
See examples/riot/README for further information.
LwIP
====
./autogen.sh
./configure --disable-tests --disable-documentation --disable-examples --disable-dtls
cd examples/lwip
make
Executable is ./server. See examples/lwip/README for further information.
Contiki-NG
==========
./autogen.sh
./configure --disable-tests --disable-documentation --disable-examples --disable-dtls
cd examples/contiki
make
Executable is ./server.native. See examples/contiki/README for further
information.
Windows
=======
Install OpenSSL (minimum version 1.1.0) including the development libraries if
not already installed.
Within Visual Studio, "Clone or check out code" using the repository
https://github.com/obgm/libcoap.git
You may need to update the SDK version of the libcoap Windows Project files to
match that of the SDK version of the Visual Studio you are using. In Solution
Explorer with the view set to libcoap.sln, right click "Solution 'libcoap'"
and then "Retarget solution".
You may need to edit win32\libcoap.props to update the OpenSSLRootDir and
OpenSSLRootDirDbg variables to point to the top level directory where OpenSSL
is installed so that the include, lib etc. directories are correctly set up.
Note: Make sure that you include a trailing \ in the variable definitions.
Alternatively you can build everything in Visual Studio with CMake.
MinGW
=====
As there are many ways to install MinGW, depending on the different
installed packages, random failures can occur (usually because of conflicts
with cygwin based packages). Below is a way known to work with libcoap
on a Windows host.
Remove any old copy of MSYS2 using Windows program remove.
Download https://repo.msys2.org/distrib/x86_64/msys2-x86_64-20230318.exe and
run the executable, accepting the defaults.
In a UCRT64 window, add in the following packages
pacman -S git
pacman -S vim
pacman -S mingw-w64-ucrt-x86_64-cmake
pacman -S mingw-w64-ucrt-x86_64-gcc
pacman -S mingw-w64-ucrt-x86_64-openssl
Alternatively, in a MINGW64 window, add in the following packages
pacman -S git
pacman -S vim
pacman -S mingw-w64-x86_64-cmake
pacman -S mingw-w64-x86_64-gcc
pacman -S mingw-w64-x86_64-openssl
Then clone a copy of the github libcoap repository in a UCRT64 or MINGW64 window
git clone https://github.com/obgm/libcoap.git
cd libcoap
Then build the libcoap library and example executables (which will be in the
build directory)
cmake -E remove_directory build
cmake -E make_directory build
cd build
cmake .. -DENABLE_DOCS=OFF -DDTLS_BACKEND=openssl
cmake --build .
+923
View File
@@ -0,0 +1,923 @@
# CMakeLists.txt for libcoap
#
# Copyright (C) 2020 Carlos Gomes Martinho <carlos.gomes_martinho@siemens.com>
# Copyright (C) 2020-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
#
# SPDX-License-Identifier: BSD-2-Clause
#
# This file is part of the CoAP library libcoap. Please see README for terms
# of use.
cmake_minimum_required(VERSION 3.10)
project(
libcoap
VERSION 4.3.4
LANGUAGES CXX C)
set(LIBCOAP_API_VERSION 3)
set(LIBCOAP_ABI_VERSION 3.1.1)
set(COAP_LIBRARY_NAME "coap-${LIBCOAP_API_VERSION}")
option(
BUILD_SHARED_LIBS
"Build shared libs"
OFF)
#
# global compiler options
# (need to do it before add_library())
#
add_compile_options(
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-pedantic>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wcast-qual>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wextra>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wformat-security>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Winline>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wmissing-declarations>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wmissing-prototypes>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wnested-externs>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wpointer-arith>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wshadow>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wstrict-prototypes>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wswitch-default>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wswitch-enum>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wunused>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wwrite-strings>)
if(MINGW)
add_compile_options(
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:-Wno-format>
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:-Wno-format-security>)
endif()
if(${WARNING_TO_ERROR})
add_compile_options(
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Werror>)
endif()
if(CMAKE_GENERATOR MATCHES "Visual Studio")
option(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS "Export all symbols when compiling to a .dll" ON)
# add_compile_options(/Wall /wd4100 /wd4820 /wd4668 /wd4061)
if(${WARNING_TO_ERROR})
add_compile_options(/WX)
endif()
endif()
#
# The libcoap library
#
add_library(${COAP_LIBRARY_NAME})
set_property(TARGET ${COAP_LIBRARY_NAME} PROPERTY C_STANDARD 99)
if(${CMAKE_VERSION} VERSION_GREATER "3.20.0")
cmake_policy(SET CMP0115 OLD) # Supresses libcoap configuration warning
endif()
set_target_properties(${COAP_LIBRARY_NAME} PROPERTIES SOVERSION ${LIBCOAP_API_VERSION})
set_target_properties(${COAP_LIBRARY_NAME} PROPERTIES VERSION ${LIBCOAP_ABI_VERSION})
#
# options to tweak the library
#
option(
ENABLE_DTLS
"enable building with DTLS support"
ON)
set(DTLS_BACKEND
"default"
CACHE
STRING
"\
Name of the dtls backend, only relevant if `ENABLE_DTLS` is ON which is default. \
Possible values: default, gnutls, openssl, tinydtls and mbedtls. \
If specified then this library will be searched and if found also used. \
If not found then the cmake configuration will stop with an error. \
If not specified, then cmake will try to use the first one found in the following order: \
gnutls, openssl, tinydtls, mbedtls \
")
set_property(
CACHE DTLS_BACKEND
PROPERTY STRINGS
default
openssl
gnutls
tinydtls
mbedtls)
option(
USE_VENDORED_TINYDTLS
"compile with the tinydtls project in the submodule if on, otherwise try to find the compiled lib with find_package"
ON)
option(
ENABLE_CLIENT_MODE
"compile with support for client mode code"
ON)
option(
ENABLE_SERVER_MODE
"compile with support for server mode code"
ON)
option(
ENABLE_OSCORE
"compile with support for OSCORE"
ON)
option(
WITH_OBSERVE_PERSIST
"compile with observe persist support for server restarts"
ON)
option(
WITH_EPOLL
"compile with epoll support"
ON)
option(
ENABLE_SMALL_STACK
"enable if the system has small stack size"
OFF)
option(
ENABLE_TCP
"enable building with TCP support"
ON)
option(
ENABLE_IPV4
"enable building with IPv4 support"
ON)
option(
ENABLE_IPV6
"enable building with IPv6 support"
ON)
option(
ENABLE_AF_UNIX
"enable building with Unix socket support"
ON)
option(
ENABLE_WS
"enable building with WebSockets support"
ON)
option(
ENABLE_ASYNC
"enable building with async separate response support"
ON)
option(
ENABLE_Q_BLOCK
"enable building with Q-Block (RFC9177) support"
ON)
option(
ENABLE_TESTS
"build also tests"
OFF)
option(
ENABLE_EXAMPLES
"build also examples"
ON)
option(
ENABLE_DOCS
"build also doxygen documentation"
ON)
option(
WARNING_TO_ERROR
"force all compiler warnings to be errors"
OFF)
set(MAX_LOGGING_LEVEL
"8"
CACHE
STRING
"\
Only build logging code up to and including the specified logging level (0 - 8)[default=8]]
")
set_property(
CACHE DTLS_BACKEND
PROPERTY STRINGS
"0"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8")
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 11)
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
if(APPLE)
add_definitions(-D__APPLE_USE_RFC_3542=1)
endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_BINARY_DIR})
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(CheckCSourceCompiles)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckSymbolExists)
include(CheckTypeSize)
include(TestBigEndian)
# check for headers
check_include_file(assert.h HAVE_ASSERT_H)
check_include_file(string.h HAVE_STRING_H)
check_include_file(strings.h HAVE_STRINGS_H)
check_include_file(byteswap.h HAVE_BYTESWAP_H)
check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(errno.h HAVE_ERRNO_H)
check_include_file(limits.h HAVE_LIMITS_H)
check_include_file(memory.h HAVE_MEMORY_H)
check_include_file(strings.h HAVE_STRINGS_H)
check_include_file(string.h HAVE_STRING_H)
check_include_file(sys/sysctl.h HAVE_SYS_SYSCTL_H)
check_include_file(net/if.h HAVE_NET_IF_H)
check_include_file(ifaddrs.h HAVE_IFADDRS_H)
check_include_file(netinet/in.h HAVE_NETINET_IN_H)
check_include_file(sys/epoll.h HAVE_EPOLL_H)
check_include_file(sys/timerfd.h HAVE_TIMERFD_H)
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(stdbool.h HAVE_STDBOOL_H)
check_include_file(netdb.h HAVE_NETDB_H)
check_include_file(pthread.h HAVE_PTHREAD_H)
check_include_file(stdlib.h HAVE_STDINT_H)
check_include_file(stdint.h HAVE_STDLIB_H)
check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H)
check_include_file(sys/socket.h HAVE_SYS_SOCKET_H)
check_include_file(sys/stat.h HAVE_SYS_STAT_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
check_include_file(sys/unistd.h HAVE_SYS_UNISTD_H)
check_include_file(time.h HAVE_TIME_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(float.h HAVE_FLOAT_H)
check_include_file(stddef.h HAVE_STDDEF_H)
check_include_file(winsock2.h HAVE_WINSOCK2_H)
check_include_file(ws2tcpip.h HAVE_WS2TCPIP_H)
# check for functions
check_function_exists(malloc HAVE_MALLOC)
check_function_exists(memset HAVE_MEMSET)
check_function_exists(select HAVE_SELECT)
check_function_exists(socket HAVE_SOCKET)
check_function_exists(strcasecmp HAVE_STRCASECMP)
check_function_exists(pthread_mutex_lock HAVE_PTHREAD_MUTEX_LOCK)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_function_exists(strnlen HAVE_STRNLEN)
check_function_exists(strrchr HAVE_STRRCHR)
check_function_exists(getrandom HAVE_GETRANDOM)
check_function_exists(random HAVE_RANDOM)
check_function_exists(if_nametoindex HAVE_IF_NAMETOINDEX)
# check for symbols
if(WIN32 AND NOT MINGW)
set(HAVE_STRUCT_CMSGHDR 1)
message(STATUS "setting HAVE_STRUCT_CMSGHDR")
else()
check_symbol_exists(
CMSG_FIRSTHDR
sys/socket.h
HAVE_STRUCT_CMSGHDR)
endif()
if(${ENABLE_CLIENT_MODE})
set(COAP_CLIENT_SUPPORT "1")
message(STATUS "compiling with client support")
else()
message(STATUS "compiling without client support")
endif()
if(${ENABLE_SERVER_MODE})
set(COAP_SERVER_SUPPORT "1")
message(STATUS "compiling with server support")
else()
message(STATUS "compiling without server support")
endif()
if(${ENABLE_OSCORE})
set(COAP_OSCORE_SUPPORT "1")
message(STATUS "compiling with OSCORE support")
else()
message(STATUS "compiling without OSCORE support")
endif()
if(${ENABLE_WS} AND $(ENABLE_TCP))
set(COAP_WS_SUPPORT "1")
message(STATUS "compiling with WebSockets support")
else()
if(${ENABLE_WS})
set(ENABLE_WS OFF)
message(STATUS "WebSockets disabled as TCP not enabled")
endif()
message(STATUS "compiling without WebSockets support")
endif()
if(${ENABLE_ASYNC})
set(COAP_ASYNC_SUPPORT "1")
message(STATUS "compiling with async separate response support")
else()
message(STATUS "compiling without async separate response support")
endif()
if(${ENABLE_IPV4})
set(COAP_IPV4_SUPPORT "1")
message(STATUS "compiling with IPv4 support")
else()
message(STATUS "compiling without IPv4 support")
endif()
if(${ENABLE_IPV6})
set(COAP_IPV6_SUPPORT "1")
message(STATUS "compiling with IPv6 support")
else()
message(STATUS "compiling without IPv6 support")
endif()
if(${ENABLE_AF_UNIX})
set(COAP_AF_UNIX_SUPPORT "1")
message(STATUS "compiling with Unix socket support")
else()
message(STATUS "compiling without Unix socket support")
endif()
if(${ENABLE_Q_BLOCK})
set(COAP_Q_BLOCK_SUPPORT "1")
message(STATUS "compiling with Q-Block (RFC9177) support")
else()
message(STATUS "compiling without Q-Block (RFC9177) support")
endif()
if(${WITH_OBSERVE_PERSIST})
set(COAP_WITH_OBSERVE_PERSIST "1")
message(STATUS "compiling with observe persistence support")
else()
message(STATUS "compiling without observe persistence support")
endif()
if(${WITH_EPOLL}
AND HAVE_EPOLL_H
AND HAVE_TIMERFD_H)
set(COAP_EPOLL_SUPPORT "1")
message(STATUS "compiling with epoll support")
else()
if(${WITH_EPOLL})
set(WITH_EPOLL OFF)
message(STATUS "epoll disabled as kernel support not available")
endif()
message(STATUS "compiling without epoll support")
endif()
if(ENABLE_SMALL_STACK)
set(ENABLE_SMALL_STACK "${ENABLE_SMALL_STACK}")
message(STATUS "compiling with small stack support")
endif()
if(${MAX_LOGGING_LEVEL} MATCHES "[0-7]")
set(COAP_MAX_LOGGING_LEVEL ${MAX_LOGGING_LEVEL})
message(STATUS "compiling with max logging level set to ${MAX_LOGGING_LEVEL}")
else()
message(STATUS "compiling with max logging level set to none")
endif()
set(WITH_GNUTLS OFF)
set(WITH_OPENSSL OFF)
set(WITH_TINYDTLS OFF)
set(WITH_MBEDTLS OFF)
function(compile_tinydtls)
set(TINYDTLS_SOURCES_DIR ${CMAKE_CURRENT_LIST_DIR}/ext/tinydtls)
set(TINYDTLS_SOURCES_GENERATED ${TINYDTLS_SOURCES_DIR}/dtls_config.h)
message(STATUS "compiling the tinydtls lib")
include(ExternalProject)
externalproject_add(
external_tinydtls
SOURCE_DIR "${TINYDTLS_SOURCES_DIR}"
BUILD_IN_SOURCE 1
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CONFIGURE_COMMAND
${TINYDTLS_SOURCES_DIR}/configure
--disable-manpages
--prefix=${CMAKE_BINARY_DIR}
BUILD_COMMAND make install
INSTALL_COMMAND ""
LOG_DOWNLOAD 1
LOG_CONFIGURE 1)
externalproject_add_step(
external_tinydtls autoreconf
COMMAND ./autogen.sh
ALWAYS 1
WORKING_DIRECTORY "${TINYDTLS_SOURCES_DIR}"
DEPENDERS configure
DEPENDEES download)
# Let cmake know that it needs to execute the external_tinydtls target to generate those files.
add_custom_command(
OUTPUT ${TINYDTLS_SOURCES_GENERATED}
WORKING_DIRECTORY "${TINYDTLS_SOURCES_DIR}"
COMMAND "make install"
DEPENDS external_tinydtls)
add_dependencies(${COAP_LIBRARY_NAME} external_tinydtls)
if(BUILD_SHARED_LIBS)
set(LIBTINYDTLS_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib/libtinydtls.so")
else()
set(LIBTINYDTLS_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib/libtinydtls.a")
endif()
add_library(
tinydtls
UNKNOWN
IMPORTED)
set_target_properties(
tinydtls
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
"${CMAKE_CURRENT_BINARY_DIR}/include"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${LIBTINYDTLS_PATH}")
endfunction()
if(ENABLE_DTLS)
message(STATUS "compiling with DTLS support")
message(STATUS "DTLS_BACKEND: ${DTLS_BACKEND}")
if(DTLS_BACKEND
STREQUAL
"default")
# try to find a crypto lib and use it, use the first one found
# libgnutls (e.g. debian libgnutls28-dev)
find_package(GnuTLS)
if(GnuTLS_FOUND)
set(WITH_GNUTLS ON)
message(STATUS "compiling with gnutls support")
set(COAP_WITH_LIBGNUTLS 1)
else()
# gnutls not found
find_package(OpenSSL)
if(OpenSSL_FOUND)
set(WITH_OPENSSL ON)
message(STATUS "compiling with openssl support")
set(COAP_WITH_LIBOPENSSL 1)
else()
# openssl not found
# libmbedtls (e.g. debian libmbedtls-dev)
find_package(MbedTLS)
if(MbedTLS_FOUND)
set(WITH_MBEDTLS ON)
message(STATUS "compiling with mbedtls support")
set(COAP_WITH_LIBMBEDTLS 1)
else()
# mbedtls not found
if(USE_VENDORED_TINYDTLS)
compile_tinydtls()
else()
find_package(TinyDTLS)
if(TINYDTLS_FOUND)
else()
# no cryto lib found
message(
FATAL_ERROR
"cannot find any cryto lib, either install one or compile without DTLS support"
)
endif()
endif()
set(WITH_TINYDTLS ON)
message(STATUS "compiling with tinydtls support")
set(COAP_WITH_LIBTINYDTLS 1)
endif()
endif()
endif()
else()
# DTLS_BACKEND variable is not empty, so set all to false and set the only right to true
set(WITH_GNUTLS OFF)
set(WITH_TINYDTLS OFF)
set(WITH_MBEDTLS OFF)
set(WITH_OPENSSL OFF)
if(DTLS_BACKEND
STREQUAL
"gnutls")
# libgnutls (e.g. debian libgnutls28-dev)
find_package(GnuTLS REQUIRED)
set(WITH_GNUTLS ON)
message(STATUS "compiling with gnutls support")
set(COAP_WITH_LIBGNUTLS 1)
endif()
if(DTLS_BACKEND
STREQUAL
"openssl")
# libssl (e.g. debian libssl1.0-dev)
find_package(OpenSSL REQUIRED)
set(WITH_OPENSSL ON)
message(STATUS "compiling with openssl support")
set(COAP_WITH_LIBOPENSSL 1)
endif()
if(DTLS_BACKEND
STREQUAL
"mbedtls")
# libmbedtls (e.g. debian libmbedtls-dev)
find_package(MbedTLS REQUIRED)
set(WITH_MBEDTLS ON)
message(STATUS "compiling with mbedtls support")
set(COAP_WITH_LIBMBEDTLS 1)
endif()
if(DTLS_BACKEND
STREQUAL
"tinydtls")
if(USE_VENDORED_TINYDTLS)
compile_tinydtls()
else(USE_VENDORED_TINYDTLS)
find_package(TinyDTLS REQUIRED)
endif(USE_VENDORED_TINYDTLS)
message(STATUS "compiling with tinydtls support")
set(WITH_TINYDTLS ON)
set(COAP_WITH_LIBTINYDTLS 1)
endif()
endif()
endif()
execute_process(COMMAND git describe --tags --dirty --always
RESULT_VARIABLE USING_GIT
OUTPUT_VARIABLE LIBCOAP_PACKAGE_BUILD
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if(NOT ${USING_GIT} EQUAL 0)
set(LIBCOAP_PACKAGE_BUILD ${PROJECT_VERSION})
else()
set(LIBCOAP_PACKAGE_BUILD "${LIBCOAP_PACKAGE_BUILD}")
endif()
set(PACKAGE_URL "https://libcoap.net/")
set(PACKAGE_NAME "${PROJECT_NAME}")
set(PACKAGE_TARNAME "${PROJECT_NAME}")
set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(PACKAGE_VERSION "${PROJECT_VERSION}")
set(PACKAGE_BUGREPORT "libcoap-developers@lists.sourceforge.net")
set(LIBCOAP_PACKAGE_VERSION "${PACKAGE_VERSION}")
set(LIBCOAP_PACKAGE_URL "${PACKAGE_URL}")
set(LIBCOAP_PACKAGE_NAME "${PACKAGE_NAME}")
set(LIBCOAP_PACKAGE_STRING "${PACKAGE_STRING}")
set(LIBCOAP_PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}")
message(STATUS "")
message(STATUS "libcoap Configuration Summary:")
message(STATUS "")
message(STATUS "PACKAGE VERSION..................${PACKAGE_VERSION}")
message(STATUS "PACKAGE SOURCE...................${LIBCOAP_PACKAGE_BUILD}")
message(STATUS "LIBRARY API VERSION..............${LIBCOAP_API_VERSION}")
message(STATUS "LIBRARY ABI VERSION..............${LIBCOAP_ABI_VERSION}")
message(STATUS "ENABLE_DTLS:.....................${ENABLE_DTLS}")
message(STATUS "ENABLE_TCP:......................${ENABLE_TCP}")
message(STATUS "ENABLE_IPV4:.....................${ENABLE_IPV4}")
message(STATUS "ENABLE_IPV6:.....................${ENABLE_IPV6}")
message(STATUS "ENABLE_AF_UNIX:..................${ENABLE_AF_UNIX}")
message(STATUS "ENABLE_WEBSOCKETS:...............${ENABLE_WS}")
message(STATUS "ENABLE_Q_BLOCK:..................${ENABLE_Q_BLOCK}")
message(STATUS "ENABLE_CLIENT_MODE:..............${ENABLE_CLIENT_MODE}")
message(STATUS "ENABLE_SERVER_MODE:..............${ENABLE_SERVER_MODE}")
message(STATUS "ENABLE_OSCORE:...................${ENABLE_OSCORE}")
message(STATUS "ENABLE_ASYNC:....................${ENABLE_ASYNC}")
message(STATUS "ENABLE_DOCS:.....................${ENABLE_DOCS}")
message(STATUS "ENABLE_EXAMPLES:.................${ENABLE_EXAMPLES}")
message(STATUS "DTLS_BACKEND:....................${DTLS_BACKEND}")
message(STATUS "WITH_GNUTLS:.....................${WITH_GNUTLS}")
message(STATUS "WITH_TINYDTLS:...................${WITH_TINYDTLS}")
message(STATUS "WITH_OPENSSL:....................${WITH_OPENSSL}")
message(STATUS "WITH_MBEDTLS:....................${WITH_MBEDTLS}")
message(STATUS "HAVE_LIBTINYDTLS:................${COAP_WITH_LIBTINYDTLS}")
message(STATUS "HAVE_LIBGNUTLS:..................${COAP_WITH_LIBGNUTLS}")
message(STATUS "HAVE_LIBOPENSSL:.................${COAP_WITH_LIBOPENSSL}")
message(STATUS "HAVE_LIBMBEDTLS:.................${COAP_WITH_LIBMBEDTLS}")
message(STATUS "WITH_EPOLL:......................${WITH_EPOLL}")
message(STATUS "WITH_OBSERVE_PERSIST:............${WITH_OBSERVE_PERSIST}")
message(STATUS "BUILD_SHARED_LIBS:...............${BUILD_SHARED_LIBS}")
message(STATUS "MAX_LOGGING_LEVEL:...............${MAX_LOGGING_LEVEL}")
message(STATUS "WARNING_TO_ERROR:................${WARNING_TO_ERROR}")
message(STATUS "CMAKE_C_COMPILER:................${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_CXX_COMPILER_ID:...........${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMAKE_BUILD_TYPE:................${CMAKE_BUILD_TYPE}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR:..........${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "CMAKE_HOST_SYSTEM_NAME:..........${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "CMAKE_GENERATOR:.................${CMAKE_GENERATOR}")
message(STATUS "")
set(top_srcdir "${CMAKE_CURRENT_LIST_DIR}")
set(top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
if(ENABLE_TCP)
set(COAP_DISABLE_TCP 0)
else(ENABLE_TCP)
set(COAP_DISABLE_TCP 1)
endif(ENABLE_TCP)
# creates config header file in build directory
configure_file(${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/coap${LIBCOAP_API_VERSION}/coap.h)
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake_coap_config.h.in
${CMAKE_CURRENT_BINARY_DIR}/coap_config.h)
configure_file(${CMAKE_CURRENT_LIST_DIR}/tests/test_common.h.in
${CMAKE_CURRENT_LIST_DIR}/tests/test_common.h)
#
# sources
#
target_sources(
${COAP_LIBRARY_NAME}
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/coap_address.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_asn1.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_async.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_block.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_cache.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_debug.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_dtls.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_encode.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_event.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_hashkey.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_io.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_layers.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_mem.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_net.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_netif.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_notls.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_option.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_oscore.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_pdu.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_prng.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_resource.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_session.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_str.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_subscribe.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_tcp.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_time.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_uri.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_ws.c
# no need to parse those files if we do not need them
$<$<BOOL:${COAP_WITH_LIBOPENSSL}>:${CMAKE_CURRENT_LIST_DIR}/src/coap_openssl.c>
$<$<BOOL:${COAP_WITH_LIBTINYDTLS}>:${CMAKE_CURRENT_LIST_DIR}/src/coap_tinydtls.c>
$<$<BOOL:${COAP_WITH_LIBGNUTLS}>:${CMAKE_CURRENT_LIST_DIR}/src/coap_gnutls.c>
$<$<BOOL:${COAP_WITH_LIBMBEDTLS}>:${CMAKE_CURRENT_LIST_DIR}/src/coap_mbedtls.c>
# needed for OSCORE is enabled
$<$<BOOL:${COAP_OSCORE_SUPPORT}>:${CMAKE_CURRENT_LIST_DIR}/src/oscore/oscore.c>
$<$<BOOL:${COAP_OSCORE_SUPPORT}>:${CMAKE_CURRENT_LIST_DIR}/src/oscore/oscore_cbor.c>
$<$<BOOL:${COAP_OSCORE_SUPPORT}>:${CMAKE_CURRENT_LIST_DIR}/src/oscore/oscore_context.c>
$<$<BOOL:${COAP_OSCORE_SUPPORT}>:${CMAKE_CURRENT_LIST_DIR}/src/oscore/oscore_cose.c>
$<$<BOOL:${COAP_OSCORE_SUPPORT}>:${CMAKE_CURRENT_LIST_DIR}/src/oscore/oscore_crypto.c>
# headers
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/libcoap.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_address.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_async.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_block.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_cache.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_debug.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_dtls.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_encode.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_event.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_io.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_mem.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_net.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_option.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_pdu.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_prng.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_resource.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_session.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_str.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_subscribe.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_time.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_uri.h
${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}/coap_ws.h)
target_include_directories(
${COAP_LIBRARY_NAME}
PUBLIC # config headers are generated during configuration time
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/>
$<INSTALL_INTERFACE:include/>
$<$<AND:$<BOOL:${COAP_WITH_LIBTINYDTLS}>,$<BOOL:${USE_VENDORED_TINYDTLS}>>:${CMAKE_BINARY_DIR}/include/tinydtls>
$<$<BOOL:${COAP_WITH_LIBGNUTLS}>:${GNUTLS_INCLUDE_DIR}>
$<$<BOOL:${COAP_WITH_LIBMBEDTLS}>:${MBEDTLS_INCLUDE_DIRS}>)
target_link_libraries(
${COAP_LIBRARY_NAME}
PUBLIC $<$<BOOL:${COAP_WITH_LIBOPENSSL}>:OpenSSL::SSL>
$<$<BOOL:${COAP_WITH_LIBOPENSSL}>:OpenSSL::Crypto>
$<$<BOOL:${COAP_WITH_LIBGNUTLS}>:${GNUTLS_LIBRARIES}>
$<$<BOOL:${COAP_WITH_LIBTINYDTLS}>:tinydtls>
$<$<BOOL:${COAP_WITH_LIBMBEDTLS}>:${MBEDTLS_LIBRARY}>
$<$<BOOL:${COAP_WITH_LIBMBEDTLS}>:${MBEDX509_LIBRARY}>
$<$<BOOL:${COAP_WITH_LIBMBEDTLS}>:${MBEDCRYPTO_LIBRARY}>
$<$<BOOL:${MINGW}>:ws2_32>)
target_compile_options(
${COAP_LIBRARY_NAME}
PUBLIC -DLIBCOAP_PACKAGE_BUILD="${LIBCOAP_PACKAGE_BUILD}")
add_library(
${PROJECT_NAME}::${COAP_LIBRARY_NAME}
ALIAS
${COAP_LIBRARY_NAME})
#
# tests
#
if(ENABLE_TESTS)
add_executable(
testdriver
${CMAKE_CURRENT_LIST_DIR}/tests/testdriver.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_common.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_encode.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_encode.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_error_response.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_error_response.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_options.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_options.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_oscore.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_oscore.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_pdu.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_pdu.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_sendqueue.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_sendqueue.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_session.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_session.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_tls.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_tls.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_uri.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_uri.h
${CMAKE_CURRENT_LIST_DIR}/tests/test_wellknown.c
${CMAKE_CURRENT_LIST_DIR}/tests/test_wellknown.h)
# tests require libcunit (e.g. debian libcunit1-dev)
target_link_libraries(testdriver PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME}
-lcunit)
endif()
#
# examples
#
if(ENABLE_EXAMPLES)
add_executable(coap-client ${CMAKE_CURRENT_LIST_DIR}/examples/coap-client.c)
target_link_libraries(coap-client
PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME})
add_executable(coap-rd ${CMAKE_CURRENT_LIST_DIR}/examples/coap-rd.c)
target_include_directories(coap-rd
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/coap${LIBCOAP_API_VERSION}>)
target_link_libraries(coap-rd PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME})
add_executable(coap-server ${CMAKE_CURRENT_LIST_DIR}/examples/coap-server.c)
target_link_libraries(coap-server
PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME})
if(NOT WIN32 AND NOT MINGW)
add_executable(etsi_iot_01 ${CMAKE_CURRENT_LIST_DIR}/examples/etsi_iot_01.c)
target_link_libraries(etsi_iot_01
PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME})
add_executable(tiny ${CMAKE_CURRENT_LIST_DIR}/examples/tiny.c)
target_link_libraries(tiny PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME})
add_executable(oscore-interop-server
${CMAKE_CURRENT_LIST_DIR}/examples/oscore-interop-server.c)
target_link_libraries(oscore-interop-server
PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME})
endif()
endif()
#
# docs
#
if(ENABLE_DOCS)
find_package(Doxygen)
if(Doxygen_FOUND)
# set input and output files
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
# Make necessary temporary directories
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/man_tmp)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/man_html)
# request to configure the file
configure_file(
${DOXYGEN_IN}
${DOXYGEN_OUT}
@ONLY)
# note the option ALL which allows to build the docs together with the
# application
add_custom_target(
doc_doxygen ALL
COMMAND ${DOXYGEN_EXECUTABLE} -u > /dev/null 2>&1
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
message(STATUS "Setup up the Doxygen documention build")
else(Doxygen_FOUND)
message(
WARNING
"Doxygen need to be installed to generate the doxygen documentation")
endif(Doxygen_FOUND)
endif()
#
# install
#
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
set(LIBCOAP_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
install(
TARGETS ${COAP_LIBRARY_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${LIBCOAP_CONFIG_INSTALL_DIR}
NAMESPACE ${PROJECT_NAME}::
COMPONENT dev)
configure_package_config_file(
cmake/Config.cmake.in
${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION
${LIBCOAP_CONFIG_INSTALL_DIR})
write_basic_package_version_file(
${PROJECT_NAME}ConfigVersion.cmake
COMPATIBILITY SameMajorVersion)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION ${LIBCOAP_CONFIG_INSTALL_DIR}
COMPONENT dev)
install(
DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT dev
FILES_MATCHING
PATTERN "*.h"
PATTERN "coap.h" EXCLUDE
PATTERN "coap_riot.h" EXCLUDE
PATTERN "*_internal.h" EXCLUDE
PATTERN "oscore*" EXCLUDE)
install(
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT dev
FILES_MATCHING
PATTERN "*.h")
if(ENABLE_EXAMPLES)
install(
TARGETS coap-server coap-client coap-rd
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT dev)
if(NOT WIN32 AND NOT MINGW)
install(
TARGETS etsi_iot_01 tiny oscore-interop-server
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT dev)
endif()
endif()
+263
View File
@@ -0,0 +1,263 @@
#######################################################
# Developer information for contributing to libcoap #
#######################################################
1. The basics
~~~~~~~~~~~~~
The libcoap project is a FOSS project that is dual licensed. The maintainer
for the libcoap is Olaf Bergmann <bergmann@tzi.org>.
Any contributions have to be made under the terms of the
license
* BSD 2-Clause (The BSD 2-Clause License)
Contributions made up to 2017-06-01 have been made under the dual
license model BSD 2-Clause and GPL v2+ (The GNU General Public License
2.0 or later).
The used VCS for libcoap is Git, the main repository is living on GitHub.
You can clone (or fork directly on GitHub) on the repository site:
https://github.com/obgm/libcoap
Please refer also to the libcoap website for additional information
https://libcoap.net/
The build environment is grounded on the classical autotools or CMake, the
GNU GCC and the LLVM C-compiler (CLang) are supported. The Windows VS build
systems are supported.
Doxygen is used for creating a HTML based online documentation of the
libcoap library.
2. Communications
~~~~~~~~~~~~~~~~~
The main discussion and development platform for libcoap is the mailing list
on Sourceforge.
No matter if you just have a simple question, some specific problem or
want to discuss some patches, please write it to the mailing list. Please
avoid personal mailings to the maintainer (or some other contributor) if
your questions will probably be in the interest of other users too.
You can subscribe to the list here:
https://lists.sourceforge.net/lists/listinfo/libcoap-developers
The archive of the list can be found on:
https://sourceforge.net/p/libcoap/mailman/libcoap-developers
Alternatively, Issues can be raised at https://github.com/obgm/libcoap/issues
3. Starting contributing
~~~~~~~~~~~~~~~~~~~~~~~~
As written above, libcoap is maintained with the Git tools so you should be
familiar with the various git commands.
The libcoap project is using just two main branches, the 'main' branch is
holding the point releases, all the development process is going on in the
'develop' branch.
To start any contributing you first have to clone the git tree from the main
repository on GitHub:
git clone https://github.com/obgm/libcoap.git
4. Working on the source
~~~~~~~~~~~~~~~~~~~~~~~~
As one golden rule you should work on improvements within *your* own local
development branch! To do so you have to first checkout the 'develop' branch
as local branch and then start on top on this branch your own branch. So
create (or better say checkout) the local 'develop' branch:
cd libcoap
git checkout develop origin/develop
Now you can simply start your own local branch (for example 'my-develop')
with the 'origin/develop' as parent so you can later create the patches
against the the upstream development branch:
git checkout -b my-develop
At this point you can now work with git, modify the source, commit
the changes, amend if needed and test your work.
At some point you will have to generate patches to post them on the mailing
list (and/or push your changes into your public Git tree). Multiple commits
for your branch should be squash'ed into a single commit. This can be done
one of two ways.
Way One: Push your changes to the github repository.
git push origin my-develop
Then go to https://github.com/obgm/libcoap/pulls and create your pull request
for others to review. If changes are needed, then commit and squash changes
and push the (forced) changes again.
git push -f origin my-develop
Way Two: Post your patch series on the mailing list so other contributors
will see your work and give further suggestions or discuss your work.
To be able to send a patch series you will now create the series itself as
single patches, this will be going easy with the 'git format-patch' command
against the 'develop' branch, remember this is the upstream primary
development branch.
To not mix up your series with probably unrelated patches let git place the
patches within a defined directory. Also, while create the patches, tell git to
create a cover letter patch so you can append some introducing words that will
hold probably explanations why you create the patches in the way you have done.
git format-patch --cover-letter -o ../patches4libcoap
This command will create a patch series in ../patches4libcoap where you find a
patch named '0000-cover-letter.patch'. Please modify this patch with some
useful information's for the mailing list. After finish this you now can send
your patches to libcoap-developers@lists.sourceforge.net
git send-email ../patches4libcoap/* --to=libcoap-developers@lists.sourceforge.net
5. Coding rules
~~~~~~~~~~~~~~~
As every FOSS project the libcoap project needs also some rules for coding.
There are lots but the main ones following are important!
5.1 pre-commit
--------------
pre-commit is used to check the the syntax of *.c and *.h files according to
the libcoap coding rules. The files are checked on github for every 'git push',
and can be locally checked if pre-commit is installed for every 'git commit'.
$ cd libcoap
$ pip install pre-commit
$ pre-commit install --allow-missing-config
5.2 License and Copyright
-------------------------
Every new file must contain a license and the copyright holder(s). Please
take a look into existing files and adopt the needed changes to your new
file(s).
5.3 Source Code Indentation
---------------------------
* For better reading the indentation is set to 2 characters as spaces, this
is depended on the often used nested functions like 'if-else'. Don't use
TABs any where (apart from Makefile's indenting where TABs are mandatory)!
Avoid trailing white spaces at the end of a line.
It's appropriate to set up a modline like this one at first line within
the source file:
--8<----
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
--->8--
* For functions defined in *.h files, the function return type should be
defined on the same line as the function name declaration. For functions
defined in *.c files, the function return type should be defined on the
previous line (for both declarations and implementations).
* Single lines within the source code should not be longer then 78
characters.
* If there are functions with a lot of parameters that do not fit into the above
rule split the declaration (in the *.h) and the implementation (in the *.c)
into single lines per parameter. Each parameter should be aligned with the
first defined parameter. For example like this (from src/coap_block.c):
--8<----
int
coap_add_block(coap_pdu_t *pdu,
unsigned int len,
const unsigned char *data,
unsigned int block_num,
unsigned char block_szx) {
--->8--
5.4 Source Code Documentation
-----------------------------
* A useful source code documentation is mandatory. Mostly to be done within the
source code files, but more complex description should be done in extra
README files.
* Please set up/adjust the doxygen documentation if you create new functions or
change existing functions. The doxygen documentation has to be done in the
header files as they are the public part of the libcoap and only use the
@-syntax for doxygen commands (akin to javadoc).
5.5 API Changes
---------------
* Never break the API!
Don't remove old functions and if there some changes are needed in some kind
always provide a wrapper for the old call to let the library be backward
compatible and mark the old function as @deprecated in the doxygen comment.
Please discuss needed changes on the mailing list.
5.6 Patches and Commits
-----------------------
* Git commits must be atomic and contain a declarative subject line (max 50
characters if possible) and a body for a statement if needed.
Use the opportunity to write a good explanation why your patch/commit is to
handle the changes in the way you have done. Remember that other users can
read your code but not necessary understand why the code is written this
way. Don't use something to generic like "bugfix commit".
* A patch/commit or a series of patches/commits have to ensure that the
whole project is able to build up every thing, in short: Do not break
any make target and test your work.
* Every patch/commit should handle one single logical change. If more than
one patch/commit is needed for a change explain it, respect the point
above. If your subject line become much larger than 50 characters then
typically your patch is to big for one single commit.
* Commit message should begin with a submodule or unit the commit is for.
Doing this in your commit message helps to find thematic other changes. If
you have to search and find something with 'git log | grep [foo]' you will
see why this is useful. Examples:
rd.c: Fixed type-specifier warning
Makefile.am: Added missing src/coap_address.c
address.[hc]: make coap_address_equals() not inline on POSIX
6. Where to start contributing?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are various things you could starting on to contribute, the best
is you simply pick up an issue you can easily see and just improve the
situation. Please take also a look into the file TODO and choose a point
from there or point the maintainer to add other things here too.
* Documentation
We always need better documentation on the source code, as well as improving
the doxygen documentation in the header files. Updating the man pages for
missing functions helps.
Also updated documentation on the usage of the libcoap and the example
binaries is always useful. So we appreciate any help on this.
* Manual Pages for example binaries
Manual pages are provided for the example binaries which have become more
complex over time with a variety of configuration options. It is possible
to work out how to use particular application functionality by reading the
examples source code. Improving documentation for usage would be useful.
* Manual Pages for public API
As well as the doxygen documentation, manual pages are being written for the
public licoap API where functions are defined, what the parameters mean as
well as providing simple coding examples. These manual pages are also
embedded in the doxygen output, the latest copy of which can be seen at
https://libcoap.net/doc/reference/develop/
Updating these manual pages for the missing functions, correcting errors
or providing simple examples of function usage would be helpful.
* HowTo's
The libcoap library has now a lot of functions you can use.
Unfortunately there is no good user guide on how to use the libcoap in
any external project. This means there is no HowTo or CheatSheet for a
programming person available. Do you want to write up something?
* Missing functionality
There are some features that are still missing inside the libcoap. For
example some DTLS implementations and proxy functionality.
+6
View File
@@ -0,0 +1,6 @@
libcoap is published as open-source software without any warranty of any kind.
Use is permitted under the terms of the simplified BSD 2-Clause license.
It includes public domain software. libcoap binaries may also
include open-source software with their respective licensing terms.
Please refer to LICENSE for further details.
+383
View File
@@ -0,0 +1,383 @@
2023-09-18 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.3.4:
* Clean up use of tags.
* Support for MacOS with Contiki-NG builds.
* Support for Windows with OpenSSL 3.x builds.
* Reported bugs fixed.
* Documentation updated.
2023-09-12 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.3.3:
* Fix ABI version.
2023-07-13 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.3.2:
* Source files reformatted according to pre-commit rules.
* Support for RFC8613 (OSCORE).
* Support for RFC8974 (Extended Tokens).
* Support for RFC9177 (Q-Block).
* Support for latest RIOT code and new examples.
* Support for MinGW builds.
* Support for AF_UNIX sockets.
* Support for WebSockets (RFC8323).
* Support for IPv4 only and IPv6 only libcoap builds.
* Support for defining maximum logging level.
* Support for maintaining Observer requests over server restarts.
* Support for Contiki-NG.
* Support for latest LwIP, including using TinyDTLS.
* libcoap now has protocol layered support, separating out the
logical layers. Stack now is:-
- Application
- libcoap - CoAP
- libcoap - CoAP-Session
- libcoap - (D)TLS I/F using external (D)TLS Library
- libcoap - Netif
- libcoap - Sockets
- Kernel Network Stack
* Fixes CVE-2023-30362 and CVE-2023-35862.
* Reported bugs fixed.
* Examples now support separate logging levels for libcoap and (D)TLS.
* syslog LOG_ logging levels replaced with COAP_LOG_ logging levels.
* New public API functions to aid / reduce application coding.
* Remove requirement for applications to have sockaddr knowledge.
* Support for clients sending IPv4 broadcast requests.
* Documentation added and updated (Doxygen and man).
2022-08-17 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.3.1:
* Support for Server only and Client only libcoap builds.
* Add support for repeating requests in coap-client.
* Add in support for defining resources that support multicast.
* Add in more support for async delayed requests.
* Add in support for not closing down Observe when closing session.
* Support for RFC7390, RFC8516 and RFC9175.
* Warn when Tokens are re-used.
* Warn when Options are repeated that are not defined as being
repeatable.
* Support for TLS when using Mbed TLS library.
* Support for Mbed TLS 3.1
* Add in BERT support for block handling.
* More rigorous error handling for Block transfers.
* Support for using external or submodule TinyDTLS.
* Cmake - add in Apple build support.
* Source files renamed to be more consistent in naming.
* Update native Windows VC builds to use libcoap-3 instead of libcoap-2.
* Reported bugs fixed.
* Example applications Help report include build version.
* Documentation added and updated (Doxygen and man).
2021-05-04 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.3.0:
* Include directory updated from include/coap2 to include/coap3 as
this is a major version change.
* Other code references updated from coap2 to coap3.
* Examples now have the underlying (D)TLS library name as a suffix.
E.g. coap-server-openssl
* Examples and libraries can be installed with default names using
./configure --enable-add-default-names
* Many call-back handlers have had their parameter lists changed, some
variables are made const and other ones removed as they can be easily
reconstructed if needed.
* Some functions have their parameters changed to const.
* Internal structures made opaque to applications, requiring the
applications to access the structure information via a new set of
functions. The new functions are of the form coap_X_get_Y() or
coap_X_set_Y() where X is the structure (e.g. session) and Y is
the variable.
* coap_async_state_t
* coap_attr_t
* coap_context_t
* coap_packet_t
* coap_pdu_t
* coap_resource_t
* coap_session_t
* coap_socket_t
* Header files are moved into libcoap space and so are accessed by coap
sub-directory - e.g. #include <coap3/coap.h>.
* RFC7959 (Block handling) moved into libcoap from application code
considerably simplifying application code. See coap_block(3) man page.
* CoAP Cache Key support.
* Support for cmake builds.
* Support for RIOT builds.
* Support for Cygwin builds.
* Proxy support for coap-server, enhanced coap-client capabilities
* Updated async support.
* Multicast requests now randomly delayed before the response is
sent.
* Additional RFC support - RFC8768.
* Mbed TLS DTLS library support.
* (D)TLS support for RPK and PKCS11.
* Additional (D)TLS support for PSK (e.g. Identity Hints).
* PKI support consistent across all supported (D)TLS libraries.
* Support for disabling TCP for code reduction.
* More rigorous checking and appropriate rejection of inbound PDU
options.
* Additional unit tests.
* Reported bugs fixed.
* Example applications help reports on (D)TLS library capabilities
and versions.
* Documentation added and updated (Doxygen and man).
2019-11-05 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.2.1:
* Builds now support silent rules
* Support building with TinyDTLS as a shared library
* Added in EPOLL support
* Added in support for constrained stacks
* Server sessions hashed for performance lookup
* coap_endpoint_t and coap_subscription_t made opaque to applications
* Documentation updated
2019-02-11 Olaf Bergmann <bergmann@tzi.org>
Change summary for version 4.2.0:
* DTLS support improvements (OpenSSL, GnuTLS, tinydtls)
* Pre-shared keys, X.509 certificates
* new session abstraction
* TCP and TLS support
* improved documentation; manual pages
* changes in internal PDU structure
* improved examples (DTLS usage, block-wise transfer)
* docker images for continuous integration
* support for Google OSS fuzzer
* MS Visual Studio project for Windows builds
2017-07-10 Olaf Bergmann <bergmann@tzi.org>
* DTLS support (OpenSSL, tinyDTLS) by Jean-Claude Michelou
* Win32 support by Jean-Claude Michelou
* New Session API by Jean-Claude Michelou
2016-02-16 Olaf Bergmann <bergmann@tzi.org>
* Fixed build for Contiki3 and LwIP
* .travis.yml: Enabled continuous integration for platforms
POSIX and Contiki
2015-03-11 Olaf Bergmann <bergmann@tzi.org>
* include/coap/resource.h: Replaced custom list structures by
utlist macros.
2015-03-09 Olaf Bergmann <bergmann@tzi.org>
* src/uri.c (coap_split_path): Fixed URI parser bug and
removed broken parse iterator.
2015-03-05 Olaf Bergmann <bergmann@tzi.org>
* src/coap_time.c (coap_ticks): Changed POSIX implementation
to fixed point arithmetic and removed clock_offset.
2015-02-21 Olaf Bergmann <bergmann@tzi.org>
* net.c (coap_send_confirmed): Use fixed point arithmetic
to calculate retransmission timeout.
2015-02-20 Olaf Bergmann <bergmann@tzi.org>
* coap_list.[hc]: Moved old list implementation into
sub-directory examples and replaced by linked lists
from utlist.h. As a result, the list must be sorted
explicitly with LL_SORT).
2015-02-19 Olaf Bergmann <bergmann@tzi.org>
* net.c (coap_send_confirmed): Fixed retransmission timeout
calculation and renamed transmission parameters according to
Section 4.8 of RFC 7252.
2015-02-17 Olaf Bergmann <bergmann@tzi.org>
* major rework to get Contiki and lwip running
* many fixed bugs and warnings
2014-06-18 Olaf Bergmann <bergmann@tzi.org>
* mem.c (coap_malloc_type): New functions for allocating memory.
On POSIX systems, coap_malloc_type() and coap_free_type() are just
wrapper functions for malloc() and free(), while on Contiki and
LWIP distinct arrays are used for each type.
2014-03-09 Olaf Bergmann <bergmann@tzi.org>
* net.c (coap_cancel): Removed 7.31 again and implemented new
method for cancelling observe relationships.
2014-02-25 Olaf Bergmann <bergmann@tzi.org>
* net.c (coap_cancel): Handling of 7.31 responses to cancel
notifications (see Section 4.6 of draft-ietf-core-observe-12)
2014-02-04 Olaf Bergmann <bergmann@tzi.org>
* resource.c (coap_print_link): This function now takes an offset
where printing starts. This is used for generating blocks on the
fly.
* net.c (wellknown_response): Added support for Block2 options
when generating a response for .well-known/core.
* block.h (coap_opt_block_num): Fixed handling of zero-length
options. COAP_OPT_BLOCK_LAST now returns NULL when the option
value's length is zero.
2014-01-07 Olaf Bergmann <bergmann@tzi.org>
* resource.c (coap_print_link): Output partial resource
descriptions. The function now provides a sliding window over the
textual representation of the resource. Output starts at the given
offset and ends at the buffer's upper bound. The meaning of the
return value has changed to allow distinguishing whether or not
the resource description has been truncated at the buffer's upper
bound.
(print_wellknown): Support for the new coap_print_link(). An
additional parameter now is used to provide the offset into the
resource description. The meaning of the return value has been
adjusted accordingly.
2013-12-23 Olaf Bergmann <bergmann@tzi.org>
* configure.in: merged with LWIP port from chrysn
<https://git.gitorious.org/coap-lwip/coap-lwip.git>. This
introduces new compiler flags WITH_POSIX and WITH_LWIP to
distinguish target platforms.
2013-09-03 Olaf Bergmann <bergmann@tzi.org>
* option.h (coap_option_setb): increased size of option type
argument
* tests/test_error_response.c (t_init_error_response_tests): new
tests for error response generation
* tests/test_pdu.c (t_encode_pdu5): fixed number for option Accept
* net.c (coap_new_error_response): fixed option size calculation
2013-07-04 Olaf Bergmann <bergmann@tzi.org>
* net.c (coap_new_context): register critical Accept option
* pdu.c: option codes for Accept and Size1 according to coap-18
2013-02-01 Olaf Bergmann <bergmann@tzi.org>
* coap_time.h (coap_clock_init_impl): fix invalid preprocessor
directive. #warning is now only used for gcc only (close sf bug #15)
* net.c (wellknown_response): applied patch from chrysn to
fix bug in generation of .well-known/core representation
2013-01-21 Olaf Bergmann <bergmann@tzi.org>
* option.h: renamed option field in coap_opt_iterator_t to
next_option to detect erroneous use in old code
2013-01-18 Olaf Bergmann <bergmann@tzi.org>
* configure.in: new option --with-tests to enable unit tests
* tests/testdriver.c: unit tests for parser functions
* pdu.c (coap_pdu_parse): new PDU parser for Klaus-encoding
according to coap-13
* net.c (coap_read): call coap_pdu_parse() to check PDU integrity
* option.c: Klaus-encoding for coap-13, including new option
iterator interface
2012-11-20 Olaf Bergmann <bergmann@tzi.org>
* net.c (next_option_safe): made option parsing more robust in
presence of option jumps
* pdu.h: new option codes from draft-ietf-core-coap-12
* option.c (coap_opt_setlength): new function to set option length
* uri.c (make_decoded_option): use coap_opt_setlength() instead of
obsolete macro COAP_OPT_SETLENGTH.
2012-11-19 Olaf Bergmann <bergmann@tzi.org>
* uri.c (make_decoded_option): use coap_opt_encode() instead of writing
2012-11-03 Olaf Bergmann <bergmann@tzi.org>
* net.c (coap_read): read new option encoding
2012-11-01 Olaf Bergmann <bergmann@tzi.org>
* option.c (coap_opt_size, coap_opt_value, coap_opt_length):
several functions to access fields of options (possibly preceeded
by option jump)
2012-10-25 Olaf Bergmann <bergmann@tzi.org>
* option.c (coap_opt_encode): new function for option encoding
with option jumps
2012-03-23 Olaf Bergmann <bergmann@tzi.org>
* examples/client.c (clear_obs): clear observation relationship after
user-specified duration
2012-03-21 Olaf Bergmann <bergmann@tzi.org>
* resource.c (print_wellknown): filtering by attributes
2012-03-19 Olaf Bergmann <bergmann@tzi.org>
* pdu.c (coap_add_option): allow more than 15 options.
2012-03-15 Olaf Bergmann <bergmann@tzi.org>
* examples/client.c (cmdline_uri): split path and query here to
make it easier to include these options in subsequent requests for
block transfer.
2012-03-14 Olaf Bergmann <bergmann@tzi.org>
* examples/etsi_iot_01.c: Support for POST, PUT, DELETE on /test
2012-03-13 Olaf Bergmann <bergmann@tzi.org>
* encode.c (coap_encode_var_bytes): more efficient coding for 0
2012-03-11 Olaf Bergmann <bergmann@tzi.org>
* examples/etsi_iot_01.c: Test cases for 1st ETSI CoAP Plugtest,
March 24/25, 2012 in Paris, France.
2012-03-10 Olaf Bergmann <bergmann@tzi.org>
* block.c: support for block transfer.
2012-03-07 Olaf Bergmann <bergmann@tzi.org>
* examples/client.c (usage): new command line options
-B to set timeout after which the main loop is left.
-e to specify a payload (incompatible with -f)
(message_handler): bugfixes
* resource.h: (coap_method_handler_t): new API for method handlers.
Copyright 2012 Olaf Bergmann, TZI
Copying and distribution of this file, with or without modification, are
permitted provided the copyright notice and this notice are preserved.
+7
View File
@@ -0,0 +1,7 @@
FROM obgm/libcoap:build-env
ENV libcoap_dir=/libcoap
ADD . $libcoap_dir
WORKDIR $libcoap_dir
RUN ./autogen.sh --clean && ./autogen.sh
+98
View File
@@ -0,0 +1,98 @@
############################################################################
#
# GnuTLS dual versions
#
# Works with CentOS 7
#
############################################################################
#
# Add in alternative GnuTLS support into /usr/local, and put all the
# libraries into /usr/local/lib.
#
# Need the latest of the following packages
#
# gmp (used 6.2.0) https://gmplib.org/#DOWNLOAD
# nettle (used 3.6) https://ftp.gnu.org/gnu/nettle/
# gnutls (used 3.6.13) https://www.gnutls.org/download.html
#
GMP_VER=6.2.0
NETTLE_VER=3.6
GNUTLS_VER=3.6.13
#
# gmp
#
tar xovf gmp-${GMP_VER}.tar.xz
cd gmp-${GMP_VER}
./configure
make
sudo make install
cd ..
#
# nettle (by default wants to go into /usr/local/lib64 which gets messy)
#
tar zxovf nettle-${NETTLE_VER}.tar.gz
cd nettle-${NETTLE_VER}
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --libdir=/usr/local/lib \
LDFLAGS="-L/usr/local/lib"
make
sudo make install
cd ..
tar xovf gnutls-${GNUTLS_VER}.tar.xz
cd gnutls-${GNUTLS_VER}
#
#
# You may need to make the following change if you have an old version of
# p11-kit
#
# $ diff -Nau a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
# --- a/lib/pkcs11_privkey.c 2020-05-26 11:49:27.374385645 +0100
# +++ b/lib/pkcs11_privkey.c 2020-05-26 11:58:24.300510455 +0100
# @@ -265,13 +265,13 @@
# # define CKG_MGF1_SHA384 0x00000003UL
# # define CKG_MGF1_SHA512 0x00000004UL
#
# +#endif
# struct ck_rsa_pkcs_pss_params {
# ck_mechanism_type_t hash_alg;
# /* ck_rsa_pkcs_mgf_type_t is not defined in old versions of p11-kit */
# unsigned long mgf;
# unsigned long s_len;
# };
# -#endif
#
# static const struct hash_mappings_st hash_mappings[] =
# {
#
#
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --with-included-unistring \
--disable-hardware-acceleration --disable-tests --with-included-libtasn1 \
--disable-doc LDFLAGS="-L/usr/local/lib"
make
sudo make install
cd ..
############################################################################
#
# libcoap build with updated GnuTLS
#
############################################################################
# Get the latest libcoap
git clone https://github.com/obgm/libcoap.git
# Build code
cd libcoap
./autogen.sh
# Update --enable- / --disable- options as appropriate
# libcoap libraries are put into /usr/lib64 for ease of linking
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --libdir=/usr/lib64 \
--with-gnutls --enable-tests --enable-examples --disable-doxygen \
--enable-manpages
make
sudo make install
cd ..
+50
View File
@@ -0,0 +1,50 @@
############################################################################
#
# OpenSSL dual versions
#
# Works with CentOS 7
#
############################################################################
#
# Add in alternative OpenSSL support into /opt/openssl. /opt/openssl is
# chosen instead of the default of /usr/local so that existing utilities
# continue to use the original version of OpenSSL and so only specific
# applications that requires the newer version of OpenSSL will pick up the
# new code.
#
# Download latest stable version of openssl.X.Y.Z.tar.gz from
# https://www.openssl.org/source/
tar zxovf openssl.X.Y.Z.tar.gz
cd openssl.X.Y.X
./config --prefix=/opt/openssl --openssldir=/opt/openssl
make
sudo make install_sw
# The following should not clash the existing OpenSSL lib*.so.1.0 usage unless
# the previous OpenSSL version is 1.1.0 or later.
# It just makes things for running executables a lot simpler.
sudo cp /opt/openssl/lib/lib*.so.1.1 /lib64
cd ..
############################################################################
#
# libcoap build with updated OpenSSL
#
############################################################################
# Get the latest libcoap
git clone https://github.com/obgm/libcoap.git
# Build code
cd libcoap
./autogen.sh
# Update --enable- / --disable- options as appropriate
# libcoap libraries are put into /usr/lib64 for ease of linking
PKG_CONFIG_PATH=/opt/openssl/lib/pkgconfig ./configure --libdir=/usr/lib64 \
--with-openssl --enable-tests --enable-examples --disable-doxygen \
--disable-manpages
make
sudo make install
cd ..
+90
View File
@@ -0,0 +1,90 @@
############################################################################
#
# SoftHSMv2 dual versions
#
# Works with CentOS 7
#
# The opensc package needs to be installed.
#
############################################################################
#
# Install a software HSM module for doing the PKCS11 testing of libcoap.
# Real hardware can be used if you have the appropriate library module.
#
# It is assumed that the opensc package is installed.
#
# When installing SoftHSMv2 from your system's package manager, check that the
# OpenSSL version is at least 1.1.0. If not, then you will need to dual
# install SoftHSMv2 as below; otherwise you can use the existing SoftHSMv2.
#
# SoftHSMv2 is built using OpenSSL, but GnuTLS can use the PKCS11 interface.
# Note that if the default OpenSSL version is less than 1.1.0, you will need
# to install a dual stack version of OpenSSL as per HOWTO.dual.openssl.
#
# Creates module /usr/local/lib/softhsm/libsofthsm2.so
#
# Add line below to /etc/security/limits.conf to support memory locking
* - memlock unlimited
# Get the latest SoftHSM
git clone https://github.com/opendnssec/SoftHSMv2.git
# Build code
cd SoftHSMv2/
sh autogen.sh
PKG_CONFIG_PATH=/opt/openssl/lib/pkgconfig ./configure --enable-silent-rules \
--with-crypto-backend=openssl --disable-gost LDFLAGS=-L/opt/openssl/lib \
CPPFLAGS=-I/opt/openssl/include --with-openssl=/opt/openssl
make
# You may need to comment out constexpr lines (fixes for gcc10) in
# src/lib/crypto/PublicKey.h src/lib/crypto/PrivateKey.h if you get
# compile errors.
sudo make install
cd ..
# Make sure p11-kit softhsm modules have the correct module: fully qualified
# path where the entry is of the form (in particular for GnuTLS) :-
# /usr/share/p11-kit/modules/softhsm*
#
# module: /usr/local/lib/softhsm/libsofthsm2.so
# The user you are running this as needs to be in the group defined for
# /var/lib/softhsm/tokens/. E.g.
# $ sudo ls -ld /var/lib/softhsm/tokens/
# drwxrws--- 3 root softhsm 4096 May 3 09:52 /var/lib/softhsm/tokens/
# which is softhsm in this case (It could be ods). To verify if you are in
# the correct group
# $ id
# To add user to this group
# $ sudo usermod -a -G softhsm <user>
# and log out and back in again.
#
############################################################################
#
# libp11 (needed for OpenSSL as it provides the PKCS11 engine)
#
############################################################################
#
# Install a pkcs11 library for OpenSSL to use as an engine.
# [GnuTLS has this built in]
#
# Get the latest libp11
git clone https://github.com/OpenSC/libp11.git
# Build code
cd libp11
./bootstrap
PKG_CONFIG_PATH=/opt/openssl/lib/pkgconfig ./configure \
--with-pkcs11-module=/usr/local/lib/softhsm/libsofthsm2.so
make
sudo make install
cd ..
# Verify that pkcs11 is available
/opt/openssl/bin/openssl engine pkcs11 -t
+129
View File
@@ -0,0 +1,129 @@
#
# Using PKCS11 with libcoap.
#
# This HOWTO works for CentOS 7.
#
# As CentOS 7 uses OpenSSL prior to 1.1.0, dual OpenSSL support needs to be
# set up and used for libcoap. See HOWTO.dual.openssl for setting this up.
#
# It also is possible that you want to use GnuTLS - and want to use a later
# version. HOWTO.dual.gnutls for setting this up.
#
# OpenSSL and GnuTLS are currently supported
#
############################################################################
#
# Testing examples
#
############################################################################
#
# Update PKCS11 token with certificates and keys
#
# Assumption is that you already have the following PEM files
# ca-cert.pem - The certificate of the CA that signed Server and Client
# server-cert.pem - Contains the server certificate in PEM format
# server-key.pem - Contains the server private key in PEM format
# client-cert.pem - Contains the server certificate in PEM format
# client-key.pem - Contains the server private key in PEM format
#
# Tokens will be stored under /var/lib/softhsm/tokens/
#
# The user you are running this as needs to be in the group defined for
# /var/lib/softhsm/tokens/. E.g.
# $ sudo ls -ld /var/lib/softhsm/tokens/
# drwxrws--- 3 root softhsm 4096 May 3 09:52 /var/lib/softhsm/tokens/
# which is softhsm in this case (It could be ods). To verify if you are in
# the correct group
# $ id
# To add user to this group
# $ sudo usermod -a -G softhsm <user>
# and log out and back in again.
#
# Set libsofthsm2.so to use (may be /usr/lib/softhsm/libsofthsm2.so)
LIBSOFTHSM=/usr/local/lib/softhsm/libsofthsm2.so
# Initialize Soft HSM token
# Note: slot 0 is re-allocated to slot XXX. This is presented as a decimal
# number, the hex equivalent (leading 0x) can be used for any slot options..
# Set SO PIN to 4321, user PIN to 1234
softhsm2-util --init-token --slot 0 --label "token-0" --pin 1234 --so-pin 4321
# CA Certificate (different id to Server/Client Public Certificate)
# (GnuTLS requires this to be trusted)
p11tool --so-login --load-certificate ca-cert.pem --write --label ca-cert \
--set-so-pin 4321 --id cc00 --mark-trusted "pkcs11:token=token-0"
# Server Private Key
openssl pkcs8 -topk8 -inform PEM -outform PEM -in server-key.pem \
-out server-key.pk8 -nocrypt
softhsm2-util --import server-key.pk8 --label "server-key" --id aa00 \
--pin 1234 --token "token-0"
# Server Public Certificate
# (Use different id to private key, but not the same as CA/Client cert)
openssl x509 -in server-cert.pem -out server-cert.der -outform DER
pkcs11-tool --module $LIBSOFTHSM --pin 1234 \
--write-object ./server-cert.der --type cert --id aa01 \
--label "server-cert" --token-label "token-0"
# Client Private Key
openssl pkcs8 -topk8 -inform PEM -outform PEM -in client-key.pem \
-out client-key.pk8 -nocrypt
softhsm2-util --import client-key.pk8 --label "client-key" --id bb00 \
--pin 1234 --token "token-0"
# Client Public Certificate
# (Use different id to private key, but not the same as CA/Client cert)
openssl x509 -in client-cert.pem -out client-cert.der -outform DER
pkcs11-tool --module $LIBSOFTHSM --pin 1234 \
--write-object ./client-cert.der --type cert --id bb01 \
--label "client-cert" --token-label "token-0"
# Verify token is correctly populated
pkcs11-tool --module=$LIBSOFTHSM -t
pkcs11-tool --module=$LIBSOFTHSM --list-objects \
--pin 1234 --token-label "token-0"
p11tool --list-all pkcs11:model=SoftHSM%20v2
#
# Run coap-server using PKCS11 (-C option may need to be -C cert.der)
#
coap-server -C 'pkcs11:token=token-0;id=%cc%00?pin-value=1234' \
-c 'pkcs11:token=token-0;id=%aa%01?pin-value=1234' \
-j 'pkcs11:token=token-0;id=%aa%00?pin-value=1234' -v9
# or
coap-server -C 'pkcs11:token=token-0;id=%cc%00' \
-c 'pkcs11:token=token-0;id=%aa%01' \
-j 'pkcs11:token=token-0;id=%aa%00' -J 1234 -v9
# or
coap-server -C 'pkcs11:token=token-0;object=ca-cert' \
-c 'pkcs11:token=token-0;object=server-cert' \
-j 'pkcs11:token=token-0;object=server-key' -J 1234 -v9
#
# Run coap-client using PKCS11 (-C option may need to be -C cert.der)
#
coap-client -C 'pkcs11:token=token-0;id=%cc%00?pin-value=1234' \
-c 'pkcs11:token=token-0;id=%bb%01?pin-value=1234' \
-j 'pkcs11:token=token-0;id=%bb%00?pin-value=1234' -v9 coaps://[::1]
# or
coap-client -C 'pkcs11:token=token-0;id=%cc%00' \
-c 'pkcs11:token=token-0;id=%bb%01' \
-j 'pkcs11:token=token-0;id=%bb%00' -J 1234 -v9 coaps://[::1]
# or
coap-client -C 'pkcs11:token=token-0;object=ca-cert' \
-c 'pkcs11:token=token-0;object=client-cert' \
-j 'pkcs11:token=token-0;object=client-key' -J 1234 -v9 coaps://[::1]
#
# Client and Server using RPK (GnuTLS only)
#
coap-server -M 'pkcs11:token=token-0;object=server-key' -J 1234 -v9
# and
coap-client -M 'pkcs11:token=token-0;object=client-key' -J 1234 -v9 coaps://[::1]
+124
View File
@@ -0,0 +1,124 @@
Copyright (c) 2010--2023, Olaf Bergmann and others
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
========================================================================
getopt.c
License information for getopt.c. This file is only used on Windows
builds of the executables in the examples folder:
/*
* This file was copied from the following newsgroup posting:
*
* Newsgroups: mod.std.unix
* Subject: public domain AT&T getopt source
* Date: 3 Nov 85 19:34:15 GMT
*
* Here's something you've all been waiting for: the AT&T public domain
* source for getopt(3). It is the code which was given out at the 1985
* UNIFORUM conference in Dallas. I obtained it by electronic mail
* directly from AT&T. The people there assure me that it is indeed
* in the public domain.
*/
========================================================================
uthash
libcoap uses uthash.h and utlist.h from Troy D. Hanson
(https://troydhanson.github.io/uthash/). These files use the revised
BSD license (BSD-1-Clause license) as included in these two source
files. These files are named coap_uthash_internal.h and
coap_utlist_internal.h respectively to make sure the correct versions
are included.
========================================================================
oscore cose
Copyright (c) 2018, SICS, RISE AB
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Institute nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
========================================================================
OpenSSL
Binaries that are linked against OpenSSL include software developed
by the OpenSSL Project for use in the OpenSSL Toolkit.
(http://www.openssl.org/). Please consult the OpenSSL license
(https://www.openssl.org/source/license.html) for licensing terms.
========================================================================
GnuTLS
When compiled with GnuTLS support, this software includes components
that are licensed under the terms of the the GNU Lesser General Public
License, version 2.1
(https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html).
========================================================================
tinyDTLS
When compiled with tinyDTLS support, this software includes components
that are licensed under the terms of the Eclipse Distribution License 1.0
(http://www.eclipse.org/org/documents/edl-v10.php).
========================================================================
Mbed TLS
When compiled with Mbed TLS support, this software includes components
that are licensed under the terms of the Apache 2.0 license
(http://www.apache.org/licenses/LICENSE-2.0).
========================================================================
RIOT
When compiled with RIOT support, this software includes components
that are licensed under the terms of the the GNU Lesser General Public
License, version 2.1
(https://raw.githubusercontent.com/RIOT-OS/RIOT/master/LICENSE).
+367
View File
@@ -0,0 +1,367 @@
# Makefile.am for libcoap
#
# Copyright (C) 2010-2023 Olaf Bergmann <bergmann@tzi.org>
# Copyright (C) 2015-2017 Carsten Schoenert <c.schoenert@t-online.de>
# Copyright (C) 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
#
# SPDX-License-Identifier: BSD-2-Clause
#
# This file is part of the CoAP C library libcoap. Please see README and
# COPYING for terms of use.
## Place generated object files (.o) into the same directory as their source
## files, in order to avoid collisions when non-recursive make is used.
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
LIBCOAP_PACKAGE_BUILD = @DOLLAR_SIGN@(shell git describe --tags --dirty --always 2>/dev/null || echo @PACKAGE_VERSION@)
## Source files specifically for OSCORE
libcoap_OSCORE_sources = \
src/oscore/oscore.c \
src/oscore/oscore_cbor.c \
src/oscore/oscore_context.c \
src/oscore/oscore_cose.c \
src/oscore/oscore_crypto.c
## Additional files for the distribution archive
EXTRA_DIST = \
BUILDING \
CONTRIBUTE \
TODO \
LICENSE \
CMakeLists.txt \
cmake_coap_config.h.in \
cmake/Config.cmake.in \
cmake/FindMbedTLS.cmake \
cmake/FindTinyDTLS.cmake \
coap_config.h.contiki \
coap_config.h.riot \
coap_config.h.windows \
libcoap-$(LIBCOAP_API_VERSION).pc.in \
libcoap-$(LIBCOAP_API_VERSION).map \
libcoap-$(LIBCOAP_API_VERSION).sym \
examples/coap_list.h \
examples/getopt.c \
examples/contiki/coap_config.h \
examples/contiki/Makefile \
examples/contiki/Makefile.contiki \
examples/contiki/project-conf.h \
examples/contiki/README \
examples/contiki/server.c \
examples/lwip/client.c \
examples/lwip/client-coap.c \
examples/lwip/client-coap.h \
examples/lwip/Makefile \
examples/lwip/README \
examples/lwip/server.c \
examples/lwip/server-coap.c \
examples/lwip/server-coap.h \
examples/lwip/config/coap_config.h \
examples/lwip/config/coap_config.h.in \
examples/lwip/config/lwipopts.h \
examples/lwip/config/lwippools.h \
examples/riot/examples_libcoap_client/client-coap.c \
examples/riot/examples_libcoap_client/client-coap.h \
examples/riot/examples_libcoap_client/Kconfig \
examples/riot/examples_libcoap_client/main.c \
examples/riot/examples_libcoap_client/Makefile \
examples/riot/examples_libcoap_client/Makefile.ci \
examples/riot/examples_libcoap_client/README.md \
examples/riot/examples_libcoap_server/main.c \
examples/riot/examples_libcoap_server/Makefile \
examples/riot/examples_libcoap_server/Makefile.ci \
examples/riot/examples_libcoap_server/README.md \
examples/riot/examples_libcoap_server/server-coap.c \
examples/riot/examples_libcoap_server/server-coap.h \
examples/riot/examples_libcoap_server/Kconfig \
examples/riot/Makefile \
examples/riot/pkg_libcoap/Kconfig \
examples/riot/pkg_libcoap/Makefile \
examples/riot/pkg_libcoap/Makefile.dep \
examples/riot/pkg_libcoap/Makefile.include \
examples/riot/pkg_libcoap/Makefile.libcoap \
examples/riot/README \
Makefile.libcoap \
include/coap$(LIBCOAP_API_VERSION)/coap_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_riot.h \
include/coap$(LIBCOAP_API_VERSION)/coap_asn1_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_async_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_block_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_cache_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_crypto_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_debug_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_dtls_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_hashkey_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_io_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_layers_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_mutex_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_net_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_netif_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_oscore_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_pdu_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_resource_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_session_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_subscribe_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_tcp_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_uri_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_uthash_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_utlist_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_ws_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap.h.in \
include/coap$(LIBCOAP_API_VERSION)/coap.h.riot \
include/coap$(LIBCOAP_API_VERSION)/coap.h.riot.in \
include/coap$(LIBCOAP_API_VERSION)/coap.h.windows \
include/coap$(LIBCOAP_API_VERSION)/coap.h.windows.in \
include/oscore/oscore_cbor.h \
include/oscore/oscore_context.h \
include/oscore/oscore_cose.h \
include/oscore/oscore_crypto.h \
include/oscore/oscore.h \
src/coap_io_contiki.c \
src/coap_io_lwip.c \
src/coap_io_riot.c \
tests/test_error_response.h \
tests/test_encode.h \
tests/test_options.h \
tests/test_oscore.h \
tests/test_pdu.h \
tests/test_sendqueue.h \
tests/test_session.h \
tests/test_tls.h \
tests/test_uri.h \
tests/test_wellknown.h \
win32/coap-client/coap-client.vcxproj \
win32/coap-client/coap-client.vcxproj.filters \
win32/coap-rd/coap-rd.vcxproj \
win32/coap-rd/coap-rd.vcxproj.filters \
win32/coap-server/coap-server.vcxproj \
win32/coap-server/coap-server.vcxproj.filters \
win32/libcoap.sln \
win32/libcoap.vcxproj \
win32/libcoap.vcxproj.filters \
win32/testdriver/testdriver.vcxproj \
win32/testdriver/testdriver.vcxproj.filters \
win32/testdriver/testdriver.vcxproj.user
# This is a mirror of files depending on COAP_OSCORE_SUPPORT included in src as per
# libcoap_@LIBCOAP_NAME_SUFFIX@_la_SOURCES
if !COAP_OSCORE_SUPPORT
EXTRA_DIST += $(libcoap_OSCORE_sources)
endif # !COAP_OSCORE_SUPPORT
AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include $(WARNING_CFLAGS) \
$(DTLS_CFLAGS) -std=c99 $(EXTRA_CFLAGS) \
-DLIBCOAP_PACKAGE_BUILD='"$(LIBCOAP_PACKAGE_BUILD)"'
SUBDIRS = $(subdirs) . man doc tests examples
## Define a libtool archive target "libcoap-@LIBCOAP_NAME_SUFFIX@.la", with
## @LIBCOAP_NAME_SUFFIX@ substituted into the generated Makefile at configure
## time.
## The libtool archive file (.la) will be installed into the directory named
## by the predefined variable $(bindir), along with the actual shared library
## file (.so).
lib_LTLIBRARIES = libcoap-@LIBCOAP_NAME_SUFFIX@.la
libcoap_@LIBCOAP_NAME_SUFFIX@_la_CFLAGS = \
-fPIC \
-fPIE \
$(AM_CFLAGS)
## Define the source file list for the "libcoap.la" target.
## Note that it is not necessary to list header files which are already listed
## elsewhere in a _HEADERS variable assignment.
libcoap_@LIBCOAP_NAME_SUFFIX@_la_SOURCES = \
src/coap_address.c \
src/coap_asn1.c \
src/coap_async.c \
src/coap_block.c \
src/coap_cache.c \
src/coap_debug.c \
src/coap_dtls.c \
src/coap_encode.c \
src/coap_event.c \
src/coap_hashkey.c \
src/coap_gnutls.c \
src/coap_io.c \
src/coap_layers.c \
src/coap_mbedtls.c \
src/coap_mem.c \
src/coap_net.c \
src/coap_netif.c \
src/coap_notls.c \
src/coap_openssl.c \
src/coap_option.c \
src/coap_oscore.c \
src/coap_pdu.c \
src/coap_prng.c \
src/coap_resource.c \
src/coap_session.c \
src/coap_str.c \
src/coap_subscribe.c \
src/coap_tcp.c \
src/coap_time.c \
src/coap_tinydtls.c \
src/coap_uri.c \
src/coap_ws.c
if COAP_OSCORE_SUPPORT
libcoap_@LIBCOAP_NAME_SUFFIX@_la_SOURCES += $(libcoap_OSCORE_sources)
endif # COAP_OSCORE_SUPPORT
## Define the list of public header files and their install location.
## The API version is appended to the install folder to being able to
## co-install various versions of libcoap.
libcoap_includedir = $(includedir)/coap$(LIBCOAP_API_VERSION)/
# If there is a API change to something $(LIBCOAP_API_VERSION) > 1 the install
# prefix for the header files has to change to not conflict the older version
# if the user want's to install both versions. There will be something used like
# libcoap_include_HEADERS = \
# $(top_srcdir)/include/coap-$(LIBCOAP_API_VERSION)/*
libcoap_include_HEADERS = \
$(top_builddir)/include/coap$(LIBCOAP_API_VERSION)/coap.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/libcoap.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_address.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_async.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_block.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_cache.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_debug.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_dtls.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_encode.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_event.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_forward_decls.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_io.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_mem.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_net.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_option.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_oscore.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_pdu.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_prng.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_resource.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_session.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_str.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_subscribe.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_time.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_uri.h \
$(top_srcdir)/include/coap$(LIBCOAP_API_VERSION)/coap_ws.h
## Instruct libtool to include API version information in the generated shared
## library file (.so). The library ABI version will later defined in configure.ac,
## so that all version information is kept in one place.
libcoap_@LIBCOAP_NAME_SUFFIX@_la_LDFLAGS = \
-version-info $(LT_LIBCOAP_CURRENT):$(LT_LIBCOAP_REVISION):$(LT_LIBCOAP_AGE) \
@libcoap_SYMBOLS@ \
$(DTLS_LIBS) \
-pie
## Collect symbols here we want to ignore while building the helper files
## libcoap-$(LIBCOAP_API_VERSION).{map,sym} for the linker.
CTAGS_IGNORE=-I " \
coap_pdu_from_pbuf \
coap_lwip_dump_memory_pools \
coap_lwip_set_input_wait_handler \
coap_print_contiki_prefix \
"
# This helper is called by libcoap-$(LIBCOAP_API_VERSION).{map,sym} to see if
# configure has detected a usable version of the ctags program and aborts if not.
check_ctags:
@if [ "$(CTAGS_PROG)" = "" ]; then \
echo ;\
echo "There was no ctags program found by the configure script!" ;\
echo "ctags is needed for running this target! Please note the warning about the missed ctags program of the configure script." ;\
echo ;\
exit 1;\
fi
## Helper target to generate the symbol table needed by libtool.
## The .map format is used when ld supports linker scripts, otherwise
## it must fall back to a plain symbol file.
update-map-file: libcoap-$(LIBCOAP_API_VERSION).map libcoap-$(LIBCOAP_API_VERSION).sym
libcoap-$(LIBCOAP_API_VERSION).map: check_ctags $(libcoap_include_HEADERS)
( echo "VER_$(LIBCOAP_API_VERSION) {" ; \
echo "global:" ; \
$(CTAGS_PROG) $(CTAGS_IGNORE) -f - --c-kinds=p $(libcoap_include_HEADERS) | awk '/^coap_/ { print " " $$1 ";" }' | LC_ALL=C sort -u ; \
echo "local:" ; \
echo " *;" ; \
echo "};" ) > $(top_builddir)/$@.new
mv $(top_builddir)/$@.new $(top_builddir)/$@
libcoap-$(LIBCOAP_API_VERSION).sym: check_ctags $(libcoap_include_HEADERS)
( $(CTAGS_PROG) $(CTAGS_IGNORE) -f - --c-kinds=p $(libcoap_include_HEADERS) | awk '/^coap_/ { print $$1 }' | LC_ALL=C sort -u ) \
> $(top_builddir)/$@.new
mv $(top_builddir)/$@.new $(top_builddir)/$@
## Install the generated pkg-config file (.pc) into the expected location for
## architecture-dependent package configuration information. Occasionally,
## pkg-config files are also used for architecture-independent data packages,
## in which case the correct install location would be $(datadir)/pkgconfig.
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libcoap-$(LIBCOAP_NAME_SUFFIX).pc
## Define an independent executable script for inclusion in the distribution
## archive. However, it will not be installed on an end user's system due to
## the noinst_ prefix.
dist_noinst_SCRIPTS = autogen.sh
## Set up a common library that causes linking against the common library
## to link with the actual library with (D)TLS support
if BUILD_ADD_DEFAULT_NAMES
install-exec-hook:
(cd $(DESTDIR)$(libdir) ; \
if [ -f libcoap-$(LIBCOAP_NAME_SUFFIX).so ] ; then \
rm -f libcoap-$(LIBCOAP_API_VERSION).so ; \
$(LN_S) libcoap-$(LIBCOAP_NAME_SUFFIX).so libcoap-$(LIBCOAP_API_VERSION).so ; \
fi ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).a ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).la ; \
$(LN_S) libcoap-$(LIBCOAP_NAME_SUFFIX).a libcoap-$(LIBCOAP_API_VERSION).a ; \
$(LN_S) libcoap-$(LIBCOAP_NAME_SUFFIX).la libcoap-$(LIBCOAP_API_VERSION).la ; \
$(MKDIR_P) $(DESTDIR)$(pkgconfigdir) ; \
cd $(DESTDIR)$(pkgconfigdir) ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).pc ; \
$(LN_S) libcoap-$(LIBCOAP_NAME_SUFFIX).pc libcoap-$(LIBCOAP_API_VERSION).pc)
uninstall-hook:
(cd $(DESTDIR)$(libdir) ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).a ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).la ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).so ; \
cd $(DESTDIR)$(pkgconfigdir) ; \
rm -f libcoap-$(LIBCOAP_API_VERSION).pc)
endif # BUILD_ADD_DEFAULT_NAMES
## various *-local targets
## Remove the helper files for the linker and the pkg-config file if there
## is 'make distclean' called. NOTE: To re create the *.{map,sym} files you
## need to call the target update-map-file after the configure script was
## running!
clean-local:
-find \( -name '*.gcda' -o -name '*.gcno' -o -name '*.gcov' \) -delete
distclean-local:
@rm -f src/*.o src/*.lo
rm -f libcoap-$(LIBCOAP_API_VERSION).map
rm -f libcoap-$(LIBCOAP_API_VERSION).sym
rm -f libcoap-$(LIBCOAP_NAME_SUFFIX).pc
@echo
@echo " ---> Please note the following important advice! <---"
@echo " The files libcoap-$(LIBCOAP_API_VERSION).{map,sym} are removed by the distclean target!"
@echo " To regenerate this two files you need to call 'make update-map-file' first before any"
@echo " other Make target. Otherwise the build of libcoap will fail!"
@echo
## Ensure we have actual *.{map,sym} files if we create a release tarball.
dist-local: update-map-file
## Finaly some phony targets, just to ensure those targets are always buildable
## no matter if the user has created same called files.
.PHONY: update-map-file check_ctags
+5
View File
@@ -0,0 +1,5 @@
LIBCOAP_DIR = os/net/app-layer/libcoap
MODULES += $(LIBCOAP_DIR)/src
MODULES += $(LIBCOAP_DIR)/include
MODULES_SOURCES_EXCLUDES += coap_io_riot.c
MODULES_SOURCES_EXCLUDES += coap_io_lwip.c
View File
Symlink
+1
View File
@@ -0,0 +1 @@
README.md
+97
View File
@@ -0,0 +1,97 @@
# libcoap: A C implementation of the Constrained Application Protocol (RFC 7252)
[![Build Status: main](https://github.com/obgm/libcoap/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/obgm/libcoap/actions?query=branch:main)
[![Build Status: develop](https://github.com/obgm/libcoap/actions/workflows/main.yml/badge.svg?branch=develop)](https://github.com/obgm/libcoap/actions?query=branch:develop)
[![Static Analysis](https://scan.coverity.com/projects/10970/badge.svg?flat=1)](https://scan.coverity.com/projects/obgm-libcoap)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libcoap.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libcoap)
[![CIFuzz Status](https://github.com/obgm/libcoap/actions/workflows/cifuzz.yml/badge.svg?branch=develop)](https://github.com/obgm/libcoap/actions/workflows/cifuzz.yml)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
Copyright (C) 2010—2023 by Olaf Bergmann <bergmann@tzi.org> and others
ABOUT LIBCOAP
=============
libcoap is a C implementation of a lightweight application-protocol
for devices that are constrained their resources such as computing
power, RF range, memory, bandwidth, or network packet sizes. This
protocol, CoAP, is standardized by the IETF as RFC 7252. For further
information related to CoAP, see <https://coap.space> or
[CoAP Wiki](https://en.wikipedia.org/wiki/Constrained_Application_Protocol).
You might want to check out
[libcoap-minimal](https://github.com/obgm/libcoap-minimal) for usage
examples.
DOCUMENTATION
=============
Documentation and further information can be found at
<https://libcoap.net>.
PACKAGE CONTENTS
================
This package contains a protocol parser and basic networking
functions for platforms with support for malloc() and BSD-style
sockets. In addition, there is support for Contiki-NG,
Espressif/ESP-IDF, LwIP and RIOT-OS hosted environments.
The following RFCs are supported
* [RFC7252: The Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7252)
* [RFC7390: Group Communication for the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7390)
* [RFC7641: Observing Resources in the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7641)
* [RFC7959: Block-Wise Transfers in the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7959)
* [RFC7967: Constrained Application Protocol (CoAP) Option for No Server Response](https://rfc-editor.org/rfc/rfc7967)
* [RFC8132: PATCH and FETCH Methods for the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc8132)
* [RFC8323: CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets](https://rfc-editor.org/rfc/rfc8323)
* [RFC8516: "Too Many Requests" Response Code for the Constrained Application Protocol](https://rfc-editor.org/rfc/rfc8516)
* [RFC8613: Object Security for Constrained RESTful Environments (OSCORE)](https://rfc-editor.org/rfc/rfc8613)
* [RFC8768: Constrained Application Protocol (CoAP) Hop-Limit Option](https://rfc-editor.org/rfc/rfc8768)
* [RFC8974: Extended Tokens and Stateless Clients in the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc8974)
* [RFC9175: CoAP: Echo, Request-Tag, and Token Processing](https://rfc-editor.org/rfc/rfc9175)
* [RFC9177: Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission](https://rfc-editor.org/rfc/rfc9177)
There is (D)TLS support for the following libraries
* [OpenSSL](https://www.openssl.org) (Minimum version 1.1.0) [PKI, PSK and PKCS11]
* [GnuTLS](https://www.gnutls.org) (Minimum version 3.3.0) [PKI, PSK, RPK(3.6.6+) and PKCS11]
* [Mbed TLS](https://www.trustedfirmware.org/projects/mbed-tls/) (Minimum version 2.7.10) [PKI and PSK]
* [TinyDTLS](https://github.com/eclipse/tinydtls) [PSK and RPK] [DTLS Only]
The examples directory contain a CoAP client, CoAP Resource Directory server
and a CoAP server to demonstrate the use of this library.
BUILDING
========
Further information can be found at <https://libcoap.net/install.html>
and [BUILDING](https://raw.githubusercontent.com/obgm/libcoap/develop/BUILDING).
LICENSE INFORMATION
===================
This library is published as open-source software without any warranty
of any kind. Use is permitted under the terms of the simplified BSD
license. It includes public domain software. libcoap binaries may also
include open-source software with their respective licensing terms.
Please refer to
[LICENSE](https://raw.githubusercontent.com/obgm/libcoap/develop/LICENSE)
for further details.
+33
View File
@@ -0,0 +1,33 @@
# Security Policy
## No Warranty
Per the terms of the BSD-2-Clause license, libcoap is offered "as is" and
without any guarantee or warranty pertaining to its operation. While every
reasonable effort is made by its maintainers to ensure the product remains
free of security vulnerabilities, users are ultimately responsible for
conducting their own evaluations of each software release.
## Reporting a Suspected Vulnerability
If you believe you've uncovered a security vulnerability and wish to report
it confidentially, you may do so via email. Please note that any reported
vulnerabilities **MUST** meet all the following conditions:
* Affects the most recent stable release of libcoap, or a current beta release
* Is reproducible following a prescribed set of instructions
Please note that we **DO NOT** accept reports generated by automated tooling
which merely suggest that a file or file(s) _may_ be vulnerable under certain
conditions, as these are most often innocuous.
If you believe that you've found a vulnerability which meets all of these
conditions, please email a brief description of the suspected bug and
instructions for reproduction to **libcoap-security@tzi.org**. Please do NOT
create a public GitHub issue.
### Bug Bounties
As libcoap is provided as free open source software, we do not offer any monetary
compensation for vulnerability or bug reports, however your contributions are greatly
appreciated.
+27
View File
@@ -0,0 +1,27 @@
This is a simple file for all kinds of stuff related on development for
libcoap. Please append (and remove) any issue you think its worthy.
Classification of issues:
Critical -> Break the library in some kind or a missing feature, maybe not
directly but later
Serious -> No regression on the user side, more likly on the libcoap
development
Minor -> Things that are nice to have, but they are not time critical
=================
* CRITICAL ISSUES
=================
================
* SERIOUS ISSUES
================
-> Create some development rules like:
--> How to submit patches? What about pull requests?
--> How to implement/change platform related code?
-> Further improve the API documentation
==============
* MINOR ISSUES
==============
-> Adding a logo for libcoap
Executable
+142
View File
@@ -0,0 +1,142 @@
#!/bin/sh -e
# uncomment the set command for debugging
#set -x
# function to check for needed helper tools
check_helper() {
#echo "Checking for $1 ..."
TOOL=`which "$1" || echo none`
if [ "$TOOL" = "none" ]; then
echo
echo "Couldn't find '$1'!"
RET=1
else
RET=0
fi
}
PROJECT="libcoap"
AUTOGEN_FILES="
INSTALL
aclocal.m4 ar-lib
coap_config.h coap_config.h.in* compile config.guess config.h* config.log config.status config.sub configure
depcomp
doc/Doxyfile doc/doxyfile.stamp doc/doxygen_sqlite3.db doc/Makefile doc/Makefile.in
examples/*.o examples/coap-client examples/coap-server examples/coap-rd
examples/Makefile examples/Makefile.in
include/coap3/coap.h
install-sh
libcoap-*.pc libtool ltmain.sh
man/coap*.[357] man/coap*.txt man/Makefile man/Makefile.in
missing
Makefile Makefile.in
stamp-h1 src/.dirstamp libcoap*.la* src/*.*o
tests/*.o tests/Makefile tests/Makefile.in tests/testdriver tests/test_common.h
tests/oss-fuzz/Makefile.ci
m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4
"
AUTOGEN_DIRS="
.deps
.libs autom4te.cache/
doc/html/
examples/.deps/ examples/.libs
man/.deps
man/tmp
src/.deps/ src/.libs/
tests/.deps/
"
# checking for cleaner argument
echo
if [ "$1" = "--clean" ]; then
echo "removing autogenerated files ..."
rm -rf $AUTOGEN_FILES $AUTOGEN_DIRS
echo "done"
exit
else
echo "[HINT] You can run 'autogen.sh --clean' to remove all generated files by the autotools."
echo
fi
# checking for autoreconf
check_helper autoconf
if [ "$RET" = "1" ]; then
echo "You probably need to install the package 'autoconf'."
ERROR=1
else
echo "Found 'autoconf'."
fi
# checking for aclocal
check_helper aclocal
if [ "$RET" = "1" ]; then
echo "You probably need to install the package 'automake'."
ERROR=1
else
echo "Found 'aclocal'."
fi
# checking for pkg-config
check_helper pkg-config
if [ "$RET" = "1" ]; then
echo "You probably need to install the package 'pkg-config|pkgconf'."
ERROR=1
else
echo "Found 'pkg-config'."
fi
# checking for libtool
# The libtool helper maybe installed as 'libtoolize', checking for 'libtool' first.
check_helper libtool
if [ "$RET" = "1" ]; then
# O.k. libtool not found, searching for libtoolize.
check_helper libtoolize
if [ "$RET" = "1" ]; then
echo "You probably need to install the package 'libtool'."
# That's bad, we found nothing!
ERROR=1
else
echo "Found 'libtoolize'."
break
fi
else
echo "Found 'libtool'."
fi
# exit if one tool isn't available
if [ "$ERROR" = "1" ]; then
echo
echo "One or more needed tools are missing, exiting ..."
echo "Please install the needed software packages and restart 'autogen.sh' again."
echo
exit 1
fi
echo
echo " ---> Found all needed tools! That's fine."
echo
# countinue otherwise
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
# Creating the directory m4 before calling autoreconf to
# not struggle with old versions of aclocal.
mkdir -p $srcdir/m4
# create ar-lib if not present to avoid autoreconf throwing an error
# when the file is missing. As autoreconf is called with --force
# the file will get updated with the proper contents afterwards.
touch ar-lib
echo "Generating needed autotools files for $PROJECT by running autoreconf ..."
autoreconf --force --install --verbose "$srcdir"
echo
echo "You can now run './configure --help' to see possible configuration options."
echo "Otherwise process the configure script to create the makefiles and generated helper files."
echo
+5
View File
@@ -0,0 +1,5 @@
imagename
build.sh
*~
.*.swp
\#*#
+7
View File
@@ -0,0 +1,7 @@
FROM debian:testing-slim
RUN apt-get update && apt-get install -y autoconf automake gcc clang \
libtool libtool-bin make pkg-config libcunit1-dev libssl-dev \
libgnutls28-dev libmbedtls-dev exuberant-ctags git valgrind \
graphviz doxygen libxml2-utils xsltproc docbook-xml docbook-xsl asciidoc
RUN apt-get clean
+36
View File
@@ -0,0 +1,36 @@
FROM obgm/libcoap:build-env
RUN apt-get update && apt-get install -y cmake git g++
RUN apt-get clean
ENV libcoap_dir=/home/libcoap
ADD . $libcoap_dir
WORKDIR $libcoap_dir
RUN ./autogen.sh --clean && ./autogen.sh
RUN ./configure --disable-documentation --enable-tests --enable-examples --with-openssl && make install clean
WORKDIR /home
RUN git clone --depth 1 https://github.com/cabo/cn-cbor.git && cd cn-cbor && ./build.sh all doc install
# The image for development with libcoap
FROM debian:testing-slim
RUN apt-get update && apt-get install -y autoconf automake gcc g++ gdb libtool libtool-bin make \
pkg-config libssl-dev libgnutls28-dev libmbedtls-dev
RUN apt-get install -y iproute2 lsof net-tools inetutils-ping netcat-openbsd less vim
RUN apt-get clean
COPY --from=0 /usr/local/include/coap3 /usr/local/include/coap3
COPY --from=0 /usr/local/lib /usr/local/lib
COPY --from=0 /usr/local/bin/coap-client /usr/local/bin/
COPY --from=0 /usr/local/include/cn-cbor /usr/local/include/cn-cbor
RUN echo "/usr/local/lib" >>/etc/ld.so.conf.d/usr_local.conf && ldconfig /usr/local/lib
ARG user=user
RUN adduser --disabled-password --gecos '' $user
RUN chown -R $user:$user /home/$user
WORKDIR /home/$user
USER $user
EXPOSE 5683 5684
+16
View File
@@ -0,0 +1,16 @@
#! /usr/bin/env bash
pushd $(dirname $0)
. ./imagename
# see https://stackoverflow.com/a/2924755 for switching boldface on/off
bold=$(tput bold)
normal=$(tput sgr0)
echo "${bold}**** Creating build-env image ****${normal}"
docker build -f Dockerfile.build-env -t $USER/$IMAGE:build-env .
echo "${bold}**** Creating develop image ****${normal}"
docker build -f Dockerfile.develop -t $USER/$IMAGE:develop ..
popd
+2
View File
@@ -0,0 +1,2 @@
USER=obgm
IMAGE=libcoap
+25
View File
@@ -0,0 +1,25 @@
# to format cmake files we use cmake-format:
# pip install cmake-format --upgrade
# information about the configuration here:
# https://github.com/cheshirekow/cmake_format
# How wide to allow formatted cmake files
line_width: 80
# How many spaces to tab for indent
tab_size: 2
# Format command names consistently as 'lower' or 'upper' case
command_case: "lower"
first_comment_is_literal: False
# enable comment markup parsing and reflow
enable_markup: False
# If arglists are longer than this, break them always
max_subargs_per_line: 1
max_subgroups_hwrap: 2
max_pargs_hwrap: 2
+4
View File
@@ -0,0 +1,4 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")
+35
View File
@@ -0,0 +1,35 @@
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
find_library(MBEDTLS_LIBRARY mbedtls)
find_library(MBEDX509_LIBRARY mbedx509)
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
set(MBEDTLS_LIBRARIES
"${MBEDTLS_LIBRARY}"
"${MBEDX509_LIBRARY}"
"${MBEDCRYPTO_LIBRARY}")
if(MBEDTLS_LIBRARY)
set(MbedTLS_FOUND TRUE)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
MBEDTLS
DEFAULT_MSG
MBEDTLS_INCLUDE_DIRS
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY)
mark_as_advanced(
MBEDTLS_INCLUDE_DIRS
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY)
message(STATUS "MBEDTLS_INCLUDE_DIRS: ${MBEDTLS_INCLUDE_DIRS}")
message(STATUS "MBEDTLS_LIBRARY: ${MBEDTLS_LIBRARY}")
message(STATUS "MBEDX509_LIBRARY: ${MBEDX509_LIBRARY}")
message(STATUS "MBEDCRYPTO_LIBRARY: ${MBEDCRYPTO_LIBRARY}")
message(STATUS "MBEDTLS_LIBRARIES: ${MBEDTLS_LIBRARIES}")
+88
View File
@@ -0,0 +1,88 @@
# FindTinyDTLS
# -----------
#
# Find the tinyDTLS encryption library.
#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines the following :prop_tgt:`IMPORTED` targets:
#
# ``tinydtls``
# The tinyDTLS ``tinydtls`` library, if found.
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# This module will set the following variables in your project:
#
# ``TINYDTLS_FOUND``
# System has the tinyDTLS library.
# ``TINYDTLS_INCLUDE_DIR``
# The tinyDTLS include directory.
# ``TINYDTLS_LIBRARIES``
# All tinyDTLS libraries.
#
# Hints
# ^^^^^
#
# Set ``TINYDTLS_ROOT_DIR`` to the root directory of an tinyDTLS installation.
if(TINYDTLS_ROOT_DIR)
set(_EXTRA_FIND_ARGS "NO_CMAKE_FIND_ROOT_PATH")
endif()
find_path(
TINYDTLS_INCLUDE_DIR
NAMES tinydtls/dtls.h
PATH_SUFFIXES include
HINTS ${PROJECT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${TINYDTLS_ROOT_DIR}
${_EXTRA_FIND_ARGS})
find_library(
TINYDTLS_LIBRARIES
NAMES tinydtls
PATH_SUFFIXES lib
HINTS ${PROJECT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${TINYDTLS_ROOT_DIR}
${_EXTRA_FIND_ARGS})
if(TINYDTLS_LIBRARIES)
set(TINYDTLS_FOUND TRUE)
else()
set(TINYDTLS_FOUND FALSE)
if(TinyDTLS_FIND_REQUIRED)
message(FATAL_ERROR "Tinydtls could not be found")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
tinyDTLS
FOUND_VAR
TINYDTLS_FOUND
REQUIRED_VARS
TINYDTLS_INCLUDE_DIR
TINYDTLS_LIBRARIES
VERSION_VAR)
if(NOT
TARGET
tinydtls)
add_library(
tinydtls
UNKNOWN
IMPORTED)
set_target_properties(
tinydtls
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${TINYDTLS_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${TINYDTLS_LIBRARIES}")
endif()
message(STATUS "TINYDTLS_INCLUDE_DIR: ${TINYDTLS_INCLUDE_DIR}")
message(STATUS "TINYDTLS_LIBRARIES: ${TINYDTLS_LIBRARIES}")
message(STATUS "TINYDTLS_ROOT_DIR: ${TINYDTLS_ROOT_DIR}")
+210
View File
@@ -0,0 +1,210 @@
/*
* cmake_coap_config.h -- cmake configuration for libcoap
*
* Copyright (C) 2020 Carlos Gomes Martinho <carlos.gomes_martinho@siemens.com>
* Copyright (C) 2021-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#if ! defined(_WIN32)
#define _GNU_SOURCE
#endif
/* Define to 1 if you have <ws2tcpip.h> header file. */
#cmakedefine HAVE_WS2TCPIP_H @HAVE_WS2TCPIP_H@
/* Define to 1 if the system has small stack size. */
#cmakedefine COAP_CONSTRAINED_STACK @COAP_CONSTRAINED_STACK@
/* Define to 1 if you have <winsock2.h> header file. */
#cmakedefine HAVE_WINSOCK2_H @HAVE_WINSOCK2_H@
/* Define to 1 if the library has client support. */
#cmakedefine COAP_CLIENT_SUPPORT @COAP_CLIENT_SUPPORT@
/* Define to 1 if the library has server support. */
#cmakedefine COAP_SERVER_SUPPORT @COAP_SERVER_SUPPORT@
/* Define to 1 if the library is to have observe persistence. */
#cmakedefine COAP_WITH_OBSERVE_PERSIST @COAP_WITH_OBSERVE_PERSIST@
/* Define to 1 if the system has epoll support. */
#cmakedefine COAP_EPOLL_SUPPORT @COAP_EPOLL_SUPPORT@
/* Define to 1 if the library has OSCORE support. */
#cmakedefine COAP_OSCORE_SUPPORT @COAP_OSCORE_SUPPORT@
/* Define to 1 if the library has WebSockets support. */
#cmakedefine COAP_WS_SUPPORT @COAP_WS_SUPPORT@
/* Define to 1 if the library has async separate response support. */
#cmakedefine COAP_ASYNC_SUPPORT @COAP_ASYNC_SUPPORT@
/* Define to 0-8 for maximum logging level. */
#cmakedefine COAP_MAX_LOGGING_LEVEL @COAP_MAX_LOGGING_LEVEL@
/* Define to 1 to build without TCP support. */
#cmakedefine01 COAP_DISABLE_TCP
/* Define to 1 to build with IPv4 support. */
#cmakedefine COAP_IPV4_SUPPORT @COAP_IPV4_SUPPORT@
/* Define to 1 to build with IPv6 support. */
#cmakedefine COAP_IPV6_SUPPORT @COAP_IPV6_SUPPORT@
/* Define to 1 to build with Unix socket support. */
#cmakedefine COAP_AF_UNIX_SUPPORT @COAP_AF_UNIX_SUPPORT@
/* Define to 1 to build with Q-Block (RFC 9177) support. */
#cmakedefine COAP_Q_BLOCK_SUPPORT @COAP_Q_BLOCK_SUPPORT@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H @HAVE_ARPA_INET_H@
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H @HAVE_ASSERT_H@
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@
/* Define to 1 if you have the `getaddrinfo' function. */
#cmakedefine HAVE_GETADDRINFO @HAVE_GETADDRINFO@
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@
/* Define to 1 if you have the <erno.h> header file. */
#cmakedefine HAVE_ERRNO_H @HAVE_ERRNO_H@
/* Define to 1 if the system has openssl */
#cmakedefine COAP_WITH_LIBOPENSSL @COAP_WITH_LIBOPENSSL@
/* Define to 1 if the system has libgnutls28 */
#cmakedefine COAP_WITH_LIBGNUTLS @COAP_WITH_LIBGNUTLS@
/* Define to 1 if the system has libtinydtls */
#cmakedefine COAP_WITH_LIBTINYDTLS @COAP_WITH_LIBTINYDTLS@
/* Define to 1 if the system has libmbedtls */
#cmakedefine COAP_WITH_LIBMBEDTLS @COAP_WITH_LIBMBEDTLS@
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@
/* Define to 1 if you have the `malloc' function. */
#cmakedefine HAVE_MALLOC @HAVE_MALLOC@
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@
/* Define to 1 if you have the `memset' function. */
#cmakedefine HAVE_MEMSET @HAVE_MEMSET@
/* Define to 1 if you have the `if_nametoindex' function. */
#cmakedefine HAVE_IF_NAMETOINDEX @HAVE_IF_NAMETOINDEX@
/* Define to 1 if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H @HAVE_NETDB_H@
/* Define to 1 if you have the <net/if.h> header file. */
#cmakedefine HAVE_NET_IF_H @HAVE_NET_IF_H@
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H @HAVE_NETINET_IN_H@
/* Define to 1 if you have the <pthread.h> header file. */
#cmakedefine HAVE_PTHREAD_H @HAVE_PTHREAD_H@
/* Define to 1 if you have the `pthread_mutex_lock' function. */
#cmakedefine HAVE_PTHREAD_MUTEX_LOCK @HAVE_PTHREAD_MUTEX_LOCK@
/* Define to 1 if you have the `select' function. */
#cmakedefine HAVE_SELECT @HAVE_SELECT@
/* Define to 1 if you have the `socket' function. */
#cmakedefine HAVE_SOCKET @HAVE_SOCKET@
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@
/* Define to 1 if you have the `strcasecmp' function. */
#cmakedefine HAVE_STRCASECMP @HAVE_STRCASECMP@
/* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H @HAVE_STRING_H@
/* Define to 1 if you have the `strnlen' function. */
#cmakedefine HAVE_STRNLEN @HAVE_STRNLEN@
/* Define to 1 if you have the `strrchr' function. */
#cmakedefine HAVE_STRRCHR @HAVE_STRRCHR@
/* Define to 1 if you have the `getrandom' function. */
#cmakedefine HAVE_GETRANDOM @HAVE_GETRANDOM@
/* Define to 1 if you have the `randon' function. */
#cmakedefine HAVE_RANDOM @HAVE_RANDOM@
/* Define to 1 if the system has the type `struct cmsghdr'. */
#cmakedefine HAVE_STRUCT_CMSGHDR @HAVE_STRUCT_CMSGHDR@
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#cmakedefine HAVE_SYS_IOCTL_H @HAVE_SYS_IOCTL_H@
/* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_SOCKET_H @HAVE_SYS_SOCKET_H@
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
/* Define to 1 if you have the <sys/unistd.h> header file. */
#cmakedefine HAVE_SYS_UNISTD_H @HAVE_SYS_UNISTD_H@
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H @HAVE_TIME_H@
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@
/* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@"
/* Define to the home page for this package. */
#cmakedefine PACKAGE_URL "@PACKAGE_URL@"
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(snprintf)
#define snprintf _snprintf
#endif
#endif /* COAP_CONFIG_H_ */
+105
View File
@@ -0,0 +1,105 @@
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
/* Define to 1 if libcoap supports client mode code. */
#define COAP_CLIENT_SUPPORT 1
/* Define to 1 if libcoap supports server mode code. */
#define COAP_SERVER_SUPPORT 1
/* Define to 1 if the system has small stack size. */
#define COAP_CONSTRAINED_STACK 1
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 1
/* Define to 1 to build support for IPv4 packets. */
/* #undef COAP_IPV4_SUPPORT 1 */
/* Define to 1 to build support for IPv6 packets. */
#define COAP_IPV6_SUPPORT 1
/* Define to 1 to build support for Unix socket packets. */
/* #undef COAP_AF_UNIX_SUPPORT 1 */
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
/* Define to 1 to build support for persisting observes. */
/* #undef COAP_WITH_OBSERVE_PERSIST 1 */
/* Define to 1 to build with WebSockets support. */
/* #undef COAP_WS_SUPPORT 1 */
/* Define to 1 to build with Q-Block (RFC9177) support. */
/* #undef COAP_Q_BLOCK_SUPPORT 1 */
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "libcoap-developers@lists.sourceforge.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libcoap"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libcoap 4.3.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libcoap"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://libcoap.net/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "4.3.4"
#define WITH_CONTIKI 1
#define HASH_NONFATAL_OOM 1
#ifndef HEAPMEM_CONF_ARENA_SIZE
#define HEAPMEM_CONF_ARENA_SIZE 6144
#endif
#endif /* COAP_CONFIG_H_ */
+345
View File
@@ -0,0 +1,345 @@
/*
* coap_config.h.riot -- RIOT configuration for libcoap
*
* Copyright (C) 2021-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#define WITH_POSIX 1
#ifndef COAP_CONSTRAINED_STACK
#define COAP_CONSTRAINED_STACK 1
#endif
#ifdef CONFIG_LIBCOAP_MAX_LOGGING_LEVEL
#ifndef COAP_MAX_LOGGING_LEVEL
/* Define to 1 to build without TCP support. */
#define COAP_MAX_LOGGING_LEVEL CONFIG_LIBCOAP_MAX_LOGGING_LEVEL
#endif /* COAP_MAX_LOGGING_LEVEL */
#endif /* CONFIG_LIBCOAP_MAX_LOGGING_LEVEL */
#ifdef CONFIG_LIBCOAP_IPV4_SUPPORT
#ifndef COAP_IPV4_SUPPORT
/* Define to 1 to build with IPv4 support. */
#define COAP_IPV4_SUPPORT 1
#endif /* COAP_IPV4_SUPPORT */
#endif /* CONFIG_LIBCOAP_IPV4_SUPPORT */
#ifdef CONFIG_LIBCOAP_IPV6_SUPPORT
#ifndef COAP_IPV6_SUPPORT
/* Define to 1 to build with IPv6 support. */
#define COAP_IPV6_SUPPORT 1
#endif /* COAP_IPV6_SUPPORT */
#endif /* CONFIG_LIBCOAP_IPV6_SUPPORT */
#ifdef CONFIG_LIBCOAP_AF_UNIX_SUPPORT
#ifndef COAP_AF_UNIX_SUPPORT
/* Define to 1 to build with Unix socket support. */
#define COAP_AF_UNIX_SUPPORT 1
#endif /* COAP_AF_UNIX_SUPPORT */
#endif /* CONFIG_LIBCOAP_AF_UNIX_SUPPORT */
#ifdef CONFIG_LIBCOAP_TCP_SUPPORT
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 0
#endif /* COAP_DISABLE_TCP */
#endif /* CONFIG_LIBCOAP_TCP_SUPPORT */
#ifdef CONFIG_LIBCOAP_OSCORE_SUPPORT
#ifndef COAP_OSCORE_SUPPORT
/* Define to 1 if the library has OSCORE support. */
#define COAP_OSCORE_SUPPORT 1
#endif /* COAP_OSCORE_SUPPORT */
#endif /* CONFIG_LIBCOAP_OSCORE_SUPPORT */
#ifdef CONFIG_LIBCOAP_WITH_OBSERVE_PERSIST
#ifndef COAP_WITH_OBSERVE_PERSIST
/* Define to 1 if the library has Observe persist support. */
#define COAP_WITH_OBSERVE_PERSIST 0
#endif /* COAP_WITH_OBSERVE_PERSIST */
#endif /* CONFIG_LIBCOAP_WITH_OBSERVE_PERSIST */
#ifdef CONFIG_LIBCOAP_WS_SUPPORT
#ifndef COAP_WS_SUPPORT
/* Define to 1 if the library has WebSockets support. */
#define COAP_WS_SUPPORT 0
#endif /* COAP_WS_SUPPORT */
#endif /* CONFIG_LIBCOAP_WS_SUPPORT */
#ifdef CONFIG_LIBCOAP_Q_BLOCK_SUPPORT
#ifndef COAP_Q_BLOCK_SUPPORT
/* Define to 1 to build with Q-Block (RFC9177) support. */
#define COAP_Q_BLOCK_SUPPORT 0
#endif /* COAP_Q_BLOCK_SUPPORT */
#endif /* CONFIG_LIBCOAP_Q_BLOCK_SUPPORT */
#ifdef CONFIG_LIBCOAP_CLIENT_SUPPORT
#ifndef COAP_CLIENT_SUPPORT
/* Define to 1 if the library has client support. */
#define COAP_CLIENT_SUPPORT 1
#endif /* COAP_CLIENT_SUPPORT */
#endif /* CONFIG_LIBCOAP_CLIENT_SUPPORT */
#ifdef CONFIG_LIBCOAP_SERVER_SUPPORT
#ifndef COAP_SERVER_SUPPORT
/* Define to 1 if the library has server support. */
#define COAP_SERVER_SUPPORT 1
#endif /* COAP_SERVER_SUPPORT */
#endif /* CONFIG_LIBCOAP_SERVER_SUPPORT */
#ifdef CONFIG_LIBCOAP_ASYNC_SUPPORT
#ifndef COAP_ASYNC_SUPPORT
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
#endif /* COAP_ASYNC_SUPPORT */
#endif /* CONFIG_LIBCOAP_ASYNC_SUPPORT */
#ifdef CONFIG_LIBCOAP_MAX_STRING_SIZE
#ifndef COAP_MAX_STRING_SIZE
#define COAP_MAX_STRING_SIZE CONFIG_LIBCOAP_MAX_STRING_SIZE
#endif /* COAP_MAX_STRING_SIZE */
#endif /* CONFIG_LIBCOAP_OSCORE_SUPPORT */
#ifdef CONFIG_LIBCOAP_MAX_ENDPOINTS
#ifndef COAP_MAX_ENDPOINTS
#define COAP_MAX_ENDPOINTS CONFIG_LIBCOAP_MAX_ENDPOINTS
#endif /* COAP_MAX_ENDPOINTS */
#endif /* CONFIG_LIBCOAP_MAX_ENDPOINTS */
#ifdef CONFIG_LIBCOAP_MAX_RESOURCES
#ifndef COAP_MAX_RESOURCES
#define COAP_MAX_RESOURCES CONFIG_LIBCOAP_MAX_RESOURCES
#endif /* COAP_MAX_RESOURCES */
#endif /* CONFIG_LIBCOAP_MAX_RESOURCES */
#ifdef CONFIG_LIBCOAP_MAX_ATTRIBUTE_SIZE
#ifndef COAP_MAX_ATTRIBUTE_SIZE
#define COAP_MAX_ATTRIBUTE_SIZE CONFIG_LIBCOAP_MAX_ATTRIBUTE_SIZE
#endif /* COAP_MAX_ATTRIBUTE_SIZE */
#endif /* CONFIG_LIBCOAP_MAX_ATTRIBUTE_SIZE */
#ifdef CONFIG_LIBCOAP_MAX_ATTRIBUTES
#ifndef COAP_MAX_ATTRIBUTES
#define COAP_MAX_ATTRIBUTES CONFIG_LIBCOAP_MAX_ATTRIBUTES
#endif /* COAP_MAX_ATTRIBUTES */
#endif /* CONFIG_LIBCOAP_MAX_ATTRIBUTES */
#ifdef CONFIG_LIBCOAP_MAX_PACKETS
#ifndef COAP_MAX_PACKETS
#define COAP_MAX_PACKETS CONFIG_LIBCOAP_MAX_PACKETS
#endif /* COAP_MAX_PACKETS */
#endif /* CONFIG_LIBCOAP_MAX_PACKETS */
#ifdef CONFIG_LIBCOAP_MAX_NODES
#ifndef COAP_MAX_NODES
#define COAP_MAX_NODES CONFIG_LIBCOAP_MAX_NODES
#endif /* COAP_MAX_NODES */
#endif /* CONFIG_LIBCOAP_MAX_NODES */
#ifdef CONFIG_LIBCOAP_MAX_CONTEXTS
#ifndef COAP_MAX_CONTEXTS
#define COAP_MAX_CONTEXTS CONFIG_LIBCOAP_MAX_CONTEXTS
#endif /* COAP_MAX_CONTEXTS */
#endif /* CONFIG_LIBCOAP_MAX_CONTEXTS */
#ifdef CONFIG_LIBCOAP_MAX_PDUS
#ifndef COAP_MAX_PDUS
#define COAP_MAX_PDUS CONFIG_LIBCOAP_MAX_PDUS
#endif /* COAP_MAX_PDUS */
#endif /* CONFIG_LIBCOAP_MAX_PDUS */
#ifdef CONFIG_LIBCOAP_MAX_DTLS_SESSIONS
#ifndef COAP_MAX_DTLS_SESSIONS
#define COAP_MAX_DTLS_SESSIONS CONFIG_LIBCOAP_MAX_DTLS_SESSIONS
#endif /* COAP_MAX_DTLS_SESSIONS */
#endif /* CONFIG_LIBCOAP_MAX_DTLS_SESSIONS */
#ifdef CONFIG_LIBCOAP_MAX_SESSIONS
#ifndef COAP_MAX_SESSIONS
#define COAP_MAX_SESSIONS CONFIG_LIBCOAP_MAX_SESSIONS
#endif /* COAP_MAX_SESSIONS */
#endif /* CONFIG_LIBCOAP_MAX_SESSIONS */
#ifdef CONFIG_LIBCOAP_MAX_OPTION_SIZE
#ifndef COAP_MAX_OPTION_SIZE
#define COAP_MAX_OPTION_SIZE CONFIG_LIBCOAP_MAX_OPTION_SIZE
#endif /* COAP_MAX_OPTION_SIZE */
#endif /* CONFIG_LIBCOAP_MAX_OPTION_SIZE */
#ifdef CONFIG_LIBCOAP_MAX_OPTIONS
#ifndef COAP_MAX_OPTIONS
#define COAP_MAX_OPTIONS CONFIG_LIBCOAP_MAX_OPTIONS
#endif /* COAP_MAX_OPTIONS */
#endif /* CONFIG_LIBCOAP_MAX_OPTIONS */
#ifdef CONFIG_LIBCOAP_MAX_CACHE_KEYS
#ifndef COAP_MAX_CACHE_KEYS
#define COAP_MAX_CACHE_KEYS CONFIG_LIBCOAP_MAX_CACHE_KEYS
#endif /* COAP_MAX_CACHE_KEYS */
#endif /* CONFIG_LIBCOAP_MAX_CACHE_KEYS */
#ifdef CONFIG_LIBCOAP_MAX_CACHE_ENTRIES
#ifndef COAP_MAX_CACHE_ENTRIES
#define COAP_MAX_CACHE_ENTRIES CONFIG_LIBCOAP_MAX_CACHE_ENTRIES
#endif /* COAP_MAX_CACHE_ENTRIES */
#endif /* CONFIG_LIBCOAP_MAX_CACHE_ENTRIES */
#ifdef CONFIG_LIBCOAP_MAX_LG_CRCVS
#ifndef COAP_MAX_LG_CRCVS
#define COAP_MAX_LG_CRCVS CONFIG_LIBCOAP_MAX_LG_CRCVS
#endif /* COAP_MAX_LG_CRCVS */
#endif /* CONFIG_LIBCOAP_MAX_LG_CRCVS */
#ifdef CONFIG_LIBCOAP_MAX_LG_SRCVS
#ifndef COAP_MAX_LG_SRCVS
#define COAP_MAX_LG_SRCVS CONFIG_LIBCOAP_MAX_LG_SRCVS
#endif /* COAP_MAX_LG_SRCVS */
#endif /* CONFIG_LIBCOAP_MAX_LG_SRCVS */
#ifdef CONFIG_LIBCOAP_MAX_LG_XMITS
#ifndef COAP_MAX_LG_XMITS
#define COAP_MAX_LG_XMITS CONFIG_LIBCOAP_MAX_LG_XMITS
#endif /* COAP_MAX_LG_XMITS */
#endif /* CONFIG_LIBCOAP_MAX_LG_XMITS */
#ifndef COAP_DISABLE_TCP
#if MODULE_SOCK_TCP
#define COAP_DISABLE_TCP 0
#else /* ! MODULE_SOCK_TCP */
#define COAP_DISABLE_TCP 1
#endif /* ! MODULE_SOCK_TCP */
#endif /* COAP_DISABLE_TCP */
#ifdef MODULE_TINYDTLS
#ifndef COAP_WITH_LIBTINYDTLS
#define COAP_WITH_LIBTINYDTLS 1
#endif /* ! COAP_WITH_LIBTINYDTLS */
#endif /* MODULE_TINYDTLS */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the `getaddrinfo' function. */
/* #undef HAVE_GETADDRINFO */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
/* #undef HAVE_LIMITS_H */
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H */
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <netdb.h> header file. */
/* #undef HAVE_NETDB_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the `select' function. */
/* #undef HAVE_SELECT */
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
/* #undef HAVE_SYS_STAT_H */
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/unistd.h> header file. */
#define HAVE_SYS_UNISTD_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "libcoap-developers@lists.sourceforge.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libcoap"
/* Define to the version of this package. */
#define PACKAGE_VERSION "4.3.4"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libcoap 4.3.4"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
#endif /* COAP_CONFIG_H_ */
+345
View File
@@ -0,0 +1,345 @@
/*
* coap_config.h.riot -- RIOT configuration for libcoap
*
* Copyright (C) 2021-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#define WITH_POSIX 1
#ifndef COAP_CONSTRAINED_STACK
#define COAP_CONSTRAINED_STACK 1
#endif
#ifdef CONFIG_LIBCOAP_MAX_LOGGING_LEVEL
#ifndef COAP_MAX_LOGGING_LEVEL
/* Define to 1 to build without TCP support. */
#define COAP_MAX_LOGGING_LEVEL CONFIG_LIBCOAP_MAX_LOGGING_LEVEL
#endif /* COAP_MAX_LOGGING_LEVEL */
#endif /* CONFIG_LIBCOAP_MAX_LOGGING_LEVEL */
#ifdef CONFIG_LIBCOAP_IPV4_SUPPORT
#ifndef COAP_IPV4_SUPPORT
/* Define to 1 to build with IPv4 support. */
#define COAP_IPV4_SUPPORT 1
#endif /* COAP_IPV4_SUPPORT */
#endif /* CONFIG_LIBCOAP_IPV4_SUPPORT */
#ifdef CONFIG_LIBCOAP_IPV6_SUPPORT
#ifndef COAP_IPV6_SUPPORT
/* Define to 1 to build with IPv6 support. */
#define COAP_IPV6_SUPPORT 1
#endif /* COAP_IPV6_SUPPORT */
#endif /* CONFIG_LIBCOAP_IPV6_SUPPORT */
#ifdef CONFIG_LIBCOAP_AF_UNIX_SUPPORT
#ifndef COAP_AF_UNIX_SUPPORT
/* Define to 1 to build with Unix socket support. */
#define COAP_AF_UNIX_SUPPORT 1
#endif /* COAP_AF_UNIX_SUPPORT */
#endif /* CONFIG_LIBCOAP_AF_UNIX_SUPPORT */
#ifdef CONFIG_LIBCOAP_TCP_SUPPORT
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 0
#endif /* COAP_DISABLE_TCP */
#endif /* CONFIG_LIBCOAP_TCP_SUPPORT */
#ifdef CONFIG_LIBCOAP_OSCORE_SUPPORT
#ifndef COAP_OSCORE_SUPPORT
/* Define to 1 if the library has OSCORE support. */
#define COAP_OSCORE_SUPPORT 1
#endif /* COAP_OSCORE_SUPPORT */
#endif /* CONFIG_LIBCOAP_OSCORE_SUPPORT */
#ifdef CONFIG_LIBCOAP_WITH_OBSERVE_PERSIST
#ifndef COAP_WITH_OBSERVE_PERSIST
/* Define to 1 if the library has Observe persist support. */
#define COAP_WITH_OBSERVE_PERSIST 0
#endif /* COAP_WITH_OBSERVE_PERSIST */
#endif /* CONFIG_LIBCOAP_WITH_OBSERVE_PERSIST */
#ifdef CONFIG_LIBCOAP_WS_SUPPORT
#ifndef COAP_WS_SUPPORT
/* Define to 1 if the library has WebSockets support. */
#define COAP_WS_SUPPORT 0
#endif /* COAP_WS_SUPPORT */
#endif /* CONFIG_LIBCOAP_WS_SUPPORT */
#ifdef CONFIG_LIBCOAP_Q_BLOCK_SUPPORT
#ifndef COAP_Q_BLOCK_SUPPORT
/* Define to 1 to build with Q-Block (RFC9177) support. */
#define COAP_Q_BLOCK_SUPPORT 0
#endif /* COAP_Q_BLOCK_SUPPORT */
#endif /* CONFIG_LIBCOAP_Q_BLOCK_SUPPORT */
#ifdef CONFIG_LIBCOAP_CLIENT_SUPPORT
#ifndef COAP_CLIENT_SUPPORT
/* Define to 1 if the library has client support. */
#define COAP_CLIENT_SUPPORT 1
#endif /* COAP_CLIENT_SUPPORT */
#endif /* CONFIG_LIBCOAP_CLIENT_SUPPORT */
#ifdef CONFIG_LIBCOAP_SERVER_SUPPORT
#ifndef COAP_SERVER_SUPPORT
/* Define to 1 if the library has server support. */
#define COAP_SERVER_SUPPORT 1
#endif /* COAP_SERVER_SUPPORT */
#endif /* CONFIG_LIBCOAP_SERVER_SUPPORT */
#ifdef CONFIG_LIBCOAP_ASYNC_SUPPORT
#ifndef COAP_ASYNC_SUPPORT
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
#endif /* COAP_ASYNC_SUPPORT */
#endif /* CONFIG_LIBCOAP_ASYNC_SUPPORT */
#ifdef CONFIG_LIBCOAP_MAX_STRING_SIZE
#ifndef COAP_MAX_STRING_SIZE
#define COAP_MAX_STRING_SIZE CONFIG_LIBCOAP_MAX_STRING_SIZE
#endif /* COAP_MAX_STRING_SIZE */
#endif /* CONFIG_LIBCOAP_OSCORE_SUPPORT */
#ifdef CONFIG_LIBCOAP_MAX_ENDPOINTS
#ifndef COAP_MAX_ENDPOINTS
#define COAP_MAX_ENDPOINTS CONFIG_LIBCOAP_MAX_ENDPOINTS
#endif /* COAP_MAX_ENDPOINTS */
#endif /* CONFIG_LIBCOAP_MAX_ENDPOINTS */
#ifdef CONFIG_LIBCOAP_MAX_RESOURCES
#ifndef COAP_MAX_RESOURCES
#define COAP_MAX_RESOURCES CONFIG_LIBCOAP_MAX_RESOURCES
#endif /* COAP_MAX_RESOURCES */
#endif /* CONFIG_LIBCOAP_MAX_RESOURCES */
#ifdef CONFIG_LIBCOAP_MAX_ATTRIBUTE_SIZE
#ifndef COAP_MAX_ATTRIBUTE_SIZE
#define COAP_MAX_ATTRIBUTE_SIZE CONFIG_LIBCOAP_MAX_ATTRIBUTE_SIZE
#endif /* COAP_MAX_ATTRIBUTE_SIZE */
#endif /* CONFIG_LIBCOAP_MAX_ATTRIBUTE_SIZE */
#ifdef CONFIG_LIBCOAP_MAX_ATTRIBUTES
#ifndef COAP_MAX_ATTRIBUTES
#define COAP_MAX_ATTRIBUTES CONFIG_LIBCOAP_MAX_ATTRIBUTES
#endif /* COAP_MAX_ATTRIBUTES */
#endif /* CONFIG_LIBCOAP_MAX_ATTRIBUTES */
#ifdef CONFIG_LIBCOAP_MAX_PACKETS
#ifndef COAP_MAX_PACKETS
#define COAP_MAX_PACKETS CONFIG_LIBCOAP_MAX_PACKETS
#endif /* COAP_MAX_PACKETS */
#endif /* CONFIG_LIBCOAP_MAX_PACKETS */
#ifdef CONFIG_LIBCOAP_MAX_NODES
#ifndef COAP_MAX_NODES
#define COAP_MAX_NODES CONFIG_LIBCOAP_MAX_NODES
#endif /* COAP_MAX_NODES */
#endif /* CONFIG_LIBCOAP_MAX_NODES */
#ifdef CONFIG_LIBCOAP_MAX_CONTEXTS
#ifndef COAP_MAX_CONTEXTS
#define COAP_MAX_CONTEXTS CONFIG_LIBCOAP_MAX_CONTEXTS
#endif /* COAP_MAX_CONTEXTS */
#endif /* CONFIG_LIBCOAP_MAX_CONTEXTS */
#ifdef CONFIG_LIBCOAP_MAX_PDUS
#ifndef COAP_MAX_PDUS
#define COAP_MAX_PDUS CONFIG_LIBCOAP_MAX_PDUS
#endif /* COAP_MAX_PDUS */
#endif /* CONFIG_LIBCOAP_MAX_PDUS */
#ifdef CONFIG_LIBCOAP_MAX_DTLS_SESSIONS
#ifndef COAP_MAX_DTLS_SESSIONS
#define COAP_MAX_DTLS_SESSIONS CONFIG_LIBCOAP_MAX_DTLS_SESSIONS
#endif /* COAP_MAX_DTLS_SESSIONS */
#endif /* CONFIG_LIBCOAP_MAX_DTLS_SESSIONS */
#ifdef CONFIG_LIBCOAP_MAX_SESSIONS
#ifndef COAP_MAX_SESSIONS
#define COAP_MAX_SESSIONS CONFIG_LIBCOAP_MAX_SESSIONS
#endif /* COAP_MAX_SESSIONS */
#endif /* CONFIG_LIBCOAP_MAX_SESSIONS */
#ifdef CONFIG_LIBCOAP_MAX_OPTION_SIZE
#ifndef COAP_MAX_OPTION_SIZE
#define COAP_MAX_OPTION_SIZE CONFIG_LIBCOAP_MAX_OPTION_SIZE
#endif /* COAP_MAX_OPTION_SIZE */
#endif /* CONFIG_LIBCOAP_MAX_OPTION_SIZE */
#ifdef CONFIG_LIBCOAP_MAX_OPTIONS
#ifndef COAP_MAX_OPTIONS
#define COAP_MAX_OPTIONS CONFIG_LIBCOAP_MAX_OPTIONS
#endif /* COAP_MAX_OPTIONS */
#endif /* CONFIG_LIBCOAP_MAX_OPTIONS */
#ifdef CONFIG_LIBCOAP_MAX_CACHE_KEYS
#ifndef COAP_MAX_CACHE_KEYS
#define COAP_MAX_CACHE_KEYS CONFIG_LIBCOAP_MAX_CACHE_KEYS
#endif /* COAP_MAX_CACHE_KEYS */
#endif /* CONFIG_LIBCOAP_MAX_CACHE_KEYS */
#ifdef CONFIG_LIBCOAP_MAX_CACHE_ENTRIES
#ifndef COAP_MAX_CACHE_ENTRIES
#define COAP_MAX_CACHE_ENTRIES CONFIG_LIBCOAP_MAX_CACHE_ENTRIES
#endif /* COAP_MAX_CACHE_ENTRIES */
#endif /* CONFIG_LIBCOAP_MAX_CACHE_ENTRIES */
#ifdef CONFIG_LIBCOAP_MAX_LG_CRCVS
#ifndef COAP_MAX_LG_CRCVS
#define COAP_MAX_LG_CRCVS CONFIG_LIBCOAP_MAX_LG_CRCVS
#endif /* COAP_MAX_LG_CRCVS */
#endif /* CONFIG_LIBCOAP_MAX_LG_CRCVS */
#ifdef CONFIG_LIBCOAP_MAX_LG_SRCVS
#ifndef COAP_MAX_LG_SRCVS
#define COAP_MAX_LG_SRCVS CONFIG_LIBCOAP_MAX_LG_SRCVS
#endif /* COAP_MAX_LG_SRCVS */
#endif /* CONFIG_LIBCOAP_MAX_LG_SRCVS */
#ifdef CONFIG_LIBCOAP_MAX_LG_XMITS
#ifndef COAP_MAX_LG_XMITS
#define COAP_MAX_LG_XMITS CONFIG_LIBCOAP_MAX_LG_XMITS
#endif /* COAP_MAX_LG_XMITS */
#endif /* CONFIG_LIBCOAP_MAX_LG_XMITS */
#ifndef COAP_DISABLE_TCP
#if MODULE_SOCK_TCP
#define COAP_DISABLE_TCP 0
#else /* ! MODULE_SOCK_TCP */
#define COAP_DISABLE_TCP 1
#endif /* ! MODULE_SOCK_TCP */
#endif /* COAP_DISABLE_TCP */
#ifdef MODULE_TINYDTLS
#ifndef COAP_WITH_LIBTINYDTLS
#define COAP_WITH_LIBTINYDTLS 1
#endif /* ! COAP_WITH_LIBTINYDTLS */
#endif /* MODULE_TINYDTLS */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the `getaddrinfo' function. */
/* #undef HAVE_GETADDRINFO */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
/* #undef HAVE_LIMITS_H */
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H */
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <netdb.h> header file. */
/* #undef HAVE_NETDB_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the `select' function. */
/* #undef HAVE_SELECT */
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
/* #undef HAVE_SYS_STAT_H */
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/unistd.h> header file. */
#define HAVE_SYS_UNISTD_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#define PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the version of this package. */
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
#endif /* COAP_CONFIG_H_ */
+185
View File
@@ -0,0 +1,185 @@
/*
* coap_config.h.windows -- Windows configuration for libcoap
*
* Copyright (C) 2017-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#if defined(_WIN32)
/* Define to 1 if you have <ws2tcpip.h> header file. */
#define HAVE_WS2TCPIP_H 1
/* Define to 1 if you have <winsock2.h> header file. */
#define HAVE_WINSOCK2_H 1
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the `malloc' function. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if the system has the type `struct cmsghdr'. */
#define HAVE_STRUCT_CMSGHDR 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(snprintf)
#define snprintf _snprintf
#endif
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 0
#endif
#ifndef COAP_IPV4_SUPPORT
/* Define to 1 to build with IPv4 support. */
#define COAP_IPV4_SUPPORT 1
#endif
#ifndef COAP_IPV6_SUPPORT
/* Define to 1 to build with IPv6 support. */
#define COAP_IPV6_SUPPORT 1
#endif
#ifndef COAP_AF_UNIX_SUPPORT
/* Define to 1 to build with Unix socket support. */
#define COAP_AF_UNIX_SUPPORT 0
#endif
#ifndef COAP_CLIENT_SUPPORT
/* Define if libcoap supports client mode code. */
#define COAP_CLIENT_SUPPORT 1
#endif
#ifndef COAP_SERVER_SUPPORT
/* Define if libcoap supports server mode code. */
#define COAP_SERVER_SUPPORT 1
#endif
#ifndef COAP_WITH_OBSERVE_PERSIST
/* Define to build support for persisting observes. */
#define COAP_WITH_OBSERVE_PERSIST 0
#endif
#ifndef COAP_WS_SUPPORT
/* Define to 1 to build with WebSockets support. */
#define COAP_WS_SUPPORT 0
#endif
#ifndef COAP_Q_BLOCK_SUPPORT
/* Define to 1 to build with Q-Block (RFC9177) support. */
#define COAP_Q_BLOCK_SUPPORT 0
#endif
#ifndef COAP_MAX_LOGGING_LEVEL
/* Define to 0-8 for maximum logging level. */
#define COAP_MAX_LOGGING_LEVEL 8
#endif
#ifndef COAP_OSCORE_SUPPORT
/* Define to 1 to build with OSCORE support. */
#define COAP_OSCORE_SUPPORT 1
#endif
#ifndef COAP_ASYNC_SUPPORT
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
#endif
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "libcoap-developers@lists.sourceforge.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libcoap"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libcoap 4.3.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libcoap"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://libcoap.net/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "4.3.4"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define this to 1 for ancillary data on MacOS */
/* #undef __APPLE_USE_RFC_3542 */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
#endif
#endif /* COAP_CONFIG_H_ */
+185
View File
@@ -0,0 +1,185 @@
/*
* coap_config.h.windows -- Windows configuration for libcoap
*
* Copyright (C) 2017-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#if defined(_WIN32)
/* Define to 1 if you have <ws2tcpip.h> header file. */
#define HAVE_WS2TCPIP_H 1
/* Define to 1 if you have <winsock2.h> header file. */
#define HAVE_WINSOCK2_H 1
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the `malloc' function. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if the system has the type `struct cmsghdr'. */
#define HAVE_STRUCT_CMSGHDR 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(snprintf)
#define snprintf _snprintf
#endif
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 0
#endif
#ifndef COAP_IPV4_SUPPORT
/* Define to 1 to build with IPv4 support. */
#define COAP_IPV4_SUPPORT 1
#endif
#ifndef COAP_IPV6_SUPPORT
/* Define to 1 to build with IPv6 support. */
#define COAP_IPV6_SUPPORT 1
#endif
#ifndef COAP_AF_UNIX_SUPPORT
/* Define to 1 to build with Unix socket support. */
#define COAP_AF_UNIX_SUPPORT 0
#endif
#ifndef COAP_CLIENT_SUPPORT
/* Define if libcoap supports client mode code. */
#define COAP_CLIENT_SUPPORT 1
#endif
#ifndef COAP_SERVER_SUPPORT
/* Define if libcoap supports server mode code. */
#define COAP_SERVER_SUPPORT 1
#endif
#ifndef COAP_WITH_OBSERVE_PERSIST
/* Define to build support for persisting observes. */
#define COAP_WITH_OBSERVE_PERSIST 0
#endif
#ifndef COAP_WS_SUPPORT
/* Define to 1 to build with WebSockets support. */
#define COAP_WS_SUPPORT 0
#endif
#ifndef COAP_Q_BLOCK_SUPPORT
/* Define to 1 to build with Q-Block (RFC9177) support. */
#define COAP_Q_BLOCK_SUPPORT 0
#endif
#ifndef COAP_MAX_LOGGING_LEVEL
/* Define to 0-8 for maximum logging level. */
#define COAP_MAX_LOGGING_LEVEL 8
#endif
#ifndef COAP_OSCORE_SUPPORT
/* Define to 1 to build with OSCORE support. */
#define COAP_OSCORE_SUPPORT 1
#endif
#ifndef COAP_ASYNC_SUPPORT
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
#endif
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#define PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "@PACKAGE_TARNAME@"
/* Define to the home page for this package. */
#define PACKAGE_URL "@PACKAGE_URL@"
/* Define to the version of this package. */
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define this to 1 for ancillary data on MacOS */
/* #undef __APPLE_USE_RFC_3542 */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
#endif
#endif /* COAP_CONFIG_H_ */
+1330
View File
File diff suppressed because it is too large Load Diff
+2614
View File
File diff suppressed because it is too large Load Diff
+298
View File
@@ -0,0 +1,298 @@
# doc/Makefile.am
#
# Copyright (C) 2015-2018 Carsten Schoenert <c.schoenert@t-online.de>
# 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
#
# SPDX-License-Identifier: BSD-2-Clause
#
# This file is part of the CoAP C library libcoap. Please see README and
# COPYING for terms of use.
# We can only perfom the targets in this directory if doxygen is present.
CLEANFILES = \
doxygen_sqlite3.db
EXTRA_DIST = \
docbook.local.css \
upgrade_4.2.1_4.3.0.txt \
upgrade_4.3.0_4.3.1.txt \
upgrade_4.3.1_4.3.2.txt \
upgrade_4.3.2_4.3.3.txt \
upgrade_4.3.3_4.3.4.txt \
main.md \
module_api_wrap.h
if HAVE_DOXYGEN
man-page-cleanup:
@rm -f $(top_builddir)/doc/DoxygenLayout.xml
@rm -rf $(top_builddir)/doc/man_tmp
@rm -rf $(top_builddir)/doc/man_html
man-page-prepare: man-page-cleanup
@$(MKDIR_P) $(top_builddir)/doc/man_tmp
@$(MKDIR_P) $(top_builddir)/doc/man_html
man-page-start: man-page-prepare
## Setup the man page tab
@echo '' > $(top_builddir)/doc/scratch_insert_file
@echo ' <tab type="usergroup" visible="yes" url="@ref manpage" title="Manual Pages">' > $(top_builddir)/doc/insert_file
@echo ' <tab type="usergroup" visible="yes" url="@ref man_summary" title="Man Pages Summary">' >> $(top_builddir)/doc/insert_file
##
@echo '/** @page manpage Manual Pages' > $(top_builddir)/doc/man_tmp/manpage.dox
@echo ' Here are the libcoap API and Example manual pages:' >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo ' <table class="directory">' >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " <tr>" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " <td class=\"entry\" align=\"left\"> @ref man_summary </td><td class=\"desc\" align=\"left\">Man Pages Summary</td>" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " </tr>" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " <tr class=\"even\">" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " <td class=\"entry\" align=\"left\"> @ref man_individual </td><td class=\"desc\" align=\"left\">Individual Man Pages</td>" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " </tr>" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo " </table>" >> $(top_builddir)/doc/man_tmp/manpage.dox
@echo ' */' >> $(top_builddir)/doc/man_tmp/manpage.dox
##
@echo '/** @page man_summary Manual Pages Summary' > $(top_builddir)/doc/man_tmp/man_summary.dox
@echo ' Here are a list of libcoap API summary man pages, some of which have code examples, and Examples:' >> $(top_builddir)/doc/man_tmp/man_summary.dox
@echo ' <table class="directory">' >> $(top_builddir)/doc/man_tmp/man_summary.dox
##
@echo '/** @page man_individual Individual Manual Pages' > $(top_builddir)/doc/man_tmp/man_individual.dox
@echo ' Here are a list of libcoap API individual man pages, some of which have code examples:' >> $(top_builddir)/doc/man_tmp/man_individual.dox
@echo ' <table class="directory">' >> $(top_builddir)/doc/man_tmp/man_individual.dox
##
## Setup the upgrading tab
@echo '/** @page upgrading Upgrading' > $(top_builddir)/doc/man_tmp/upgrading.dox
@echo ' Upgrading between libcoap versions:' >> $(top_builddir)/doc/man_tmp/upgrading.dox
@echo ' <table class="directory">' >> $(top_builddir)/doc/man_tmp/upgrading.dox
man-page-build: upg-page-build man-page-start
@MAN_FILES=`find $(top_srcdir)/man/ -type f -name "coap.txt.in" ; find $(top_srcdir)/man/ -type f -name "coap_*.in" | LC_ALL=C sort ; find $(top_srcdir)/man/ -type f -name "coap-*.in" | LC_ALL=C sort` ;\
MAN3_FILES=`find $(top_srcdir)/man/ -type f -name "coap_*.in" | LC_ALL=C sort` ;\
UPG_FILES=`find $(top_srcdir)/doc/ -type f -name "upgrade_*.txt" | LC_ALL=C sort` ;\
HTML_FILES=`find $(top_builddir)/man/ -type f -name "*.html"` ;\
COUNT_MAN_FILES=`echo $${MAN_FILES} | wc -w` ;\
COUNT_HTML_FILES=`echo $${HTML_FILES} | wc -w` ;\
## We need the HTML files from the Asciidoc source files, check if they around, otherwise build them.
if [ "$${COUNT_MAN_FILES}" != "$${COUNT_HTML_FILES}" ]; then \
$(MAKE) -C ../man ;\
fi ;\
##
## Build the summary man pages
##
for FILE in $${MAN_FILES} ; do \
BASE=`basename $${FILE} | cut -d. -f 1` ;\
MANUAL=`egrep -B 1 "^====" $${FILE} | head -1` ;\
SUMMARY=`egrep -B 2 "^SYNOPSIS" $${FILE} | ${SED} 's/coap-//g' | cut -d\- -f2 | cut -c2- | head -1` ;\
if [ -z "$${SUMMARY}" ] ; then \
SUMMARY=`egrep -B 2 "^DESCRIPTION" $${FILE} | ${SED} 's/coap-//g' | cut -d\- -f2 | cut -c2- | head -1` ;\
fi ;\
##
## Fix and copy .html file across
##
if [ -f $(top_builddir)/man/$${BASE}.html ]; then \
## Correct case sensitive Name and Synopsis on master (used later)
$(SED) -i 's^<h2>Name</h2>^<h2>NAME</h2>^g' $(top_builddir)/man/$${BASE}.html ;\
$(SED) -i 's^<h2>Synopsis</h2>^<h2>SYNOPSIS</h2>^g' $(top_builddir)/man/$${BASE}.html ;\
cp -f $(top_builddir)/man/$${BASE}.html $(top_builddir)/doc/man_html/$${BASE}.html ;\
else \
echo "ERROR: $(top_builddir)/man/$${BASE}.html not found!";\
exit 1 ;\
fi ;\
## Build the manual insert page
echo "/// @page man_$${BASE} $${MANUAL}" > $(top_builddir)/doc/man_tmp/$${MANUAL}.dox ;\
echo "/// @htmlinclude $${BASE}.html $${MANUAL}" >> $(top_builddir)/doc/man_tmp/$${MANUAL}.dox ;\
## Update insert_file (the list is sorted appropriately)
echo " <tab type=\"user\" visible=\"yes\" url=\"@ref man_$${BASE}\" title=\"$${MANUAL} - $${SUMMARY}\" intro=\"\"/>" >> $(top_builddir)/doc/insert_file ;\
## Update the summary man page
echo " <tr$${ROW_EVEN}>" >> $(top_builddir)/doc/man_tmp/man_summary.dox ;\
echo " <td class=\"entry\" align=\"left\"> @ref man_$${BASE} </td><td class=\"desc\" align=\"left\">$${SUMMARY}</td>" >> $(top_builddir)/doc/man_tmp/man_summary.dox ;\
echo " </tr>" >> $(top_builddir)/doc/man_tmp/man_summary.dox ;\
if [ -z "$${ROW_EVEN}" ] ; then \
ROW_EVEN=" class=\"even\"" ;\
else \
ROW_EVEN= ;\
fi \
done ;\
##
## Close off the man page summary file
##
echo ' </table>' >> $(top_builddir)/doc/man_tmp/man_summary.dox ;\
echo ' */' >> $(top_builddir)/doc/man_tmp/man_summary.dox ;\
echo ' </tab>' >> $(top_builddir)/doc/insert_file ;\
##
## Build the individual man pages
##
echo ' <tab type="usergroup" visible="yes" url="@ref man_individual" title="Individual Man Pages">' >> $(top_builddir)/doc/insert_file ;\
for FILE in $${MAN3_FILES} ; do \
BASE=`basename $${FILE} | cut -d. -f 1` ;\
LIST=`${SED} -ne '/^NAME/,/^SYNOPSIS/p;/^SYNOPSIS/q' $${FILE} | ${SED} -ne '/coap_/{ s/ *, *//g ; p }' | egrep -v "^$${BASE}$$"` ;\
for ENTRY in $${LIST} ; do \
MANUAL="$${ENTRY}(3)" ;\
## Build the manual insert page
echo "/// @page man_$${ENTRY} $${MANUAL}" > $(top_builddir)/doc/man_tmp/$${MANUAL}.dox ;\
echo "/// @htmlinclude $${ENTRY}.html $${MANUAL}" >> $(top_builddir)/doc/man_tmp/$${MANUAL}.dox ;\
## Create html file
cat $(top_builddir)/man/$${BASE}.html | ${SED} "s/Function: $${ENTRY}(/<a class=\"anchor\" id=\"$${ENTRY}\"><\/a>\0/" > $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
## Update scratch_insert_file for sorting later
echo "$${ENTRY}" >> $(top_builddir)/doc/scratch_insert_file ;\
done ;\
done ;\
##
## Process the (sorted) list of individual man pages
##
for ENTRY in `cat $(top_builddir)/doc/scratch_insert_file | LC_ALL=C sort -u` ; do \
## Update the individual man page
MANUAL="$${ENTRY}(3)" ;\
echo " <tab type=\"user\" visible=\"yes\" url=\"@ref man_$${ENTRY}\" title=\"$${MANUAL}\" intro=\"\"/>" >> $(top_builddir)/doc/insert_file ;\
echo " <tr$${ROW_EVEN}>" >> $(top_builddir)/doc/man_tmp/man_individual.dox ;\
echo " <td class=\"entry\" align=\"left\"> @ref man_$${ENTRY} </td><td class=\"desc\" align=\"left\"></td>" >> $(top_builddir)/doc/man_tmp/man_individual.dox ;\
echo " </tr>" >> $(top_builddir)/doc/man_tmp/man_individual.dox ;\
if [ -z "$${ROW_EVEN}" ] ; then \
ROW_EVEN=" class=\"even\"" ;\
else \
ROW_EVEN= ;\
fi \
done ;\
##
## Close off the individual man pages
##
echo ' </table>' >> $(top_builddir)/doc/man_tmp/man_individual.dox ;\
echo ' */' >> $(top_builddir)/doc/man_tmp/man_individual.dox ;\
echo ' </tab>' >> $(top_builddir)/doc/insert_file ;\
##
## Close off the man page top level
##
echo ' </tab>' >> $(top_builddir)/doc/insert_file ;\
##
## Add in the deprecated tab
##
echo ' <tab type="user" visible="yes" url="@ref deprecated" title="Deprecated Items" intro=""/>' >> $(top_builddir)/doc/insert_file ;\
##
## Start the upgrade tab
##
echo ' <tab type="usergroup" visible="yes" url="@ref upgrading" title="Upgrading">' >> $(top_builddir)/doc/insert_file ;\
for FILE in $${UPG_FILES} ; do \
BASE=`basename $${FILE} | $(SED) "s/\.txt$$//g"`; \
UPGRADE=`echo $${BASE} | $(SED) "s/^upgrade_//g"`; \
CUPGRADE=`echo $${UPGRADE} | $(SED) "s/\./-/g"`; \
SUMMARY=`head -1 $${FILE} | ${SED} 's/^= //g'` ;\
## Build the upgrade insert page
echo "/// @page upg_$${CUPGRADE} $${UPGRADE}" > $(top_builddir)/doc/man_tmp/$${UPGRADE}.dox ;\
echo "/// @htmlinclude $${BASE}.html $${UPGRADE}" >> $(top_builddir)/doc/man_tmp/$${UPGRADE}.dox ;\
## Update insert_file
echo " <tab type=\"user\" visible=\"yes\" url=\"@ref upg_$${CUPGRADE}\" title=\"$${SUMMARY}\" intro=\"\"/>" >> $(top_builddir)/doc/insert_file ;\
## Update the upgrading page
echo " <tr$${ROW_EVEN}>" >> $(top_builddir)/doc/man_tmp/upgrading.dox ;\
echo " <td class=\"entry\" align=\"left\"> @ref upg_$${CUPGRADE} </td><td class=\"desc\" align=\"left\">$${SUMMARY}</td>" >> $(top_builddir)/doc/man_tmp/upgrading.dox ;\
echo " </tr>" >> $(top_builddir)/doc/man_tmp/upgrading.dox ;\
if [ -z "$${ROW_EVEN}" ] ; then \
ROW_EVEN=" class=\"even\"" ;\
else \
ROW_EVEN= ;\
fi ;\
if [ -f $(top_builddir)/doc/$${BASE}.html ]; then \
cp -f $(top_builddir)/doc/$${BASE}.html $(top_builddir)/doc/man_html/$${BASE}.html ;\
## Correct case sensitive Name and Synopsis
$(SED) -i 's^<div class="toc"><p><strong>^<div class="section"><p><strong>^' $(top_builddir)/doc/man_html/$${BASE}.html ;\
else \
echo "ERROR: $(top_builddir)/doc/$${BASE}.html not found!";\
exit 1 ;\
fi \
done ;\
##
## Close off the upgrading tab
##
echo ' </table>' >> $(top_builddir)/doc/man_tmp/upgrading.dox ;\
echo ' */' >> $(top_builddir)/doc/man_tmp/upgrading.dox ;\
##
## Close off the insert file list
##
echo ' </tab>' >> $(top_builddir)/doc/insert_file ;\
##
## Create and Update the DoxygenLayout.xml file
##
$(DOXYGEN) -u > /dev/null 2>&1 ;\
$(DOXYGEN) -l ;\
$(SED) -i 's/<tab type="pages" visible="yes" /<tab type="pages" visible="no" /g' $(top_builddir)/doc/DoxygenLayout.xml ;\
$(SED) -i '/<tab type="examples" visible=.*/r insert_file' $(top_builddir)/doc/DoxygenLayout.xml ;\
##
## Fix up man html files, adding links
##
for FILE in $${MAN_FILES} `cat $(top_builddir)/doc/scratch_insert_file` ; do \
ENTRY=`basename $${FILE} | cut -d . -f1` ;\
## Functions defined in the body
$(SED) -i "s^\(<span class=\"strong\"><strong>\)\(coap[_-][0-9a-z_]*\)\(</strong></span>(\|(\)^\1<a class=\"st-desc\" href=\"man_\2.html#\2\" target=\"_self\">\2</a>\3^g" $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
## Function definitions
$(SED) -i "s^\(<span class=\"strong\"><strong>Function: \)\(coap_[0-9a-z_]*\)\(</strong></span>(\|(\)^\1<a class=\"st-desc\" href=\"man_\2.html#\2\" target=\"_self\">\2</a>\3^g" $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
## The SYNOPSIS entries
$(SED) -i "s^\(<p><span class=\"strong\"><strong>[a-z0-9_ \*]*\)\(coap_[0-9a-z_]*\)\([(;]\)^\1<a class=\"st-synopsis\" href=\"man_\2.html#\2\" target=\"_self\">\2</a>\3^g" $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
## Function in NAME and Examples
$(SED) -i "s^\([ =,]\|[(!>]\|\^\)\(coap_[0-9a-z_]*\)\([(,]\| \-\| \xe2\x80\x94\)^\1<a href=\"man_\2.html#\2\" target=\"_self\">\2</a>\3^g" $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
## Do for a second time in case of overlaps
$(SED) -i "s^\([ =,]\|[(!>]\|\^\)\(coap_[0-9a-z_]*\)\([(,]\| \-\| \xe2\x80\x94\)^\1<a href=\"man_\2.html#\2\" target=\"_self\">\2</a>\3^g" $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
done ;\
##
## Do the highlighting
##
for ENTRY in `cat $(top_builddir)/doc/scratch_insert_file` ; do \
${SED} -i "s/\($${ENTRY}\)\([<(\*, ]\)/<span class=\"man-highlight\">\1<\/span>\2/g" $(top_builddir)/doc/man_html/$${ENTRY}.html ;\
done
if BUILD_MANPAGES
UPG_LIST = upgrade_4.2.1_4.3.0.txt upgrade_4.3.0_4.3.1.txt upgrade_4.3.1_4.3.2.txt upgrade_4.3.2_4.3.3.txt upgrade_4.3.3_4.3.4.txt
upg-page-build:
@for FILE in $(UPG_LIST) ; do \
$(A2X) -d article --format xhtml -D $(top_builddir)/doc/ $(top_srcdir)/doc/$${FILE} ;\
done
all: man-page-build
$(DOXYGEN) Doxyfile
@$(RM) $(top_builddir)/doc/insert_file $(top_builddir)/doc/scratch_insert_file
@cp -f $(top_srcdir)/doc/docbook.local.css $(top_builddir)/doc/html/docbook-xsl.css
else
#
# Need to make sure the man directories are in place, but empty
all: man-page-prepare
$(DOXYGEN) Doxyfile
endif # BUILD_MANPAGES
clean-local:
-rm -rf $(top_builddir)/doc/html $(top_builddir)/doc/man_tmp $(top_builddir)/doc/man_html $(top_builddir)/doc/DoxygenLayout.xml $(top_builddir)/doc/docbook-xsl.css $(top_builddir)/doc/*.html
distclean-local: clean-local
endif # HAVE_DOXYGEN
install-data-hook:
if HAVE_DOXYGEN
@if [ ! -d $(top_builddir)/doc/html ]; then \
echo ;\
echo " No install data in '$(top_builddir)/doc/html' found! Please run 'make all' first." ;\
echo ;\
exit 1 ;\
fi
$(MKDIR_P) $(DESTDIR)$(htmldir)/html || exit 1
cp -a -f $(top_builddir)/doc/html $(DESTDIR)$(htmldir)
find $(DESTDIR)$(htmldir) -type f -name "*.md5" -delete
endif # HAVE_DOXYGEN
if BUILD_LICENSE_INSTALL
$(MKDIR_P) $(DESTDIR)$(docdir) || exit 1
$(INSTALL_DATA) $(top_srcdir)/LICENSE $(DESTDIR)$(docdir)
$(INSTALL_DATA) $(top_srcdir)/COPYING $(DESTDIR)$(docdir)
$(INSTALL_DATA) $(top_srcdir)/README $(DESTDIR)$(docdir)
endif # BUILD_LICENSE_INSTALL
uninstall-hook:
if BUILD_LICENSE_INSTALL
@if [ -d $(DESTDIR)$(docdir) ] ; then \
(cd $(DESTDIR)$(docdir) ; rm -f LICENSE README COPYING) ; \
fi
endif # BUILD_LICENSE_INSTALL
if HAVE_DOXYGEN
-rm -rf $(DESTDIR)$(htmldir)/html
endif # HAVE_DOXYGEN
.PHONY: man-page-cleanup man-page-prepare man-page-start man-page-build
+47
View File
@@ -0,0 +1,47 @@
body pre {
margin: 0.5em 10% 0.5em 1em;
line-height: 1.0;
color: navy;
}
dl {
margin: .2em 0;
line-height: 1.2;
}
dt {
margin-top: 0.1em;
}
span.man-highlight { background: yellow; }
a.st-desc {
font-weight: bold;
color: black;
text-decoration: none;
}
a.st-desc:visited {
font-weight: bold;
color: black;
text-decoration: none;
}
a.st-desc:hover {
text-decoration: underline;
}
a.st-synopsis {
font-weight: bold;
color: black;
text-decoration: none;
}
a.st-synopsis:visited {
font-weight: bold;
color: black;
text-decoration: none;
}
a.st-synopsis:hover {
text-decoration: underline;
}
+75
View File
@@ -0,0 +1,75 @@
libcoap {#mainpage}
=======
A C implementation of the Constrained Application Protocol (RFC 7252)
=====================================================================
Copyright (C) 2010--2023 by Olaf Bergmann <bergmann@tzi.org> and others
About libcoap
=============
libcoap is a C implementation of a lightweight application-protocol
for devices that are constrained their resources such as computing
power, RF range, memory, bandwidth, or network packet sizes. This
protocol, CoAP, is standardized by the IETF as RFC 7252. For further
information related to CoAP, see <https://coap.space> or
[CoAP Wiki](https://en.wikipedia.org/wiki/Constrained_Application_Protocol).
You might want to check out
[libcoap-minimal](https://github.com/obgm/libcoap-minimal) for usage
examples.
The following RFCs are supported
* [RFC7252: The Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7252)
* [RFC7390: Group Communication for the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7390)
* [RFC7641: Observing Resources in the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7641)
* [RFC7959: Block-Wise Transfers in the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc7959)
* [RFC7967: Constrained Application Protocol (CoAP) Option for No Server Response](https://rfc-editor.org/rfc/rfc7967)
* [RFC8132: PATCH and FETCH Methods for the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc8132)
* [RFC8323: CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets](https://rfc-editor.org/rfc/rfc8323)
* [RFC8516: "Too Many Requests" Response Code for the Constrained Application Protocol](https://rfc-editor.org/rfc/rfc8516)
* [RFC8613: Object Security for Constrained RESTful Environments (OSCORE)](https://rfc-editor.org/rfc/rfc8613)
* [RFC8768: Constrained Application Protocol (CoAP) Hop-Limit Option](https://rfc-editor.org/rfc/rfc8768)
* [RFC8974: Extended Tokens and Stateless Clients in the Constrained Application Protocol (CoAP)](https://rfc-editor.org/rfc/rfc8974)
* [RFC9175: CoAP: Echo, Request-Tag, and Token Processing](https://rfc-editor.org/rfc/rfc9175)
* [RFC9177: Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission](https://rfc-editor.org/rfc/rfc9177)
There is (D)TLS support for the following libraries
* [OpenSSL](https://www.openssl.org) (Minimum version 1.1.0) [PKI, PSK and PKCS11]
* [GnuTLS](https://www.gnutls.org) (Minimum version 3.3.0) [PKI, PSK, RPK(3.6.6+) and PKCS11]
* [Mbed TLS](https://www.trustedfirmware.org/projects/mbed-tls/) (Minimum version 2.7.10) [PKI and PSK]
* [TinyDTLS](https://github.com/eclipse/tinydtls) [PSK and RPK] [DTLS Only]
Documentation
=============
This set of pages contains the current set of documention for the libcoap APIs.
License Information
===================
This library is published as open-source software without any warranty
of any kind. Use is permitted under the terms of the simplified BSD
license. It includes public domain software. libcoap binaries may also
include open-source software with their respective licensing terms.
Please refer to
[LICENSE](https://raw.githubusercontent.com/obgm/libcoap/develop/LICENSE)
for further details in the source.
+21
View File
@@ -0,0 +1,21 @@
/* doc/module_api_wrap.h
*
* Copyright (C) 2021-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP C library libcoap. Please see README and
* COPYING for terms of use.
*/
/**
* @file module_api_wrap.h
* @brief Doxygen specific wrapper for Modules layout
*/
/**
* @defgroup application_api Application API
* Application API Structures, Macros, Typedefs, Enums and Functions
* @defgroup internal_api Libcoap Internal API
* libcoap Internal API Structures, Macros, Typedefs, Enums and Functions
*/
+431
View File
@@ -0,0 +1,431 @@
= Upgrade from 4.2.1 to 4.3.0
== Summary
When compiling 4.2.1 based code with a 4.3.0 environment, this will initially
throw up many errors as the API has been updated to make future coding simpler,
adds more functionality and adds more rigorous coding checks. Updating your
code with the following steps will significantly reduce the reported issues.
The examples are now also named with the (D)TLS library type as a suffix.
E.g. coap-client is now coap-client-openssl.
== Include directory changes
Because of the API changes, the libcoap's include file directory has changed from `coap2/` to `coap3/`. Also, there is now no need to define additional include paths to the compiler options such as `-I include/coap3`.
=== Update coap2 to coap3
Example
----
4.2.1
#include <coap2/coap.h>
4.3.0
#include <coap3/coap.h>
----
No other libcoap include files need to be included in your application.
== Call-back handler updates
Infrequently used parameters (which can easily be recreated) have been removed
and others have been made const. These call-back handlers are those
registered with the `coap_register_*()` functions as follows:
=== coap_register_handler()
The definition of `coap_method_handler_t` has been updated, so all the
functions registered by `coap_register_handler()` need to be updated. Any
application functions called by these functions may need to include `const` in
their calling parameters.
Example
----
4.2.1
static void
hnd_get_time(coap_context_t *context,
coap_resource_t *resource,
coap_session_t *session,
coap_pdu_t *request,
coap_binary_t *token,
coap_string_t *query,
coap_pdu_t *response) {
4.3.0
static void
hnd_get_time(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
----
If `context` or `token` need to be recreated, this is done by
----
coap_context_t *context = coap_session_get_context(session);
coap_bin_const_t rcvd_token = coap_pdu_get_token(request);
----
=== coap_register_response_handler()
The definition of `coap_response_handler_t` has been updated, so all the
functions registered by `coap_register_response_handler()` need to be updated.
Any application functions called by these functions may need to include `const`
in their calling parameters. There is a new handler function exit code
`COAP_RESPONSE_FAIL` (if the response is not liked and needs to be rejected
with a `RST` packet) or `COAP_RESPONSE_OK`. Note that `coap_tid_t` has been
replaced with `coap_mid_t` to reflect the parameter is the message id.
Example
----
4.2.1
static void
message_handler(struct coap_context_t *context,
coap_session_t *session,
coap_pdu_t *sent,
coap_pdu_t *received,
const coap_tid_t id) {
4.3.0
static coap_response_t
message_handler(coap_session_t *session,
const coap_pdu_t *sent,
const coap_pdu_t *received,
const coap_mid_t mid) {
----
If `context` needs to be recreated, this is done by
----
coap_context_t *context = coap_session_get_context(session);
----
=== coap_register_nack_handler()
The definition of `coap_nack_handler_t` has been updated, so all the functions
registered by `coap_register_nack_handler()` need to be updated. Any
application functions called by these functions may need to include `const` in
their calling parameters. Note that `coap_tid_t` has been replaced with
`coap_mid_t` to reflect the parameter is the message id.
Example
----
4.2.1
static void
nack_handler(coap_context_t *context,
coap_session_t *session,
coap_pdu_t *sent,
coap_nack_reason_t reason,
const coap_tid_t id) {
4.3.0
static void
nack_handler(coap_session_t *session,
const coap_pdu_t *sent,
const coap_nack_reason_t reason,
const coap_mid_t mid) {
----
If `context` needs to be recreated, this is done by
----
coap_context_t *context = coap_session_get_context(session);
----
=== coap_register_event_handler()
The definition of `coap_event_handler_t` been updated, so all the functions
registered by `coap_register_event_handler()` need to be updated. Any
application functions called by these functions may need to include `const` in
their calling parameters.
Example
----
4.2.1
static int
event_handler(coap_context_t *context,
coap_event_t event,
struct coap_session_t *session) {
4.3.0
static int
event_handler(coap_session_t *session,
const coap_event_t event) {
----
Note the reversed order of the parameters. If `context` needs to be
recreated, this is done by
----
coap_context_t *context = coap_session_get_context(session);
----
=== coap_register_ping_handler()
The definition of `coap_ping_handler_t` been updated, so all the functions
registered by `coap_register_ping_handler()` need to be updated. Any
application functions called by these functions may need to include `const` in
their calling parameters. Note that `coap_tid_t` has been replaced with
`coap_mid_t` to reflect the parameter is the message id.
Example
----
4.2.1
void
ping_handler(coap_context_t *context,
coap_session_t *session,
coap_pdu_t *received,
const coap_tid_t id);
4.3.0
void
ping_handler(coap_session_t *session,
const coap_pdu_t *received,
const coap_mid_t mid);
----
If `context` needs to be recreated, this is done by
----
coap_context_t *context = coap_session_get_context(session);
----
=== coap_register_pong_handler()
The definition of `coap_pong_handler_t` been updated, so all the functions
registered by `coap_register_pong_handler()` need to be updated. Any
application functions called by these functions may need to include `const` in
their calling parameters. Note that `coap_tid_t` has been replaced with
`coap_mid_t` to reflect the parameter is the message id.
Example
----
4.2.1
void
pong_handler(coap_context_t *context,
coap_session_t *session,
coap_pdu_t *received,
const coap_tid_t id);
4.3.0
void
pong_handler(coap_session_t *session,
const coap_pdu_t *received,
const coap_mid_t mid);
----
If `context` needs to be recreated, this is done by
----
coap_context_t *context = coap_session_get_context(session);
----
== libcoap structures no longer directly accessible
Many of the structures internally used by libcoap are no longer exposed to
applications. Additional functions of the form `coap_X_get_Y()` and
`coap_X_set_Y()` where `X` is the structure type and `Y` is the variable. Below
is a non exhaustive set of examples,
=== coap_pdu_t code variable
Example
----
4.2.1
if (received->code ==
4.3.0
coap_pdu_code_t rcvd_code = coap_pdu_get_code(received);
...
if (rcvd_code ==
----
Example
----
4.2.1
response->code = COAP_RESPONSE_CODE(404);
4.3.0
coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
----
Note that more descriptive names are now supported for the response codes, but
the old form can still be used.
=== coap_pdu_t type variable
Example
----
4.2.1
if (received->type ==
4.3.0
coap_pdu_code_t rcvd_type = coap_pdu_get_type(received);
...
if (rcvd_type ==
----
Example
----
4.2.1
request->type = COAP_MESSAGE_NON;
4.3.0
coap_pdu_set_type(request, COAP_MESSAGE_NON);
----
=== coap_pdu_t token variable
Example
----
4.2.1
static inline int
check_token(coap_pdu_t *received) {
return received->token_length == the_token.length &&
memcmp(received->token, the_token.s, the_token.length) == 0;
}
4.3.0
static inline int
check_token(const coap_pdu_t *received) {
coap_bin_const_t rcvd_token = coap_pdu_get_token(received);
return rcvd_token.length == the_token.length &&
memcmp(rcvd_token.s, the_token.s, the_token.length) == 0;
}
----
=== coap_session_t context variable
Example
----
4.2.1
if (session->context ==
4.3.0
coap_context_t context = coap_session_get_context(session);
...
if (context ==
----
=== coap_session_t proto variable
Example
----
4.2.1
if (session->proto ==
4.3.0
coap_proto_t proto = coap_session_get_proto(session);
...
if (proto ==
----
== Functions with changed parameters
Some functions have had the parameters updated. Below are some of the more common ones.
=== coap_pdu_init()
The definition of the second parameter has changed from `coap_request_t` to
`coap_pdu_code_t`.
Example
----
4.2.1
pdu = coap_pdu_init(msgtype,
COAP_REQUEST_GET,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
4.3.0
pdu = coap_pdu_init(msgtype,
COAP_REQUEST_CODE_GET,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
----
Note that the second parameter (`COAP_REQUEST_CODE_GET`) goes further than
just request codes and includes the possibility of response codes (e.g.
`COAP_RESPONSE_CODE_CREATED`) from the `enum coap_pdu_code_t`. Hence the
addition of `_CODE` in the parameter value.
=== coap_get_data()
The definition of the third parameter has been changed to be `const`
Example
----
4.2.1
uint8_t *data;
...
ret = coap_get_data(pdu, &length, &data);
4.3.0
const uint8_t *data;
...
ret = coap_get_data(pdu, &length, &data);
----
== Large Data Handling
Splitting up large data transmission into blocks (RFC7959) can now all be
handled by internally by libcoap, removing the need for applications to know
anything about how to work with blocks, or need to do any block packet loss
recovery. In simple terms, `coap_context_set_block_mode()` must be called,
`coap_add_data()` (or `coap_add_data_blocked_response()`) is replaced by
`coap_add_data_large_response()` or `coap_add_data_large_request()`, and
`coap_get_data_large()` used instead of `coap_get_data()`. See man page
`coap_block(3)` for further information.
There are 3 ways of handling the block transfers
=== Application does all the work
This is how things were done in 4.2.1. The application recognizes the next
block request coming in and then generates the next block response (including
setting up the PDU if client). To continue using this method,
`coap_context_set_block_mode()` must not be called and none of the `_large`
functions used.
=== Application sees individual blocks
By calling `coap_context_set_block_mode(context, COAP_BLOCK_USE_LIBCOAP)` and
using the `_large` functions, all the existing code that builds the next block
response is no longer needed (and must be removed to prevent packet
request/response duplication) as libcoap does this for the application.
By calling `coap_get_data_large()`, the application can determine if this is
the first block or not (using `offset` value), whether the first block is all
the data (`offset` = `0`, `length` = `total`) and whether this is the last
block (`offset` + `length` = `total`). It is the responsibility of the
application to re-assemble the individual blocks into a single body of data.
If this is the request handler in a server, the server still needs to return a
`2.31 (Continue)` response code if the received data is not for the final block,
otherwise a `2.01 (Created)` or `2.04 (Changed)` should be returned.
=== Application only sees all the data
By calling `coap_context_set_block_mode(context,
COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY)` and using the `_large`
functions, all the existing code that builds the next block response is no
longer needed (and must be removed to prevent request/response packet
duplication) as libcoap does this for the application.
`coap_get_data_large()` will only return the entire body of data (`offset`
always `0`, `length` = `total`) and there is no need to re-assemble individual
blocks into a large body of data.
In RAM constrained environments, option 2 may be the preferred method.
== Observe Handling
In the server's request handler's call-back, there is no longer any need to
check whether this is an Observe call (or Observe triggered requesting
additional response call) and add in the Observe Option into the response pdu.
This is now added by libcoap, and trying to add in the Observe Option for the
second time in the call-back handler will throw up a Informational warning.
For the client, there is a new function `coap_cancel_observe()` that can be
called to cancel an observation on the server. To use it,
`coap_context_set_block_mode()` has to be called prior to sending the initial
request containing the Observe option.
== Unused function parameters
`UNUSED_PARAM` has been replaced with `COAP_UNUSED`. If `COAP_UNUSED` is used,
then the definition for `UNUSED_PARAM` can be removed.
== CoAP Message IDs
`coap_tid_t` has been replaced with `coap_mid_t`, as well as `COAP_TID_INVALID`
has been replaced with `COAP_MID_INVALID`. This is so that the Message ID aligns
with the definition in RFC7252.
== Async Support
The `async` support has been re-written to simplify usage, and allows the
underlying libcoap to do the main management / work. A primary change is to
register the async request with a defined delay time before triggering - which
if set to 0 is an infinite time and the delay time subsequently updated if
required. Consequently the `coap_async_*()` functions now have different
parameters.
+6
View File
@@ -0,0 +1,6 @@
= Upgrade from 4.3.0 to 4.3.1
== Summary
The source and binary APIs are the same for 4.3.0 and 4.3.1 with just extra
functionality making it forward, but not necessarily backward compatible.
+6
View File
@@ -0,0 +1,6 @@
= Upgrade from 4.3.1 to 4.3.2
== Summary
The source and binary APIs are the same for 4.3.1 and 4.3.2 with just extra
functionality making it forward, but not necessarily backward compatible.
+5
View File
@@ -0,0 +1,5 @@
= Upgrade from 4.3.2 to 4.3.3
== Summary
No code or binary changes required.
+5
View File
@@ -0,0 +1,5 @@
= Upgrade from 4.3.3 to 4.3.4
== Summary
No code or binary changes required.
+145
View File
@@ -0,0 +1,145 @@
# examples/Makefile.am
#
# Copyright (C) 2015 Carsten Schoenert <c.schoenert@t-online.de>
# Copyright (C) 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
#
# SPDX-License-Identifier: BSD-2-Clause
#
# This file is part of the CoAP C library libcoap. Please see README and
# COPYING for terms of use.
EXTRA_DIST = \
share.libcoap.examples.Makefile \
share.libcoap.examples.README \
coap_list.h \
getopt.c \
interop/a_client.conf \
interop/b_server.conf \
interop/c_client.conf \
interop/d_server.conf \
interop/e_client.conf \
interop/f_client.conf \
interop/g_client.conf \
oscore_testcases.sh
# just do nothing if 'BUILD_EXAMPLES' isn't defined
if BUILD_EXAMPLES
# picking up the default warning CFLAGS into AM_CFLAGS
AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
$(WARNING_CFLAGS) $(DTLS_CFLAGS) -std=c99 $(EXTRA_CFLAGS)
#
bin_PROGRAMS =
noinst_PROGRAMS =
check_PROGRAMS =
if HAVE_CLIENT_SUPPORT
bin_PROGRAMS += coap-client@LIBCOAP_DTLS_LIB_EXTENSION_NAME@
check_PROGRAMS += coap-tiny
if BUILD_ADD_DEFAULT_NAMES
noinst_PROGRAMS += coap-client
endif # BUILD_ADD_DEFAULT_NAMES
endif # HAVE_CLIENT_SUPPORT
if HAVE_SERVER_SUPPORT
bin_PROGRAMS += coap-server@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ \
coap-rd@LIBCOAP_DTLS_LIB_EXTENSION_NAME@
check_PROGRAMS += coap-etsi_iot_01 oscore-interop-server
if BUILD_ADD_DEFAULT_NAMES
noinst_PROGRAMS += coap-server coap-rd
endif # BUILD_ADD_DEFAULT_NAMES
if ! HAVE_CLIENT_SUPPORT
coap_server_CPPFLAGS=-DSERVER_CAN_PROXY=0
coap_server@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_CPPFLAGS=-DSERVER_CAN_PROXY=0
endif # ! HAVE_CLIENT_SUPPORT
endif # HAVE_SERVER_SUPPORT
coap_client_SOURCES = coap-client.c
coap_client_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_server_SOURCES = coap-server.c
coap_server_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_rd_SOURCES = coap-rd.c
coap_rd_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_client@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_SOURCES = coap-client.c
coap_client@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_server@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_SOURCES = coap-server.c
coap_server@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_rd@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_SOURCES = coap-rd.c
coap_rd@LIBCOAP_DTLS_LIB_EXTENSION_NAME@_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_etsi_iot_01_SOURCES = etsi_iot_01.c
coap_etsi_iot_01_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
oscore_interop_server_SOURCES = oscore-interop-server.c
oscore_interop_server_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
coap_tiny_SOURCES = tiny.c
coap_tiny_LDADD = $(DTLS_LIBS) \
$(top_builddir)/.libs/libcoap-$(LIBCOAP_NAME_SUFFIX).la
endif # BUILD_EXAMPLES
if BUILD_EXAMPLES_SOURCE
EXAMPLES_DIR = $(DESTDIR)$(datadir)/libcoap/examples
EXAMPLES_SRC = coap-client.c coap-server.c
endif # BUILD_EXAMPLES_SOURCE
## Install example files
install-exec-hook:
if BUILD_EXAMPLES_SOURCE
$(MKDIR_P) $(EXAMPLES_DIR)
(cd $(top_srcdir)/examples ; \
$(INSTALL_DATA) $(EXAMPLES_SRC) ../LICENSE ../COPYING $(EXAMPLES_DIR) ; \
$(INSTALL_DATA) share.libcoap.examples.Makefile $(EXAMPLES_DIR)/Makefile; \
$(INSTALL_DATA) share.libcoap.examples.README $(EXAMPLES_DIR)/README)
endif # BUILD_EXAMPLES_SOURCE
if BUILD_ADD_DEFAULT_NAMES
if [ -d "$(DESTDIR)$(bindir)" ] ; then \
(cd $(DESTDIR)$(bindir) && \
(if [ -f coap-client@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ ] ; then \
rm -f coap-client ; \
$(LN_S) coap-client@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ coap-client ; \
fi ; \
if [ -f coap-server@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ ] ; then \
rm -f coap-server ; \
$(LN_S) coap-server@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ coap-server ; \
fi ; \
if [ -f coap-rd@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ ] ; then \
rm -f coap-rd ; \
$(LN_S) coap-rd@LIBCOAP_DTLS_LIB_EXTENSION_NAME@ coap-rd ; \
fi) \
) ; \
fi
endif # BUILD_ADD_DEFAULT_NAMES
uninstall-hook:
if BUILD_EXAMPLES_SOURCE
rm -rf $(DESTDIR)$(datadir)/libcoap/examples
endif # BUILD_EXAMPLES_SOURCE
if BUILD_ADD_DEFAULT_NAMES
rm -f $(DESTDIR)$(bindir)/coap-client
rm -f $(DESTDIR)$(bindir)/coap-server
rm -f $(DESTDIR)$(bindir)/coap-rd
endif # BUILD_ADD_DEFAULT_NAMES
+43
View File
@@ -0,0 +1,43 @@
This README documents the test cases supported for the 1st ETSI CoAP
plugtest on March 24/25 in Paris, France.
<http://www.etsi.org/plugtests/coap/coap.htm>
Legend:
[+] full support
[o] partial support
[-] no support
[?] needs check
[ ] has open issues
Mandatory Tests
[+] TD_COAP_CORE_01 Perform GET transaction (CON mode)
[+] TD_COAP_CORE_02 Perform POST transaction (CON mode)
[+] TD_COAP_CORE_03 Perform PUT transaction (CON mode)
[+] TD_COAP_CORE_04 Perform DELETE transaction (CON mode)
[+] TD_COAP_CORE_05 Perform GET transaction (NON mode)
[+] TD_COAP_CORE_06 Perform POST transaction (NON mode)
[+] TD_COAP_CORE_07 Perform PUT transaction (NON mode)
[+] TD_COAP_CORE_08 Perform DELETE transaction (NON mode)
[+] TD_COAP_CORE_09 Perform GET transaction with delayed response (CON mode, no piggyback)
[+] TD_COAP_CORE_10 Handle request containing Token option
[+] TD_COAP_CORE_11 Handle request not containing Token option
[+] TD_COAP_CORE_12 Handle request containing several Uri-Path options
[+] TD_COAP_CORE_13 Handle request containing several Uri-Query options
[?] TD_COAP_CORE_14 Interoperate in lossy context (CON mode, piggybacked response)
[?] TD_COAP_CORE_15 Interoperate in lossy context (CON mode, delayed response)
Optional Tests
[ ] TD_COAP_LINK_01 Access to well-known interface for resource discovery
[-] TD_COAP_LINK_02 Use filtered requests for limiting discovery results
[+] TD_COAP_BLOCK_01 Handle GET blockwise transfer for large resource (early negotiation)
[+] TD_COAP_BLOCK_02 Handle GET blockwise transfer for large resource (late negotiation)
[-] TD_COAP_BLOCK_03 Handle PUT blockwise transfer for large resource
[-] TD_COAP_BLOCK_04 Handle POST blockwise transfer for large resource
[-] TD_COAP_OBS_01 Handle resource observation
[-] TD_COAP_OBS_02 Stop resource observation
[-] TD_COAP_OBS_03 Client detection of deregistration (Max-Age)
[-] TD_COAP_OBS_04 Server detection of deregistration (client OFF)
[-] TD_COAP_OBS_05 Server detection of deregistration (explicit RST)
File diff suppressed because it is too large Load Diff
+879
View File
@@ -0,0 +1,879 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 * -*- */
/* coap -- simple implementation of the Constrained Application Protocol (CoAP)
* as defined in RFC 7252
*
* Copyright (C) 2010--2015,2022-2023 Olaf Bergmann <bergmann@tzi.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms of
* use.
*/
/**
* @file coap-rd.c
* @brief CoRE resource directory
*
* @see https://tools.ietf.org/html/draft-ietf-core-resource-directory
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>
#ifdef _WIN32
#define strcasecmp _stricmp
#include "getopt.c"
#if !defined(S_ISDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#else
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#endif
#include <coap3/coap.h>
#define COAP_RESOURCE_CHECK_TIME 2
#define RD_ROOT_STR "rd"
#define RD_ROOT_SIZE 2
static char *cert_file = NULL; /* Combined certificate and private key in PEM */
static char *ca_file = NULL; /* CA for cert_file - for cert checking in PEM */
static char *root_ca_file = NULL; /* List of trusted Root CAs in PEM */
static int verify_peer_cert = 1; /* PKI granularity - by default set */
#define MAX_KEY 64 /* Maximum length of a pre-shared key in bytes. */
static uint8_t key[MAX_KEY];
static ssize_t key_length = 0;
static int key_defined = 0;
static const char *hint = "CoAP";
static size_t extended_token_size = COAP_TOKEN_DEFAULT_MAX;
static int enable_ws = 0;
static int ws_port = 80;
static int wss_port = 443;
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
typedef struct rd_t {
size_t etag_len; /**< actual length of @c etag */
unsigned char etag[8]; /**< ETag for current description */
coap_string_t data; /**< points to the resource description */
} rd_t;
rd_t *resources = NULL;
static ssize_t
cmdline_read_key(char *arg, unsigned char *buf, size_t maxlen) {
size_t len = strnlen(arg, maxlen);
if (len) {
memcpy(buf, arg, len);
return len;
}
return -1;
}
static int
cmdline_ws(char *arg) {
char *cp = strchr(arg, ',');
if (cp) {
if (cp != arg)
ws_port = atoi(arg);
cp++;
if (*cp != '\000')
wss_port = atoi(cp);
} else {
ws_port = atoi(arg);
}
return 1;
}
static inline rd_t *
rd_new(void) {
rd_t *rd;
rd = (rd_t *)coap_malloc(sizeof(rd_t));
if (rd)
memset(rd, 0, sizeof(rd_t));
return rd;
}
static void
rd_delete(rd_t *rd) {
if (rd) {
coap_free(rd->data.s);
coap_free(rd);
}
}
static void
resource_rd_delete(void *ptr) {
rd_delete(ptr);
}
static int quit = 0;
/* SIGINT handler: set quit to 1 for graceful termination */
static void
handle_sigint(int signum COAP_UNUSED) {
quit = 1;
}
static void
hnd_get_resource(coap_resource_t *resource,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
rd_t *rd = coap_resource_get_userdata(resource);
unsigned char buf[3];
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_option(response,
COAP_OPTION_CONTENT_TYPE,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_APPLICATION_LINK_FORMAT),
buf);
if (rd && rd->etag_len)
coap_add_option(response, COAP_OPTION_ETAG, rd->etag_len, rd->etag);
if (rd && rd->data.s)
coap_add_data(response, rd->data.length, rd->data.s);
}
static void
hnd_put_resource(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
#if 1
coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_IMPLEMENTED);
#else /* FIXME */
coap_opt_iterator_t opt_iter;
coap_opt_t *token, *etag;
coap_pdu_t *response;
size_t size = sizeof(coap_hdr_t);
int type = (request->hdr->type == COAP_MESSAGE_CON)
? COAP_MESSAGE_ACK : COAP_MESSAGE_NON;
rd_t *rd = NULL;
unsigned char code; /* result code */
const uint8_t *data;
coap_string_t tmp;
HASH_FIND(hh, resources, resource->uri_path.s, resource->uri_path.length, rd);
if (rd) {
/* found resource object, now check Etag */
etag = coap_check_option(request, COAP_OPTION_ETAG, &opt_iter);
if (!etag || (COAP_OPT_LENGTH(etag) != rd->etag_len)
|| memcmp(COAP_OPT_VALUE(etag), rd->etag, rd->etag_len) != 0) {
if (coap_get_data(request, &tmp.length, &data)) {
tmp.s = (unsigned char *)coap_malloc(tmp.length);
if (!tmp.s) {
coap_log_debug("hnd_put_rd: cannot allocate storage for new rd\n");
code = COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE;
goto finish;
}
coap_free(rd->data.s);
rd->data.s = tmp.s;
rd->data.length = tmp.length;
memcpy(rd->data.s, data, rd->data.length);
}
}
if (etag) {
rd->etag_len = min(COAP_OPT_LENGTH(etag), sizeof(rd->etag));
memcpy(rd->etag, COAP_OPT_VALUE(etag), rd->etag_len);
}
code = COAP_RESPONSE_CODE_CHANGED;
/* FIXME: update lifetime */
} else {
code = COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE;
}
finish:
/* FIXME: do not create a new response but use the old one instead */
response = coap_pdu_init(type, code, request->hdr->id, size);
if (!response) {
coap_log_debug("cannot create response for mid=0x%x\n",
request->hdr->id);
return;
}
if (request->hdr->token_length)
coap_add_token(response, request->hdr->token_length, request->hdr->token);
if (coap_send(ctx, peer, response) == COAP_INVALID_MID) {
coap_log_debug("hnd_get_rd: cannot send response for mid=0x%x\n",
request->hdr->id);
}
#endif
}
static void
hnd_delete_resource(coap_resource_t *resource,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
rd_t *rd = coap_resource_get_userdata(resource);
if (rd) {
rd_delete(rd);
}
/* FIXME: link attributes for resource have been created dynamically
* using coap_malloc() and must be released. */
coap_delete_resource(NULL, resource);
coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
}
static void
hnd_get_rd(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
unsigned char buf[3];
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_option(response,
COAP_OPTION_CONTENT_TYPE,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_APPLICATION_LINK_FORMAT),
buf);
coap_add_option(response,
COAP_OPTION_MAXAGE,
coap_encode_var_safe(buf, sizeof(buf), 0x2ffff), buf);
}
static int
parse_param(const uint8_t *search,
size_t search_len,
unsigned char *data,
size_t data_len,
coap_string_t *result) {
if (result)
memset(result, 0, sizeof(coap_string_t));
if (!search_len)
return 0;
while (search_len <= data_len) {
/* handle parameter if found */
if (memcmp(search, data, search_len) == 0) {
data += search_len;
data_len -= search_len;
/* key is only valid if we are at end of string or delimiter follows */
if (!data_len || *data == '=' || *data == '&') {
while (data_len && *data != '=') {
++data;
--data_len;
}
if (data_len > 1 && result) {
/* value begins after '=' */
result->s = ++data;
while (--data_len && *data != '&') {
++data;
result->length++;
}
}
return 1;
}
}
/* otherwise proceed to next */
while (--data_len && *data++ != '&')
;
}
return 0;
}
static void
add_source_address(coap_resource_t *resource,
const coap_address_t *peer) {
#define BUFSIZE 64
char *buf;
size_t n = 1;
coap_str_const_t attr_val;
buf = (char *)coap_malloc(BUFSIZE);
if (!buf)
return;
n = coap_print_addr(peer, (uint8_t *)buf, BUFSIZE);
if (n) {
attr_val.s = (const uint8_t *)buf;
attr_val.length = n;
coap_add_attr(resource,
coap_make_str_const("A"),
&attr_val,
0);
}
coap_free(buf);
#undef BUFSIZE
}
static rd_t *
make_rd(const coap_pdu_t *pdu) {
rd_t *rd;
const uint8_t *data;
coap_opt_iterator_t opt_iter;
coap_opt_t *etag;
rd = rd_new();
if (!rd) {
coap_log_debug("hnd_get_rd: cannot allocate storage for rd\n");
return NULL;
}
if (coap_get_data(pdu, &rd->data.length, &data)) {
rd->data.s = (unsigned char *)coap_malloc(rd->data.length);
if (!rd->data.s) {
coap_log_debug("hnd_get_rd: cannot allocate storage for rd->data\n");
rd_delete(rd);
return NULL;
}
memcpy(rd->data.s, data, rd->data.length);
}
etag = coap_check_option(pdu, COAP_OPTION_ETAG, &opt_iter);
if (etag) {
rd->etag_len = min(coap_opt_length(etag), sizeof(rd->etag));
memcpy(rd->etag, coap_opt_value(etag), rd->etag_len);
}
return rd;
}
static void
hnd_post_rd(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_resource_t *r;
#define LOCSIZE 68
unsigned char *loc;
size_t loc_size;
coap_string_t h = {0, NULL}, ins = {0, NULL}, rt = {0, NULL}, lt = {0, NULL}; /* store query parameters */
unsigned char *buf;
coap_str_const_t attr_val;
coap_str_const_t resource_val;
loc = (unsigned char *)coap_malloc(LOCSIZE);
if (!loc) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR);
return;
}
memcpy(loc, RD_ROOT_STR, RD_ROOT_SIZE);
loc_size = RD_ROOT_SIZE;
loc[loc_size++] = '/';
/* store query parameters for later use */
if (query) {
parse_param((const uint8_t *)"h", 1, query->s, query->length, &h);
parse_param((const uint8_t *)"ins", 3, query->s, query->length, &ins);
parse_param((const uint8_t *)"lt", 2, query->s, query->length, &lt);
parse_param((const uint8_t *)"rt", 2, query->s, query->length, &rt);
}
if (h.length) { /* client has specified a node name */
memcpy(loc + loc_size, h.s, min(h.length, LOCSIZE - loc_size - 1));
loc_size += min(h.length, LOCSIZE - loc_size - 1);
if (ins.length && loc_size > 1) {
loc[loc_size++] = '-';
memcpy((char *)(loc + loc_size),
ins.s, min(ins.length, LOCSIZE - loc_size - 1));
loc_size += min(ins.length, LOCSIZE - loc_size - 1);
}
} else { /* generate node identifier */
loc_size +=
snprintf((char *)(loc + loc_size), LOCSIZE - loc_size - 1,
"%x", coap_pdu_get_mid(request));
if (loc_size > 1) {
if (ins.length) {
loc[loc_size++] = '-';
memcpy((char *)(loc + loc_size),
ins.s,
min(ins.length, LOCSIZE - loc_size - 1));
loc_size += min(ins.length, LOCSIZE - loc_size - 1);
} else {
coap_tick_t now;
coap_ticks(&now);
loc_size += snprintf((char *)(loc + loc_size),
LOCSIZE - loc_size - 1,
"-%x",
(unsigned int)(now & (unsigned int)-1));
}
}
}
/* TODO:
* - use lt to check expiration
*/
resource_val.s = loc;
resource_val.length = loc_size;
r = coap_resource_init(&resource_val, 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_resource);
coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put_resource);
coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete_resource);
if (ins.s) {
buf = (unsigned char *)coap_malloc(ins.length + 2);
if (buf) {
/* add missing quotes */
buf[0] = '"';
memcpy(buf + 1, ins.s, ins.length);
buf[ins.length + 1] = '"';
attr_val.s = buf;
attr_val.length = ins.length + 2;
coap_add_attr(r,
coap_make_str_const("ins"),
&attr_val,
0);
coap_free(buf);
}
}
if (rt.s) {
buf = (unsigned char *)coap_malloc(rt.length + 2);
if (buf) {
/* add missing quotes */
buf[0] = '"';
memcpy(buf + 1, rt.s, rt.length);
buf[rt.length + 1] = '"';
attr_val.s = buf;
attr_val.length = rt.length + 2;
coap_add_attr(r,
coap_make_str_const("rt"),
&attr_val,
0);
coap_free(buf);
}
}
add_source_address(r, coap_session_get_addr_remote(session));
{
rd_t *rd;
rd = make_rd(request);
if (rd) {
coap_resource_set_userdata(r, rd);
} else {
/* FIXME: send error response and delete r */
}
}
coap_add_resource(coap_session_get_context(session), r);
/* create response */
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
{
/* split path into segments and add Location-Path options */
unsigned char _b[LOCSIZE];
unsigned char *b = _b;
size_t buflen = sizeof(_b);
int nseg;
nseg = coap_split_path(loc, loc_size, b, &buflen);
while (nseg--) {
coap_add_option(response,
COAP_OPTION_LOCATION_PATH,
coap_opt_length(b),
coap_opt_value(b));
b += coap_opt_size(b);
}
}
coap_free(loc);
}
static void
init_resources(coap_context_t *ctx) {
coap_resource_t *r;
r = coap_resource_init(coap_make_str_const(RD_ROOT_STR), 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_rd);
coap_register_request_handler(r, COAP_REQUEST_POST, hnd_post_rd);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("40"), 0);
coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"core.rd\""), 0);
coap_add_attr(r, coap_make_str_const("ins"), coap_make_str_const("\"default\""), 0);
coap_add_resource(ctx, r);
coap_resource_release_userdata_handler(ctx, resource_rd_delete);
}
static void
usage(const char *program, const char *version) {
const char *p;
char buffer[120];
const char *lib_build = coap_package_build();
p = strrchr(program, '/');
if (p)
program = ++p;
fprintf(stderr, "%s v%s -- CoRE Resource Directory implementation\n"
"(c) 2011-2012,2019-2023 Olaf Bergmann <bergmann@tzi.org> and others\n\n"
"Build: %s\n"
"%s\n"
, program, version, lib_build,
coap_string_tls_version(buffer, sizeof(buffer)));
fprintf(stderr, "%s\n", coap_string_tls_support(buffer, sizeof(buffer)));
fprintf(stderr, "\n"
"Usage: %s [-g group] [-G group_if] [-p port] [-v num] [-A address]\n"
"\t [-w [port][,secure_port]] [-T max_token_size] [-V num]\n"
"\t [[-h hint] [-k key]]\n"
"\t [[-c certfile] [-C cafile] [-n] [-R trust_casfile]]\n"
"General Options\n"
"\t-g group\tJoin the given multicast group.\n"
"\t \t\tNote: DTLS over multicast is not currently supported\n"
"\t-G group_if\tUse this interface for listening for the multicast\n"
"\t \t\tgroup. This can be different from the implied interface\n"
"\t \t\tif the -A option is used\n"
"\t-p port\t\tListen on specified port\n"
"\t-v num \t\tVerbosity level (default 4, maximum is 8) for general\n"
"\t \t\tCoAP logging\n"
"\t-w [port][,secure_port]\n"
"\t \t\tEnable WebSockets support on port (WS) and/or secure_port\n"
"\t \t\t(WSS), comma separated\n"
"\t-A address\tInterface address to bind to\n"
"\t-T max_token_length\tSet the maximum token length (8-65804)\n"
"\t-V num \t\tVerbosity level (default 3, maximum is 7) for (D)TLS\n"
"\t \t\tlibrary logging\n"
"PSK Options (if supported by underlying (D)TLS library)\n"
"\t-h hint\t\tIdentity Hint. Default is CoAP. Zero length is no hint\n"
"\t-k key \t\tPre-Shared Key. This argument requires (D)TLS with PSK\n"
"\t \t\tto be available. This cannot be empty if defined.\n"
"\t \t\tNote that both -c and -k need to be defined\n"
"\t \t\tfor both PSK and PKI to be concurrently supported\n"
"PKI Options (if supported by underlying (D)TLS library)\n"
"\t-c certfile\tPEM file containing both CERTIFICATE and PRIVATE KEY\n"
"\t \t\tThis argument requires (D)TLS with PKI to be available\n"
"\t-n \t\tDisable remote peer certificate checking. This gives\n"
"\t \t\tclients the ability to use PKI, but without any defined\n"
"\t \t\tcertificates\n"
"\t-C cafile\tPEM file that contains a list of one or\n"
"\t \t\tmore CAs that are to be passed to the client for the\n"
"\t \t\tclient to determine what client certificate to use.\n"
"\t \t\tNormally, this list of CAs would be the root CA and and\n"
"\t \t\tany intermediate CAs. Ideally the server certificate\n"
"\t \t\tshould be signed by the same CA so that mutual\n"
"\t \t\tauthentication can take place. The contents of cafile\n"
"\t \t\tare added to the trusted store of root CAs.\n"
"\t \t\tUsing the -C or -R options will will trigger the\n"
"\t \t\tvalidation of the client certificate unless overridden\n"
"\t \t\tby the -n option\n"
"\t-R trust_casfile\tPEM file containing the set of trusted root CAs\n"
"\t \t\tthat are to be used to validate the client certificate.\n"
"\t \t\tAlternatively, this can point to a directory containing\n"
"\t \t\ta set of CA PEM files.\n"
"\t \t\tUsing '-R trust_casfile' disables common CA mutual\n"
"\t \t\tauthentication which can only be done by using\n"
"\t \t\t'-C cafile'.\n"
"\t \t\tUsing the -C or -R options will will trigger the\n"
"\t \t\tvalidation of the client certificate unless overridden\n"
"\t \t\tby the -n option\n"
,
program);
}
static void
fill_keystore(coap_context_t *ctx) {
if (cert_file == NULL && key_defined == 0) {
if (coap_dtls_is_supported() || coap_tls_is_supported()) {
coap_log_debug("(D)TLS not enabled as neither -k or -c options specified\n");
}
}
if (cert_file) {
coap_dtls_pki_t dtls_pki;
memset(&dtls_pki, 0, sizeof(dtls_pki));
dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION;
if (ca_file || root_ca_file) {
/*
* Add in additional certificate checking.
* This list of enabled can be tuned for the specific
* requirements - see 'man coap_encryption'.
*/
dtls_pki.verify_peer_cert = verify_peer_cert;
dtls_pki.check_common_ca = !root_ca_file;
dtls_pki.allow_self_signed = 1;
dtls_pki.allow_expired_certs = 1;
dtls_pki.cert_chain_validation = 1;
dtls_pki.cert_chain_verify_depth = 2;
dtls_pki.check_cert_revocation = 1;
dtls_pki.allow_no_crl = 1;
dtls_pki.allow_expired_crl = 1;
dtls_pki.validate_cn_call_back = NULL;
dtls_pki.cn_call_back_arg = NULL;
dtls_pki.validate_sni_call_back = NULL;
dtls_pki.sni_call_back_arg = NULL;
}
dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM;
dtls_pki.pki_key.key.pem.public_cert = cert_file;
dtls_pki.pki_key.key.pem.private_key = cert_file;
dtls_pki.pki_key.key.pem.ca_file = ca_file;
/* If general root CAs are defined */
if (root_ca_file) {
struct stat stbuf;
if ((stat(root_ca_file, &stbuf) == 0) && S_ISDIR(stbuf.st_mode)) {
coap_context_set_pki_root_cas(ctx, NULL, root_ca_file);
} else {
coap_context_set_pki_root_cas(ctx, root_ca_file, NULL);
}
}
coap_context_set_pki(ctx, &dtls_pki);
}
if (key_defined) {
coap_dtls_spsk_t dtls_psk;
memset(&dtls_psk, 0, sizeof(dtls_psk));
dtls_psk.version = COAP_DTLS_SPSK_SETUP_VERSION;
dtls_psk.validate_id_call_back = NULL;
dtls_psk.validate_sni_call_back = NULL;
dtls_psk.psk_info.hint.s = (const uint8_t *)hint;
dtls_psk.psk_info.hint.length = hint ? strlen(hint) : 0;
dtls_psk.psk_info.key.s = key;
dtls_psk.psk_info.key.length = key_length;
coap_context_set_psk2(ctx, &dtls_psk);
}
}
static coap_context_t *
get_context(const char *node, const char *port) {
coap_context_t *ctx = NULL;
coap_addr_info_t *info = NULL;
coap_addr_info_t *info_list = NULL;
coap_str_const_t local;
int have_ep = 0;
uint16_t u_s_port = 0;
uint16_t s_port = 0;
int scheme_hint_bits = 0;
ctx = coap_new_context(NULL);
if (!ctx) {
return NULL;
}
/* Need PKI/RPK/PSK set up before we set up (D)TLS endpoints */
fill_keystore(ctx);
if (node) {
local.s = (const uint8_t *)node;
local.length = strlen(node);
}
if (port) {
u_s_port = atoi(port);
s_port = u_s_port + 1;
}
scheme_hint_bits =
coap_get_available_scheme_hint_bits(cert_file != NULL || key_defined != 0,
enable_ws, COAP_PROTO_NONE);
info_list = coap_resolve_address_info(node ? &local : NULL, u_s_port, s_port,
ws_port, wss_port,
AI_PASSIVE | AI_NUMERICHOST,
scheme_hint_bits,
COAP_RESOLVE_TYPE_LOCAL);
for (info = info_list; info != NULL; info = info->next) {
coap_endpoint_t *ep;
ep = coap_new_endpoint(ctx, &info->addr, info->proto);
if (!ep) {
coap_log_warn("cannot create endpoint for proto %u\n",
info->proto);
} else {
have_ep = 1;
}
}
coap_free_address_info(info_list);
if (!have_ep) {
coap_log_err("No context available for interface '%s'\n", node);
coap_free_context(ctx);
return NULL;
}
return ctx;
}
static int
cmdline_read_extended_token_size(char *arg) {
extended_token_size = strtoul(arg, NULL, 0);
if (extended_token_size < COAP_TOKEN_DEFAULT_MAX) {
coap_log_err("Extended Token Length must be 8 or greater\n");
return 0;
} else if (extended_token_size > COAP_TOKEN_EXT_MAX) {
coap_log_err("Extended Token Length must be 65804 or less\n");
return 0;
}
return 1;
}
int
main(int argc, char **argv) {
coap_context_t *ctx;
int result;
char addr_str[NI_MAXHOST] = "::";
char port_str[NI_MAXSERV] = "5683";
char *group = NULL;
char *group_if = NULL;
int opt;
coap_log_t log_level = COAP_LOG_WARN;
coap_log_t dtls_log_level = COAP_LOG_ERR;
#ifndef _WIN32
struct sigaction sa;
#endif
/* Initialize libcoap library */
coap_startup();
while ((opt = getopt(argc, argv, "A:c:C:g:G:h:k:n:R:p:v:T:V:w:")) != -1) {
switch (opt) {
case 'A' :
strncpy(addr_str, optarg, NI_MAXHOST-1);
addr_str[NI_MAXHOST - 1] = '\0';
break;
case 'c' :
cert_file = optarg;
break;
case 'C' :
ca_file = optarg;
break;
case 'g' :
group = optarg;
break;
case 'G' :
group_if = optarg;
break;
case 'h' :
if (!optarg[0]) {
hint = NULL;
break;
}
hint = optarg;
break;
case 'k' :
key_length = cmdline_read_key(optarg, key, MAX_KEY);
if (key_length < 0) {
coap_log_crit("Invalid Pre-Shared Key specified\n");
break;
}
key_defined = 1;
break;
case 'n':
verify_peer_cert = 0;
break;
case 'p' :
strncpy(port_str, optarg, NI_MAXSERV-1);
port_str[NI_MAXSERV - 1] = '\0';
break;
case 'R' :
root_ca_file = optarg;
break;
case 'T':
if (!cmdline_read_extended_token_size(optarg)) {
exit(1);
}
break;
case 'v' :
log_level = strtol(optarg, NULL, 10);
break;
case 'V':
dtls_log_level = strtol(optarg, NULL, 10);
break;
case 'w':
if (!coap_ws_is_supported() || !cmdline_ws(optarg)) {
fprintf(stderr, "WebSockets not enabled in libcoap\n");
exit(1);
}
enable_ws = 1;
break;
default:
usage(argv[0], LIBCOAP_PACKAGE_VERSION);
exit(1);
}
}
coap_set_log_level(log_level);
coap_dtls_set_log_level(dtls_log_level);
ctx = get_context(addr_str, port_str);
if (!ctx)
return -1;
if (group)
coap_join_mcast_group_intf(ctx, group, group_if);
init_resources(ctx);
if (extended_token_size > COAP_TOKEN_DEFAULT_MAX)
coap_context_set_max_token_size(ctx, extended_token_size);
#ifdef _WIN32
signal(SIGINT, handle_sigint);
#else
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = handle_sigint;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* So we do not exit on a SIGPIPE */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
#endif
while (!quit) {
result = coap_io_process(ctx, COAP_RESOURCE_CHECK_TIME * 1000);
if (result >= 0) {
/* coap_check_resource_list( ctx ); */
}
}
coap_free_context(ctx);
coap_cleanup();
return 0;
}
File diff suppressed because it is too large Load Diff
+66
View File
@@ -0,0 +1,66 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 * -*- */
/* coap_list.c -- CoAP list structures
*
* Copyright (C) 2010,2011,2015 Olaf Bergmann <bergmann@tzi.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms of
* use.
*/
/*
* examples/coap_list.[ch] are DEPRECATED. You should be using
* struct coap_optlist_t instead with the following functions which are a part
* of libcoap.
*
* coap_new_optlist()
* coap_insert_optlist()
* coap_delete_optlist()
* coap_add_optlist_pdu()
*
* See 'man coap_pdu_setup' for further information.
*
* examples/coap_list.[ch] files will be removed in a future release
* They are left here to support building backward compatability of old versions
* of coap-client
*/
#include <stdio.h>
#include <string.h>
#include <coap3/coap.h>
int
coap_insert(coap_list_t **head, coap_list_t *node) {
if (!node) {
coap_log_warn("cannot create option Proxy-Uri\n");
} else {
/* must append at the list end to avoid re-ordering of
* options during sort */
LL_APPEND((*head), node);
}
return node != NULL;
}
int
coap_delete(coap_list_t *node) {
if (node) {
coap_free(node);
}
return 1;
}
void
coap_delete_list(coap_list_t *queue) {
coap_list_t *elt, *tmp;
if (!queue)
return;
LL_FOREACH_SAFE(queue, elt, tmp) {
coap_delete(elt);
}
}
+52
View File
@@ -0,0 +1,52 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 * -*- */
/* coap_list.h -- CoAP list structures
*
* Copyright (C) 2010,2011,2015 Olaf Bergmann <bergmann@tzi.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms of
* use.
*/
/*
* examples/coap_list.[ch] are DEPRECATED. You should be using
* struct coap_optlist_t instead with the following functions which are a part
* of libcoap.
*
* coap_new_optlist()
* coap_insert_optlist()
* coap_delete_optlist()
* coap_add_optlist_pdu()
*
* See 'man coap_pdu_setup' for further information.
*
* examples/coap_list.[ch] files will be removed in a future release
* They are left here to support building backward compatibility of old versions
* of coap-client
*/
#ifndef COAP_LIST_H_
#define COAP_LIST_H_
#include <coap3/utlist.h>
typedef struct coap_list_t {
struct coap_list_t *next;
char data[];
} coap_list_t;
/**
* Adds node to given queue, ordered by specified order function. Returns 1
* when insert was successful, 0 otherwise.
*/
int coap_insert(coap_list_t **queue, coap_list_t *node);
/* destroys specified node */
int coap_delete(coap_list_t *node);
/* removes all items from given queue and frees the allocated storage */
void coap_delete_list(coap_list_t *queue);
#endif /* COAP_LIST_H_ */
+2
View File
@@ -0,0 +1,2 @@
contiki-ng/
server.native
+33
View File
@@ -0,0 +1,33 @@
CONTIKI=contiki-ng
TARGET?=native
WITH_CONTIKI_NG_BRANCH=release/v4.9
all: $(CONTIKI) check-version server
$(CONTIKI):
git clone --depth 1 https://github.com/contiki-ng/contiki-ng.git $@
echo "Updating $(CONTIKI) to ${WITH_CONTIKI_NG_BRANCH}"
(cd ${CONTIKI} ; git pull --tags 2> /dev/null ; git checkout ${WITH_CONTIKI_NG_BRANCH})
cd $(CONTIKI)/os/net/app-layer && rm -rf libcoap && ln -s ../../../../../.. libcoap
check-version:
@(if [ -d $(CONTIKI) ] ; then \
cd $(CONTIKI) ; \
TAG=`git describe --tags --all`; \
if [ "$$TAG" != ${WITH_CONTIKI_NG_BRANCH} ] ; then \
if [ "$$TAG" != "tags/${WITH_CONTIKI_NG_BRANCH}" ] ; then \
git pull --tags 2> /dev/null ; \
echo "Updating $(CONTIKI) to ${WITH_CONTIKI_NG_BRANCH}" ; \
git checkout ${WITH_CONTIKI_NG_BRANCH} ; \
cd os/net/app-layer && rm -rf libcoap && ln -s ../../../../../.. libcoap ; \
fi ; \
fi ; \
fi)
server: $(CONTIKI)
$(MAKE) -f Makefile.contiki CONTIKI=$(CONTIKI) TARGET=$(TARGET) server
clean:
$(MAKE) -f Makefile.contiki CONTIKI=$(CONTIKI) TARGET=$(TARGET) clean
rm -rf build
+12
View File
@@ -0,0 +1,12 @@
CONTIKI_PROJECT = server
all: $(CONTIKI_PROJECT)
CONTIKI = ../../../..
ifneq ($(NODE_ADDR),)
CFLAGS += -DNODE_ADDR=$(NODE_ADDR)
endif
MODULES += os/net/app-layer/libcoap
include $(CONTIKI)/Makefile.include
+24
View File
@@ -0,0 +1,24 @@
Example of libcoap running on Contiki-NG
========================================
To run the example, do
$ make
$ sudo ./server.native
and query `coap://[fd00::302:304:506:708]/time?ticks` with any coap tool,
or query `coap://[fd00::302:304:506:708]/.well-known/core`
This will
* download Contiki-NG from the upstream git sources
* build the server application
* run the server application, creating a virtual network device tap0 (unless
that exists)
* configure your network interface to make the server accessible.
* return the appropriate response from the server to the client.
The server creates a resource for 'time' with a query 'ticks'. This is
reported for `.well-known/core`. The work flow for adding more resources does
not differ from regular libcoap usage.
+1
View File
@@ -0,0 +1 @@
../../coap_config.h.contiki
+7
View File
@@ -0,0 +1,7 @@
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#include "coap_config.h"
#define LOG_CONF_LEVEL_COAP 5
#endif /* PROJECT_CONF_H_ */
+192
View File
@@ -0,0 +1,192 @@
/* coap-server.c -- Example CoAP server using Contiki and libcoap
*
* Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include "contiki-net.h"
#include "coap3/coap.h"
static coap_context_t *coap_context;
static clock_time_t clock_offset;
/* changeable clock base (see handle_put_time()) */
static clock_time_t my_clock_base = 0;
static coap_resource_t *time_resource = NULL; /* just for testing */
PROCESS(coap_server_process, "CoAP server process");
AUTOSTART_PROCESSES(&coap_server_process);
/*---------------------------------------------------------------------------*/
void
init_coap_server(coap_context_t **ctx) {
uip_ds6_addr_t *my_address;
coap_address_t listen_addr;
assert(ctx);
my_address = uip_ds6_get_global(ADDR_PREFERRED);
uip_ipaddr_copy(&listen_addr.addr, &my_address->ipaddr);
coap_address_set_port(&listen_addr, COAP_DEFAULT_PORT);
*ctx = coap_new_context(&listen_addr);
if (!*ctx) {
coap_log_crit("cannot create CoAP context\r\n");
}
coap_context_set_max_idle_sessions(*ctx, 2);
}
/*---------------------------------------------------------------------------*/
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
void
hnd_get_time(coap_resource_t *resource, coap_session_t *session,
const coap_pdu_t *request, const coap_string_t *query,
coap_pdu_t *response) {
unsigned char buf[40];
size_t len;
coap_tick_t now;
coap_tick_t t;
if (my_clock_base) {
/* calculate current time */
coap_ticks(&t);
now = my_clock_base + (t / COAP_TICKS_PER_SECOND);
if (query != NULL
&& coap_string_equal(query, coap_make_str_const("ticks"))) {
/* output ticks */
len = snprintf((char *)buf, sizeof(buf), "%u", (unsigned int)now);
} else { /* output human-readable time */
struct tm *tmp;
time_t tnow = now;
tmp = gmtime(&tnow);
if (!tmp) {
/* If 'tnow' is not valid */
coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
return;
} else {
len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
}
}
coap_add_data_blocked_response(request, response,
COAP_MEDIATYPE_TEXT_PLAIN, 1,
len,
buf);
} else {
/* if my_clock_base was deleted, we pretend to have no such resource */
coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
}
}
void
init_coap_resources(coap_context_t *ctx) {
coap_resource_t *r;
#if 0
r = coap_resource_init(NULL, 0, 0);
coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"General Info\""), 0);
coap_add_resource(ctx, r);
#endif
/* store clock base to use in /time */
my_clock_base = clock_offset;
r = coap_resource_init(coap_make_str_const("time"), 0);
if (!r)
goto error;
coap_resource_set_get_observable(r, 1);
time_resource = r;
coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time);
#if 0
coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time);
coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time);
#endif
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
/* coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"Internal Clock\""), 0); */
coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"ticks\""), 0);
coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""), 0);
coap_add_resource(ctx, r);
#if 0
if (coap_async_is_supported()) {
r = coap_resource_init(coap_make_str_const("async"), 0);
coap_register_handler(r, COAP_REQUEST_GET, hnd_get_async);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_resource(ctx, r);
}
#endif
return;
error:
coap_log_crit("cannot create resource\n");
}
/* struct etimer notify_timer; */
struct etimer dirty_timer;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(coap_server_process, ev, data) {
PROCESS_BEGIN();
/* Initialize libcoap library */
coap_startup();
clock_offset = clock_time();
init_coap_server(&coap_context);
if (!coap_context) {
coap_log_emerg("cannot create context\n");
PROCESS_EXIT();
}
init_coap_resources(coap_context);
/* etimer_set(&notify_timer, 5 * CLOCK_SECOND); */
etimer_set(&dirty_timer, 30 * CLOCK_SECOND);
while (1) {
PROCESS_YIELD();
if (ev == PROCESS_EVENT_TIMER && etimer_expired(&dirty_timer)) {
coap_resource_notify_observers(time_resource, NULL);
etimer_reset(&dirty_timer);
}
}
coap_cleanup();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
+210
View File
@@ -0,0 +1,210 @@
#!/bin/bash
# test coap implementation for the ETSI CoAP Plugtest in March 2012
# with test cases described in Plugtests Guide First Draft V0.0.16
COAP_CLIENT=./coap-client
tcpdump=/usr/sbin/tcpdump
DEFAULTPORT=5683
CLIENTPORT=61701
# directory for logging
LOGDIR=logs
# set client's verbose level
callopts=" -v 5"
longtimeout=180
clienttimeout=$longtimeout
timeoutcmd=/usr/bin/timeout
#URIREGEX=.*\/.*
# resembles approximately an ip address
IPADDRREGEX="^[1-2]?[0-9]{1,2}\.[1-2]?[0-9]{1,2}\.[1-2]?[0-9]{1,2}\.[1-2]?[0-9]{1,2}"
# FIXME IPV6 address
IP6REGEX=".*:.*:.*"
# Testcase groups
CORE=( TD_COAP_CORE_01 TD_COAP_CORE_02 TD_COAP_CORE_03
TD_COAP_CORE_04 TD_COAP_CORE_05 TD_COAP_CORE_06 TD_COAP_CORE_07
TD_COAP_CORE_08 TD_COAP_CORE_09 TD_COAP_CORE_10 TD_COAP_CORE_11
TD_COAP_CORE_12 TD_COAP_CORE_13 TD_COAP_CORE_14 TD_COAP_CORE_15 )
LINK=( TD_COAP_LINK_01 TD_COAP_LINK_02 )
BLOCK=( TD_COAP_BLOCK_01 TD_COAP_BLOCK_02 TD_COAP_BLOCK_03 TD_COAP_BLOCK_04 )
OBS=( TD_COAP_OBS_01 TD_COAP_OBS_02 TD_COAP_OBS_03 TD_COAP_OBS_04 TD_COAP_OBS_05 )
testgroups=( CORE LINK BLOCK OBS )
# if no test cases are specified, we want to run all tests
testnumber=-1
group=''
source `dirname $0`/etsi_testcases.sh
function usage {
echo "Usage: `basename $0` [-n testnumber] [-g groupname] [-t timeout] [-P server_port] [-p client port] [-d logdir] [-v] -i interface server_address" 1>&2
echo "-n test case to be accomplished" 1>&2
echo "-g group to be tested" 1>&2
echo "-t time in seconds until timout for single test" 1>&2
echo "-i interface to use for tcpdump" 1>&2
echo "-P port of server" 1>&2
echo "-p port client listens on" 1>&2
echo "-d directory for logfiles" 1>&2
echo "-v verbose level" 1>&2
}
function run_test {
tn=$1
clientopts=''
if [ -z $1 ]; then
echo "missing argument for run_test"
exit 1
fi
echo -e "running test: $tn"
if [ $(type -t $tn) ] ; then
$tn $tn
echo
else
echo "not implemented"
echo
fi
}
while getopts "n:g:t:i:P:p:d:v" OPTION;
do
# A missing argument for an option leads getopts to take the next
# option as the parameter. We want to prevent that.
case $OPTARG in
-*) echo "Missing argument for option \"-$OPTION\"."
echo $USAGE
exit 1
;;
esac
case $OPTION in
n) # number of test case
testnumber=$((OPTARG-1))
;;
g) # name of test group
# is there a group with that name?
for i in "${testgroups[@]}"
do
# group doesn't have to be case sensitive
tmpgroup=$(echo $OPTARG | tr '[:lower:]' '[:upper:]')
if [ $i == $tmpgroup ] ; then
group=$tmpgroup
break
fi
done
if [ -z $group ] ; then
echo "No such group:" $OPTARG". Available groups are: ${testgroups[@]}"
exit 1
fi
;;
t)
# add timeout to client parameters
clienttimeout=$((OPTARG))
callopts="$callopts -B $clienttimeout"
;;
i)
# interface tcpdump listens on
INTERFACE=$OPTARG
;;
P)
# port the server listens on
SERVERPORT=$((OPTARG))
;;
p)
# port the client listens on
CLIENTPORT=$((OPTARG))
;;
d)
# directory tcpdump writes the logfiles into
LOGDIR=$OPTARG
;;
v)
verbose=1
;;
?)
# any other option is invalid
echo -e $USAGE 1>&2
exit 1
;;
esac
done
# catch last argument: server address
ARGS=$(($#+1))
SERVERADDRESS=${@: -1}
if [[ ! $((ARGS-OPTIND)) -eq 1 ]]; then
echo -e "\nno server address specified"
usage
exit 1
fi
# if no port number was specified by user, the server address for the
# coap-client is $SERVERADDRESS
if [ -z $SERVERPORT ]; then
SERVERPORT=$DEFAULTPORT
if [[ $SERVERADDRESS =~ $IP6REGEX ]]; then
SERVERTUP=\[$SERVERADDRESS\]
else
SERVERTUP=$SERVERADDRESS
fi
else
if [[ $SERVERADDRESS =~ $IP6REGEX ]]; then
SERVERTUP=\[$SERVERADDRESS\]:$SERVERPORT
else
SERVERTUP=$SERVERADDRESS:$SERVERPORT
fi
fi
# create directory for logging, if it's not already there
if [[ ! -e $LOGDIR ]]; then
mkdir -p $LOGDIR
if [ $? ]; then
echo created directory \""$LOGDIR"\" for logging
fi
fi
# the interface for tcpdump is mandatory
if [ -z $INTERFACE ]; then
echo -e "\nno interface given"
exit 1
fi
# determine which tests to run
if [ -n "$group" ] ; then
echo group: $group
if [[ ! $testnumber -eq -1 ]] ; then
groupsize=$(eval "echo \${#$(echo $group)[@]}")
# is there a testcase with number $testnumber in group $group
if [ $testnumber -ge $groupsize -o $testnumber -lt 0 ] ; then
echo "No such testcase number: $OPTARG. Test cases numbers are 1 to" $groupsize
exit 1
else
# run test with group $group and number $testnumber
run_test $(eval "echo \${$(echo $group)[$testnumber]}")
fi
else
# if no testnumber was specified, we want to run all tests in that group
for i in $(eval "echo \${$(echo $group)[@]}") ; do
run_test $i
done
fi
else
# run all tests of all groups
for j in ${testgroups[@]} ; do
echo "group: $j"
for k in $(eval "echo \${$(echo $j)[@]}") ; do
run_test $k
done
done
fi
+636
View File
@@ -0,0 +1,636 @@
/* CoAP server for first ETSI CoAP plugtest, March 2012
*
* Copyright (C) 2012--2013 Olaf Bergmann <bergmann@tzi.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see
* README for terms of use.
*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#include <coap3/coap.h>
#define COAP_RESOURCE_CHECK_TIME_SEC 1
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
/* temporary storage for dynamic resource representations */
static int quit = 0;
#define COAP_OPT_BLOCK_SZX_MAX 6 /**< allowed maximum for block szx value */
#define REQUIRE_ETAG 0x01 /* flag for coap_payload_t: require ETag option */
typedef struct {
unsigned int flags; /* some flags to control behavior */
size_t max_data; /* maximum size allocated for @p data */
uint16_t media_type; /* media type for this object */
size_t length; /* length of data */
unsigned char data[]; /* the actual contents */
} coap_payload_t;
/* SIGINT handler: set quit to 1 for graceful termination */
static void
handle_sigint(int signum COAP_UNUSED) {
quit = 1;
}
#define INDEX "libcoap server for ETSI CoAP Plugtest, March 2012, Paris\n" \
"Copyright (C) 2012 Olaf Bergmann <bergmann@tzi.org>\n\n"
static coap_payload_t *
coap_new_payload(size_t size) {
coap_payload_t *p;
p = (coap_payload_t *)coap_malloc(sizeof(coap_payload_t) + size);
if (p) {
memset(p, 0, sizeof(coap_payload_t));
p->max_data = size;
}
return p;
}
static inline coap_payload_t *
coap_find_payload(coap_resource_t *resource) {
return coap_resource_get_userdata(resource);
}
static void
coap_add_payload(coap_resource_t *resource, coap_payload_t *payload) {
assert(payload);
coap_resource_set_userdata(resource, payload);
}
static inline void
coap_delete_payload(coap_resource_t *resource) {
coap_free(coap_resource_get_userdata(resource));
coap_resource_set_userdata(resource, NULL);
}
static void
coap_free_userdata(void *data) {
coap_free(data);
}
#if 0
static void
hnd_get_index(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
coap_pdu_t *request COAP_UNUSED,
coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
unsigned char buf[3];
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_TEXT_PLAIN),
buf);
coap_add_option(response, COAP_OPTION_MAXAGE,
coap_encode_var_safe(buf, sizeof(buf), 0x2ffff), buf);
coap_add_data(response, strlen(INDEX), (const uint8_t *)INDEX);
}
#endif
static void
hnd_get_resource(coap_resource_t *resource,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_payload_t *test_payload;
test_payload = coap_find_payload(resource);
if (!test_payload) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR);
return;
}
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_blocked_response(request, response,
test_payload->media_type, -1,
test_payload->length,
test_payload->data);
return;
}
/* DELETE handler for dynamic resources created by POST /test */
static void
hnd_delete_resource(coap_resource_t *resource,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_payload_t *payload;
payload = coap_find_payload(resource);
if (payload)
coap_delete_payload(resource);
coap_delete_resource(NULL, resource);
coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
}
static void
hnd_post_test(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_opt_iterator_t opt_iter;
coap_opt_t *option;
coap_payload_t *test_payload;
size_t len;
coap_str_const_t *uri;
const uint8_t *data;
#define BUFSIZE 20
int res;
unsigned char _buf[BUFSIZE];
unsigned char *buf = _buf;
size_t buflen = BUFSIZE;
coap_get_data(request, &len, &data);
/* allocate storage for resource and to hold URI */
test_payload = coap_new_payload(len);
snprintf((char *)buf, buflen, "test/%p", (void *)test_payload);
uri = coap_new_str_const(buf, strlen((char *)buf));
if (!(test_payload && uri)) {
coap_log_crit("cannot allocate new resource under /test");
coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR);
coap_free(test_payload);
coap_free(uri);
} else {
coap_resource_t *r;
test_payload->length = len;
memcpy(test_payload->data, data, len);
r = coap_resource_init(uri, COAP_RESOURCE_FLAGS_RELEASE_URI);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_resource);
coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete_resource);
/* set media_type if available */
option = coap_check_option(request, COAP_OPTION_CONTENT_TYPE, &opt_iter);
if (option) {
test_payload->media_type =
coap_decode_var_bytes(coap_opt_value(option), coap_opt_length(option));
}
coap_add_resource(coap_session_get_context(session), r);
coap_add_payload(r, test_payload);
/* add Location-Path */
res = coap_split_path(uri->s, uri->length, buf, &buflen);
while (res--) {
coap_add_option(response, COAP_OPTION_LOCATION_PATH,
coap_opt_length(buf), coap_opt_value(buf));
buf += coap_opt_size(buf);
}
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
}
}
static void
hnd_put_test(coap_resource_t *resource,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_opt_iterator_t opt_iter;
coap_opt_t *option;
coap_payload_t *payload;
size_t len;
const uint8_t *data;
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
coap_get_data(request, &len, &data);
payload = coap_find_payload(resource);
if (payload && payload->max_data < len) { /* need more storage */
coap_delete_payload(resource);
payload = NULL;
/* bug: when subsequent coap_new_payload() fails, our old contents
is gone */
}
if (!payload) { /* create new payload */
payload = coap_new_payload(len);
if (!payload)
goto error;
coap_add_payload(resource, payload);
}
payload->length = len;
memcpy(payload->data, data, len);
option = coap_check_option(request, COAP_OPTION_CONTENT_TYPE, &opt_iter);
if (option) {
/* set media type given in request */
payload->media_type =
coap_decode_var_bytes(coap_opt_value(option), coap_opt_length(option));
} else {
/* set default value */
payload->media_type = COAP_MEDIATYPE_TEXT_PLAIN;
}
/* FIXME: need to change attribute ct of resource.
To do so, we need dynamic management of the attribute value
*/
return;
error:
coap_log_warn("cannot modify resource\n");
coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR);
}
static void
hnd_delete_test(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
/* the ETSI validation tool does not like empty resources... */
#if 0
coap_payload_t *payload;
payload = coap_find_payload(resource);
if (payload)
payload->length = 0;
#endif
coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
}
static void
hnd_get_query(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_opt_iterator_t opt_iter;
coap_opt_filter_t f;
coap_opt_t *q;
size_t len, L;
unsigned char buf[70];
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_option(response, COAP_OPTION_CONTENT_TYPE,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_TEXT_PLAIN),
buf);
coap_option_filter_clear(&f);
coap_option_filter_set(&f, COAP_OPTION_URI_QUERY);
coap_option_iterator_init(request, &opt_iter, &f);
len = 0;
while ((len < sizeof(buf)) && (q = coap_option_next(&opt_iter))) {
L = min(sizeof(buf) - len, 11);
memcpy(buf + len, "Uri-Query: ", L);
len += L;
L = min(sizeof(buf) - len, coap_opt_length(q));
memcpy(buf + len, coap_opt_value(q), L);
len += L;
if (len < sizeof(buf))
buf[len++] = '\n';
}
coap_add_data(response, len, buf);
}
/* handler for TD_COAP_CORE_16 */
static void
hnd_get_separate(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_opt_iterator_t opt_iter;
coap_opt_t *option;
coap_opt_filter_t f;
unsigned long delay = 5;
if (request) {
coap_async_t *async;
coap_bin_const_t token = coap_pdu_get_token(request);
async = coap_find_async(session, token);
if (!async) {
/* Set up an async request to trigger delay in the future */
/* search for option delay in query list */
coap_option_filter_clear(&f);
coap_option_filter_set(&f, COAP_OPTION_URI_QUERY);
coap_option_iterator_init(request, &opt_iter, &f);
while ((option = coap_option_next(&opt_iter))) {
if (strncmp("delay=", (const char *)coap_opt_value(option), 6) == 0) {
unsigned int i;
unsigned long d = 0;
for (i = 6; i < coap_opt_length(option); ++i)
d = d * 10 + coap_opt_value(option)[i] - '0';
/* don't allow delay to be less than COAP_RESOURCE_CHECK_TIME*/
delay = d < COAP_RESOURCE_CHECK_TIME_SEC
? COAP_RESOURCE_CHECK_TIME_SEC
: d;
coap_log_debug("set delay to %lu\n", delay);
break;
}
}
async = coap_register_async(session,
request,
COAP_TICKS_PER_SECOND * delay);
if (async == NULL) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE);
return;
}
/* Not setting response code will cause empty ACK to be sent
if Confirmable */
return;
}
}
/* no request (observe) or async set up, so this is the delayed request */
coap_add_data(response, 4, (const uint8_t *)"done");
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
/* async is automatically removed by libcoap */
}
static coap_payload_t *
make_large(const char *filename) {
coap_payload_t *payload;
FILE *inputfile = NULL;
struct stat statbuf;
if (!filename)
return NULL;
/* read from specified input file */
if (stat(filename, &statbuf) < 0) {
coap_log_warn("cannot stat file %s\n", filename);
return NULL;
}
payload = coap_new_payload(statbuf.st_size);
if (!payload)
return NULL;
inputfile = fopen(filename, "r");
if (!inputfile) {
coap_log_warn("cannot read file %s\n", filename);
coap_free(payload);
return NULL;
}
payload->length = fread(payload->data, 1, statbuf.st_size, inputfile);
payload->media_type = 41;
fclose(inputfile);
return payload;
}
static void
init_resources(coap_context_t *ctx) {
coap_resource_t *r;
coap_payload_t *test_payload;
test_payload = coap_new_payload(200);
if (!test_payload) {
coap_log_crit("cannot allocate resource /test");
} else {
test_payload->length = 13;
memcpy(test_payload->data, "put data here", test_payload->length);
/* test_payload->media_type is 0 anyway */
r = coap_resource_init(coap_make_str_const("test"), 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_resource);
coap_register_request_handler(r, COAP_REQUEST_POST, hnd_post_test);
coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put_test);
coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete_test);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("test"), 0);
coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("core#b"), 0);
#if 0
coap_add_attr(r, coap_make_str_const("obs"), NULL, 0);
#endif
coap_add_resource(ctx, r);
coap_resource_release_userdata_handler(ctx, coap_free_userdata);
coap_add_payload(r, test_payload);
}
/* TD_COAP_BLOCK_01
* TD_COAP_BLOCK_02 */
test_payload = make_large("etsi_iot_01_largedata.txt");
if (!test_payload) {
coap_log_crit("cannot allocate resource /large\n");
} else {
r = coap_resource_init(coap_make_str_const("large"), 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_resource);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("41"), 0);
coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("large"), 0);
coap_add_resource(ctx, r);
test_payload->flags |= REQUIRE_ETAG;
coap_add_payload(r, test_payload);
}
/* For TD_COAP_CORE_12 */
test_payload = coap_new_payload(20);
if (!test_payload) {
coap_log_crit("cannot allocate resource /seg1/seg2/seg3\n");
} else {
test_payload->length = 10;
memcpy(test_payload->data, "segsegseg!", test_payload->length);
/* test_payload->media_type is 0 anyway */
r = coap_resource_init(coap_make_str_const("seg1/seg2/seg3"), 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_resource);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_resource(ctx, r);
coap_add_payload(r, test_payload);
}
/* For TD_COAP_CORE_13 */
r = coap_resource_init(coap_make_str_const("query"), 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_query);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_resource(ctx, r);
/* For TD_COAP_CORE_16 */
r = coap_resource_init(coap_make_str_const("separate"), 0);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_separate);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("seperate"), 0);
coap_add_resource(ctx, r);
}
static void
usage(const char *program, const char *version) {
const char *p;
p = strrchr(program, '/');
if (p)
program = ++p;
fprintf(stderr, "%s v%s -- ETSI CoAP plugtest server\n"
"(c) 2012 Olaf Bergmann <bergmann@tzi.org>\n\n"
"usage: %s [-A address] [-p port]\n\n"
"\t-A address\tinterface address to bind to\n"
"\t-p port\t\tlisten on specified port\n"
"\t-v num\t\tverbosity level (default: 3)\n",
program, version, program);
}
static coap_context_t *
get_context(const char *node, const char *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, port, &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 <= (socklen_t)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;
}
int
main(int argc, char **argv) {
coap_context_t *ctx;
int result;
char addr_str[NI_MAXHOST] = "::";
char port_str[NI_MAXSERV] = "5683";
int opt;
coap_log_t log_level = COAP_LOG_WARN;
struct sigaction sa;
/* Initialize libcoap library */
coap_startup();
while ((opt = getopt(argc, argv, "A:p:v:")) != -1) {
switch (opt) {
case 'A' :
strncpy(addr_str, optarg, NI_MAXHOST-1);
addr_str[NI_MAXHOST - 1] = '\0';
break;
case 'p' :
strncpy(port_str, optarg, NI_MAXSERV-1);
port_str[NI_MAXSERV - 1] = '\0';
break;
case 'v' :
log_level = strtol(optarg, NULL, 10);
break;
default:
usage(argv[0], LIBCOAP_PACKAGE_VERSION);
exit(1);
}
}
coap_set_log_level(log_level);
ctx = get_context(addr_str, port_str);
if (!ctx)
return -1;
init_resources(ctx);
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = handle_sigint;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* So we do not exit on a SIGPIPE */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
while (!quit) {
result = coap_io_process(ctx, COAP_RESOURCE_CHECK_TIME * 1000);
if (result >= 0) {
/* coap_check_resource_list( ctx ); */
}
}
coap_free_context(ctx);
coap_cleanup();
return 0;
}
+7
View File
@@ -0,0 +1,7 @@
<large>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sit amet sapien ac leo bibendum suscipit at sed ipsum. Aliquam in mauris nec felis dictum lobortis a et erat. Pellentesque tempus urna vulputate purus faucibus ac pretium massa volutpat. Maecenas at tellus neque, quis elementum ante. Morbi molestie, elit placerat rhoncus faucibus, urna nunc accumsan diam, vel porta eros sem vel augue. Proin metus dolor, tristique a accumsan eget, suscipit vel ante. Suspendisse feugiat, nisl non viverra convallis, ante nibh congue lectus, sodales ultrices turpis massa sed elit.
Praesent posuere laoreet nulla eu accumsan. Vestibulum consequat molestie erat, ut laoreet arcu mattis non. Maecenas viverra elementum mauris, vitae pretium elit ultrices sit amet. Sed sit amet elit sit amet dui imperdiet consequat. Donec viverra leo mollis lorem varius lacinia mollis nulla posuere. Phasellus felis odio, tempor et sodales non, facilisis fermentum eros. Duis dignissim massa at ante euismod vel laoreet mi tristique. Nulla libero dolor, pretium vitae vulputate eget, luctus at sapien. Praesent aliquam nisl ut urna pretium eu rhoncus ipsum eleifend. Sed lobortis vestibulum est eu eleifend. Sed vitae luctus erat. Sed vel dolor quam, tempor venenatis dolor.
Vivamus a est a neque condimentum fermentum sed quis dui. Maecenas rhoncus imperdiet tortor, vitae viverra lectus ornare vulputate. Nam congue pulvinar faucibus. Vivamus id mauris at tortor porta volutpat. Donec non velit a tellus placerat iaculis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse at felis ligula, vel euismod velit. Aliquam in odio urna.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ac risus ipsum. Donec vel purus risus, eu molestie nisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse consequat libero eu augue ornare volutpat mollis sed dui. Ut sed. </large>
+765
View File
@@ -0,0 +1,765 @@
#!/bin/bash
function start_tcpdump {
testfunc=$1
logfile=$LOGDIR/"$testfunc"_$(date +%s).dump
tcpdumpcmd="$tcpdump -i $INTERFACE host $SERVERADDRESS and (udp port $SERVERPORT or icmp) -s0 -n -w $logfile"
if [ $verbose ]; then
echo "$tcpdumpcmd"
$tcpdumpcmd&
else
$tcpdumpcmd 2>/dev/null&
fi
tcpdumppid=$!
# wait until tcpdump is ready to write
for t in {0..20} ; do
if [ ! -e $logfile ] ; then
sleep 0.1
else
sleep 1
if [ $verbose ]; then
echo "tcpdump started"
fi
break
fi
done
}
function kill_tcpdump {
kill $tcpdumppid 2>/dev/null || ERROR=1
if [ $ERROR ]; then
echo "tcpdump failed."
exit 1
fi
}
function start_coap_test {
if [ -z $1 ]; then
echo "missing argument for start_coap_test"
exit 1
fi
start_tcpdump $1
if [ $verbose ]; then
echo "client command: $COAP_CLIENT $clientopts $testaddress"
fi
echo -e "\nOutput of client:"
# for OBS
if [[ ! -z $2 ]]; then
testfifo=/tmp/tmpfifo$(date +%s)
mkfifo $testfifo
$COAP_CLIENT $clientopts "$testaddress" &> $testfifo &
clientpid=$!
($timeoutcmd $clienttimeout cat $testfifo | if read -n 1 char; then echo "output: $char" ; fi) 2>/dev/null
# when client has written an output to fifo, kill client
kill $clientpid
rm $testfifo
if [[ $2 == "wait" ]] ; then
echo "Client killed. Waiting.."
sleep $longtimeout
fi
else
$COAP_CLIENT $clientopts "$testaddress"
fi
kill_tcpdump
}
##
# Perform GET (CON mode) on resource /test
#
# pre: resource /test exists and can handle GET with arbitrary payload
#
# client sends GET request with Type=0(CON) and Code=1(GET)
#
# check if sent request contains Type value indicating 0 and Code
# value indicating 1
#
# check if server sends response containing Code = 69(2.05 Content),
# the same Message ID as that of previous request, content type option
#
# verify that server displays received information
#
function TD_COAP_CORE_01 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/test
echo "perform GET (CON mode) on resource $testaddress"
start_coap_test $1
}
##
# Perform POST transaction (CON mode) on resource /test: create
# resource /test
#
# pre: resource /test doesn't exist but can be created on /test
#
# client sends POST with Type=0(CON), Code=2(POST), arbitrary payload,
# Content type option
#
# check: client sends request containing Type value indicating 0 and
# Code value indicating 2
#
# verify: Server displays received information
#
# check: server sends response containing Code=69(2.01 Created), same
# message ID as that of the previous request, Content type option
#
# verify: client displays received information
#
function TD_COAP_CORE_02 {
# -t 0: content type text/plain
clientopts="$callopts -m post -t 0 -e sometext"
testaddress=coap://$SERVERTUP/test
echo "perform POST (CON) on resource $testaddress"
start_coap_test $1
}
##
# Perform PUT transaction (CON mode) on resource /test
#
# pre: resource /test exists which can handle PUT
#
# Client sends a PUT request with Type=0(CON), Code=3(PUT), arbitrary
# payload, content type option
#
# check: sent request contains Type value indicating 0 and Code value
# indicating 3
#
# verify: server displays received information
#
# check: Server sends response containing Code=68(2.04 Changed), same
# Message ID as that of the previous request
#
# verify: client displays received response
#
function TD_COAP_CORE_03 {
clientopts="$callopts -m put -t 0 -e sometext"
testaddress=coap://$SERVERTUP/test
echo "perform PUT (CON) on resource $testaddress"
start_coap_test $1
}
##
# Perform DELETE transaction (CON mode) on resource /test
#
# pre: resource /test exists which can handle DELETE
#
# Client sends a DELETE request with Type=0(CON), Code=4(DELETE)
#
# check: sent request contains Type value indicating 0 and Code value
# indicating 4
#
# check: Server sends response containing Code=66(2.02 Deleted), same
# Message ID as that of the previous request
#
# verify: client displays received response
#
function TD_COAP_CORE_04 {
clientopts="$callopts -m delete"
testaddress=coap://$SERVERTUP/test
echo "perform DELETE (CON) on resource $testaddress"
start_coap_test $1
}
##
# Perform GET transaction (NON mode) on resource /test
#
# pre: resource /test exits which can handle GET
#
# Client sends a GET request with Type=1(NON), Code=1(GET)
#
# check: sent request contains Type value indicating 1 and Code value
# indicating 1
#
# check: Server sends response containing Type=1(NON), Code=69(2.05
# Content), content type option
#
# verify: client displays received response
#
function TD_COAP_CORE_05 {
# -N: send non-confirmable message
clientopts="$callopts -m get -N"
testaddress=coap://$SERVERTUP/test
echo "perform GET (NON mode) on resource $testaddress"
start_coap_test $1
}
##
# Perform POST transaction (NON mode), create resource on /test
#
# pre: resource on /test doesn't exist but can be created
#
# Client sends a POST request with Type=1(NON), Code=2(POST),
# arbitrary payload, content type option
#
# check: sent request contains Type value indicating 1 and Code value
# indicating 2
#
# verify: Server displays the received information
#
# check: Server sends response containing Type=1(NON), Code=65(2.01
# Created)
#
# verify: client displays received response
#
function TD_COAP_CORE_06 {
clientopts="$callopts -m post -t 0 -e sometext -N"
testaddress=coap://$SERVERTUP/test
echo "perform POST (NON) on resource $testaddress"
start_coap_test $1
}
##
# Perform PUT transaction (NON mode) on resource /test
#
# pre: /test exists and can handle PUT
#
# Client sends a PUT request with Type=1(NON), Code=3(PUT),
# arbitrary payload, content type option
#
# check: sent request contains Type value indicating 1 and Code value
# indicating 3
#
# verify: Server displays the received information
#
# check: Server sends response containing Type=1(NON), Code=68(2.04
# Changed)
#
# verify: client displays received response
#
function TD_COAP_CORE_07 {
clientopts="$callopts -m put -t 0 -e sometext -N"
testaddress=coap://$SERVERTUP/test
echo "perform PUT (NON) on resource $testaddress"
start_coap_test $1
}
##
# Perform DELETE transaction (NON mode) on resource /test
#
# pre: /test exists and can handle DELETE
#
# Client sends a DELETE request with Type=1(NON), Code=4(DELETE)
#
# check: sent request contains Type value indicating 1 and Code value
# indicating 4
#
# check: Server sends response containing Type=1(NON), Code=66(2.02
# Deleted)
#
# verify: client displays received response
#
function TD_COAP_CORE_08 {
clientopts="$callopts -m delete -N"
testaddress=coap://$SERVERTUP/test
echo "perform DELETE (NON) on resource $testaddress"
start_coap_test $1
}
##
# Perform GET transaction with a separate response on resource /separate
#
# pre: resource /separate exists which cannot be served immediately and which
# cannot be acknowledged in a piggy-backed way
#
# Client sends a confirmable GET request to server's resource
#
# check: sent request contains Type=0(CON), Code=1(GET), client
# generated Message ID
#
# check: Server sends response containing Type=2(ACK), message ID same
# as the request, empty Payload
#
# check: Server sends response containing Type=0(CON), Code=69(2.05
# content), Payload=Content of the requested resource, Content type option
#
# check: Client sends response containing Type=2(ACK), message ID same
# as the response, empty Payload
#
# verify: client displays received response
#
function TD_COAP_CORE_09 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/separate
echo "perform GET (CON) on resource $testaddress which cannot be served immediately"
start_coap_test $1
}
##
# Perform GET transaction with Token on resource /test
#
# pre: resource /test exists which can handle GET requests
#
# Client sends a confirmable GET request to server's resource
# including Token option
#
# check: sent request contains Type=0(CON) and Code=1(GET), client
# generated Token value, length of the token which should be between 1
# to 8 B, Option Type=Token
#
# check: Server sends response containing Code=69(2.05 content),
# length of the token should be between 1 to 8 B, Token value same as
# the requested, Payload=Content of the requested resource, Content
# type option
#
# verify: client displays received response
#
function TD_COAP_CORE_10 {
clientopts="$callopts -m get -T sometok"
testaddress=coap://$SERVERTUP/test
echo "perform GET (CON) on resource $testaddress with Token"
start_coap_test $1
}
##
# Perform GET transaction without Token on resource /test
#
# pre: resource /test exists which can handle GET requests
#
# Client sends a confirmable GET request to server's resource
# not containing Token option
#
# check: sent request contains Type=0(CON) and Code=1(GET), no Token
# option
#
# check: Server sends response containing Code=69(2.05 content), no
# Token option, Payload=Content of the requested resource, Content
# type option
#
# verify: client displays received response
#
function TD_COAP_CORE_11 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/test
echo "perform GET (CON mode) without Token on resource $testaddress"
start_coap_test $1
}
##
# Perform GET transaction to resource /seg1/seg2/seg3
#
# pre: resource /seg1/seg2/seg3 exists on server
#
# Client sends a confirmable GET request to server's resource
#
# check: sent request contains Type=0(CON) and Code=1(GET), Option
# type=URI-Path (one for each path segment)
#
# check: Server sends response containing Code=69(2.05 content),
# Payload=Content of the requested resource, Content type option
#
# verify: client displays received response
#
function TD_COAP_CORE_12 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/seg1/seg2/seg3
echo "perform GET (CON mode) on resource $testaddress"
start_coap_test $1
}
##
# Perform GET transaction to resource /query
#
# pre: resource /query exists on server
#
# Client sends a confirmable GET request with three Query parameters
# (e.g. ?first=1&second=2&third=3) to server's resource
#
# check: sent request contains Type=0(CON) and Code=1(GET), Option
# type=URI-Query (More than one query parameter)
#
# check: Server sends response containing Type=0/2(Con/ACK),
# Code=69(2.05 content), Payload=Content of the requested resource,
# Content type option
#
# verify: client displays received response
#
function TD_COAP_CORE_13 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/query
query="?first=1&second=2&third=3"
echo -e "perform GET (CON mode) on resource $testaddress with query $query"
testaddress=$testaddress$query
start_coap_test $1
}
##
# Perform GET transaction to resource /test in lossy context
#
# pre: gateway is introduced and configured to produce packet loss,
# resource /test exists on server
#
# Configuration=CoAP_CFG_02
#
# observe: One dropped request, one dropped request ACK, one dropped
# response, one dropped response ACK and its retransmission, test
# sequence should be executed several times
#
# Client sends a confirmable GET request to server's resource
#
# check: sent request contains Type=0(CON) and Code=1(GET), Client
# generated Message ID
#
# check: Server sends response containing Type=2(ACK), Code=69(2.05
# content), Payload=Content of the requested resource, Content type
# option
#
# verify: client displays received response
#
function TD_COAP_CORE_14 {
clientopts="$callopts -m get"
#FIXME: address for lossy context?
testaddress=coap://$SERVERTUP/test
echo "perform GET (CON mode) on resource $testaddress in lossy context"
start_coap_test $1
}
##
# Perform GET transaction to resource /separate in lossy context
#
# pre: gateway is introduced and configured to produce packet loss,
# resource /separate exists which cannot be served immediately and
# which cannot be acknowledged in a piggy-backed way
#
# Configuration=CoAP_CFG_02
#
# observe: One dropped request, one dropped request ACK, one dropped
# response, one dropped response ACK and its retransmission, test
# sequence should be executed several times
#
# Client sends a confirmable GET request to server's resource
#
# check: sent request contains Type=0(CON) and Code=1(GET), Client
# generated Message ID
#
# check: server sends response containing Type=2(ACK), Message ID same
# as the request, empty Payload
#
# check: Server sends response containing Type=0(CON), Code=69(2.05
# content), Payload=Content of the requested resource, Content type
# option
#
# check: Client sends response containing Type=2(ACK), message ID same
# as the response, empty Payload
#
# verify: client displays received response
#
function TD_COAP_CORE_15 {
clientopts="$callopts -m get"
#FIXME: address for lossy context?
testaddress=coap://$SERVERTUP/separate
echo "perform GET (CON mode) on resource $testaddress in lossy context"
start_coap_test $1
}
### LINK ###
##
# Access to well-known interface for resource discovery
#
# Pre: client supports CoRE Link Format, server supports
# /.well-known/core resource and the CoRE Link Format
#
# Client retrieves Server's list of resource
#
# check: client sends GET request for /.well-known/core resource
#
# check: server sends response containing content-type option
# indicating 40 (application/link-format), payload indicating all the
# links available on Server
#
# client displays the list of resources available on Server
#
function TD_COAP_LINK_01 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/.well-known/core
echo "retrieve server's list of resource"
start_tcpdump $1
if [ $verbose ]; then
echo "client command: $COAP_CLIENT $clientopts $testaddress"
fi
clientoutput=$($COAP_CLIENT $clientopts "$testaddress")
if [[ ! $(echo $clientoutput | grep rt) ]] ; then
echo "no resource with attribute rt found on server"
else
rt="${clientoutput##*rt=}"
rt="${rt%%;*}"
fi
echo -e "\nOutput of client:"
echo -e $clientoutput
echo
kill_tcpdump
}
##
# Use filtered requests for limiting discovery results
#
# Pre: client supports CoRE Link Format, server supports CoRE Link
# Format and offers different types of resources (Type 1, Type 2
# (extracted from /.well-knwon/core resource
#
# Client retrieves Server's list of resource of a specific Type 1
#
# check: client sends GET request for /.well-known/core resource
# containing URI-Query indicating "rt=Type1"
#
# check: server sends response containing content-type option
# indicating 40 (application/link-format), payload indicating only the
# links of type Type1 available on server
#
# client displays the list of resources of type Type1 available on Server
#
function TD_COAP_LINK_02 {
clientopts="$callopts -m get"
echo "retrieve server's list of resource for appropriate type"
if [[ ! -z $rt ]]; then
testaddress="coap://$SERVERTUP/.well-known/core?rt=$rt"
else
echo "no appropriate resource found. Skipping test"
return
fi
start_coap_test $1
}
### BLOCK ###
##
# Perform GET blockwise transfer for large resource (early negotiation)
#
# pre: Client supports Block transfers, Server supports Block
# transfers, Server offers a large resource /large, client knows
# /large requires block transfer
#
# Client is requested to retrieve resource /large
#
# check: client sends a GET request containing Block2 option indicating block
# number 0 and desired block size
#
# check: Each request contains Block2 option indicating block number
# of the next block and size of the last received block
#
# check: server sends further responses containing Block2 option
# indicating block number and size
#
# verify: client displays received response
#
function TD_COAP_BLOCK_01 {
clientopts="$callopts -m get -b 1024"
testaddress=coap://$SERVERTUP/large
echo "perform GET on large resource $testaddress (early negotiation)"
start_coap_test $1
}
##
# Perform GET blockwise transfer for large resource (late negotiation)
#
# pre: Client supports Block transfers, Server supports Block
# transfers, Server offers a large resource /large, client does not
# know /large requires block transfer
#
# Client is requested to retrieve resource /large
#
# check: client sends a GET request not containing Block2 option
#
# check: server sends response containing Block2 option indicating
# block number and size
#
# check: Each request contains Block2 option indicating block number
# of the next block and size of the last received block or the desired
# size of the next block
#
# check: server sends further responses containing Block2 option
# indicating block number and size
#
# verify: client displays received response
#
function TD_COAP_BLOCK_02 {
clientopts="$callopts -m get"
testaddress=coap://$SERVERTUP/large
echo "perform GET blockwise transfer for large resource (late negotiation) on resource $testaddress"
start_coap_test $1 stop
}
##
# Perform PUT blockwise transfer for large resource
#
# pre: Client supports Block transfers, Server supports Block
# transfers, Server offers a large updatable resource /large-update
#
# Client is requested to retrieve resource /large-update on server
#
# check: client sends a PUT request containing Block1 option
# indicating block number 0 and block size
#
# check: client sends further request containing Block1 option
# indicating block number and size
#
# verify: server indicates presence of the complete updated resource
# /large-update
#
function TD_COAP_BLOCK_03 {
clientopts="$callopts -m put -b 1024"
testaddress=coap://$SERVERTUP/large-update
echo "perform PUT on large resource $testaddress"
start_coap_test $1
}
##
# Perform POST blockwise transfer for large resource
#
# pre: Client supports Block transfers, Server supports Block
# transfers, Server accepts creation of new resources on /large-create
#
# Client is requested to create a new resource on server
#
# check: client sends a POST request containing Block1 option
# indicating block number 0 and block size
#
# check: client sends further requests containing Block1 option
# indicating block number and size
#
# verify: server indicates presence of the complete new resource
#
function TD_COAP_BLOCK_04 {
clientopts="$callopts -m post -b 1024"
testaddress=coap://$SERVERTUP/large-create
echo "perform POST on large resource $testaddress"
start_coap_test $1
}
# # OBS
##
# Handle observe option
#
# pre: client supports Observe option, server supports observe option,
# server offers an observable resource /obs which changes periodically
# (e.g. every 5s.)
#
# client is requested to observe resource /obs on server
#
# check: client sends a GET request containing observe option
#
# verify: client displays the received information
#
# check: server sends response containing observe option indicating
# increasing values, as resource changes
#
# verify: client displays the updated information
#
function TD_COAP_OBS_01 {
# we need some time to verify the correct behavior
clientopts="$callopts -s 0" #"-v 5 -B $longtimeout -s 0"
testaddress=coap://$SERVERTUP/obs
echo "observe resource $testaddress"
start_coap_test $1
}
##
# Stop resource observation
#
# pre: client supports Observe option, server supports observe option,
# server offers an observable resource /obs which changes periodically
# (e.g. every 5s.), client is observing /obs on server
#
# client is requested to stop observing resource /obs on server
#
# check: client sends a GET request not containing observe option
#
# verify: client displays the received information
#
# check: server does not send further response
#
# verify: client does not display the updated information
#
# function TD_COAP_OBS_02 {
# #FIXME: client does not support stopping yet
# we need some time to verify the correct behavior
# clientopts="-v 5 -B $longtimeout -s 1"
# testaddress=coap://$SERVERTUP/obs
# echo "stop observing resource $testaddress"
# start_coap_test $1
# }
##
# client detection of deregistration (Max-Age)
#
# pre: client supports Observe option, server supports observe option,
# server offers an observable resource /obs which changes periodically
# (e.g. every 5s.), client is observing /obs on server
#
# Server is rebooted
#
# check: Server does not send notifications
#
# verify: Client does not display updated information
#
# verify: After Max-Age expiration, client sends a new GET with observe
# option for Server's observable resource
#
# check: Sent request contains Observe option indicating 0
#
# check: Server sends response containing Observe option
#
# verify: client displays the received information
#
# check: Server sends response containing Observe option indicating
# increasing values, as resource changes
#
# verify: Client displays the updated information
#
function TD_COAP_OBS_03 {
clientopts="$callopts -s 0"#"-v5 -B $longtimeout -s 0"
testaddress=coap://$SERVERTUP/obs
echo "client detection of deregistration (Max-Age)"
start_coap_test $1
}
##
# Server detection of deregistration (client OFF)
#
# pre: client supports Observe option, server supports observe option,
# server offers an observable resource /obs which changes periodically
# (e.g. every 5s.), client is observing /obs on server
#
# Client is switched off
#
# check: Servers confirmable responses are not acknowledged
#
# verify: After some delay, Server does not send further responses
#
function TD_COAP_OBS_04 {
clientopts="$callopts -s 0"
#"-v 5 -B $longtimeout -s 0"
testaddress=coap://$SERVERTUP/obs
echo "server detection of deregistration (client off)"
start_coap_test $1 wait
}
##
# Server detection of deregistration (explicit RST)
#
# pre: client supports Observe option, server supports observe option,
# server offers an observable resource /obs which changes periodically
# (e.g. every 5s.), client is observing /obs on server
#
# Client is rebooted
#
# check: Server sends response containing Observe option
#
# verify: Client discards response and does not display information
#
# check: Client sends RST to Server
#
# check: Server does not send further response
#
function TD_COAP_OBS_05 {
clientopts="$callopts -s 0 -p $CLIENTPORT"
#"-v 5 -B $longtimeout -p $CLIENTPORT -s 0"
testaddress=coap://$SERVERTUP/obs
echo "server detection of deregistration (explicit RST)"
start_coap_test $1 stop
clientopts="$callopts -p $CLIENTPORT -s 0 -N"
#"-v 5 -B $clienttimeout -p $CLIENTPORT -s 0 -N"
testaddress=coap://[::1]/obs
start_coap_test $1
}
+65
View File
@@ -0,0 +1,65 @@
/*
* This file was copied from the following newsgroup posting:
*
* Newsgroups: mod.std.unix
* Subject: public domain AT&T getopt source
* Date: 3 Nov 85 19:34:15 GMT
*
* Here's something you've all been waiting for: the AT&T public domain
* source for getopt(3). It is the code which was given out at the 1985
* UNIFORUM conference in Dallas. I obtained it by electronic mail
* directly from AT&T. The people there assure me that it is indeed
* in the public domain.
*/
#include <stdio.h>
#include <string.h>
static int optind = 1;
static int optopt;
static char *optarg;
static int
getopt(int argc, char *argv[], const char *opts) {
static int sp = 1;
int c;
char *cp;
if (sp == 1) {
if (optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return EOF;
else if (!strcmp(argv[optind], "--")) {
optind++;
return EOF;
}
}
optopt = c = argv[optind][sp];
if (c == ':' || !(cp = strchr(opts, c))) {
fprintf(stderr, ": illegal option -- %c\n", c);
if (argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return '?';
}
if (*++cp == ':') {
if (argv[optind][sp+1] != '\0')
optarg = &argv[optind++][sp+1];
else if (++optind >= argc) {
fprintf(stderr, ": option requires an argument -- %c\n", c);
sp = 1;
return '?';
} else
optarg = argv[optind++];
sp = 1;
} else {
if (argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = NULL;
}
return c;
}
+8
View File
@@ -0,0 +1,8 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
sender_id,hex,""
recipient_id,hex,"01"
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
+8
View File
@@ -0,0 +1,8 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
sender_id,hex,"01"
recipient_id,hex,""
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
+9
View File
@@ -0,0 +1,9 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
id_context,hex,"37cbf3210017a2d3"
sender_id,hex,""
recipient_id,hex,"01"
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
+9
View File
@@ -0,0 +1,9 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
id_context,hex,"37cbf3210017a2d3"
sender_id,hex,"01"
recipient_id,hex,""
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
+8
View File
@@ -0,0 +1,8 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
sender_id,hex,"010101"
recipient_id,hex,"01"
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
+10
View File
@@ -0,0 +1,10 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
sender_id,hex,""
recipient_id,hex,"01"
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
break_sender_key,bool,true
+10
View File
@@ -0,0 +1,10 @@
master_secret,hex,"0102030405060708090a0b0c0d0e0f10"
master_salt,hex,"9e7ca92223786340"
sender_id,hex,""
recipient_id,hex,"01"
replay_window,integer,30
aead_alg,integer,10
hkdf_alg,integer,-10
ssn_freq,integer,4
break_recipient_key,bool,true
+10
View File
@@ -0,0 +1,10 @@
# not going for submodules here to keep things easy
lwip
lwip-contrib
# never objects, and not the resulting binary
*.o
client
client-dtls
server
server-dtls
+273
View File
@@ -0,0 +1,273 @@
# Makefile
#
# Copyright (C) 2010-2023 Olaf Bergmann <bergmann@tzi.org> and others
#
# SPDX-License-Identifier: BSD-2-Clause
#
# This file is part of the CoAP C library libcoap. Please see README and
# COPYING for terms of use.
libcoap_dir = ../..
LIBCOAP_API_VERSION = $(shell if [ -f $(libcoap_dir)/configure.ac ]; then \
sed -ne 's/^LIBCOAP_API_VERSION=\([0-9]\+\).*$$/\1/p' $(libcoap_dir)/configure.ac; \
else echo -n "3"; fi)
coap_include_dir = $(libcoap_dir)/include/coap$(LIBCOAP_API_VERSION)
WITH_LWIP_BRANCH=STABLE-2_1_3_RELEASE
WITH_LWIP_CONTRIB_BRANCH=STABLE-2_1_0_RELEASE
# Update to latest TinyDTLS submodule as defined for libcoap
WITH_TINYDTLS_BRANCH=f1d47d533b70ac10e4ff0ae3a088dfe4f265d242
# Need to determine which library clock_gettime() resides in (as found by ./autogen.sh)
LDLIBS := $(shell if [ -f $(libcoap_dir)/config.log ] ; then \
grep ac_cv_search_clock_gettime=- $(libcoap_dir)/config.log|cut -d= -f2 ; fi)
#
# Remove the 4 -dtls checks from "all" if you do not want DTLS included in
# some of the built objects.
#
all: lwip \
lwip-contrib \
check-version \
check-tinydtls \
$(coap_include_dir)/coap.h \
lib-server \
server \
lib-client \
client \
lib-server-dtls \
server-dtls \
lib-client-dtls \
client-dtls
lwip:
git clone --depth 1 https://git.savannah.nongnu.org/git/lwip.git -b $(WITH_LWIP_BRANCH)
(cd lwip ; git checkout $(WITH_LWIP_BRANCH))
$(MAKE)
lwip-contrib:
git clone --depth 1 https://git.savannah.nongnu.org/git/lwip/lwip-contrib.git -b $(WITH_LWIP_CONTRIB_BRANCH)
(cd lwip-contrib ; git checkout $(WITH_LWIP_CONTRIB_BRANCH))
$(MAKE)
check-version:
@(if [ -d lwip ] ; then \
cd lwip ; \
TAG=`git describe --tags --all`; \
if [ "$$TAG" != ${WITH_LWIP_BRANCH} ] ; then \
if [ "$$TAG" != "tags/${WITH_LWIP_BRANCH}" ] ; then \
echo "Updating lwip to ${WITH_LWIP_BRANCH}" ; \
cd .. ; \
rm -rf lwip ; \
${MAKE}; \
fi ; \
fi ; \
fi)
@(if [ -d lwip-contrib ] ; then \
cd lwip-contrib ; \
TAG=`git describe --tags`; \
if [ "$$TAG" != ${WITH_LWIP_CONTRIB_BRANCH} ] ; then \
if [ "$$TAG" != "tags/${WITH_LWIP_CONTRIB_BRANCH}" ] ; then \
echo "Updating lwip-contib to ${WITH_LWIP_CONTRIB_BRANCH}" ; \
cd .. ; \
rm -rf lwip-contrib ; \
${MAKE}; \
fi ; \
fi ; \
fi)
# base libcoap git has empty ext/tinydtls
check-tinydtls:
@(if [ ! -d $(libcoap_dir)/ext/tinydtls ] ; then \
mkdir -p $(libcoap_dir)/ext ; \
(cd $(libcoap_dir)/ext ; git clone https://github.com/eclipse/tinydtls.git) ; \
(cd $(libcoap_dir)/ext/tinydtls ; git checkout ${WITH_TINYDTLS_BRANCH}) ; \
fi ; \
if [ ! -f $(libcoap_dir)/ext/tinydtls/dtls.c ] ; then \
IN_GIT=`git rev-parse --is-inside-work-tree` ; \
if [ "$$IN_GIT" = "true" ] ; then \
(cd $(libcoap_dir) ; git submodule init ; git submodule update) ; \
else \
(cd $(libcoap_dir)/ext ; git clone https://github.com/eclipse/tinydtls.git) ; \
(cd $(libcoap_dir)/ext/tinydtls ; git checkout ${WITH_TINYDTLS_BRANCH}) ; \
fi ; \
if [ ! -f $(libcoap_dir)/ext/tinydtls/dtls.c ] ; then \
exit 1 ; \
fi ; \
fi ; \
IN_GIT=`git rev-parse --is-inside-work-tree` ; \
if [ "$$IN_GIT" = "true" ] ; then \
PWDDIR=`pwd` ; \
cd $(libcoap_dir) ; TAG=`git ls-tree HEAD ext/tinydtls | cut -d\ -f3 | cut -f1` ;\
if [ ! -z "$$TAG" ] ; then \
if [ "$$TAG" != ${WITH_TINYDTLS_BRANCH} ] ; then \
echo "Update WITH_TINYDTLS_BRANCH in Makefile to $$TAG" >&2 ; \
exit 1 ; \
fi ;\
fi ;\
cd $$PWDDIR ; \
fi ;\
if [ ! -f $(libcoap_dir)/ext/tinydtls/dtls_config.h ] ; then \
(cd $(libcoap_dir)/ext/tinydtls ; ./autogen.sh ; ./configure) ; \
${MAKE} ; \
fi)
# lwip and coap opts (include early to shadow the lwip-contrib/ports/unix/proj/minimal/ file and any ../../config.h)
CFLAGS += -DWITH_LWIP -iquote./config $(EXTRA_CFLAGS)
# lwip library
CFLAGS += -Ilwip/src/include/ -Ilwip/src/include/ipv4/ \
-Ilwip-contrib/ports/unix/port/include/ \
-Ilwip-contrib/ports/unix/proj/minimal/
LWIP_SRC = def.c init.c tapif.c etharp.c netif.c timeouts.c stats.c udp.c \
tcp.c pbuf.c ip4_addr.c ip4.c inet_chksum.c tcp_in.c tcp_out.c \
icmp.c raw.c ip4_frag.c sys_arch.c ethernet.c ip.c mem.c memp.c
vpath %.c lwip/src/core/ lwip-contrib/ports/unix/proj/minimal/ \
lwip/src/netif/ lwip/src/core/ipv4/ lwip-contrib/ports/unix/port/ \
lwip-contrib/ports/unix/port/netif/
# CFLAGS += -DLWIP_UNIX_LINUX
# if ipv6 is used
vpath %.c lwip/src/core/ipv6/
LWIP_SRC += mld6.c ip6.c icmp6.c ethip6.c nd6.c ip6_addr.c ip6_frag.c
CN_LWIP_OBJ =$(patsubst %.c,lib-client/%.o,$(LWIP_SRC))
SN_LWIP_OBJ =$(patsubst %.c,lib-server/%.o,$(LWIP_SRC))
CD_LWIP_OBJ =$(patsubst %.c,lib-client-dtls/%.o,$(LWIP_SRC))
SD_LWIP_OBJ =$(patsubst %.c,lib-server-dtls/%.o,$(LWIP_SRC))
# coap library
CFLAGS += -std=gnu99
CFLAGS += -I$(libcoap_dir)/include
vpath %.c $(libcoap_dir)/src
COAP_SRC = coap_address.c \
coap_asn1.c \
coap_async.c \
coap_block.c \
coap_cache.c \
coap_debug.c \
coap_dtls.c \
coap_encode.c \
coap_hashkey.c \
coap_io.c \
coap_io_lwip.c \
coap_layers.c \
coap_net.c \
coap_netif.c \
coap_notls.c \
coap_option.c \
coap_oscore.c \
coap_pdu.c \
coap_resource.c \
coap_session.c \
coap_subscribe.c \
coap_tinydtls.c \
coap_str.c \
coap_tcp.c \
coap_uri.c \
coap_ws.c
CN_COAP_OBJ =$(patsubst %.c,lib-client/%.o,$(COAP_SRC))
SN_COAP_OBJ =$(patsubst %.c,lib-server/%.o,$(COAP_SRC))
CD_COAP_OBJ =$(patsubst %.c,lib-client-dtls/%.o,$(COAP_SRC))
SD_COAP_OBJ =$(patsubst %.c,lib-server-dtls/%.o,$(COAP_SRC))
# tinydtls library
vpath %.c $(libcoap_dir)/ext/tinydtls $(libcoap_dir)/ext/tinydtls/sha2 $(libcoap_dir)/ext/tinydtls/aes $(libcoap_dir)/ext/tinydtls/ecc
TINYDTLS_CFLAGS = -I. -I$(libcoap_dir)/ext -I$(libcoap_dir)/ext/tinydtls -DDTLSv12 -DWITH_SHA256 -DSHA2_USE_INTTYPES_H -DDTLS_CHECK_CONTENTTYPE -DCOAP_WITH_LIBTINYDTLS -DHAVE_DTLS_SET_LOG_HANDLER=1
DTLS_SRC = dtls.c \
dtls_debug.c \
crypto.c \
dtls_time.c \
hmac.c \
sha2.c \
session.c \
peer.c \
netq.c \
rijndael_wrap.c \
rijndael.c \
ecc.c \
ccm.c \
dtls_prng.c
CN_DTLS_OBJ =$(patsubst %.c,lib-client/%.o,$(DTLS_SRC))
SN_DTLS_OBJ =$(patsubst %.c,lib-server/%.o,$(DTLS_SRC))
CD_DTLS_OBJ =$(patsubst %.c,lib-client-dtls/%.o,$(DTLS_SRC))
SD_DTLS_OBJ =$(patsubst %.c,lib-server-dtls/%.o,$(DTLS_SRC))
CFLAGS += -g3 -Wall -Wextra -pedantic -O0
CN_APP_OBJ =$(patsubst %.c,lib-client/%.o,client.c client-coap.c)
SN_APP_OBJ =$(patsubst %.c,lib-server/%.o,server.c server-coap.c)
CD_APP_OBJ =$(patsubst %.c,lib-client-dtls/%.o,client.c client-coap.c)
SD_APP_OBJ =$(patsubst %.c,lib-server-dtls/%.o,server.c server-coap.c)
CN_OBJS = ${CN_APP_OBJ} ${CN_LWIP_OBJ} ${CN_COAP_OBJ}
SN_OBJS = ${SN_APP_OBJ} ${SN_LWIP_OBJ} ${SN_COAP_OBJ}
CD_OBJS = ${CD_APP_OBJ} ${CD_LWIP_OBJ} ${CD_COAP_OBJ} ${CD_DTLS_OBJ}
SD_OBJS = ${SD_APP_OBJ} ${SD_LWIP_OBJ} ${SD_COAP_OBJ} ${SD_DTLS_OBJ}
$(coap_include_dir)/coap.h:
@(if [ ! -f $(coap_include_dir)/coap.h ] ; then \
(cd $(libcoap_dir) ; ./autogen.sh ; ./configure --disable-dtls --disable-man) ; \
${MAKE}; \
fi)
${SN_OBJS} ${SD_OBJS}: $(coap_include_dir)/coap.h server-coap.h
server: ${SN_OBJS}
$(CC) $(CFLAGS) ${SN_OBJS} -o server ${LDLIBS}
server-dtls: ${SD_OBJS}
$(CC) $(CFLAGS) ${SD_OBJS} -o server-dtls ${LDLIBS}
${CN_OBJS} ${CD_OBJS}: $(coap_include_dir)/coap.h client-coap.h
client: ${CN_OBJS}
$(CC) $(CFLAGS) ${CN_OBJS} -o client ${LDLIBS}
client-dtls: ${CD_OBJS}
$(CC) $(CFLAGS) ${CD_OBJS} -o client-dtls ${LDLIBS}
lib-server:
@mkdir -p $@
lib-server/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h
$(CC) ${CFLAGS} -DCOAP_SERVER_SUPPORT -c $< -o $@
lib-server-dtls:
@mkdir -p $@
lib-server-dtls/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h
$(CC) ${CFLAGS} ${TINYDTLS_CFLAGS} -DCOAP_SERVER_SUPPORT -c $< -o $@
lib-client:
@mkdir -p $@
lib-client/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h
$(CC) ${CFLAGS} -DCOAP_CLIENT_SUPPORT -c $< -o $@
lib-client-dtls:
@mkdir -p $@
lib-client-dtls/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h
$(CC) ${CFLAGS} ${TINYDTLS_CFLAGS} -DCOAP_CLIENT_SUPPORT -c $< -o $@
clean:
rm -rf server server-dtls client client-dtls \
${CN_OBJS} ${SN_OBJS} ${CD_OBJS} ${SD_OBJS} \
lib-server lib-server-dtls lib-client lib-client-dtls
.PHONY: all clean
+79
View File
@@ -0,0 +1,79 @@
Example of libcoap running on lwIP
==================================
To run the server example, do
$ make
$ sudo ./server # No TinyDTLS support
or
$ sudo ./server-dtls # With TinyDTLS support
(and in a second terminal)
$ sudo ip a a dev tap0 192.168.113.1/24
and query `coap://192.168.113.2/time?ticks` with any coap tool,
or query `coap://192.168.113.2/.well-known/core`.
(If server-dtls is running, you can use coaps:// as appropriate.)
This will
* download lwip and lwip-contrib from the upstream git sources
* build the server application
* run the server application, creating a virtual network device tap0 (unless
that exists)
* configure your network interface to make the server accessible.
* return the appropriate response from the server to the client.
The server supports the following options
"-k PSK" option where PSK defines the DTLS PSK to use (default is "secretPSK").
(Only works for server-dtls.)
"-v level" option where logging "level" can be 0 to 7 (default is 4).
"-V level" option where DTLS logging "level" can be 0 to 7 (default is 3).
(Only works for server-dtls.)
The server creates a resource for 'time' with a query 'ticks'. This is
reported for `.well-known/core`. The work flow for adding more resources does
not differ from regular libcoap usage. If you seem to run out of memory
creating the resources, tweak the number of pre-allocated resources
in `config/lwippools.h`.
To run the client example
$ make
$ sudo ./client # No TinyDTLS support
or
$ sudo ./client-dtls # With TinyDTLS support
As client (or client-dtls) tries to connect to coap://libcoap.net/, the tap0
interface will need IP forwarding enabled
$ sudo sysctl -w net.ipv4.conf.default.forwarding=1
Then you will need IP forwarding enabled on your public interface
(where eth0 is replaced by your public facing interface name)
for response packets
$ sudo sysctl -w net.eth0.conf.default.forwarding=1
As well as the interface connecting to the internet will need a NAT rule to
masquerade the internal IP address (192.168.114.2) to the IP of the outgoing
interface (where eth0 is replaced by your public facing interface name)
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
The client supports the following options
"-k PSK" option where PSK defines the DTLS PSK to use (default is "secretPSK").
(Only works for client-dtls.)
"-u id" option where id defines the DTLS id to use (default is "abc").
(Only works for client-dtls.)
"-v level" option where logging "level" can be 0 to 7 (default is 4).
"-V level" option where DTLS logging "level" can be 0 to 7 (default is 3).
(Only works for client-dtls.)
The client supports an optional parameter which is the CoAP URI to connect to
.e.g "coap://libcoap.net/.well-known/core". The default
is "coap://libcoap.net/" for client and client-dtls.
Using "coaps://libcoap.net" will establish a DTLS session if there is
DTLS support compiled in (client-dtls).
+240
View File
@@ -0,0 +1,240 @@
/*
* client-coap.c -- LwIP example
*
* Copyright (C) 2013-2016 Christian Amsüss <chrysn@fsfe.org>
* Copyright (C) 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include "coap_config.h"
#include <coap3/coap.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "client-coap.h"
#ifndef COAP_URI
#define COAP_URI "coap://libcoap.net"
#endif /* COAP_URI */
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
static coap_context_t *main_coap_context = NULL;
static coap_optlist_t *optlist = NULL;
static int quit = 0;
static coap_response_t
message_handler(coap_session_t *session,
const coap_pdu_t *sent,
const coap_pdu_t *received,
const coap_mid_t id) {
const uint8_t *data;
size_t len;
size_t offset;
size_t total;
(void)session;
(void)sent;
(void)id;
if (coap_get_data_large(received, &len, &data, &offset, &total)) {
printf("%*.*s", (int)len, (int)len, (const char *)data);
if (len + offset == total) {
printf("\n");
quit = 1;
}
}
return COAP_RESPONSE_OK;
}
static void
nack_handler(coap_session_t *session COAP_UNUSED,
const coap_pdu_t *sent COAP_UNUSED,
const coap_nack_reason_t reason,
const coap_mid_t id COAP_UNUSED) {
switch (reason) {
case COAP_NACK_TOO_MANY_RETRIES:
case COAP_NACK_NOT_DELIVERABLE:
case COAP_NACK_RST:
case COAP_NACK_TLS_FAILED:
coap_log_err("cannot send CoAP pdu\n");
quit = 1;
break;
case COAP_NACK_ICMP_ISSUE:
default:
;
}
return;
}
static int
resolve_address(const char *host, const char *service, coap_address_t *dst,
int scheme_hint_bits) {
coap_addr_info_t *addr_info;
coap_str_const_t str_host;
uint16_t port = service ? atoi(service) : 0;
int ret = 0;
str_host.s = (const uint8_t *)host;
str_host.length = strlen(host);
addr_info = coap_resolve_address_info(&str_host, port, port, port, port,
AF_UNSPEC, scheme_hint_bits,
COAP_RESOLVE_TYPE_REMOTE);
if (addr_info) {
ret = 1;
*dst = addr_info->addr;
}
coap_free_address_info(addr_info);
return ret;
}
void
client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
int argc, char **argv) {
coap_session_t *session = NULL;
coap_pdu_t *pdu;
coap_address_t dst;
coap_mid_t mid;
int len;
coap_uri_t uri;
char portbuf[8];
#define BUFSIZE 100
unsigned char buf[BUFSIZE];
int res;
const char *use_uri = COAP_URI;
int opt;
coap_log_t log_level = COAP_LOG_WARN;
coap_log_t dtls_log_level = COAP_LOG_ERR;
const char *use_psk = "secretPSK";
const char *use_id = "abc";
coap_pdu_type_t pdu_type = COAP_MESSAGE_CON;
/* Initialize libcoap library */
coap_startup();
while ((opt = getopt(argc, argv, ":k:Nu:v:V:")) != -1) {
switch (opt) {
case 'k':
use_psk = optarg;
break;
case 'u':
use_id = optarg;
break;
case 'v':
log_level = atoi(optarg);
break;
case 'N':
pdu_type = COAP_MESSAGE_NON;
break;
case 'V':
dtls_log_level = atoi(optarg);
break;
default:
printf("%s [-k PSK] [-u id] [-v level] [ -V level] [URI]\n", argv[0]);
exit(1);
}
}
if (optind < argc) {
use_uri = argv[optind];
}
coap_set_log_level(log_level);
coap_dtls_set_log_level(dtls_log_level);
/* Parse the URI */
len = coap_split_uri((const unsigned char *)use_uri, strlen(use_uri), &uri);
LWIP_ASSERT("Failed to parse uri", len == 0);
LWIP_ASSERT("Unsupported URI type", uri.scheme == COAP_URI_SCHEME_COAP ||
uri.scheme == COAP_URI_SCHEME_COAPS);
if (uri.scheme == COAP_URI_SCHEME_COAPS) {
LWIP_ASSERT("DTLS not supported", coap_dtls_is_supported());
}
snprintf(portbuf, sizeof(portbuf), "%d", uri.port);
snprintf((char *)buf, sizeof(buf), "%*.*s", (int)uri.host.length,
(int)uri.host.length, (const char *)uri.host.s);
/* resolve destination address where server should be sent */
len = resolve_address((const char *)buf, portbuf, &dst, 1 << uri.scheme);
LWIP_ASSERT("Failed to resolve address", len > 0);
main_coap_context = coap_new_context(NULL);
LWIP_ASSERT("Failed to initialize context", main_coap_context != NULL);
coap_context_set_block_mode(main_coap_context, COAP_BLOCK_USE_LIBCOAP);
coap_lwip_set_input_wait_handler(main_coap_context, input_wait, input_arg);
if (uri.scheme == COAP_URI_SCHEME_COAP) {
session = coap_new_client_session(main_coap_context, NULL, &dst,
COAP_PROTO_UDP);
} else {
static coap_dtls_cpsk_t dtls_psk;
static char client_sni[256];
memset(client_sni, 0, sizeof(client_sni));
memset(&dtls_psk, 0, sizeof(dtls_psk));
dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
if (uri.host.length)
memcpy(client_sni, uri.host.s,
min(uri.host.length, sizeof(client_sni) - 1));
else
memcpy(client_sni, "localhost", 9);
dtls_psk.client_sni = client_sni;
dtls_psk.psk_info.identity.s = (const uint8_t *)use_id;
dtls_psk.psk_info.identity.length = strlen(use_id);
dtls_psk.psk_info.key.s = (const uint8_t *)use_psk;
dtls_psk.psk_info.key.length = strlen(use_psk);
session = coap_new_client_session_psk2(main_coap_context, NULL, &dst,
COAP_PROTO_DTLS, &dtls_psk);
}
LWIP_ASSERT("Failed to create session", session != NULL);
coap_register_response_handler(main_coap_context, message_handler);
coap_register_nack_handler(main_coap_context, nack_handler);
/* construct CoAP message */
pdu = coap_pdu_init(pdu_type,
COAP_REQUEST_CODE_GET,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
LWIP_ASSERT("Failed to create PDU", pdu != NULL);
len = coap_uri_into_options(&uri, &dst, &optlist, 1, buf, sizeof(buf));
LWIP_ASSERT("Failed to create options", len == 0);
/* Add option list (which will be sorted) to the PDU */
if (optlist) {
res = coap_add_optlist_pdu(pdu, &optlist);
LWIP_ASSERT("Failed to add options to PDU", res == 1);
}
/* and send the PDU */
mid = coap_send(session, pdu);
LWIP_ASSERT("Failed to send PDU", mid != COAP_INVALID_MID);
}
void
client_coap_finished(void) {
coap_delete_optlist(optlist);
coap_free_context(main_coap_context);
main_coap_context = NULL;
coap_cleanup();
}
int
client_coap_poll(void) {
coap_io_process(main_coap_context, 1000);
return quit;
}
+29
View File
@@ -0,0 +1,29 @@
/*
* server-coap.h -- LwIP example
*
* Copyright (C) 2013-2016 Christian Amsüss <chrysn@fsfe.org>
* Copyright (C) 2022-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include "coap_config.h"
#include <coap3/coap.h>
/* Start up the CoAP Client */
void client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
int argc, char **argv);
/* Close down CoAP activity */
void client_coap_finished(void);
/*
* Call this when you think that work needs to be done
*
* Returns: 1 if there is no more work to be done, else 0
*/
int client_coap_poll(void);
+146
View File
@@ -0,0 +1,146 @@
/*
* Demo for libcoap on lwIP
*
* partially copied from lwip-contrib/ports/unix/proj/minimal/main.c
*
*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Adam Dunkels <adam@sics.se>
* RT timer modifications by Christiaan Simons
* lwip adaptions: chrysn <chrysn@fsfe.org>
* also, https://savannah.nongnu.org/bugs/?40245 was applied */
#include "client-coap.h"
#include <lwip/init.h>
#include <lwip/timeouts.h>
#include <netif/etharp.h>
#include <netif/tapif.h>
#include <signal.h>
#if LWIP_IPV4
static ip4_addr_t ipaddr, netmask, gw;
#endif /* LWIP_IPV4 */
static int quit = 0;
static void
handle_sigint(int signum) {
(void)signum;
client_coap_finished();
printf("Client Application finished.\n");
exit(0);
}
/*
* This function is called internally by coap_io_process() to check
* for input.
*/
static int
wait_for_input(void *arg, uint32_t milli_secs) {
struct netif *netif = (struct netif *)arg;
int ret;
(void)milli_secs;
ret = tapif_select(netif);
sys_check_timeouts();
return ret;
}
int
main(int argc, char **argv) {
struct netif netif;
#ifndef _WIN32
struct sigaction sa;
#endif
int no_more = 0;
/* startup defaults (may be overridden by one or more opts). this is
* hard-coded v4 even in presence of v6, which does auto-discovery and
* should thus wind up with an address of fe80::12:34ff:fe56:78ab%tap0
* */
#if LWIP_IPV4
IP4_ADDR(&gw, 192,168,114,1);
IP4_ADDR(&ipaddr, 192,168,114,2);
IP4_ADDR(&netmask, 255,255,255,0);
#endif /* LWIP_IPV4 */
lwip_init();
printf("TCP/IP initialized.\n");
#if LWIP_IPV4
netif_add(&netif, &ipaddr, &netmask, &gw, NULL, tapif_init, ethernet_input);
#endif /* LWIP_IPV4 */
netif.flags |= NETIF_FLAG_ETHARP;
netif_set_default(&netif);
netif_set_up(&netif);
#if LWIP_IPV6
netif_create_ip6_linklocal_address(&netif, 1);
netif_ip6_addr_set_state(&netif, 0, IP6_ADDR_PREFERRED);
#endif
/* start applications here */
#ifdef _WIN32
signal(SIGINT, handle_sigint);
#else
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = handle_sigint;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* So we do not exit on a SIGPIPE */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
#endif
client_coap_init(wait_for_input, &netif, argc, argv);
printf("Client Application started.\n");
while (!quit && !no_more) {
/*
* Poll netif, pass any read packet to lwIP
* Has internal timeout of 100 msec (sometimes less) based on
* sys_timeouts_sleeptime().
*/
tapif_select(&netif);
sys_check_timeouts();
no_more = client_coap_poll();
}
client_coap_finished();
printf("Client Application finished.\n");
return 0;
}
+78
View File
@@ -0,0 +1,78 @@
/*
* coap_config.h.lwip -- LwIP configuration for libcoap
*
* Copyright (C) 2021-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#include <lwip/opt.h>
#include <lwip/debug.h>
#include <lwip/def.h> /* provide ntohs, htons */
#define WITH_LWIP 1
#if LWIP_IPV4
#define COAP_IPV4_SUPPORT 1
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
#define COAP_IPV6_SUPPORT 1
#endif /* LWIP_IPV6 */
#ifndef COAP_CONSTRAINED_STACK
/* Define to 1 to minimize stack usage. */
#define COAP_CONSTRAINED_STACK 1
#endif
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 1
#endif
#ifndef COAP_ASYNC_SUPPORT
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
#endif
#ifndef COAP_WITH_OBSERVE_PERSIST
/* Define to 1 to build support for persisting observes. */
#define COAP_WITH_OBSERVE_PERSIST 0
#endif
#ifndef COAP_WS_SUPPORT
/* Define to 1 to build with WebSockets support. */
#define COAP_WS_SUPPORT 0
#endif
#ifndef COAP_Q_BLOCK_SUPPORT
/* Define to 1 to build with Q-Block (RFC9177) support. */
#define COAP_Q_BLOCK_SUPPORT 0
#endif
#define PACKAGE_NAME "libcoap"
#define PACKAGE_VERSION "4.3.4"
#define PACKAGE_STRING "libcoap 4.3.4"
#define assert(x) LWIP_ASSERT("CoAP assert failed", x)
/* it's just provided by libc. i hope we don't get too many of those, as
* actually we'd need autotools again to find out what environment we're
* building in */
#define HAVE_STRNLEN 1
#define HAVE_LIMITS_H
#define HAVE_NETDB_H
#define HAVE_SNPRINTF
#define HAVE_ERRNO_H
#endif /* COAP_CONFIG_H_ */
+78
View File
@@ -0,0 +1,78 @@
/*
* coap_config.h.lwip -- LwIP configuration for libcoap
*
* Copyright (C) 2021-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_CONFIG_H_
#define COAP_CONFIG_H_
#include <lwip/opt.h>
#include <lwip/debug.h>
#include <lwip/def.h> /* provide ntohs, htons */
#define WITH_LWIP 1
#if LWIP_IPV4
#define COAP_IPV4_SUPPORT 1
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
#define COAP_IPV6_SUPPORT 1
#endif /* LWIP_IPV6 */
#ifndef COAP_CONSTRAINED_STACK
/* Define to 1 to minimize stack usage. */
#define COAP_CONSTRAINED_STACK 1
#endif
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#define COAP_DISABLE_TCP 1
#endif
#ifndef COAP_ASYNC_SUPPORT
/* Define to 1 to build with support for async separate responses. */
#define COAP_ASYNC_SUPPORT 1
#endif
#ifndef COAP_WITH_OBSERVE_PERSIST
/* Define to 1 to build support for persisting observes. */
#define COAP_WITH_OBSERVE_PERSIST 0
#endif
#ifndef COAP_WS_SUPPORT
/* Define to 1 to build with WebSockets support. */
#define COAP_WS_SUPPORT 0
#endif
#ifndef COAP_Q_BLOCK_SUPPORT
/* Define to 1 to build with Q-Block (RFC9177) support. */
#define COAP_Q_BLOCK_SUPPORT 0
#endif
#define PACKAGE_NAME "@PACKAGE_NAME@"
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
#define PACKAGE_STRING "@PACKAGE_STRING@"
#define assert(x) LWIP_ASSERT("CoAP assert failed", x)
/* it's just provided by libc. i hope we don't get too many of those, as
* actually we'd need autotools again to find out what environment we're
* building in */
#define HAVE_STRNLEN 1
#define HAVE_LIMITS_H
#define HAVE_NETDB_H
#define HAVE_SNPRINTF
#define HAVE_ERRNO_H
#endif /* COAP_CONFIG_H_ */
+51
View File
@@ -0,0 +1,51 @@
/*
* lwipopts.h -- LwIP example
*
* Copyright (C) 2013-2016 Christian Amsüss <chrysn@fsfe.org>
* Copyright (C) 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#define NO_SYS 1
#define LWIP_SOCKET (NO_SYS==0)
#define LWIP_NETCONN (NO_SYS==0)
#define LWIP_NETIF_API (NO_SYS==0)
#define LWIP_IPV4 1
#define LWIP_IPV6 1
#define LWIP_IPV6_REASS 0
#define LWIP_IPV6_MLD 0
#define LWIP_ICMP6 (LWIP_IPV6==1)
#ifndef LWIP_RAND
#define LWIP_RAND() ((u32_t)rand())
#endif
#ifndef netif_get_index
#define netif_get_index(netif) ((u8_t)((netif)->num + 1))
#endif
#if NO_SYS
#define LOCK_TCPIP_CORE()
#define UNLOCK_TCPIP_CORE()
#endif
#define MEMP_USE_CUSTOM_POOLS 1
#define MEM_SIZE (4 * 1024)
/* Support a 1500 MTU packet */
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(2*6 + 2 + 1500)
/* Set if space is to be reserved for a response PDU */
#define MEMP_STATS 1
/*
* Set to display (with COAP_LOG_DEBUG) custom pools information
* (Needs MEMP_STATS set) when coap_free_context() is called.
*/
#define LWIP_STATS_DISPLAY 1
+175
View File
@@ -0,0 +1,175 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
/* Memory pool definitions for the libcoap when used with lwIP (which has its
* own mechanism for quickly allocating chunks of data with known sizes). Has
* to be findable by lwIP (ie. an #include <lwippools.h> must either directly
* include this or include something more generic which includes this), and
* MEMP_USE_CUSTOM_POOLS has to be set in lwipopts.h. */
#include "coap3/coap_internal.h"
#include "coap3/coap_net.h"
#include "coap3/coap_resource.h"
#include "coap3/coap_subscribe.h"
#ifdef COAP_WITH_LIBTINYDTLS
#ifndef LWIP_TINYDTLS_LOCAL_FIX
#define LWIP_TINYDTLS_LOCAL_FIX
#include <lwip/ip_addr.h>
/* Local copies of struct to simplify #include nightmare */
typedef struct {
unsigned char size; /**< size of session_t::addr */
unsigned short port; /**< transport layer port */
ip_addr_t addr; /**< session IP address */
int ifindex; /**< network interface index */
} l_session_t;
typedef struct l_coap_tiny_context_t {
struct dtls_context_t *dtls_context;
coap_context_t *coap_context;
coap_dtls_pki_t setup_data;
coap_binary_t *priv_key;
coap_binary_t *pub_key;
} l_coap_tiny_context_t;
#endif /* LWIP_TINYDTLS_LOCAL_FIX */
#endif /* COAP_WITH_LIBTINYDTLS */
#ifndef MEMP_NUM_COAPCONTEXT
#define MEMP_NUM_COAPCONTEXT 1
#endif
#ifndef MEMP_NUM_COAPENDPOINT
#ifdef COAP_WITH_LIBTINYDTLS
#define MEMP_NUM_COAPENDPOINT 2
#else /* ! COAP_WITH_LIBTINYDTLS */
#define MEMP_NUM_COAPENDPOINT 1
#endif /* ! COAP_WITH_LIBTINYDTLS */
#endif
/* 1 is sufficient as this is very short-lived */
#ifndef MEMP_NUM_COAPPACKET
#define MEMP_NUM_COAPPACKET 1
#endif
#ifndef MEMP_NUM_COAPNODE
#define MEMP_NUM_COAPNODE 5
#endif
#ifndef MEMP_NUM_COAPPDU
#define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE
#endif
#ifndef MEMP_NUM_COAPSESSION
#define MEMP_NUM_COAPSESSION 2
#endif
#ifndef MEMP_NUM_COAP_SUBSCRIPTION
#define MEMP_NUM_COAP_SUBSCRIPTION 4
#endif
#ifndef MEMP_NUM_COAPRESOURCE
#define MEMP_NUM_COAPRESOURCE 10
#endif
#ifndef MEMP_NUM_COAPRESOURCEATTR
#define MEMP_NUM_COAPRESOURCEATTR 20
#endif
#ifndef MEMP_NUM_COAPOPTLIST
#define MEMP_NUM_COAPOPTLIST 5
#endif
#ifndef MEMP_LEN_COAPOPTLIST
#define MEMP_LEN_COAPOPTLIST 12
#endif
#ifndef MEMP_NUM_COAPSTRING
#define MEMP_NUM_COAPSTRING 10
#endif
#ifndef MEMP_LEN_COAPSTRING
#define MEMP_LEN_COAPSTRING 40
#endif
#ifndef MEMP_NUM_COAPCACHE_KEYS
#define MEMP_NUM_COAPCACHE_KEYS (2U)
#endif /* MEMP_NUM_COAPCACHE_KEYS */
#ifndef MEMP_NUM_COAPCACHE_ENTRIES
#define MEMP_NUM_COAPCACHE_ENTRIES (2U)
#endif /* MEMP_NUM_COAPCACHE_ENTRIES */
#ifndef MEMP_NUM_COAPPDUBUF
#define MEMP_NUM_COAPPDUBUF 2
#endif
#ifndef MEMP_LEN_COAPPDUBUF
#define MEMP_LEN_COAPPDUBUF 400
#endif
#ifndef MEMP_NUM_COAPLGXMIT
#define MEMP_NUM_COAPLGXMIT 2
#endif
#ifndef MEMP_NUM_COAPLGCRCV
#define MEMP_NUM_COAPLGCRCV 2
#endif
#ifndef MEMP_NUM_COAPLGSRCV
#define MEMP_NUM_COAPLGSRCV 2
#endif
#ifndef MEMP_NUM_COAPDIGESTCTX
#define MEMP_NUM_COAPDIGESTCTX 4
#endif
#ifndef MEMP_NUM_COAPDTLS_SESSION
#define MEMP_NUM_COAPDTLS_SESSION 1
#endif
#ifndef MEMP_NUM_COAPDTLS_CONTEXT
#define MEMP_NUM_COAPDTLS_CONTEXT 1
#endif
LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT")
#ifdef COAP_SERVER_SUPPORT
LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT")
#endif /* COAP_SERVER_SUPPORT */
LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET")
LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE")
LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU")
LWIP_MEMPOOL(COAP_SESSION, MEMP_NUM_COAPSESSION, sizeof(coap_session_t), "COAP_SESSION")
#ifdef COAP_SERVER_SUPPORT
LWIP_MEMPOOL(COAP_SUBSCRIPTION, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t),
"COAP_SUBSCRIPTION")
LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE")
LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR")
#endif /* COAP_SERVER_SUPPORT */
LWIP_MEMPOOL(COAP_OPTLIST, MEMP_NUM_COAPOPTLIST, sizeof(coap_optlist_t)+MEMP_LEN_COAPOPTLIST,
"COAP_OPTLIST")
LWIP_MEMPOOL(COAP_STRING, MEMP_NUM_COAPSTRING, sizeof(coap_string_t)+MEMP_LEN_COAPSTRING,
"COAP_STRING")
#ifdef COAP_SERVER_SUPPORT
LWIP_MEMPOOL(COAP_CACHE_KEY, MEMP_NUM_COAPCACHE_KEYS, sizeof(coap_cache_key_t), "COAP_CACHE_KEY")
LWIP_MEMPOOL(COAP_CACHE_ENTRY, MEMP_NUM_COAPCACHE_ENTRIES, sizeof(coap_cache_entry_t),
"COAP_CACHE_ENTRY")
#endif /* COAP_SERVER_SUPPORT */
LWIP_MEMPOOL(COAP_PDU_BUF, MEMP_NUM_COAPPDUBUF, MEMP_LEN_COAPPDUBUF, "COAP_PDU_BUF")
LWIP_MEMPOOL(COAP_LG_XMIT, MEMP_NUM_COAPLGXMIT, sizeof(coap_lg_xmit_t), "COAP_LG_XMIT")
#ifdef COAP_CLIENT_SUPPORT
LWIP_MEMPOOL(COAP_LG_CRCV, MEMP_NUM_COAPLGCRCV, sizeof(coap_lg_crcv_t), "COAP_LG_CRCV")
#endif /* COAP_CLIENT_SUPPORT */
#ifdef COAP_SERVER_SUPPORT
LWIP_MEMPOOL(COAP_LG_SRCV, MEMP_NUM_COAPLGSRCV, sizeof(coap_lg_srcv_t), "COAP_LG_SRCV")
LWIP_MEMPOOL(COAP_DIGEST_CTX, MEMP_NUM_COAPDIGESTCTX, sizeof(coap_digest_t) + sizeof(size_t),
"COAP_DIGEST_CTX")
#endif /* COAP_SERVER_SUPPORT */
#ifdef COAP_WITH_LIBTINYDTLS
LWIP_MEMPOOL(COAP_DTLS_SESSION, MEMP_NUM_COAPDTLS_SESSION, sizeof(l_session_t), "COAP_DTLS_SESSION")
LWIP_MEMPOOL(COAP_DTLS_CONTEXT, MEMP_NUM_COAPDTLS_CONTEXT, sizeof(l_coap_tiny_context_t),
"COAP_DTLS_CONTEXT")
#endif /* COAP_WITH_LIBTINYDTLS */
+223
View File
@@ -0,0 +1,223 @@
/*
* server-coap.c -- LwIP example
*
* Copyright (C) 2013-2016 Christian Amsüss <chrysn@fsfe.org>
* Copyright (C) 2018-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include "coap_config.h"
#include <coap3/coap.h>
#include "server-coap.h"
coap_context_t *main_coap_context;
static coap_time_t clock_offset;
/* changeable clock base (see handle_put_time()) */
static coap_time_t my_clock_base = 0;
static coap_resource_t *time_resource = NULL; /* just for testing */
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
void
hnd_get_time(coap_resource_t *resource, coap_session_t *session,
const coap_pdu_t *request, const coap_string_t *query,
coap_pdu_t *response) {
unsigned char buf[40];
size_t len;
coap_tick_t now;
coap_tick_t t;
(void)resource;
(void)session;
(void)request;
/* FIXME: return time, e.g. in human-readable by default and ticks
* when query ?ticks is given. */
/* if my_clock_base was deleted, we pretend to have no such resource */
response->code =
my_clock_base ? COAP_RESPONSE_CODE(205) : COAP_RESPONSE_CODE(404);
if (my_clock_base)
coap_add_option(response, COAP_OPTION_CONTENT_FORMAT,
coap_encode_var_safe(buf, sizeof(buf),
COAP_MEDIATYPE_TEXT_PLAIN),
buf);
coap_add_option(response, COAP_OPTION_MAXAGE,
coap_encode_var_safe(buf, sizeof(buf), 0x01), buf);
if (my_clock_base) {
/* calculate current time */
coap_ticks(&t);
now = my_clock_base + (t / COAP_TICKS_PER_SECOND);
if (query != NULL
&& coap_string_equal(query, coap_make_str_const("ticks"))) {
/* output ticks */
len = snprintf((char *)buf, sizeof(buf), "%u", (unsigned int)now);
coap_add_data(response, len, buf);
}
}
}
void
init_coap_resources(coap_context_t *ctx) {
coap_resource_t *r;
#if 0
r = coap_resource_init(NULL, 0, 0);
coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"General Info\""), 0);
coap_add_resource(ctx, r);
#endif
/* store clock base to use in /time */
my_clock_base = clock_offset;
r = coap_resource_init(coap_make_str_const("time"), 0);
if (!r)
goto error;
coap_resource_set_get_observable(r, 1);
time_resource = r;
coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time);
#if 0
coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time);
coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time);
#endif
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
/* coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"Internal Clock\""), 0); */
coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"ticks\""), 0);
coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""), 0);
coap_add_resource(ctx, r);
#if 0
if (coap_async_is_supported()) {
r = coap_resource_init(coap_make_str_const("async"), 0);
coap_register_handler(r, COAP_REQUEST_GET, hnd_get_async);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_resource(ctx, r);
}
#endif
return;
error:
coap_log_crit("cannot create resource\n");
}
void
server_coap_init(coap_lwip_input_wait_handler_t input_wait,
void *input_arg, int argc, char **argv) {
int opt;
coap_log_t log_level = COAP_LOG_WARN;
coap_log_t dtls_log_level = COAP_LOG_ERR;
const char *use_psk = "secretPSK";
uint32_t scheme_hint_bits = 0;
coap_addr_info_t *info = NULL;
coap_addr_info_t *info_list = NULL;
int have_ep = 0;
coap_str_const_t node;
/* Initialize libcoap library */
coap_startup();
while ((opt = getopt(argc, argv, ":k:v:V:")) != -1) {
switch (opt) {
case 'k':
use_psk = optarg;
break;
case 'v':
log_level = atoi(optarg);
break;
case 'V':
dtls_log_level = atoi(optarg);
break;
default:
printf("%s [-k PSK] [-v level] [ -V level]\n", argv[0]);
exit(1);
}
}
coap_startup();
coap_set_log_level(log_level);
coap_dtls_set_log_level(dtls_log_level);
main_coap_context = coap_new_context(NULL);
LWIP_ASSERT("Failed to initialize context", main_coap_context != NULL);
if (coap_dtls_is_supported()) {
coap_dtls_spsk_t setup_data;
memset(&setup_data, 0, sizeof(setup_data));
setup_data.version = COAP_DTLS_SPSK_SETUP_VERSION;
setup_data.psk_info.key.s = (const uint8_t *)use_psk;
setup_data.psk_info.key.length = strlen(use_psk);
coap_context_set_psk2(main_coap_context, &setup_data);
}
node.s = (const uint8_t *)"::";
node.length = 2;
scheme_hint_bits =
coap_get_available_scheme_hint_bits(use_psk[0],
0, COAP_PROTO_NONE);
info_list = coap_resolve_address_info(&node, 0, 0,
0, 0,
0,
scheme_hint_bits,
COAP_RESOLVE_TYPE_LOCAL);
for (info = info_list; info != NULL; info = info->next) {
coap_endpoint_t *ep;
ep = coap_new_endpoint(main_coap_context, &info->addr, info->proto);
if (!ep) {
coap_log_warn("cannot create endpoint for proto %u\n",
info->proto);
} else {
have_ep = 1;
}
}
coap_free_address_info(info_list);
LWIP_ASSERT("Failed to initialize context", have_ep != 0);
/* Limit the number of idle sessions to save RAM (MEMP_NUM_COAPSESSION) */
LWIP_ASSERT("Need a minimum of 2 for MEMP_NUM_COAPSESSION", MEMP_NUM_COAPSESSION > 1);
coap_context_set_max_idle_sessions(main_coap_context, MEMP_NUM_COAPSESSION -1);
clock_offset = 1; /* Need a non-zero value */
init_coap_resources(main_coap_context);
coap_lwip_set_input_wait_handler(main_coap_context, input_wait, input_arg);
}
void
server_coap_finished(void) {
coap_free_context(main_coap_context);
main_coap_context = NULL;
coap_cleanup();
}
void
server_coap_poll(void) {
static coap_time_t last_time = 0;
coap_tick_t ticks_now;
coap_time_t time_now;
coap_io_process(main_coap_context, 1000);
coap_ticks(&ticks_now);
time_now = coap_ticks_to_rt(ticks_now);
if (last_time != time_now) {
/* This takes place once a second */
last_time = time_now;
coap_resource_notify_observers(time_resource, NULL);
}
coap_check_notify(main_coap_context);
}
+24
View File
@@ -0,0 +1,24 @@
/*
* server-coap.h -- LwIP example
*
* Copyright (C) 2013-2016 Christian Amsüss <chrysn@fsfe.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include "coap_config.h"
#include <coap3/coap.h>
/* Start up the CoAP Server */
void server_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
int argc, char **argv);
/* Close down CoAP activity */
void server_coap_finished(void);
/* call this when you think that resources could be dirty */
void server_coap_poll(void);
+149
View File
@@ -0,0 +1,149 @@
/*
* Demo for libcoap on lwIP
*
* partially copied from lwip-contrib/ports/unix/proj/minimal/main.c
*
*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Adam Dunkels <adam@sics.se>
* RT timer modifications by Christiaan Simons
* lwip adaptions: chrysn <chrysn@fsfe.org>
* also, https://savannah.nongnu.org/bugs/?40245 was applied */
#include "server-coap.h"
#include <lwip/init.h>
#include <lwip/timeouts.h>
#include <netif/etharp.h>
#include <netif/tapif.h>
#include <signal.h>
#if LWIP_IPV4
static ip4_addr_t ipaddr, netmask, gw;
#endif /* LWIP_IPV4 */
void
handle_sigint(int signum) {
(void)signum;
server_coap_finished();
printf("Server Application finished.\n");
exit(0);
}
/*
* This function is called internally by coap_io_process() to check
* for input.
*/
static int
wait_for_input(void *arg, uint32_t milli_secs) {
struct netif *netif = (struct netif *)arg;
int ret;
(void)milli_secs;
ret = tapif_select(netif);
sys_check_timeouts();
return ret;
}
int
main(int argc, char **argv) {
struct netif netif;
#ifndef _WIN32
struct sigaction sa;
#endif
/* startup defaults (may be overridden by one or more opts). this is
* hard-coded v4 even in presence of v6, which does auto-discovery and
* should thus wind up with an address of fe80::12:34ff:fe56:78ab%tap0
* */
#if LWIP_IPV4
IP4_ADDR(&gw, 192,168,113,1);
IP4_ADDR(&ipaddr, 192,168,113,2);
IP4_ADDR(&netmask, 255,255,255,0);
#endif /* LWIP_IPV4 */
lwip_init();
printf("TCP/IP initialized.\n");
#if LWIP_IPV4
netif_add(&netif, &ipaddr, &netmask, &gw, NULL, tapif_init, ethernet_input);
#endif /* LWIP_IPV4 */
netif.flags |= NETIF_FLAG_ETHARP;
netif_set_default(&netif);
netif_set_up(&netif);
#if LWIP_IPV4
printf("IP4 %s\n", ip4addr_ntoa(ip_2_ip4(&netif.ip_addr)));
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif_create_ip6_linklocal_address(&netif, 1);
#if LWIP_IPV4
printf("IP6 [%s]\n", ip6addr_ntoa(&netif.ip6_addr[0].u_addr.ip6));
#else /* ! LWIP_IPV4 */
printf("IP6 [%s]\n", ip6addr_ntoa(&netif.ip6_addr[0].addr));
#endif /* ! LWIP_IPV4 */
#endif /* LWIP_IPV6 */
/* start applications here */
#ifdef _WIN32
signal(SIGINT, handle_sigint);
#else
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = handle_sigint;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* So we do not exit on a SIGPIPE */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
#endif
server_coap_init(wait_for_input, &netif, argc, argv);
printf("Server Application started.\n");
while (1) {
/*
* Poll netif, pass any read packet to lwIP
* Has internal timeout of 100 msec (sometimes less) based on
* sys_timeouts_sleeptime().
*/
tapif_select(&netif);
sys_check_timeouts();
server_coap_poll();
}
return 0;
}
+790
View File
@@ -0,0 +1,790 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* oscore-interop-server
*
* A server for use in the RFC 8613 OSCORE interop testing.
* https://core-wg.github.io/oscore/test-spec5.html
*
* Copyright (C) 2022-2023 Olaf Bergmann <bergmann@tzi.org> and others
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>
#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#include "getopt.c"
#if !defined(S_ISDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#ifndef R_OK
#define R_OK 4
#endif
static char *
strndup(const char *s1, size_t n) {
char *copy = (char *)malloc(n + 1);
if (copy) {
memcpy(copy, s1, n);
copy[n] = 0;
}
return copy;
}
#include <io.h>
#define access _access
#define fileno _fileno
#else
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#endif
#include <coap3/coap.h>
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
static coap_oscore_conf_t *oscore_conf;
static int doing_oscore = 0;
/* set to 1 to request clean server shutdown */
static int quit = 0;
static coap_resource_t *r_observe_1;
static coap_resource_t *r_observe_2;
static int resource_flags = COAP_RESOURCE_FLAGS_NOTIFY_CON;
static uint32_t block_mode = COAP_BLOCK_USE_LIBCOAP;
static uint32_t csm_max_message_size = 0;
/* SIGINT handler: set quit to 1 for graceful termination */
static void
handle_sigint(int signum COAP_UNUSED) {
quit = 1;
}
#define INDEX "This is a OSCORE test server made with libcoap " \
"(see https://libcoap.net)\n" \
"Copyright (C) 2023 Olaf Bergmann <bergmann@tzi.org> " \
"and others\n\n"
static void
hnd_get_index(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
0x2ffff, 0, strlen(INDEX),
(const uint8_t *)INDEX, NULL, NULL);
}
#define HELLO_WORLD "Hello World!"
static void
hnd_get_hello_coap(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
-1, 0, strlen(HELLO_WORLD),
(const uint8_t *)HELLO_WORLD, NULL, NULL);
}
static void
hnd_get_hello_1(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
-1, 0, strlen(HELLO_WORLD),
(const uint8_t *)HELLO_WORLD, NULL, NULL);
}
static void
hnd_get_hello_2(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
-1, 0x2b, strlen(HELLO_WORLD),
(const uint8_t *)HELLO_WORLD, NULL, NULL);
}
static void
hnd_get_hello_3(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
5, 0, strlen(HELLO_WORLD),
(const uint8_t *)HELLO_WORLD, NULL, NULL);
}
static void
hnd_post_hello_6(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
size_t size;
const uint8_t *data;
(void)coap_get_data(request, &size, &data);
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
-1, 0, size,
data, NULL, NULL);
}
static void
hnd_put_hello_7(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
size_t size;
const uint8_t *data;
coap_opt_iterator_t opt_iter;
coap_opt_t *option;
uint64_t etag;
if ((option = coap_check_option(request, COAP_OPTION_IF_MATCH,
&opt_iter)) != NULL) {
etag = coap_decode_var_bytes8(coap_opt_value(option),
coap_opt_length(option));
if (etag != 0x7b) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_PRECONDITION_FAILED);
return;
}
}
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
(void)coap_get_data(request, &size, &data);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
-1, 0x7b, size,
data, NULL, NULL);
}
static void
hnd_get_observe1(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
static int count = 0;
count++;
switch (count) {
case 1:
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
1, 0, strlen("one"),
(const uint8_t *)"one", NULL, NULL);
break;
case 2:
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
1, 0, strlen("two"),
(const uint8_t *)"two", NULL, NULL);
break;
default:
coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
-1, 0, strlen("Terminate Observe"),
(const uint8_t *)"Terminate Observe",
NULL, NULL);
r_observe_1 = NULL;
}
}
static void
hnd_get_observe2(coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
static int count = 0;
count++;
switch (count) {
case 1:
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
1, 0, strlen("one"),
(const uint8_t *)"one", NULL, NULL);
break;
case 2:
default:
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_data_large_response(resource, session, request, response,
query, COAP_MEDIATYPE_TEXT_PLAIN,
1, 0, strlen("two"),
(const uint8_t *)"two", NULL, NULL);
r_observe_2 = NULL;
break;
}
}
static void
hnd_del_test(coap_resource_t *resource COAP_UNUSED,
coap_session_t *session COAP_UNUSED,
const coap_pdu_t *request COAP_UNUSED,
const coap_string_t *query COAP_UNUSED,
coap_pdu_t *response) {
coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
}
static void
init_resources(coap_context_t *ctx) {
coap_resource_t *r;
r = coap_resource_init(NULL, COAP_RESOURCE_FLAGS_HAS_MCAST_SUPPORT);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_index);
coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
coap_add_attr(r, coap_make_str_const("title"),
coap_make_str_const("\"General Info\""), 0);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/hello/coap"),
resource_flags);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_hello_coap);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/hello/1"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_hello_1);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/hello/2"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_hello_2);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/hello/3"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_hello_3);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/hello/6"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_POST, hnd_post_hello_6);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/hello/7"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put_hello_7);
coap_add_resource(ctx, r);
r = coap_resource_init(coap_make_str_const("oscore/observe1"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_observe1);
coap_resource_set_get_observable(r, 1);
coap_add_resource(ctx, r);
r_observe_1 = r;
r = coap_resource_init(coap_make_str_const("oscore/observe2"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get_observe2);
coap_resource_set_get_observable(r, 1);
coap_add_resource(ctx, r);
r_observe_2 = r;
r = coap_resource_init(coap_make_str_const("oscore/test"),
resource_flags | COAP_RESOURCE_FLAGS_OSCORE_ONLY);
coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_del_test);
coap_add_resource(ctx, r);
}
static uint8_t *
read_file_mem(const char *file, size_t *length) {
FILE *f;
uint8_t *buf;
struct stat statbuf;
*length = 0;
if (!file || !(f = fopen(file, "r")))
return NULL;
if (fstat(fileno(f), &statbuf) == -1) {
fclose(f);
return NULL;
}
buf = coap_malloc(statbuf.st_size+1);
if (!buf) {
fclose(f);
return NULL;
}
if (fread(buf, 1, statbuf.st_size, f) != (size_t)statbuf.st_size) {
fclose(f);
coap_free(buf);
return NULL;
}
buf[statbuf.st_size] = '\000';
*length = (size_t)(statbuf.st_size + 1);
fclose(f);
return buf;
}
static void
usage(const char *program, const char *version) {
const char *p;
char buffer[120];
const char *lib_build = coap_package_build();
p = strrchr(program, '/');
if (p)
program = ++p;
fprintf(stderr, "%s v%s -- OSCORE interop implementation\n"
"(c) 2023 Olaf Bergmann <bergmann@tzi.org> and others\n\n"
"Build: %s\n"
"%s\n"
, program, version, lib_build,
coap_string_tls_version(buffer, sizeof(buffer)));
fprintf(stderr, "%s\n", coap_string_tls_support(buffer, sizeof(buffer)));
fprintf(stderr, "\n"
"Usage: %s [-d max] [-g group] [-l loss] [-p port] [-r] [-v num]\n"
"\t\t[-A address] [-E oscore_conf_file[,seq_file]] [-G group_if]\n"
"\t\t[-L value] [-N] [-P scheme://address[:port],[name1[,name2..]]]\n"
"\t\t[-X size]\n"
"General Options\n"
"\t-d max \t\tAllow dynamic creation of up to a total of max\n"
"\t \t\tresources. If max is reached, a 4.06 code is returned\n"
"\t \t\tuntil one of the dynamic resources has been deleted\n"
"\t-g group\tJoin the given multicast group\n"
"\t \t\tNote: DTLS over multicast is not currently supported\n"
"\t-l list\t\tFail to send some datagrams specified by a comma\n"
"\t \t\tseparated list of numbers or number ranges\n"
"\t \t\t(for debugging only)\n"
"\t-l loss%%\tRandomly fail to send datagrams with the specified\n"
"\t \t\tprobability - 100%% all datagrams, 0%% no datagrams\n"
"\t \t\t(for debugging only)\n"
"\t-p port\t\tListen on specified port for UDP and TCP. If (D)TLS is\n"
"\t \t\tenabled, then the coap-server will also listen on\n"
"\t \t\t 'port'+1 for DTLS and TLS. The default port is 5683\n"
"\t-r \t\tEnable multicast per resource support. If enabled,\n"
"\t \t\tonly '/', '/async' and '/.well-known/core' are enabled\n"
"\t \t\tfor multicast requests support, otherwise all\n"
"\t \t\tresources are enabled\n"
"\t-v num \t\tVerbosity level (default 3, maximum is 9). Above 7,\n"
"\t \t\tthere is increased verbosity in GnuTLS and OpenSSL\n"
"\t \t\tlogging\n"
"\t-A address\tInterface address to bind to\n"
"\t-E oscore_conf_file[,seq_file]\n"
"\t \t\toscore_conf_file contains OSCORE configuration. See\n"
"\t \t\tcoap-oscore-conf(5) for definitions.\n"
"\t \t\tOptional seq_file is used to save the current transmit\n"
"\t \t\tsequence number, so on restart sequence numbers continue\n"
"\t-G group_if\tUse this interface for listening for the multicast\n"
"\t \t\tgroup. This can be different from the implied interface\n"
"\t \t\tif the -A option is used\n"
"\t-L value\tSum of one or more COAP_BLOCK_* flag valuess for block\n"
"\t \t\thandling methods. Default is 1 (COAP_BLOCK_USE_LIBCOAP)\n"
"\t \t\t(Sum of one or more of 1,2 and 4)\n"
"\t-N \t\tMake \"observe\" responses NON-confirmable. Even if set\n"
"\t \t\tevery fifth response will still be sent as a confirmable\n"
"\t \t\tresponse (RFC 7641 requirement)\n"
, program);
}
static coap_context_t *
get_context(const char *node, const char *port) {
coap_context_t *ctx = NULL;
int s;
struct addrinfo hints;
struct addrinfo *result, *rp;
ctx = coap_new_context(NULL);
if (!ctx) {
return NULL;
}
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, port, &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
coap_free_context(ctx);
return NULL;
}
/* iterate through results until success */
for (rp = result; rp != NULL; rp = rp->ai_next) {
coap_address_t addr;
coap_endpoint_t *ep_udp = NULL;
if (rp->ai_addrlen <= (socklen_t)sizeof(addr.addr)) {
coap_address_init(&addr);
addr.size = (socklen_t)rp->ai_addrlen;
memcpy(&addr.addr, rp->ai_addr, rp->ai_addrlen);
ep_udp = coap_new_endpoint(ctx, &addr, COAP_PROTO_UDP);
if (!ep_udp) {
coap_log_crit("cannot create UDP endpoint\n");
continue;
}
if (coap_tcp_is_supported()) {
coap_endpoint_t *ep_tcp;
ep_tcp = coap_new_endpoint(ctx, &addr, COAP_PROTO_TCP);
if (!ep_tcp) {
coap_log_crit("cannot create TCP endpoint\n");
}
}
if (ep_udp)
goto finish;
}
}
fprintf(stderr, "no context available for interface '%s'\n", node);
coap_free_context(ctx);
ctx = NULL;
finish:
freeaddrinfo(result);
return ctx;
}
static FILE *oscore_seq_num_fp = NULL;
static const char *oscore_conf_file = NULL;
static const char *oscore_seq_save_file = NULL;
static int
oscore_save_seq_num(uint64_t sender_seq_num, void *param COAP_UNUSED) {
if (oscore_seq_num_fp) {
rewind(oscore_seq_num_fp);
fprintf(oscore_seq_num_fp, "%" PRIu64 "\n", sender_seq_num);
fflush(oscore_seq_num_fp);
}
return 1;
}
static coap_oscore_conf_t *
get_oscore_conf(coap_context_t *context) {
uint8_t *buf;
size_t length;
coap_str_const_t file_mem;
uint64_t start_seq_num = 0;
buf = read_file_mem(oscore_conf_file, &length);
if (buf == NULL) {
fprintf(stderr, "OSCORE configuration file error: %s\n", oscore_conf_file);
return NULL;
}
file_mem.s = buf;
file_mem.length = length;
if (oscore_seq_save_file) {
oscore_seq_num_fp = fopen(oscore_seq_save_file, "r+");
if (oscore_seq_num_fp == NULL) {
/* Try creating it */
oscore_seq_num_fp = fopen(oscore_seq_save_file, "w+");
if (oscore_seq_num_fp == NULL) {
fprintf(stderr, "OSCORE save restart info file error: %s\n",
oscore_seq_save_file);
return NULL;
}
}
if (fscanf(oscore_seq_num_fp, "%" PRIu64, &start_seq_num) != 1) {
/* Must be empty */
start_seq_num = 0;
}
}
oscore_conf = coap_new_oscore_conf(file_mem,
oscore_save_seq_num,
NULL, start_seq_num);
coap_free(buf);
if (oscore_conf == NULL) {
fprintf(stderr, "OSCORE configuration file error: %s\n", oscore_conf_file);
return NULL;
}
coap_context_oscore_server(context, oscore_conf);
return oscore_conf;
}
static int
cmdline_oscore(char *arg) {
if (coap_oscore_is_supported()) {
char *sep = strchr(arg, ',');
if (sep)
*sep = '\000';
oscore_conf_file = arg;
if (sep) {
sep++;
oscore_seq_save_file = sep;
}
doing_oscore = 1;
return 1;
}
fprintf(stderr, "OSCORE support not enabled\n");
return 0;
}
int
main(int argc, char **argv) {
coap_context_t *ctx;
char *group = NULL;
char *group_if = NULL;
coap_tick_t now;
char addr_str[NI_MAXHOST] = "::";
char port_str[NI_MAXSERV] = "5683";
int opt;
int mcast_per_resource = 0;
coap_log_t log_level = COAP_LOG_WARN;
unsigned wait_ms;
coap_time_t t_last = 0;
int coap_fd;
fd_set m_readfds;
int nfds = 0;
uint16_t cache_ignore_options[] = { COAP_OPTION_BLOCK1,
COAP_OPTION_BLOCK2,
/* See https://rfc-editor.org/rfc/rfc7959#section-2.10 */
COAP_OPTION_MAXAGE,
/* See https://rfc-editor.org/rfc/rfc7959#section-2.10 */
COAP_OPTION_IF_NONE_MATCH
};
#ifndef _WIN32
struct sigaction sa;
#endif
/* Initialize libcoap library */
coap_startup();
while ((opt = getopt(argc, argv, "g:G:l:p:rv:A:E:L:NX:")) != -1) {
switch (opt) {
case 'A' :
strncpy(addr_str, optarg, NI_MAXHOST-1);
addr_str[NI_MAXHOST - 1] = '\0';
break;
case 'E':
if (!cmdline_oscore(optarg)) {
exit(1);
}
break;
case 'g' :
group = optarg;
break;
case 'G' :
group_if = optarg;
break;
case 'l':
if (!coap_debug_set_packet_loss(optarg)) {
usage(argv[0], LIBCOAP_PACKAGE_VERSION);
exit(1);
}
break;
case 'L':
block_mode = strtoul(optarg, NULL, 0);
if (!(block_mode & COAP_BLOCK_USE_LIBCOAP)) {
fprintf(stderr, "Block mode must include COAP_BLOCK_USE_LIBCOAP (1)\n");
exit(-1);
}
break;
case 'N':
resource_flags = COAP_RESOURCE_FLAGS_NOTIFY_NON;
break;
case 'p' :
strncpy(port_str, optarg, NI_MAXSERV-1);
port_str[NI_MAXSERV - 1] = '\0';
break;
case 'r' :
mcast_per_resource = 1;
break;
case 'v' :
log_level = strtol(optarg, NULL, 10);
break;
case 'X':
csm_max_message_size = strtol(optarg, NULL, 10);
break;
default:
usage(argv[0], LIBCOAP_PACKAGE_VERSION);
exit(1);
}
}
#ifdef _WIN32
signal(SIGINT, handle_sigint);
#else
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_handler = handle_sigint;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
/* So we do not exit on a SIGPIPE */
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
#endif
coap_dtls_set_log_level(log_level);
coap_set_log_level(log_level);
ctx = get_context(addr_str, port_str);
if (!ctx)
return -1;
init_resources(ctx);
if (mcast_per_resource)
coap_mcast_per_resource(ctx);
coap_context_set_block_mode(ctx, block_mode);
if (csm_max_message_size)
coap_context_set_csm_max_message_size(ctx, csm_max_message_size);
if (doing_oscore) {
if (get_oscore_conf(ctx) == NULL)
goto finish;
}
/* Define the options to ignore when setting up cache-keys */
coap_cache_ignore_options(ctx, cache_ignore_options,
sizeof(cache_ignore_options)/sizeof(cache_ignore_options[0]));
/* join multicast group if requested at command line */
if (group)
coap_join_mcast_group_intf(ctx, group, group_if);
coap_fd = coap_context_get_coap_fd(ctx);
if (coap_fd != -1) {
/* if coap_fd is -1, then epoll is not supported within libcoap */
FD_ZERO(&m_readfds);
FD_SET(coap_fd, &m_readfds);
nfds = coap_fd + 1;
}
wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
while (!quit) {
int result;
if (coap_fd != -1) {
/*
* Using epoll. It is more usual to call coap_io_process() with wait_ms
* (as in the non-epoll branch), but doing it this way gives the
* flexibility of potentially working with other file descriptors that
* are not a part of libcoap.
*/
fd_set readfds = m_readfds;
struct timeval tv;
coap_tick_t begin, end;
coap_ticks(&begin);
tv.tv_sec = wait_ms / 1000;
tv.tv_usec = (wait_ms % 1000) * 1000;
/* Wait until any i/o takes place or timeout */
result = select(nfds, &readfds, NULL, NULL, &tv);
if (result == -1) {
if (errno != EAGAIN) {
coap_log_debug("select: %s (%d)\n", coap_socket_strerror(),
errno);
break;
}
}
if (result > 0) {
if (FD_ISSET(coap_fd, &readfds)) {
result = coap_io_process(ctx, COAP_IO_NO_WAIT);
}
}
if (result >= 0) {
coap_ticks(&end);
/* Track the overall time spent in select() and coap_io_process() */
result = (int)(end - begin);
}
} else {
/*
* epoll is not supported within libcoap
*
* result is time spent in coap_io_process()
*/
result = coap_io_process(ctx, wait_ms);
}
if (result < 0) {
break;
} else if (result && (unsigned)result < wait_ms) {
/* decrement if there is a result wait time returned */
wait_ms -= result;
} else {
/*
* result == 0, or result >= wait_ms
* (wait_ms could have decremented to a small value, below
* the granularity of the timer in coap_io_process() and hence
* result == 0)
*/
wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
}
if (r_observe_1 || r_observe_2) {
coap_time_t t_now;
unsigned int next_sec_ms;
coap_ticks(&now);
t_now = coap_ticks_to_rt(now);
if (t_last != t_now) {
/* Happens once per second */
t_last = t_now;
if (r_observe_1)
coap_resource_notify_observers(r_observe_1, NULL);
if (r_observe_2)
coap_resource_notify_observers(r_observe_2, NULL);
}
/* need to wait until next second starts if wait_ms is too large */
next_sec_ms = 1000 - (now % COAP_TICKS_PER_SECOND) *
1000 / COAP_TICKS_PER_SECOND;
if (next_sec_ms && next_sec_ms < wait_ms)
wait_ms = next_sec_ms;
}
}
finish:
if (oscore_seq_num_fp)
fclose(oscore_seq_num_fp);
coap_free_context(ctx);
coap_cleanup();
return 0;
}
+261
View File
@@ -0,0 +1,261 @@
#!/bin/bash
#
# This script is used to run the oscore interop tests as specified in
# https://core-wg.github.io/oscore/test-spec5.html
#
# By default, this script should be run in the examples directory.
#
# Run as
# ./oscore_testcases.sh [-h remote-target-IP] [-B port-B-OSCORE] \
# [-D port-D-OSCORE] [-N port-NO-OSCORE] \
# [-s executable-for-interop-server] \
# [-c executable-for-client] \
# [-P] [-F]
#
# -h remote-target-IP
# Remote server hosting interop tests if not running the interop server on this host.
#
# -B port-B-OSCORE
# Port that the server listening on providing B OSCORE security profile
#
# -D port-D-OSCORE
# Port that the server listening on providing D OSCORE security profile
#
# -N port-N-OSCORE
# Port that the server listening on providing no security profile
#
# -s executable-for-interop-server
# Exectuable to use for the interop server if not the default of ./oscore-interop-server.
#
# -c executable-for-client
# Exectuable to use for the coap client if not the default of ./coap-client.
#
# -P
# Output partial client logs
#
# -F
# Output full client logs
#
INDIR=`dirname $0`
# Defaults
# host running oscore interop server
TARGET_IP=127.0.0.1
# Server with B OSCORE Security
S_PORT_B=5683
# Server with D OSCORE Security
S_PORT_D=5685
# Server with no Security
S_PORT_N=5687
# Client app
CLIENT=$INDIR/coap-client
# SERVER app
SERVER=$INDIR/oscore-interop-server
# Partial Logs
PARTIAL_LOGS=no
# Full Logs
FULL_LOGS=no
while getopts "c:h:s:B:D:FN:P" OPTION; do
case $OPTION in
c)
CLIENT="$OPTARG"
;;
h)
TARGET_IP="$OPTARG"
;;
s)
SERVER="$OPTARG"
;;
B)
S_PORT_B="$OPTARG"
;;
D)
S_PORT_D="$OPTARG"
;;
F)
FULL_LOGS=yes
;;
N)
S_PORT_N="$OPTARG"
;;
P)
PARTIAL_LOGS=yes
;;
*)
echo Error in options detected
echo Run as
echo "$0 [-h remote-target-IP] [-B port-B-OSCORE]"
echo " [-D port-D-OSCORE] [-N port-NO-OSCORE]"
echo " [-s executable-for-interop-server]"
echo " [-c executable-for-client]"
echo " [-P] [-F]"
exit 1
esac
done
timecheck () {
timeout $*
if [ $? = 124 ] ; then
echo "****** Timed Out ******"
fi
}
NO_PASS=0
NO_FAIL=0
# passfail count egrep-expression
passfail () {
PASS=`cat /tmp/client_out | egrep "$2" | wc -l`
if [ "$PASS" = "$1" ] ; then
echo Pass
let "NO_PASS=$NO_PASS+1"
else
echo Fail
let "NO_FAIL=$NO_FAIL+1"
fi
if [ "$FULL_LOGS" = yes ] ; then
cat /tmp/client_out
elif [ "$PARTIAL_LOGS" = yes ] ; then
cat /tmp/client_out | egrep -v " DEBG | OSC "
fi
}
$SERVER -E $INDIR/interop/b_server.conf -v8 -p $S_PORT_B > /tmp/server_b 2>&1 &
$SERVER -E $INDIR/interop/d_server.conf -v8 -p $S_PORT_D > /tmp/server_d 2>&1 &
$SERVER -v8 -p $S_PORT_N > /tmp/server_n 2>&1 &
sleep 1
# Reset sequence number counters
rm -f /tmp/client_a
rm -f /tmp/client_c
# Test 0 General checkout
echo -n "Test 0 - "
timecheck 10 $CLIENT -w -v8 coap://$TARGET_IP:$S_PORT_B/oscore/hello/coap 2>&1 | egrep -v " DEBG | OSC " > /tmp/client_out
passfail 1 "^Hello World"
# Test 1
echo -n "Test 1 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a coap://$TARGET_IP:$S_PORT_B/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^Hello World"
# Test 2
echo -n "Test 2 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/c_client.conf,/tmp/client_c coap://$TARGET_IP:$S_PORT_D/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^Hello World"
# Test 3
echo -n "Test 3 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a coap://$TARGET_IP:$S_PORT_B/oscore/hello/2?first=1 > /tmp/client_out 2>&1
passfail 1 "^Hello World"
# Test 4
echo -n "Test 4 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -A 0 coap://$TARGET_IP:$S_PORT_B/oscore/hello/3 > /tmp/client_out 2>&1
passfail 1 "^Hello World"
# Test 5
echo -n "Test 5 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -s 2 coap://$TARGET_IP:$S_PORT_B/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^Hello World"
# Test 6
echo -n "Test 6 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -s 4 coap://$TARGET_IP:$S_PORT_B/oscore/observe1 > /tmp/client_out > /tmp/client_out 2>&1
passfail 3 "^one|^two|^5.00 Terminate Observe"
# Test 7
echo -n "Test 7 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -s 2 coap://$TARGET_IP:$S_PORT_B/oscore/observe2 > /tmp/client_out 2>&1
passfail 3 "^one|^two"
# Test 8
echo -n "Test 8 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -m post -e "%4a" -t 0 coap://$TARGET_IP:$S_PORT_B/oscore/hello/6 > /tmp/client_out 2>&1
passfail 1 "^J$"
# Test 9
echo -n "Test 9 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -m put -e "%7a" -t 0 -O 1,0x7b coap://$TARGET_IP:$S_PORT_B/oscore/hello/7 > /tmp/client_out 2>&1
passfail 1 "^z"
# Test 10
echo -n "Test 10 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -m put -e "%8a" -t 0 -O 5 coap://$TARGET_IP:$S_PORT_B/oscore/hello/7 > /tmp/client_out 2>&1
passfail 1 "^4.12 Precondition Failed"
# Test 11
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 11 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf,/tmp/client_a -m delete coap://$TARGET_IP:$S_PORT_B/oscore/test > /tmp/client_out 2>&1
passfail 1 "^v:1 t:CON c:2.02 i:"
# Test 12
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 12 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/e_client.conf,/tmp/client_a coap://$TARGET_IP:$S_PORT_B/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^4.01 Security context not found"
# Test 13
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 13 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/f_client.conf,/tmp/client_a coap://$TARGET_IP:$S_PORT_B/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^4.00 Decryption failed"
# Test 14
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 14 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/g_client.conf,/tmp/client_a coap://$TARGET_IP:$S_PORT_B/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "WARN OSCORE: Decryption Failure, result code: -5"
# Test 15
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 15 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/a_client.conf coap://$TARGET_IP:$S_PORT_B/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^4.01 Replay detected"
# Test 16
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 16 - "
timeout 10 $CLIENT -w -v8 -E $INDIR/interop/e_client.conf,/tmp/client_a coap://$TARGET_IP:$S_PORT_N/oscore/hello/coap > /tmp/client_out 2>&1
passfail 1 "^4.02 Bad Option"
# Test 17
if [ "$SUPPRESS" = no ] ; then
echo
fi
echo -n "Test 17 - "
timeout 10 $CLIENT -w -v8 coap://$TARGET_IP:$S_PORT_N/oscore/hello/1 > /tmp/client_out 2>&1
passfail 1 "^4.01 Unauthorized"
KILL_SERVER=`basename $SERVER`
if [ ! -z "$KILL_SERVER" ] ; then
killall $KILL_SERVER
fi
echo
echo ===============
echo Pass: $NO_PASS
echo Fail: $NO_FAIL
#Starts with test 0
echo Total: 18
if [ "$NO_FAIL" != 0 ] ; then
exit 1
fi
+2
View File
@@ -0,0 +1,2 @@
# not going for submodules here to keep things easy
RIOT
+51
View File
@@ -0,0 +1,51 @@
# Makefile
#
# Copyright (C) 2010-2023 Olaf Bergmann <bergmann@tzi.org> and others
#
# SPDX-License-Identifier: BSD-2-Clause
#
# This file is part of the CoAP C library libcoap. Please see README and
# COPYING for terms of use.
RIOT=RIOT
TARGET?=native
all: RIOT pkg examples client server
RIOT:
git clone --depth 1 https://github.com/RIOT-OS/RIOT.git $@
pkg:
@IN_GIT=`git rev-parse --is-inside-work-tree` ; \
if [ "$${IN_GIT}" = "true" ] ; then \
rm -rf pkg_libcoap/patches ; \
mkdir -p pkg_libcoap/patches ; \
RIOT_HASH=`grep PKG_VERSION= pkg_libcoap/Makefile | cut -d= -f2` ; \
git pull --unshallow > /dev/null 2>&1 ; \
if [ ! -z "$${RIOT_HASH}" ] ; then \
(cd pkg_libcoap/patches ; git format-patch -n $${RIOT_HASH}) ; \
fi \
fi
rm -rf RIOT/pkg/libcoap && mkdir RIOT/pkg/libcoap
cd pkg_libcoap && cp -r * ../RIOT/pkg/libcoap
@HAVE_KCONFIG=`grep libcoap/Kconfig RIOT/pkg/Kconfig | wc -l` ; \
if [ "$${HAVE_KCONFIG}" = 0 ] ; then \
sed -i '/rsource "libcose\/Kconfig"/irsource "libcoap\/Kconfig"' RIOT/pkg/Kconfig ; \
fi
examples:
rm -rf RIOT/examples/libcoap-client && mkdir RIOT/examples/libcoap-client
cd examples_libcoap_client && cp -r * ../RIOT/examples/libcoap-client
rm -rf RIOT/examples/libcoap-server && mkdir RIOT/examples/libcoap-server
cd examples_libcoap_server && cp -r * ../RIOT/examples/libcoap-server
client: RIOT pkg examples
$(MAKE) -C RIOT/examples/libcoap-client/ RIOT_CI_BUILD=1
server: RIOT pkg examples
$(MAKE) -C RIOT/examples/libcoap-server/ RIOT_CI_BUILD=1
clean:
rm -rf RIOT/pkg/libcoap
rm -rf RIOT/examples/libcoap-client
rm -rf RIOT/examples/libcoap-server
+48
View File
@@ -0,0 +1,48 @@
Example of libcoap running on RIOT
==================================
To build the examples, do
$ make
This will
* download RIOT from the upstream git sources
* update the RIOT environment with pkg/libcoap, examples/libcoap-client
and examples/libcoap-server taken from pkg_libcoap/, examples_client/
and examples_server respectively/.
(updates RIOT's libcoap code to the latest commited version in your
environment).
* build the client application
* build the server application
To run (and/or rebuild) the server application
* cd RIOT/examples-libcoap-server
* make RIOT_CI_BUILD=1
* make term
* (at the shell prompt) coaps start
The server creates a resource for 'time' with a query 'ticks'. This is
reported for `.well-known/core`. The work flow for adding more resources does
not differ from regular libcoap usage.
To run (and/or rebuild) the client application
* cd RIOT/examples-libcoap-client
* make RIOT_CI_BUILD=1
* make term
* (at the shell prompt) coapc
The client will try to connect to the URI defined in app.config named
CONFIG_LIBCOAP_CLIENT_URI (unless overridden by running 'make menuconfig').
Note to developers
==================
PKG_VERSION= in pkg_libcoap/Makefile needs updating if you need a different
version of libcoap to get initially installed into RIOT/pkg/libcoap.
Kconfig support is available. Running make in the libcoap distribution
examples/riot directory will try to add in a 'rsource "libcoap/Kconfig"'
entry into RIOT/pkg/Kconfig
@@ -0,0 +1,19 @@
if USEMODULE_LIBCOAP
config LIBCOAP_CLIENT_URI
string "CoAP URI to connect to"
default "coap://[fe80::405:5aff:fe15:9b7f]/.well-known/core"
config LIBCOAP_USE_PSK
string "Secret to use for PSK communications"
default "secretPSK"
depends on USEMODULE_TINYDTLS
config LIBCOAP_USE_PSK_ID
string "User ID to use for PSK communications"
default "user_abc"
depends on USEMODULE_TINYDTLS
config LIBCOAP_SERVER_SUPPORT
bool "Set to y if server support is required"
default n
config LIBCOAP_CLIENT_SUPPORT
bool "Set to y if client support is required"
default y
endif # USEMODULE_LIBCOAP
@@ -0,0 +1,67 @@
# name of your application
APPLICATION = libcoap-client
# If no BOARD is found in the environment, use this default:
BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += netdev_default
USEMODULE += auto_init_gnrc_netif
# Activate ICMPv6 error messages
USEMODULE += gnrc_icmpv6_error
# Specify the mandatory networking module for a IPv6 routing node
USEMODULE += gnrc_ipv6_router_default
# Add a routing protocol
USEMODULE += gnrc_rpl
USEMODULE += auto_init_gnrc_rpl
# Additional networking modules that can be dropped if not needed
USEMODULE += gnrc_icmpv6_echo
# Specify the mandatory networking modules for IPv6 and UDP
USEMODULE += gnrc_ipv6_default
USEMODULE += memarray
USEMODULE += ipv4_addr
# a cryptographically secure implementation of PRNG is needed for tinydtls
# Uncomment the following 3 lines for tinydtls support
CFLAGS += -DWITH_RIOT_SOCK
USEPKG += tinydtls
USEMODULE += prng_sha1prng
# libcoap support
USEPKG += libcoap
# Configure if DNS is required
# USEMODULE += sock_dns
# Support 64 bit ticks
USEMODULE += ztimer64_xtimer_compat
# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_cmds_default
USEMODULE += ps
USEMODULE += netstats_l2
USEMODULE += netstats_ipv6
USEMODULE += netstats_rpl
# libcoap needs some space
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(3*THREAD_STACKSIZE_DEFAULT\)
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
# QUIET ?= 1
include $(RIOTBASE)/Makefile.include
@@ -0,0 +1,49 @@
BOARD_INSUFFICIENT_MEMORY := \
airfy-beacon \
b-l072z-lrwan1 \
blackpill-stm32f103c8 \
blackpill-stm32f103cb \
bluepill-stm32f030c8 \
bluepill-stm32f103c8 \
bluepill-stm32f103cb \
calliope-mini \
cc2650-launchpad \
cc2650stk \
hifive1 \
hifive1b \
i-nucleo-lrwan1 \
im880b \
lsn50 \
maple-mini \
microbit \
nrf51dk \
nrf51dongle \
nrf6310 \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f070rb \
nucleo-f072rb \
nucleo-f103rb \
nucleo-f302r8 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
opencm904 \
samd10-xmini \
saml10-xpro \
saml11-xpro \
slstk3400a \
spark-core \
stk3200 \
stm32f030f4-demo \
stm32f0discovery \
stm32f7508-dk \
stm32g0316-disco \
stm32l0538-disco \
stm32mp157c-dk2 \
yunjia-nrf51822 \
#
@@ -0,0 +1,24 @@
# libcoap client example
This example shows how to configure a client to use libcoap
## Fast configuration (Between RIOT instances):
Preparing the logical interfaces:
sudo ./../../dist/tools/tapsetup/tapsetup --create 2
## Client invocation
For the client:
PORT=tap0 make term
coapc coap://[ip6-address]/some/path
The IP address to connect to needs to be that as returned by libcoap_server,
or that of the tap0 interface, etc.
## Handling the static memory allocation
libcoap for RIOT is using the `sys/memarray` module and therefore there
are certain limits. Said resources are defined in `libcoap/src/coap_mem.c`,
but can be overwritten at compile time.
@@ -0,0 +1,8 @@
CONFIG_LIBCOAP_CLIENT_SUPPORT=y
CONFIG_LIBCOAP_CLIENT_URI="coap://[fe80::405:5aff:fe15:9b7f]/.well-known/core"
CONFIG_LIBCOAP_USE_PSK="secretPSK"
CONFIG_LIBCOAP_USE_PSK_ID="user_abc"
CONFIG_KCONFIG_USEPKG_LIBCOAP=y
# Logging levels are defined in pkg/libcoap using Kconfig
@@ -0,0 +1,253 @@
/*
* client-coap.c -- RIOT client example
*
* Copyright (C) 2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#include "coap_config.h"
#include <coap3/coap.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "client-coap.h"
#include "macros/utils.h"
#include "net/utils.h"
#include <arpa/inet.h>
#include <thread.h>
#include <debug.h>
#ifdef CONFIG_LIBCOAP_CLIENT_URI
#define COAP_CLIENT_URI CONFIG_LIBCOAP_CLIENT_URI
#else /* ! CONFIG_LIBCOAP_CLIENT_URI */
#define COAP_CLIENT_URI "coap://[fe80::405:5aff:fe15:9b7f]/.well-known/core"
#endif /* ! CONFIG_LIBCOAP_CLIENT_URI */
#ifdef CONFIG_LIBCOAP_USE_PSK
#define COAP_USE_PSK CONFIG_LIBCOAP_USE_PSK
#else /* ! CONFIG_LIBCOAP_USE_PSK */
#define COAP_USE_PSK NULL
#endif /* ! CONFIG_LIBCOAP_USE_PSK */
#ifdef CONFIG_LIBCOAP_USE_PSK_ID
#define COAP_USE_PSK_ID CONFIG_LIBCOAP_USE_PSK_ID
#else /* ! CONFIG_LIBCOAP_USE_PSK_ID */
#define COAP_USE_PSK_ID NULL
#endif /* ! CONFIG_LIBCOAP_USE_PSK_ID */
static coap_context_t *main_coap_context = NULL;
static coap_optlist_t *optlist = NULL;
static int quit = 0;
static coap_response_t
message_handler(coap_session_t *session,
const coap_pdu_t *sent,
const coap_pdu_t *received,
const coap_mid_t id) {
const uint8_t *data;
size_t len;
size_t offset;
size_t total;
(void)session;
(void)sent;
(void)id;
if (coap_get_data_large(received, &len, &data, &offset, &total)) {
printf("%*.*s", (int)len, (int)len, (const char *)data);
if (len + offset == total) {
printf("\n");
quit = 1;
}
}
return COAP_RESPONSE_OK;
}
static void
nack_handler(coap_session_t *session COAP_UNUSED,
const coap_pdu_t *sent COAP_UNUSED,
const coap_nack_reason_t reason,
const coap_mid_t id COAP_UNUSED) {
switch (reason) {
case COAP_NACK_TOO_MANY_RETRIES:
case COAP_NACK_NOT_DELIVERABLE:
case COAP_NACK_RST:
case COAP_NACK_TLS_FAILED:
case COAP_NACK_TLS_LAYER_FAILED:
case COAP_NACK_WS_LAYER_FAILED:
case COAP_NACK_WS_FAILED:
coap_log_err("cannot send CoAP pdu\n");
quit = 1;
break;
case COAP_NACK_ICMP_ISSUE:
case COAP_NACK_BAD_RESPONSE:
default:
break;
}
return;
}
static int
resolve_address(const char *host, const char *service, coap_address_t *dst,
int scheme_hint_bits) {
uint16_t port = service ? atoi(service) : 0;
int ret = 0;
coap_str_const_t str_host;
coap_addr_info_t *addr_info;
str_host.s = (const uint8_t *)host;
str_host.length = strlen(host);
addr_info = coap_resolve_address_info(&str_host, port, port, port, port,
AF_UNSPEC, scheme_hint_bits,
COAP_RESOLVE_TYPE_REMOTE);
if (addr_info) {
ret = 1;
*dst = addr_info->addr;
}
coap_free_address_info(addr_info);
return ret;
}
void
client_coap_init(int argc, char **argv) {
coap_session_t *session = NULL;
coap_pdu_t *pdu;
coap_address_t dst;
coap_mid_t mid;
int len;
coap_uri_t uri;
char portbuf[8];
#define BUFSIZE 100
unsigned char buf[BUFSIZE];
int res;
const char *coap_uri = COAP_CLIENT_URI;
if (argc > 1) {
coap_uri = argv[1];
}
/* Initialize libcoap library */
coap_startup();
coap_set_log_level(COAP_MAX_LOGGING_LEVEL);
/* Parse the URI */
len = coap_split_uri((const unsigned char *)coap_uri, strlen(coap_uri), &uri);
if (len != 0) {
coap_log_warn("Failed to parse uri %s\n", coap_uri);
goto fail;
}
snprintf(portbuf, sizeof(portbuf), "%d", uri.port);
snprintf((char *)buf, sizeof(buf), "%*.*s", (int)uri.host.length,
(int)uri.host.length, (const char *)uri.host.s);
/* resolve destination address where packet should be sent */
len = resolve_address((const char *)buf, portbuf, &dst, 1 << uri.scheme);
if (len <= 0) {
coap_log_warn("Failed to resolve address %*.*s\n", (int)uri.host.length,
(int)uri.host.length, (const char *)uri.host.s);
goto fail;
}
main_coap_context = coap_new_context(NULL);
if (!main_coap_context) {
coap_log_warn("Failed to initialize context\n");
goto fail;
}
coap_context_set_block_mode(main_coap_context, COAP_BLOCK_USE_LIBCOAP);
if (uri.scheme == COAP_URI_SCHEME_COAP) {
session = coap_new_client_session(main_coap_context, NULL, &dst,
COAP_PROTO_UDP);
} else if (uri.scheme == COAP_URI_SCHEME_COAP_TCP) {
session = coap_new_client_session(main_coap_context, NULL, &dst,
COAP_PROTO_TCP);
#if defined (COAP_USE_PSK) && defined(COAP_USE_PSK_ID)
} else {
static coap_dtls_cpsk_t dtls_psk;
static char client_sni[256];
memset(client_sni, 0, sizeof(client_sni));
memset(&dtls_psk, 0, sizeof(dtls_psk));
dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
if (uri.host.length) {
memcpy(client_sni, uri.host.s,
MIN(uri.host.length, sizeof(client_sni) - 1));
}
else {
memcpy(client_sni, "localhost", 9);
}
dtls_psk.client_sni = client_sni;
dtls_psk.psk_info.identity.s = (const uint8_t *)COAP_USE_PSK_ID;
dtls_psk.psk_info.identity.length = strlen(COAP_USE_PSK_ID);
dtls_psk.psk_info.key.s = (const uint8_t *)COAP_USE_PSK;
dtls_psk.psk_info.key.length = strlen(COAP_USE_PSK);
session = coap_new_client_session_psk2(main_coap_context, NULL, &dst,
COAP_PROTO_DTLS, &dtls_psk);
#else /* ! COAP_USE_PSK && ! COAP_USE_PSK_ID */
coap_log_err("CONFIG_LIBCOAP_USE_PSK and CONFIG_LIBCOAP_USE_PSK_ID not defined\n");
goto fail;
#endif /* ! COAP_USE_PSK && ! COAP_USE_PSK_ID */
}
if (!session) {
coap_log_warn("Failed to create session\n");
goto fail;
}
coap_register_response_handler(main_coap_context, message_handler);
coap_register_nack_handler(main_coap_context, nack_handler);
/* construct CoAP message */
pdu = coap_pdu_init(COAP_MESSAGE_CON,
COAP_REQUEST_CODE_GET,
coap_new_message_id(session),
coap_session_max_pdu_size(session));
if (!pdu) {
coap_log_warn("Failed to create PDU\n");
goto fail;
}
len = coap_uri_into_options(&uri, &dst, &optlist, 1, buf, sizeof(buf));
if (len) {
coap_log_warn("Failed to create options\n");
goto fail;
}
/* Add option list (which will be sorted) to the PDU */
if (optlist) {
res = coap_add_optlist_pdu(pdu, &optlist);
if (res != 1) {
coap_log_warn("Failed to add options to PDU\n");
goto fail;
}
}
/* and send the PDU */
mid = coap_send(session, pdu);
if (mid == COAP_INVALID_MID) {
coap_log_warn("Failed to send PDU\n");
goto fail;
}
while (!quit) {
coap_io_process(main_coap_context, 1000);
}
fail:
/* Clean up library usage so client can be run again */
quit = 0;
coap_delete_optlist(optlist);
optlist = NULL;
coap_session_release(session);
session = NULL;
coap_free_context(main_coap_context);
main_coap_context = NULL;
coap_cleanup();
}
@@ -0,0 +1,29 @@
/*
* client-coap.h -- RIOT client example
*
* Copyright (C) 2023 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef CLIENT_COAP_H
#define CLIENT_COAP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "coap_config.h"
#include <coap3/coap.h>
/* Start up the CoAP Client */
void client_coap_init(int argc, char **argv);
#ifdef __cplusplus
}
#endif
#endif /* CLIENT_COAP_H */
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
* Copyright (C) 2018 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief Example application for libcoap client
*
* @author Raul Fuentes <>
*
* @}
*/
#include <stdio.h>
#include "shell.h"
#include "msg.h"
#include "coap3/coap.h"
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
extern int client_coap_init(int argc, char **argv);
static const shell_command_t shell_commands[] = {
{ "coapc", "Start a libcoap client", client_coap_init },
{ NULL, NULL, NULL }
};
int
main(void) {
/* we need a message queue for the thread running the shell in order to
* receive potentially fast incoming networking packets */
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("RIOT libcoap client testing implementation");
/* start shell */
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
/* should be never reached */
return 0;
}
@@ -0,0 +1,12 @@
if USEMODULE_LIBCOAP
config LIBCOAP_USE_PSK
string "Secret to use for PSK communications"
default "secretPSK"
depends on USEMODULE_TINYDTLS
config LIBCOAP_SERVER_SUPPORT
bool "Set to y if server support is required"
default y
config LIBCOAP_CLIENT_SUPPORT
bool "Set to y if ongoing proxy support is required"
default n
endif # USEMODULE_LIBCOAP
@@ -0,0 +1,69 @@
# name of your application
APPLICATION = libcoap-server
# If no BOARD is found in the environment, use this default:
BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += netdev_default
USEMODULE += auto_init_gnrc_netif
# Activate ICMPv6 error messages
# USEMODULE += gnrc_icmpv6_error
# Specify the mandatory networking module for a IPv6 routing node
USEMODULE += gnrc_ipv6_router_default
# Add a routing protocol
USEMODULE += gnrc_rpl
USEMODULE += auto_init_gnrc_rpl
# Additional networking modules that can be dropped if not needed
USEMODULE += gnrc_icmpv6_echo
USEMODULE += shell_cmd_gnrc_udp
# Specify the mandatory networking modules for IPv6 and UDP
USEMODULE += gnrc_ipv6_default
USEMODULE += memarray
USEMODULE += ipv4_addr
# a cryptographically secure implementation of PRNG is needed for tinydtls
# Uncomment the following 3 lines for tinydtls support
CFLAGS += -DWITH_RIOT_SOCK
USEPKG += tinydtls
USEMODULE += prng_sha1prng
# libcoap support
USEPKG += libcoap
USEMODULE += sock_udp
# Configure if DNS is required
USEMODULE += sock_dns
# USEMODULE += xtimer
USEMODULE += ztimer64_xtimer_compat
# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_cmds_default
USEMODULE += ps
USEMODULE += netstats_l2
USEMODULE += netstats_ipv6
USEMODULE += netstats_rpl
# libcoap needs some space
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(3*THREAD_STACKSIZE_DEFAULT\)
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
include $(RIOTBASE)/Makefile.include

Some files were not shown because too many files have changed in this diff Show More