mirror of https://github.com/ARMmbed/mbed-os.git
Add 'features/nanostack/FEATURE_NANOSTACK/coap-service/' from commit 'a1982c1de752c50410d975a03f505a69972539f5'
git-subtree-dir: features/nanostack/FEATURE_NANOSTACK/coap-service git-subtree-mainline:pull/3240/headc0adb069c9
git-subtree-split:a1982c1de7
commit
1e791e2e76
|
@ -0,0 +1,10 @@
|
|||
*.a
|
||||
*.lib
|
||||
output
|
||||
lcov
|
||||
coverage
|
||||
.yotta.json
|
||||
build/
|
||||
yotta_modules/
|
||||
yotta_targets/
|
||||
upload.tar.gz
|
|
@ -0,0 +1 @@
|
|||
test/*
|
|
@ -0,0 +1,4 @@
|
|||
unittest/*
|
||||
test/*
|
||||
doxygen/*
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Unless specifically indicated otherwise in a file, files are licensed
|
||||
under the Apache 2.0 license, as can be found in: apache-2.0.txt
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Makefile for combined CoAP Service library
|
||||
#
|
||||
|
||||
# Define compiler toolchain with CC or PLATFORM variables
|
||||
# Example (GCC toolchains, default $CC and $AR are used)
|
||||
# make
|
||||
#
|
||||
# OR (Cross-compile GCC toolchain)
|
||||
# make PLATFORM=arm-linux-gnueabi-
|
||||
#
|
||||
# OR (armcc/Keil)
|
||||
# make CC=armcc AR=ArmAR
|
||||
#
|
||||
# OR (IAR-ARM)
|
||||
# make CC=iccarm
|
||||
|
||||
#
|
||||
# External sources from libService
|
||||
#
|
||||
SERVLIB_DIR := ../libService
|
||||
override CFLAGS += -I$(SERVLIB_DIR)/libService/
|
||||
|
||||
NANOSTACK_DIR := ../nanostack
|
||||
override CFLAGS += -I$(NANOSTACK_DIR)/nanostack/
|
||||
|
||||
NSDLC_DIR := ../nsdl-c
|
||||
override CFLAGS += -I$(NSDLC_DIR)/nsdl-c
|
||||
|
||||
EVENTLOOP_DIR := ../event-loop
|
||||
override CFLAGS += -I$(EVENTLOOP_DIR)/nanostack-event-loop/
|
||||
|
||||
COAPSERVICE_DIR := ../coap-service
|
||||
override CFLAGS += -I$(COAPSERVICE_DIR)/coap-service/
|
||||
override CFLAGS += -I$(COAPSERVICE_DIR)/source/include/
|
||||
|
||||
LIB = libcoap-service.a
|
||||
|
||||
SRCS := \
|
||||
source/coap_connection_handler.c \
|
||||
source/coap_message_handler.c \
|
||||
source/coap_security_handler.c \
|
||||
source/coap_service_api.c \
|
||||
|
||||
override CFLAGS += -DVERSION='"$(VERSION)"'
|
||||
|
||||
include ../libService/toolchain_rules.mk
|
||||
|
||||
$(eval $(call generate_rules,$(LIB),$(SRCS)))
|
||||
|
||||
.PHONY: release
|
||||
release:
|
||||
7z a coap-service_$(VERSION).zip *.a *.lib include
|
||||
|
||||
.PHONY: deploy_to
|
||||
deploy_to: all
|
||||
tar --transform 's,^,coap-service/,' --append -f $(TO) *.a
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# Makefile.test for COAP service unit tests
|
||||
#
|
||||
|
||||
# List of subdirectories to build
|
||||
TEST_FOLDER := ./test/
|
||||
# List of unit test directories for libraries
|
||||
UNITTESTS := $(sort $(dir $(wildcard $(TEST_FOLDER)*/unittest/*)))
|
||||
TESTDIRS := $(UNITTESTS:%=build-%)
|
||||
CLEANTESTDIRS := $(UNITTESTS:%=clean-%)
|
||||
COVERAGEFILE := ./lcov/coverage.info
|
||||
|
||||
.PHONY: test
|
||||
test: $(TESTDIRS)
|
||||
@rm -rf ./lcov
|
||||
@rm -rf ./coverage
|
||||
@mkdir -p lcov
|
||||
@mkdir -p lcov/results
|
||||
@mkdir coverage
|
||||
@find ./test -name '*.xml' | xargs cp -t ./lcov/results/
|
||||
@rm -f lcov/index.xml
|
||||
@./xsl_script.sh
|
||||
@cp junit_xsl.xslt lcov/.
|
||||
@xsltproc -o lcov/testresults.html lcov/junit_xsl.xslt lcov/index.xml
|
||||
@rm -f lcov/junit_xsl.xslt
|
||||
@rm -f lcov/index.xml
|
||||
@find ./ -name '*.gcno' | xargs cp --backup=numbered -t ./coverage/
|
||||
@find ./ -name '*.gcda' | xargs cp --backup=numbered -t ./coverage/
|
||||
@gcovr --object-directory ./coverage --exclude-unreachable-branches -e '.*/builds/.*' -e '.*/test/.*' -e '.*/yotta_modules/.*' -e '.*/stub/.*' -x -o ./lcov/gcovr.xml
|
||||
@lcov -d test/. -c -o $(COVERAGEFILE)
|
||||
@lcov -q -r $(COVERAGEFILE) "/usr*" -o $(COVERAGEFILE)
|
||||
@lcov -q -r $(COVERAGEFILE) "/test*" -o $(COVERAGEFILE)
|
||||
@lcov -q -r $(COVERAGEFILE) "/mbed-client-libservice*" -o $(COVERAGEFILE)
|
||||
@lcov -q -r $(COVERAGEFILE) "/libService*" -o $(COVERAGEFILE)
|
||||
@genhtml -q $(COVERAGEFILE) --show-details --output-directory lcov/html
|
||||
@echo coap-service unit tests built
|
||||
|
||||
$(TESTDIRS):
|
||||
@make -C $(@:build-%=%)
|
||||
|
||||
$(CLEANDIRS):
|
||||
@make -C $(@:clean-%=%) clean
|
||||
|
||||
$(CLEANTESTDIRS):
|
||||
@make -C $(@:clean-%=%) clean
|
||||
|
||||
# Extend default clean rule
|
||||
clean: clean-extra
|
||||
|
||||
clean-extra: $(CLEANDIRS) \
|
||||
$(CLEANTESTDIRS)
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef COAP_SERVICE_API_H_
|
||||
#define COAP_SERVICE_API_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "ns_address.h"
|
||||
|
||||
/**
|
||||
* This interface is used in sending and receiving of CoAP messages to multicast address and receive multiple responses.
|
||||
*/
|
||||
|
||||
// Allowed_methods
|
||||
#define COAP_SERVICE_ACCESS_ALL_ALLOWED 0x0F
|
||||
#define COAP_SERVICE_ACCESS_GET_ALLOWED 0x01
|
||||
#define COAP_SERVICE_ACCESS_PUT_ALLOWED 0x02
|
||||
#define COAP_SERVICE_ACCESS_POST_ALLOWED 0x04
|
||||
#define COAP_SERVICE_ACCESS_DELETE_ALLOWED 0x08
|
||||
|
||||
// Bits for service options
|
||||
#define COAP_SERVICE_OPTIONS_NONE 0x00
|
||||
#define COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET 0x01
|
||||
#define COAP_SERVICE_OPTIONS_SECURE 0x02
|
||||
#define COAP_SERVICE_OPTIONS_EPHEMERAL_PORT 0x04
|
||||
/** Link-layer security bypass option is set*/
|
||||
#define COAP_SERVICE_OPTIONS_SECURE_BYPASS 0x80
|
||||
|
||||
// Bits for request options
|
||||
#define COAP_REQUEST_OPTIONS_NONE 0x00
|
||||
#define COAP_REQUEST_OPTIONS_ADDRESS_DEFAULT 0x00//!< default is not setting either short or long.
|
||||
#define COAP_REQUEST_OPTIONS_ADDRESS_LONG 0x01
|
||||
#define COAP_REQUEST_OPTIONS_ADDRESS_SHORT 0x02
|
||||
#define COAP_REQUEST_OPTIONS_MULTICAST 0x04 //!< indicates that CoAP library support multicasting
|
||||
#define COAP_REQUEST_OPTIONS_SECURE_BYPASS 0x08
|
||||
|
||||
/**
|
||||
* \brief Service message response receive callback.
|
||||
*
|
||||
* Function that handles CoAP service message receiving and parsing
|
||||
*
|
||||
* \param msg_id Id number of the current message.
|
||||
* \param source_address IPv6 source address.
|
||||
* \param source_port Source port
|
||||
* \param response_ptr Pointer to CoAP header structure.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
typedef int coap_service_response_recv(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr);
|
||||
|
||||
/**
|
||||
* \brief CoAP service request callback
|
||||
*
|
||||
* CoAP service request message receiving and parsing function
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param source_address IPv6 source address.
|
||||
* \param source_port Source port
|
||||
* \param request_ptr Pointer to CoAP header structure.
|
||||
*
|
||||
* \return Status
|
||||
*/
|
||||
typedef int coap_service_request_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr);
|
||||
|
||||
/**
|
||||
* \brief Security service start callback
|
||||
*
|
||||
* Starts security service handling and fetches device password.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param address Address of sender
|
||||
* \param port Port of the device
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
typedef int coap_service_security_start_cb(int8_t service_id, uint8_t address[static 16], uint16_t port, uint8_t* pw, uint8_t *pw_len);
|
||||
|
||||
/**
|
||||
* \brief CoAP service security done callback
|
||||
*
|
||||
* CoAP service security done callback function.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param address Address of sender
|
||||
* \param keyblock Security key (40 bits)
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
typedef int coap_service_security_done_cb(int8_t service_id, uint8_t address[static 16], uint8_t keyblock[static 40]);
|
||||
|
||||
/**
|
||||
* \brief Initialise server instance.
|
||||
*
|
||||
* Initialise Thread services for the registered application.
|
||||
*
|
||||
* \param interface_id Informs registered application interface id. This parameter is passed to socket implementation.
|
||||
* \param listen_port Port that Application wants to use for communicate with coap server.
|
||||
* \param service_options Options of the current service.
|
||||
* \param *start_ptr Callback to inform security handling is started and to fetch device password.
|
||||
* \param *coap_security_done_cb Callback to inform security handling is done.
|
||||
*
|
||||
* \return service_id / -1 for failure
|
||||
*/
|
||||
extern int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options, coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb);
|
||||
|
||||
/**
|
||||
* \brief Service delete
|
||||
*
|
||||
* Removes all data related to this instance
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
*/
|
||||
extern void coap_service_delete( int8_t service_id );
|
||||
|
||||
/**
|
||||
* \brief Close secure connection
|
||||
*
|
||||
* Closes secure connection (if present), but leaves socket open.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
*/
|
||||
extern void coap_service_close_secure_connection(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port);
|
||||
|
||||
/**
|
||||
* \brief Sets password for device
|
||||
*
|
||||
* \param service_id Service id
|
||||
* \param address Device address
|
||||
* \param port Device port
|
||||
* \param pw_ptr Pointer to password.
|
||||
* \param pw_len Lenght of password.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
//int coap_service_security_key_set(int8_t service_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t pw_len);
|
||||
|
||||
/**
|
||||
* \brief Virtual socket sent callback.
|
||||
*
|
||||
* Sent data to virtual socket.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param destination_addr_ptr Receiver IPv6 address.
|
||||
* \param port Receiver port number.
|
||||
* \param *data_ptr Pointer to the data.
|
||||
* \param data_len Lenght of the data.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
typedef int coap_service_virtual_socket_send_cb(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port, const uint8_t *data_ptr, uint16_t data_len);
|
||||
|
||||
/**
|
||||
* \brief Virtual socket read.
|
||||
*
|
||||
* Receive data from virtual socket.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param source_addr_ptr Receiver IPv6 address.
|
||||
* \param port Receiver port number.
|
||||
* \param *data_ptr Pointer to the data
|
||||
* \param data_len Lenght of the data
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
extern int16_t coap_service_virtual_socket_recv(int8_t service_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);
|
||||
|
||||
/**
|
||||
* \brief Set virtual socket
|
||||
*
|
||||
* Sets virtual socket for CoAP services.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param *send_method_ptr Callback to coap virtual socket.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
extern int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_service_virtual_socket_send_cb *send_method_ptr);
|
||||
|
||||
/**
|
||||
* \brief Register unsecure callback methods to CoAP server
|
||||
*
|
||||
* Register application and informs CoAP services unsecure registery callback function.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param *uri Uri address.
|
||||
* \param port port that Application wants to use for communicate with coap server.
|
||||
* \param allowed_method Informs method that is allowed to use (used defines described above).
|
||||
* \param *request_recv_cb CoAP service request receive callback function pointer.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
extern int8_t coap_service_register_uri(int8_t service_id, const char *uri, uint8_t allowed_method, coap_service_request_recv_cb *request_recv_cb);
|
||||
|
||||
/**
|
||||
* \brief Unregister unsecure callback methods to CoAP server
|
||||
*
|
||||
* Register application and informs CoAP services unsecure registery callback function.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param *uri Uri address.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
extern int8_t coap_service_unregister_uri(int8_t service_id, const char *uri);
|
||||
|
||||
/**
|
||||
* \brief Sends CoAP service request
|
||||
*
|
||||
* Build and sends CoAP service request message.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param options Options defined above.
|
||||
* \param destination_addr IPv6 address.
|
||||
* \param destination_port Destination port
|
||||
* \param msg_type Message type can be found from sn_coap_header.
|
||||
* \param msg_code Message code can be found from sn_coap_header.
|
||||
* \param *uri Uri address.
|
||||
* \param cont_type Content type can be found from sn_coap_header.
|
||||
* \param payload_ptr Pointer to message content.
|
||||
* \param payload_len Lenght of the message.
|
||||
* \param *request_response_cb Callback to inform result of the request.
|
||||
*
|
||||
* \return msg_id Id number of the current message.
|
||||
*/
|
||||
extern uint16_t coap_service_request_send(int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16], uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri,
|
||||
sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_service_response_recv *request_response_cb);
|
||||
|
||||
/**
|
||||
* \brief Sends CoAP service response
|
||||
*
|
||||
* Build and sends CoAP service response message.
|
||||
*
|
||||
* \param service_id Id number of the current service.
|
||||
* \param msg_id Message ID number.
|
||||
* \param options Options defined above.
|
||||
* \param response_ptr Pointer to CoAP header structure.
|
||||
*
|
||||
* \return -1 For failure
|
||||
*- 0 For success
|
||||
*/
|
||||
extern int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len);
|
||||
|
||||
extern int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COAP_SERVICE_API_H_ */
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:output encoding="UTF-8" indent="yes" method="html"/>
|
||||
<xsl:strip-space elements="*"/>
|
||||
|
||||
<xsl:variable name="list"
|
||||
select="document('index.xml')/list" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<h1>
|
||||
Unittest report
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Total tests run <xsl:value-of select="sum(document($list/entry/@name)/testsuite/@tests)"/>
|
||||
, failures: <xsl:value-of select="sum(document($list/entry/@name)/testsuite/@failures) + sum(document($list/entry/@name)/testsuite/@errors)"/>
|
||||
</b>
|
||||
|
||||
<xsl:for-each select="document($list/entry/@name)" >
|
||||
<xsl:apply-templates select="testsuite"/>
|
||||
</xsl:for-each>
|
||||
</p>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="testsuite">
|
||||
<h2>
|
||||
<xsl:value-of select="@name" />
|
||||
</h2>
|
||||
<table border="1" cellSpacing="0" cellPadding="10" >
|
||||
<tr>
|
||||
<th>Tests run</th>
|
||||
<th>Tests failed</th>
|
||||
<th>Other errors</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><xsl:value-of select="@tests"/></td>
|
||||
<td><xsl:value-of select="@failures"/></td>
|
||||
<td><xsl:value-of select="@errors"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<table border="1" cellSpacing="0" cellPadding="10" >
|
||||
<tr>
|
||||
<th>Tests name</th>
|
||||
<th>PASS/FAIL</th>
|
||||
<th>Failing case</th>
|
||||
<th>Reason</th>
|
||||
</tr>
|
||||
<xsl:apply-templates select="testcase"/>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="testcase">
|
||||
<xsl:choose>
|
||||
<xsl:when test="failure">
|
||||
<tr><td><font color="#FF0000"><xsl:value-of select="@name" /></font></td><xsl:apply-templates select="failure"/></tr>
|
||||
</xsl:when>
|
||||
<xsl:when test="error">
|
||||
<tr><td><font color="#FF0000"><xsl:value-of select="@name" /></font></td><xsl:apply-templates select="error"/></tr>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<tr><td><xsl:value-of select="@name" /></td><td><font color="#00FF00">PASS</font></td><td></td><td></td></tr>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="failure">
|
||||
<td>
|
||||
<b><font color="#FF0000">FAIL</font></b>
|
||||
</td>
|
||||
<td>
|
||||
<font color="#ff0000">
|
||||
<xsl:value-of select="@message" />
|
||||
</font>
|
||||
</td>
|
||||
<td>
|
||||
<font color="#ff0000">
|
||||
<xsl:value-of select="@type" />
|
||||
</font>
|
||||
</td>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="error">
|
||||
<td>
|
||||
<b><font color="#FF0000">FAIL</font></b>
|
||||
</td>
|
||||
<td>
|
||||
<font color="#ff0000">
|
||||
<xsl:value-of select="@message" />
|
||||
</font>
|
||||
</td>
|
||||
<td>
|
||||
<font color="#ff0000">
|
||||
<xsl:value-of select="@type" />
|
||||
</font>
|
||||
</td>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "coap-service",
|
||||
"version": "4.0.3",
|
||||
"description": "CoAP Service library",
|
||||
"keywords": [
|
||||
"coap",
|
||||
"service"
|
||||
],
|
||||
"repository": {
|
||||
"url": "git@github.com:ARMmbed/coap-service.git",
|
||||
"type": "git"
|
||||
},
|
||||
"homepage": "https://github.com/ARMmbed/coap-service",
|
||||
"license": "Apache-2.0",
|
||||
"extraIncludes": [
|
||||
"coap-service",
|
||||
"nanostack-event-loop",
|
||||
"source/include"
|
||||
],
|
||||
"dependencies": {
|
||||
"nanostack-libservice": "^3.0.0",
|
||||
"mbed-client-c": "^3.0.0",
|
||||
"sal-stack-nanostack": "^5.0.0",
|
||||
"mbedtls": "^2.0.0"
|
||||
},
|
||||
"targetDependencies": {}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) 2015 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
# not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# * http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
echo
|
||||
echo "Build coap service unit tests"
|
||||
echo
|
||||
|
||||
make -f Makefile.test test
|
||||
make -f Makefile.test test clean
|
|
@ -0,0 +1,907 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "coap_connection_handler.h"
|
||||
#include "coap_security_handler.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "socket_api.h"
|
||||
#include "net_interface.h"
|
||||
#include "eventOS_event_timer.h"
|
||||
#include "coap_service_api_internal.h"
|
||||
|
||||
#define TRACE_GROUP "ThCH"
|
||||
|
||||
typedef enum session_state_e {
|
||||
SECURE_SESSION_HANDSHAKE_ONGOING = 0,
|
||||
SECURE_SESSION_OK,
|
||||
SECURE_SESSION_CLOSED
|
||||
}session_state_t;
|
||||
|
||||
typedef struct internal_socket_s {
|
||||
coap_conn_handler_t *parent;
|
||||
|
||||
uint32_t timeout_min;
|
||||
uint32_t timeout_max;
|
||||
|
||||
uint16_t listen_port; // 0 for ephemeral-port sockets
|
||||
|
||||
int16_t data_len;
|
||||
uint8_t *data;
|
||||
|
||||
int8_t socket;
|
||||
bool real_socket;
|
||||
uint8_t usage_counter;
|
||||
bool is_secure;
|
||||
|
||||
bool bypass_link_sec;
|
||||
|
||||
ns_list_link_t link;
|
||||
} internal_socket_t;
|
||||
|
||||
static NS_LIST_DEFINE(socket_list, internal_socket_t, link);
|
||||
|
||||
static void timer_cb(void* param);
|
||||
|
||||
#define TIMER_STATE_CANCELLED -1 /* cancelled */
|
||||
#define TIMER_STATE_NO_EXPIRY 0 /* none of the delays is expired */
|
||||
#define TIMER_STATE_INT_EXPIRY 1 /* the intermediate delay only is expired */
|
||||
#define TIMER_STATE_FIN_EXPIRY 2 /* the final delay is expired */
|
||||
|
||||
typedef struct secure_timer_s {
|
||||
uint8_t id;
|
||||
timeout_t *timer;
|
||||
int8_t state;
|
||||
uint32_t fin_ms;
|
||||
uint32_t int_ms;
|
||||
} secure_timer_t;
|
||||
|
||||
typedef struct secure_session {
|
||||
coap_security_t *sec_handler; //owned
|
||||
internal_socket_t *parent; //not owned
|
||||
|
||||
ns_address_t remote_host;
|
||||
uint8_t local_address[16];
|
||||
// local port is fixed by socket
|
||||
|
||||
secure_timer_t timer;
|
||||
|
||||
session_state_t session_state;
|
||||
uint32_t last_contact_time;
|
||||
ns_list_link_t link;
|
||||
} secure_session_t;
|
||||
|
||||
static NS_LIST_DEFINE(secure_session_list, secure_session_t, link);
|
||||
static int secure_session_sendto(int8_t socket_id, void *handle, const void *buf, size_t len);
|
||||
static int secure_session_recvfrom(int8_t socket_id, unsigned char *buf, size_t len);
|
||||
static void start_timer(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms);
|
||||
static int timer_status(int8_t timer_id);
|
||||
|
||||
static secure_session_t *secure_session_find_by_timer_id(int8_t timer_id)
|
||||
{
|
||||
secure_session_t *this = NULL;
|
||||
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
|
||||
if (cur_ptr->timer.id == timer_id) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static void secure_session_delete(secure_session_t *this)
|
||||
{
|
||||
if (this) {
|
||||
ns_list_remove(&secure_session_list, this);
|
||||
transactions_delete_all(this->remote_host.address, this->remote_host.identifier);
|
||||
if( this->sec_handler ){
|
||||
coap_security_destroy(this->sec_handler);
|
||||
this->sec_handler = NULL;
|
||||
}
|
||||
if(this->timer.timer){
|
||||
eventOS_timeout_cancel(this->timer.timer);
|
||||
}
|
||||
ns_dyn_mem_free(this);
|
||||
this = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static secure_session_t *secure_session_create(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
if(!address_ptr){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(MAX_SECURE_SESSION_COUNT <= ns_list_count(&secure_session_list)){
|
||||
// Seek & destroy oldest session where close notify have been sent
|
||||
secure_session_t *to_be_removed = NULL;
|
||||
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
|
||||
if(cur_ptr->session_state == SECURE_SESSION_CLOSED){
|
||||
if(!to_be_removed || cur_ptr->last_contact_time < to_be_removed->last_contact_time){
|
||||
to_be_removed = cur_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!to_be_removed){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
secure_session_delete(to_be_removed);
|
||||
}
|
||||
|
||||
secure_session_t *this = ns_dyn_mem_alloc(sizeof(secure_session_t));
|
||||
if (!this) {
|
||||
return NULL;
|
||||
}
|
||||
memset(this, 0, sizeof(secure_session_t));
|
||||
|
||||
uint8_t timer_id = 1;
|
||||
|
||||
while(secure_session_find_by_timer_id(timer_id)){
|
||||
if(timer_id == 0xff){
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
timer_id++;
|
||||
}
|
||||
this->timer.id = timer_id;
|
||||
this->remote_host.type = ADDRESS_IPV6;
|
||||
memcpy(this->remote_host.address, address_ptr, 16);
|
||||
this->remote_host.identifier = port;
|
||||
|
||||
this->sec_handler = coap_security_create(parent->socket, this->timer.id, this, ECJPAKE,
|
||||
&secure_session_sendto, &secure_session_recvfrom, &start_timer, &timer_status);
|
||||
if( !this->sec_handler ){
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->parent = parent;
|
||||
|
||||
this->session_state = SECURE_SESSION_HANDSHAKE_ONGOING;
|
||||
ns_list_add_to_start(&secure_session_list, this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
static void clear_secure_sessions(internal_socket_t *this){
|
||||
if( this ){
|
||||
ns_list_foreach_safe(secure_session_t, cur_ptr, &secure_session_list) {
|
||||
if( cur_ptr->parent == this ){
|
||||
coap_security_send_close_alert( cur_ptr->sec_handler );
|
||||
secure_session_delete(cur_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static secure_session_t *secure_session_find(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
secure_session_t *this = NULL;
|
||||
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
|
||||
if( cur_ptr->sec_handler ){
|
||||
if (cur_ptr->parent == parent && cur_ptr->remote_host.identifier == port &&
|
||||
memcmp(cur_ptr->remote_host.address, address_ptr, 16) == 0) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void recv_sckt_msg(void *cb_res);
|
||||
static void secure_recv_sckt_msg(void *cb_res);
|
||||
|
||||
static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec)
|
||||
{
|
||||
internal_socket_t *this = ns_dyn_mem_alloc(sizeof(internal_socket_t));
|
||||
if (!this) {
|
||||
return NULL;
|
||||
}
|
||||
memset(this, 0, sizeof(internal_socket_t));
|
||||
|
||||
this->data_len = 0;
|
||||
this->data = NULL;
|
||||
|
||||
this->is_secure = is_secure;
|
||||
this->usage_counter = 1;
|
||||
|
||||
this->listen_port = listen_port;
|
||||
this->real_socket = real_socket;
|
||||
this->bypass_link_sec = bypassSec;
|
||||
this->socket = -1;
|
||||
if( real_socket ){
|
||||
if( use_ephemeral_port ){ //socket_api creates ephemeral port if the one provided is 0
|
||||
listen_port = 0;
|
||||
}
|
||||
if( !is_secure ){
|
||||
this->socket = socket_open(SOCKET_UDP, listen_port, recv_sckt_msg);
|
||||
}else{
|
||||
#ifdef COAP_SECURITY_AVAILABLE
|
||||
this->socket = socket_open(SOCKET_UDP, listen_port, secure_recv_sckt_msg);
|
||||
#else
|
||||
tr_err("Secure CoAP unavailable - SSL library not configured, possibly due to lack of entropy source");
|
||||
#endif
|
||||
}
|
||||
// Socket create failed
|
||||
if(this->socket < 0){
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &(const int8_t) {bypassSec ? 0 : 1}, sizeof(int8_t));
|
||||
|
||||
// XXX API for this? May want to get clever to do recommended first query = 1 hop, retries = whole PAN
|
||||
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &(const int16_t) {16}, sizeof(int16_t));
|
||||
|
||||
// Set socket option to receive packet info
|
||||
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_RECVPKTINFO, &(const bool) {1}, sizeof(bool));
|
||||
|
||||
}else{
|
||||
this->socket = -1;
|
||||
}
|
||||
|
||||
ns_list_add_to_start(&socket_list, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
static void int_socket_delete(internal_socket_t *this)
|
||||
{
|
||||
if (this) {
|
||||
this->usage_counter--;
|
||||
if(this->usage_counter == 0){
|
||||
clear_secure_sessions(this);
|
||||
socket_close(this->socket);
|
||||
ns_list_remove(&socket_list, this);
|
||||
if( this->data ){
|
||||
ns_dyn_mem_free(this->data);
|
||||
this->data = NULL;
|
||||
}
|
||||
if(this->parent){
|
||||
ns_dyn_mem_free(this->parent);
|
||||
}
|
||||
ns_dyn_mem_free(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static internal_socket_t *int_socket_find_by_socket_id(int8_t id)
|
||||
{
|
||||
internal_socket_t *this = NULL;
|
||||
ns_list_foreach(internal_socket_t, cur_ptr, &socket_list) {
|
||||
if( cur_ptr->socket == id ) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static internal_socket_t *int_socket_find(uint16_t port, bool is_secure, bool is_real_socket, bool bypassSec)
|
||||
{
|
||||
(void) bypassSec;
|
||||
|
||||
internal_socket_t *this = NULL;
|
||||
ns_list_foreach(internal_socket_t, cur_ptr, &socket_list) {
|
||||
if( cur_ptr->listen_port == port && cur_ptr->real_socket == is_real_socket &&
|
||||
is_secure == cur_ptr->is_secure /*&& bypass_link_sec == bypassSec*/) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static int8_t send_to_real_socket(int8_t socket_id, const ns_address_t *address, const uint8_t source_address[static 16], const void *buffer, uint16_t length)
|
||||
{
|
||||
ns_iovec_t msg_iov;
|
||||
ns_msghdr_t msghdr;
|
||||
|
||||
msghdr.msg_name = (void*)address;
|
||||
msghdr.msg_namelen = sizeof(ns_address_t);
|
||||
msghdr.msg_iov = &msg_iov;
|
||||
msghdr.msg_iovlen = 1;
|
||||
msghdr.flags = 0;
|
||||
|
||||
if (memcmp(source_address, ns_in6addr_any, 16)) {
|
||||
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
|
||||
ns_cmsghdr_t *cmsg;
|
||||
ns_in6_pktinfo_t *pktinfo;
|
||||
|
||||
tr_debug("send from source address %s", trace_array(source_address, 16));
|
||||
msghdr.msg_control = ancillary_databuffer;
|
||||
msghdr.msg_controllen = sizeof(ancillary_databuffer);
|
||||
|
||||
cmsg = NS_CMSG_FIRSTHDR(&msghdr);
|
||||
cmsg->cmsg_type = SOCKET_IPV6_PKTINFO;
|
||||
cmsg->cmsg_level = SOCKET_IPPROTO_IPV6;
|
||||
cmsg->cmsg_len = NS_CMSG_LEN(sizeof(ns_in6_pktinfo_t));
|
||||
|
||||
pktinfo = (ns_in6_pktinfo_t*)NS_CMSG_DATA(cmsg);
|
||||
pktinfo->ipi6_ifindex = 0;
|
||||
memcpy(pktinfo->ipi6_addr, source_address, 16);
|
||||
} else {
|
||||
msghdr.msg_control = NULL;
|
||||
msghdr.msg_controllen = 0;
|
||||
}
|
||||
|
||||
msg_iov.iov_base = (void *)buffer;
|
||||
msg_iov.iov_len = length;
|
||||
|
||||
return socket_sendmsg(socket_id, &msghdr, 0);
|
||||
}
|
||||
|
||||
static int secure_session_sendto(int8_t socket_id, void *handle, const void *buf, size_t len)
|
||||
{
|
||||
secure_session_t *session = handle;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
|
||||
if(!sock){
|
||||
return -1;
|
||||
}
|
||||
if(!sock->real_socket){
|
||||
// Send to virtual socket cb
|
||||
int ret = sock->parent->_send_cb(sock->socket, session->remote_host.address, session->remote_host.identifier, buf, len);
|
||||
if( ret < 0 )
|
||||
return ret;
|
||||
return len;
|
||||
}
|
||||
|
||||
int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT;
|
||||
int8_t securityLinkLayer = 1;
|
||||
if (sock->bypass_link_sec) {
|
||||
securityLinkLayer = 0;
|
||||
}
|
||||
socket_setsockopt(sock->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(sock->socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
//For some reason socket_sendto returns 0 in success, while other socket impls return number of bytes sent!!!
|
||||
//TODO: check if address_ptr is valid and use that instead if it is
|
||||
|
||||
int8_t ret = send_to_real_socket(sock->socket, &session->remote_host, session->local_address, buf, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int secure_session_recvfrom(int8_t socket_id, unsigned char *buf, size_t len)
|
||||
{
|
||||
(void)len;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
|
||||
if (sock->data && sock->data_len > 0) {
|
||||
memcpy( buf, sock->data, sock->data_len );
|
||||
int l = sock->data_len;
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
sock->data_len = 0;
|
||||
return l;
|
||||
}
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback timer. Maybe called in interrupt context
|
||||
* so keep it simple.
|
||||
* TODO - might be better to use an event timer in conjunction with
|
||||
* CoAP tasklet
|
||||
*/
|
||||
static void timer_cb(void *param)
|
||||
{
|
||||
secure_session_t *sec = param;
|
||||
if( sec ){
|
||||
if(sec->timer.fin_ms > sec->timer.int_ms){
|
||||
/* Intermediate expiry */
|
||||
sec->timer.fin_ms -= sec->timer.int_ms;
|
||||
sec->timer.state = TIMER_STATE_INT_EXPIRY;
|
||||
int error = coap_security_handler_continue_connecting(sec->sec_handler);
|
||||
if(MBEDTLS_ERR_SSL_TIMEOUT == error) {
|
||||
//TODO: How do we handle timeouts?
|
||||
secure_session_delete(sec);
|
||||
}
|
||||
else{
|
||||
sec->timer.timer = eventOS_timeout_ms(timer_cb, sec->timer.int_ms, (void*)sec);
|
||||
}
|
||||
}
|
||||
else{
|
||||
/* We have counted the number of cycles - finish */
|
||||
eventOS_timeout_cancel(sec->timer.timer);
|
||||
sec->timer.fin_ms = 0;
|
||||
sec->timer.int_ms = 0;
|
||||
sec->timer.timer = NULL;
|
||||
sec->timer.state = TIMER_STATE_FIN_EXPIRY;
|
||||
int error = coap_security_handler_continue_connecting(sec->sec_handler);
|
||||
if(MBEDTLS_ERR_SSL_TIMEOUT == error) {
|
||||
//TODO: How do we handle timeouts?
|
||||
secure_session_delete(sec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void start_timer(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms)
|
||||
{
|
||||
secure_session_t *sec = secure_session_find_by_timer_id(timer_id);
|
||||
if( sec ){
|
||||
if ((int_ms > 0) && (fin_ms > 0)) {
|
||||
sec->timer.int_ms = int_ms;
|
||||
sec->timer.fin_ms = fin_ms;
|
||||
sec->timer.state = TIMER_STATE_NO_EXPIRY;
|
||||
if(sec->timer.timer){
|
||||
eventOS_timeout_cancel(sec->timer.timer);
|
||||
}
|
||||
sec->timer.timer = eventOS_timeout_ms(timer_cb, int_ms, sec);
|
||||
} else if (fin_ms == 0) {
|
||||
/* fin_ms == 0 means cancel the timer */
|
||||
sec->timer.state = TIMER_STATE_CANCELLED;
|
||||
eventOS_timeout_cancel(sec->timer.timer);
|
||||
sec->timer.fin_ms = 0;
|
||||
sec->timer.int_ms = 0;
|
||||
sec->timer.timer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int timer_status(int8_t timer_id)
|
||||
{
|
||||
secure_session_t *sec = secure_session_find_by_timer_id(timer_id);
|
||||
if( sec ){
|
||||
return (int)sec->timer.state;
|
||||
}
|
||||
return TIMER_STATE_CANCELLED;
|
||||
}
|
||||
|
||||
static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address, uint8_t dst_address[static 16])
|
||||
{
|
||||
sock->data_len = 0;
|
||||
if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) {
|
||||
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
|
||||
ns_iovec_t msg_iov;
|
||||
ns_msghdr_t msghdr;
|
||||
ns_in6_pktinfo_t *pkt = NULL;
|
||||
|
||||
if (sock->data) {
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
}
|
||||
|
||||
sock->data = ns_dyn_mem_temporary_alloc(sckt_data->d_len);
|
||||
if (!sock->data) {
|
||||
sock->data = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msghdr.msg_name = src_address;
|
||||
msghdr.msg_namelen = sizeof(ns_address_t);
|
||||
msghdr.msg_iov = &msg_iov;
|
||||
msghdr.msg_iovlen = 1;
|
||||
msghdr.msg_control = ancillary_databuffer;
|
||||
msghdr.msg_controllen = sizeof(ancillary_databuffer);
|
||||
msghdr.flags = 0;
|
||||
|
||||
msg_iov.iov_base = sock->data;
|
||||
msg_iov.iov_len = sckt_data->d_len;
|
||||
|
||||
sock->data_len = socket_recvmsg(sckt_data->socket_id, &msghdr, 0);
|
||||
|
||||
if (sock->data_len > 0) {
|
||||
ns_cmsghdr_t *cmsg = NS_CMSG_FIRSTHDR(&msghdr);
|
||||
|
||||
while (cmsg) {
|
||||
switch (cmsg->cmsg_type) {
|
||||
case SOCKET_IPV6_PKTINFO:
|
||||
pkt = (ns_in6_pktinfo_t*)NS_CMSG_DATA(cmsg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cmsg = NS_CMSG_NXTHDR(&msghdr, cmsg);
|
||||
}
|
||||
if (pkt) {
|
||||
memcpy(dst_address, pkt->ipi6_addr, 16);
|
||||
} else {
|
||||
goto return_failure;
|
||||
}
|
||||
} else {
|
||||
goto return_failure;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return_failure:
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
sock->data_len = 0;
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void secure_recv_sckt_msg(void *cb_res)
|
||||
{
|
||||
socket_callback_t *sckt_data = cb_res;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id);
|
||||
ns_address_t src_address;
|
||||
uint8_t dst_address[16] = {0};
|
||||
memset(&src_address, 0, sizeof(ns_address_t));
|
||||
|
||||
if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
|
||||
/* If received from multicast address, reject */
|
||||
if (*(dst_address) == 0xFF) {
|
||||
return;
|
||||
}
|
||||
secure_session_t *session = secure_session_find(sock, src_address.address, src_address.identifier);
|
||||
|
||||
// Create session
|
||||
if (!session) {
|
||||
session = secure_session_create(sock, src_address.address, src_address.identifier);
|
||||
}
|
||||
if (!session) {
|
||||
tr_err("secure_recv_sckt_msg session creation failed - OOM");
|
||||
return;
|
||||
}
|
||||
// Record the destination. We are not strict on local address - all
|
||||
// session_find calls match only on remote address and port. But we
|
||||
// record the last-used destination address to use it as the source of
|
||||
// outgoing packets.
|
||||
memcpy(session->local_address, dst_address, 16);
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
// Start handshake
|
||||
if (!coap_security_handler_is_started(session->sec_handler) ){
|
||||
uint8_t *pw = ns_dyn_mem_alloc(64);
|
||||
uint8_t pw_len;
|
||||
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, src_address.address, src_address.identifier, pw, &pw_len)){
|
||||
//TODO: get_password_cb should support certs and PSK also
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = pw;
|
||||
keys._priv_len = pw_len;
|
||||
coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, sock->timeout_min, sock->timeout_max);
|
||||
//TODO: error handling
|
||||
}
|
||||
ns_dyn_mem_free(pw);
|
||||
} else {
|
||||
//Continue handshake
|
||||
if (session->session_state == SECURE_SESSION_HANDSHAKE_ONGOING) {
|
||||
int ret = coap_security_handler_continue_connecting(session->sec_handler);
|
||||
// Handshake done
|
||||
if (ret == 0) {
|
||||
eventOS_timeout_cancel(session->timer.timer);
|
||||
session->timer.timer = NULL;
|
||||
session->session_state = SECURE_SESSION_OK;
|
||||
if( sock->parent->_security_done_cb ){
|
||||
sock->parent->_security_done_cb(sock->socket, src_address.address,
|
||||
src_address.identifier,
|
||||
(void *)coap_security_handler_keyblock(session->sec_handler));
|
||||
}
|
||||
} else if (ret < 0){
|
||||
// error handling
|
||||
// TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
|
||||
secure_session_delete(session);
|
||||
}
|
||||
//Session valid
|
||||
} else {
|
||||
unsigned char *data = ns_dyn_mem_temporary_alloc(sock->data_len);
|
||||
int len = 0;
|
||||
len = coap_security_handler_read(session->sec_handler, data, sock->data_len);
|
||||
if( len < 0 ){
|
||||
if (len != MBEDTLS_ERR_SSL_WANT_READ && len != MBEDTLS_ERR_SSL_WANT_WRITE &&
|
||||
len != MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
|
||||
secure_session_delete(session);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
} else {
|
||||
if (sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, data, len);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void recv_sckt_msg(void *cb_res)
|
||||
{
|
||||
socket_callback_t *sckt_data = cb_res;
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(sckt_data->socket_id);
|
||||
ns_address_t src_address;
|
||||
uint8_t dst_address[16];
|
||||
|
||||
if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
|
||||
if (sock->parent && sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
|
||||
}
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
if(!handler || !handler->socket) {
|
||||
return -1;
|
||||
}
|
||||
internal_socket_t *sock = handler->socket;
|
||||
sock->data_len = data_len;
|
||||
if (sock->data) {
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
}
|
||||
sock->data = ns_dyn_mem_temporary_alloc(data_len);
|
||||
if (data_len > 0 && !sock->data) {
|
||||
return -1;
|
||||
}
|
||||
if (data_ptr) {
|
||||
memcpy(sock->data, data_ptr, data_len);
|
||||
} else {
|
||||
if (sock->data) {
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (handler->socket->is_secure) {
|
||||
secure_session_t *session = secure_session_find(sock, address, port);
|
||||
if (!session) {
|
||||
session = secure_session_create(sock, address, port);
|
||||
}
|
||||
if (!session) {
|
||||
tr_err("coap_connection_handler_virtual_recv session creation failed - OOM");
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
|
||||
if (!coap_security_handler_is_started(session->sec_handler)) {
|
||||
uint8_t *pw = ns_dyn_mem_alloc(64);
|
||||
uint8_t pw_len;
|
||||
if (sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, address, port, pw, &pw_len)) {
|
||||
//TODO: get_password_cb should support certs and PSK also
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = pw;
|
||||
keys._priv_len = pw_len;
|
||||
coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max);
|
||||
//TODO: error handling
|
||||
ns_dyn_mem_free(pw);
|
||||
return 0;
|
||||
} else {
|
||||
ns_dyn_mem_free(pw);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (session->session_state == SECURE_SESSION_HANDSHAKE_ONGOING) {
|
||||
int ret = coap_security_handler_continue_connecting(session->sec_handler);
|
||||
if(ret == 0){
|
||||
session->session_state = SECURE_SESSION_OK;
|
||||
if( handler->_security_done_cb ){
|
||||
handler->_security_done_cb(sock->socket,
|
||||
address, port,
|
||||
(void *)coap_security_handler_keyblock(session->sec_handler));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
// error handling
|
||||
// TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
|
||||
secure_session_delete(session);
|
||||
}
|
||||
//TODO: error handling
|
||||
} else {
|
||||
unsigned char *data = ns_dyn_mem_temporary_alloc(sock->data_len);
|
||||
int len = 0;
|
||||
len = coap_security_handler_read(session->sec_handler, data, sock->data_len);
|
||||
if (len < 0) {
|
||||
if (len != MBEDTLS_ERR_SSL_WANT_READ && len != MBEDTLS_ERR_SSL_WANT_WRITE &&
|
||||
len != MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
|
||||
secure_session_delete(session);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
return 0;
|
||||
} else {
|
||||
if (sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, data, len);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* unsecure*/
|
||||
if (sock->parent->_recv_cb) {
|
||||
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, sock->data, sock->data_len);
|
||||
}
|
||||
if (sock->data) {
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
coap_conn_handler_t *connection_handler_create(receive_from_socket_cb *recv_from_cb,
|
||||
send_to_socket_cb *send_to_cb,
|
||||
get_pw_cb *pw_cb,
|
||||
security_done_cb *done_cb )
|
||||
{
|
||||
if(recv_from_cb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
coap_conn_handler_t *handler = ns_dyn_mem_alloc(sizeof(coap_conn_handler_t));
|
||||
if(!handler){
|
||||
return NULL;
|
||||
}
|
||||
memset(handler, 0, sizeof(coap_conn_handler_t));
|
||||
handler->socket = NULL;
|
||||
handler->_recv_cb = recv_from_cb;
|
||||
handler->_send_cb = send_to_cb;
|
||||
|
||||
handler->_get_password_cb = pw_cb;
|
||||
handler->_security_done_cb = done_cb;
|
||||
|
||||
return handler;
|
||||
}
|
||||
void connection_handler_destroy(coap_conn_handler_t *handler)
|
||||
{
|
||||
if(handler){
|
||||
int_socket_delete(handler->socket);
|
||||
ns_dyn_mem_free(handler);
|
||||
}
|
||||
}
|
||||
|
||||
void connection_handler_close_secure_connection( coap_conn_handler_t *handler, uint8_t destination_addr_ptr[static 16], uint16_t port )
|
||||
{
|
||||
if (handler) {
|
||||
if (handler->socket && handler->socket->is_secure) {
|
||||
secure_session_t *session = secure_session_find( handler->socket, destination_addr_ptr, port );
|
||||
if (session) {
|
||||
coap_security_send_close_alert( session->sec_handler );
|
||||
session->session_state = SECURE_SESSION_CLOSED;
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool is_real_socket, bool bypassSec)
|
||||
{
|
||||
if (!handler) {
|
||||
return -1;
|
||||
}
|
||||
//virtual socket must have send callback
|
||||
if (!is_real_socket && !handler->_send_cb) {
|
||||
return -1;
|
||||
}
|
||||
if (handler->socket) {
|
||||
int_socket_delete(handler->socket);
|
||||
}
|
||||
|
||||
internal_socket_t *current = !use_ephemeral_port?int_socket_find(listen_port, is_secure, is_real_socket, bypassSec):NULL;
|
||||
if (!current) {
|
||||
handler->socket = int_socket_create(listen_port, use_ephemeral_port, is_secure, is_real_socket, bypassSec);
|
||||
if (!handler->socket) {
|
||||
return -1;
|
||||
}
|
||||
handler->socket->parent = ns_dyn_mem_alloc(sizeof(coap_conn_handler_t));
|
||||
if (!handler->socket->parent) {
|
||||
int_socket_delete(handler->socket);
|
||||
return -1;
|
||||
}
|
||||
*handler->socket->parent = *handler;
|
||||
} else {
|
||||
current->usage_counter++;
|
||||
handler->socket = current;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t src_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
|
||||
{
|
||||
if (!handler || !handler->socket || !dest_addr) {
|
||||
return -1;
|
||||
}
|
||||
if (handler->socket->is_secure) {
|
||||
handler->socket->bypass_link_sec = bypass_link_sec;
|
||||
secure_session_t *session = secure_session_find(handler->socket, dest_addr->address, dest_addr->identifier);
|
||||
if (!session) {
|
||||
session = secure_session_create(handler->socket, dest_addr->address, dest_addr->identifier);
|
||||
if (!session) {
|
||||
return -1;
|
||||
}
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
uint8_t *pw = ns_dyn_mem_alloc(64);
|
||||
if (!pw) {
|
||||
//todo: free secure session?
|
||||
return -1;
|
||||
}
|
||||
uint8_t pw_len;
|
||||
if (handler->_get_password_cb && 0 == handler->_get_password_cb(handler->socket->socket, (uint8_t*)dest_addr->address, dest_addr->identifier, pw, &pw_len)) {
|
||||
//TODO: get_password_cb should support certs and PSK also
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = pw;
|
||||
keys._priv_len = pw_len;
|
||||
coap_security_handler_connect_non_blocking(session->sec_handler, false, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max);
|
||||
ns_dyn_mem_free(pw);
|
||||
return -2;
|
||||
} else {
|
||||
//free secure session?
|
||||
ns_dyn_mem_free(pw);
|
||||
return -1;
|
||||
}
|
||||
} else if (session->session_state == SECURE_SESSION_OK) {
|
||||
if (coap_security_handler_send_message(session->sec_handler, data_ptr, data_len ) > 0 ) {
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}else{
|
||||
if (!handler->socket->real_socket && handler->_send_cb) {
|
||||
return handler->_send_cb((int8_t)handler->socket->socket, dest_addr->address, dest_addr->identifier, data_ptr, data_len);
|
||||
}
|
||||
int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT;
|
||||
int8_t securityLinkLayer = 1;
|
||||
if (bypass_link_sec) {
|
||||
securityLinkLayer = 0;
|
||||
}
|
||||
|
||||
socket_setsockopt(handler->socket->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(handler->socket->socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
|
||||
return send_to_real_socket(handler->socket->socket, dest_addr, src_address, data_ptr, data_len);
|
||||
}
|
||||
}
|
||||
|
||||
bool coap_connection_handler_socket_belongs_to(coap_conn_handler_t *handler, int8_t socket_id)
|
||||
{
|
||||
if( !handler || !handler->socket){
|
||||
return false;
|
||||
}
|
||||
|
||||
if( handler->socket->socket == socket_id){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_t min, uint32_t max)
|
||||
{
|
||||
if(!handler || !handler->socket){
|
||||
return -1;
|
||||
}
|
||||
handler->socket->timeout_max = max;
|
||||
handler->socket->timeout_min = min;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No need to call every second - call rather like every minute (SECURE_SESSION_CLEAN_INTERVAL sets this) */
|
||||
void coap_connection_handler_exec(uint32_t time)
|
||||
{
|
||||
if(ns_list_count(&secure_session_list)){
|
||||
// Seek & destroy old sessions where close notify have been sent
|
||||
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
|
||||
if(cur_ptr->session_state == SECURE_SESSION_CLOSED ||
|
||||
cur_ptr->session_state == SECURE_SESSION_HANDSHAKE_ONGOING){
|
||||
if((cur_ptr->last_contact_time + CLOSED_SECURE_SESSION_TIMEOUT) <= time){
|
||||
secure_session_delete(cur_ptr);
|
||||
}
|
||||
}
|
||||
if(cur_ptr->session_state == SECURE_SESSION_OK){
|
||||
if((cur_ptr->last_contact_time + OPEN_SECURE_SESSION_TIMEOUT) <= time){
|
||||
secure_session_delete(cur_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_service_api_internal.h"
|
||||
#include "coap_message_handler.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "socket_api.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
#include "randLIB.h"
|
||||
|
||||
#define TRACE_GROUP "CoSA"
|
||||
|
||||
static void *own_alloc(uint16_t size)
|
||||
{
|
||||
if (size) {
|
||||
return ns_dyn_mem_temporary_alloc(size);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void own_free(void *ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
ns_dyn_mem_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static NS_LIST_DEFINE(request_list, coap_transaction_t, link);
|
||||
|
||||
static coap_transaction_t *transaction_find_client_by_token(uint8_t token[4])
|
||||
{
|
||||
coap_transaction_t *this = NULL;
|
||||
ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) {
|
||||
if (memcmp(cur_ptr->token,token,4) == 0 && cur_ptr->client_request) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static coap_transaction_t *transaction_find_server(uint16_t msg_id)
|
||||
{
|
||||
coap_transaction_t *this = NULL;
|
||||
ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) {
|
||||
if (cur_ptr->msg_id == msg_id && !cur_ptr->client_request) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static coap_transaction_t *transaction_find_by_address(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
coap_transaction_t *this = NULL;
|
||||
ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) {
|
||||
if (cur_ptr->remote_port == port && memcmp(cur_ptr->remote_address, address_ptr, 16) == 0) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static coap_transaction_t *transaction_create(void)
|
||||
{
|
||||
coap_transaction_t *this = ns_dyn_mem_alloc(sizeof(coap_transaction_t));
|
||||
if (this) {
|
||||
memset(this, 0, sizeof(coap_transaction_t));
|
||||
this->client_request = true;// default to client initiated method
|
||||
this->create_time = coap_service_get_internal_timer_ticks();
|
||||
ns_list_add_to_start(&request_list, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
static void transaction_free(coap_transaction_t *this)
|
||||
{
|
||||
if (!this) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->data_ptr) {
|
||||
ns_dyn_mem_free(this->data_ptr);
|
||||
}
|
||||
ns_dyn_mem_free(this);
|
||||
}
|
||||
|
||||
void transaction_delete(coap_transaction_t *this)
|
||||
{
|
||||
if (this) {
|
||||
ns_list_remove(&request_list, this);
|
||||
transaction_free(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void transactions_delete_all(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
coap_transaction_t *transaction = transaction_find_by_address(address_ptr, port);
|
||||
|
||||
while (transaction) {
|
||||
ns_list_remove(&request_list, transaction);
|
||||
if (transaction->resp_cb) {
|
||||
transaction->resp_cb(transaction->service_id, address_ptr, port, NULL);
|
||||
}
|
||||
sn_coap_protocol_delete_retransmission(coap_service_handle->coap, transaction->msg_id);
|
||||
transaction_free(transaction);
|
||||
transaction = transaction_find_by_address(address_ptr, port);
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t coap_rx_function(sn_coap_hdr_s *resp_ptr, sn_nsdl_addr_s *address_ptr, void *param)
|
||||
{
|
||||
coap_transaction_t *this = NULL;
|
||||
(void)address_ptr;
|
||||
(void)param;
|
||||
tr_warn("transaction was not handled %d", resp_ptr->msg_id);
|
||||
if (!resp_ptr) {
|
||||
return -1;
|
||||
}
|
||||
if( resp_ptr->token_ptr ){
|
||||
this = transaction_find_client_by_token(resp_ptr->token_ptr);
|
||||
}
|
||||
if (!this) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ns_list_remove(&request_list, this);
|
||||
if (this->resp_cb) {
|
||||
this->resp_cb(this->service_id, address_ptr->addr_ptr, address_ptr->port, NULL);
|
||||
}
|
||||
transaction_free(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
|
||||
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *)){
|
||||
|
||||
if ((used_malloc_func_ptr == NULL) || (used_free_func_ptr == NULL) || (used_tx_callback_ptr == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
coap_msg_handler_t *handle;
|
||||
handle = used_malloc_func_ptr(sizeof(coap_msg_handler_t));
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(handle, 0, sizeof(coap_msg_handler_t));
|
||||
|
||||
handle->sn_coap_tx_callback = used_tx_callback_ptr;
|
||||
|
||||
handle->sn_coap_service_free = used_free_func_ptr;
|
||||
handle->sn_coap_service_malloc = used_malloc_func_ptr;
|
||||
|
||||
handle->coap = sn_coap_protocol_init(used_malloc_func_ptr, used_free_func_ptr, used_tx_callback_ptr, &coap_rx_function);
|
||||
if( !handle->coap ){
|
||||
used_free_func_ptr(handle);
|
||||
return NULL;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
int8_t coap_message_handler_destroy(coap_msg_handler_t *handle){
|
||||
if( !handle ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( handle->coap ){
|
||||
sn_coap_protocol_destroy(handle->coap);
|
||||
}
|
||||
|
||||
//Destroy transactions
|
||||
ns_list_foreach_safe(coap_transaction_t, cur_ptr, &request_list) {
|
||||
ns_list_remove(&request_list, cur_ptr);
|
||||
ns_dyn_mem_free(cur_ptr);
|
||||
cur_ptr = NULL;
|
||||
}
|
||||
|
||||
handle->sn_coap_service_free(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
coap_transaction_t *coap_message_handler_transaction_valid(coap_transaction_t *tr_ptr)
|
||||
{
|
||||
ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) {
|
||||
if (cur_ptr == tr_ptr) {
|
||||
return tr_ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
if( !address_ptr )
|
||||
return NULL;
|
||||
return transaction_find_by_address( address_ptr, port );
|
||||
}
|
||||
|
||||
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
|
||||
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
|
||||
{
|
||||
if (!cb || !handle) {
|
||||
return -1;
|
||||
}
|
||||
sn_nsdl_addr_s src_addr;
|
||||
sn_coap_hdr_s *coap_message;
|
||||
src_addr.addr_ptr = (uint8_t *)source_addr_ptr;
|
||||
src_addr.addr_len = 16;
|
||||
src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
|
||||
src_addr.port = port;
|
||||
|
||||
coap_message = sn_coap_protocol_parse(handle->coap, &src_addr, data_len, data_ptr, NULL);
|
||||
if (coap_message == NULL) {
|
||||
tr_err("CoAP Parsing failed");
|
||||
return -1;
|
||||
}
|
||||
tr_debug("CoAP status:%d, type:%d, code:%d, id:%d", coap_message->coap_status, coap_message->msg_type, coap_message->msg_code, coap_message->msg_id);
|
||||
/* Check, if coap itself sends response, or block receiving is ongoing... */
|
||||
if (coap_message->coap_status != COAP_STATUS_OK && coap_message->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) {
|
||||
tr_debug("CoAP library responds");
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
return -1;
|
||||
}
|
||||
/* Request received */
|
||||
if (coap_message->msg_code > 0 && coap_message->msg_code < 32) {
|
||||
coap_transaction_t *transaction_ptr = transaction_create();
|
||||
if (transaction_ptr) {
|
||||
transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id);
|
||||
transaction_ptr->msg_id = coap_message->msg_id;
|
||||
transaction_ptr->client_request = false;// this is server transaction
|
||||
memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16);
|
||||
memcpy(transaction_ptr->remote_address, source_addr_ptr, 16);
|
||||
transaction_ptr->remote_port = port;
|
||||
|
||||
int ret = cb(socket_id, coap_message, transaction_ptr);
|
||||
if (ret != 0) {
|
||||
tr_debug("Service %d, no response expected", transaction_ptr->service_id);
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
transaction_delete(transaction_ptr);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
//TODO: handle error case
|
||||
}
|
||||
/* Response received */
|
||||
} else {
|
||||
coap_transaction_t *this = NULL;
|
||||
if (coap_message->token_ptr) {
|
||||
this = transaction_find_client_by_token(coap_message->token_ptr);
|
||||
}
|
||||
if (!this) {
|
||||
tr_error("client transaction not found");
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
return -1;
|
||||
}
|
||||
tr_debug("Service %d, response received", this->service_id);
|
||||
ns_list_remove(&request_list, this);
|
||||
if (this->resp_cb) {
|
||||
this->resp_cb(this->service_id, (uint8_t *)source_addr_ptr, port, coap_message);
|
||||
}
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
transaction_free(this);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16],
|
||||
uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri,
|
||||
sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_message_handler_response_recv *request_response_cb)
|
||||
{
|
||||
coap_transaction_t *transaction_ptr;
|
||||
sn_coap_hdr_s request;
|
||||
sn_nsdl_addr_s dst_addr;
|
||||
uint8_t token[4];
|
||||
uint16_t data_len;
|
||||
uint8_t *data_ptr;
|
||||
|
||||
tr_debug("Service %d, send CoAP request payload_len %d", service_id, payload_len);
|
||||
transaction_ptr = transaction_create();
|
||||
|
||||
if (!uri || !transaction_ptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
transaction_ptr->service_id = service_id;
|
||||
transaction_ptr->client_request = true;
|
||||
transaction_ptr->resp_cb = request_response_cb;
|
||||
transaction_ptr->options = options;
|
||||
memcpy(transaction_ptr->remote_address, destination_addr, 16);
|
||||
transaction_ptr->remote_port = destination_port;
|
||||
memset(&request, 0, sizeof(request));
|
||||
dst_addr.addr_ptr = (uint8_t *) destination_addr; // Cast away const and trust that nsdl doesn't modify...
|
||||
dst_addr.addr_len = 16;
|
||||
dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
|
||||
dst_addr.port = destination_port;
|
||||
|
||||
request.msg_type = msg_type;
|
||||
request.msg_code = msg_code;
|
||||
request.uri_path_ptr = (uint8_t *)uri;
|
||||
request.uri_path_len = strlen(uri);
|
||||
request.content_format = cont_type;
|
||||
|
||||
do{
|
||||
randLIB_get_n_bytes_random(token,4);
|
||||
}while(transaction_find_client_by_token(token));
|
||||
memcpy(transaction_ptr->token,token,4);
|
||||
request.token_ptr = transaction_ptr->token;
|
||||
request.token_len = 4;
|
||||
|
||||
request.payload_len = payload_len;
|
||||
request.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify...
|
||||
data_len = sn_coap_builder_calc_needed_packet_data_size(&request);
|
||||
data_ptr = own_alloc(data_len);
|
||||
if(data_len > 0 && !data_ptr){
|
||||
transaction_delete(transaction_ptr);
|
||||
return 0;
|
||||
}
|
||||
sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, &request, transaction_ptr);
|
||||
transaction_ptr->msg_id = request.msg_id;
|
||||
handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr);
|
||||
|
||||
// Free allocated data
|
||||
own_free(data_ptr);
|
||||
if(request_response_cb == NULL){
|
||||
//No response expected
|
||||
return 0;
|
||||
}
|
||||
return transaction_ptr->msg_id;
|
||||
}
|
||||
|
||||
int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len)
|
||||
{
|
||||
coap_transaction_t *transaction_ptr;
|
||||
sn_coap_hdr_s *response;
|
||||
sn_nsdl_addr_s dst_addr;
|
||||
uint16_t data_len;
|
||||
uint8_t *data_ptr;
|
||||
(void) options;
|
||||
(void)service_id;
|
||||
|
||||
tr_debug("Service %d, send CoAP response", service_id);
|
||||
if (!request_ptr || !handle) {
|
||||
tr_error("invalid params");
|
||||
return -1;
|
||||
}
|
||||
|
||||
transaction_ptr = transaction_find_server(request_ptr->msg_id);
|
||||
|
||||
if (!transaction_ptr) {
|
||||
tr_error("response transaction not found");
|
||||
return -2;
|
||||
}
|
||||
dst_addr.addr_ptr = transaction_ptr->remote_address;
|
||||
dst_addr.addr_len = 16;
|
||||
dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
|
||||
dst_addr.port = transaction_ptr->remote_port;
|
||||
|
||||
response = sn_coap_build_response(handle->coap, request_ptr, message_code);
|
||||
if( !response ){
|
||||
return -1;
|
||||
}
|
||||
response->payload_len = payload_len;
|
||||
response->payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify...
|
||||
response->content_format = content_type;
|
||||
|
||||
data_len = sn_coap_builder_calc_needed_packet_data_size(response);
|
||||
data_ptr = own_alloc(data_len);
|
||||
if (data_len > 0 && !data_ptr) {
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
|
||||
return -1;
|
||||
}
|
||||
sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, response, transaction_ptr);
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
|
||||
handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr);
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, request_ptr);
|
||||
own_free(data_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time){
|
||||
|
||||
if( !handle ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Remove outdated transactions from queue
|
||||
ns_list_foreach_safe(coap_transaction_t, transaction, &request_list) {
|
||||
if ((transaction->create_time + TRANSACTION_LIFETIME) < current_time) {
|
||||
transaction_delete(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
return sn_coap_protocol_exec(handle->coap, current_time);
|
||||
}
|
|
@ -0,0 +1,628 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "coap_security_handler.h"
|
||||
|
||||
#ifdef COAP_SECURITY_AVAILABLE
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_connection_handler.h"
|
||||
#include "randLIB.h"
|
||||
|
||||
struct coap_security_s {
|
||||
mbedtls_ssl_config _conf;
|
||||
mbedtls_ssl_context _ssl;
|
||||
|
||||
mbedtls_ctr_drbg_context _ctr_drbg;
|
||||
mbedtls_entropy_context _entropy;
|
||||
bool _is_started;
|
||||
simple_cookie_t _cookie;
|
||||
key_block_t _keyblk;
|
||||
|
||||
SecureConnectionMode _conn_mode;
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt _cacert;
|
||||
mbedtls_x509_crt _owncert;
|
||||
#endif
|
||||
mbedtls_pk_context _pkey;
|
||||
|
||||
uint8_t _pw[64];
|
||||
uint8_t _pw_len;
|
||||
|
||||
bool _is_blocking;
|
||||
int8_t _socket_id;
|
||||
int8_t _timer_id;
|
||||
void *_handle;
|
||||
send_cb *_send_cb;
|
||||
receive_cb *_receive_cb;
|
||||
start_timer_cb *_start_timer_cb;
|
||||
timer_status_cb *_timer_status_cb;
|
||||
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
const int ECJPAKE_SUITES[] = {
|
||||
MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
static const int PSK_SUITES[] = {
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static void set_timer( void *sec_obj, uint32_t int_ms, uint32_t fin_ms );
|
||||
static int get_timer( void *sec_obj );
|
||||
static int coap_security_handler_configure_keys( coap_security_t *sec, coap_security_keys_t keys );
|
||||
|
||||
int entropy_poll( void *data, unsigned char *output, size_t len, size_t *olen );
|
||||
//Point these back to M2MConnectionHandler!!!
|
||||
int f_send( void *ctx, const unsigned char *buf, size_t len );
|
||||
int f_recv(void *ctx, unsigned char *buf, size_t len);
|
||||
|
||||
static int coap_security_handler_init(coap_security_t *sec){
|
||||
const char *pers = "dtls_client";
|
||||
mbedtls_ssl_init( &sec->_ssl );
|
||||
mbedtls_ssl_config_init( &sec->_conf );
|
||||
mbedtls_ctr_drbg_init( &sec->_ctr_drbg );
|
||||
mbedtls_entropy_init( &sec->_entropy );
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt_init( &sec->_cacert );
|
||||
mbedtls_x509_crt_init( &sec->_owncert );
|
||||
#endif
|
||||
mbedtls_pk_init( &sec->_pkey );
|
||||
|
||||
memset(&sec->_cookie, 0, sizeof(simple_cookie_t));
|
||||
memset(&sec->_keyblk, 0, sizeof(key_block_t));
|
||||
|
||||
sec->_is_started = false;
|
||||
|
||||
//TODO: Must have at least 1 strong entropy source, otherwise DTLS will fail.
|
||||
//This is NOT strong even we say it is!
|
||||
if( mbedtls_entropy_add_source( &sec->_entropy, entropy_poll, NULL,
|
||||
128, 1 ) < 0 ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( ( mbedtls_ctr_drbg_seed( &sec->_ctr_drbg, mbedtls_entropy_func, &sec->_entropy,
|
||||
(const unsigned char *) pers,
|
||||
strlen( pers ) ) ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool coap_security_handler_is_started(const coap_security_t *sec)
|
||||
{
|
||||
return sec->_is_started;
|
||||
}
|
||||
|
||||
const void *coap_security_handler_keyblock(const coap_security_t *sec)
|
||||
{
|
||||
return sec->_keyblk.value;
|
||||
}
|
||||
|
||||
static void coap_security_handler_reset(coap_security_t *sec){
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_x509_crt_free(&sec->_cacert);
|
||||
mbedtls_x509_crt_free(&sec->_owncert);
|
||||
#endif
|
||||
|
||||
mbedtls_pk_free(&sec->_pkey);
|
||||
|
||||
mbedtls_entropy_free( &sec->_entropy );
|
||||
mbedtls_ctr_drbg_free( &sec->_ctr_drbg );
|
||||
mbedtls_ssl_config_free(&sec->_conf);
|
||||
mbedtls_ssl_free(&sec->_ssl);
|
||||
}
|
||||
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle, SecureConnectionMode mode,
|
||||
send_cb *socket_cb,
|
||||
receive_cb *receive_data_cb,
|
||||
start_timer_cb *timer_start_cb,
|
||||
timer_status_cb *timer_stat_cb)
|
||||
{
|
||||
if (socket_cb == NULL || receive_data_cb == NULL || timer_start_cb == NULL || timer_stat_cb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
coap_security_t *this = ns_dyn_mem_alloc(sizeof(coap_security_t));
|
||||
if( !this ){
|
||||
return NULL;
|
||||
}
|
||||
memset(this, 0, sizeof(coap_security_t));
|
||||
if (-1 == coap_security_handler_init(this)) {
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->_handle = handle;
|
||||
this->_conn_mode = mode;
|
||||
memset(this->_pw, 0, 64);
|
||||
this->_pw_len = 0;
|
||||
this->_socket_id = socket_id;
|
||||
this->_timer_id = timer_id;
|
||||
this->_send_cb = socket_cb;
|
||||
this->_receive_cb = receive_data_cb;
|
||||
this->_start_timer_cb = timer_start_cb;
|
||||
this->_timer_status_cb = timer_stat_cb;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void coap_security_destroy(coap_security_t *sec){
|
||||
if( sec ){
|
||||
coap_security_handler_reset(sec);
|
||||
ns_dyn_mem_free(sec);
|
||||
sec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**** Random number functions ****/
|
||||
|
||||
/**
|
||||
* Get a random array of bytes.
|
||||
* Called back by mbedtls when it wants to fill a buffer with random data
|
||||
* Must return 0 on success.
|
||||
*/
|
||||
static int get_random(void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
static int initialised = 0;
|
||||
uint32_t i;
|
||||
|
||||
(void)ctx; /* No context */
|
||||
|
||||
if (!initialised) {
|
||||
randLIB_seed_random();
|
||||
initialised = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
buf[i] = (uint8_t)randLIB_get_8bit();
|
||||
}
|
||||
return 0; /* Success */
|
||||
}
|
||||
|
||||
/**** Cookie functions ****/
|
||||
static int simple_cookie_write(void *ctx,
|
||||
unsigned char **p, unsigned char *end,
|
||||
const unsigned char *info, size_t ilen)
|
||||
{
|
||||
//TODO: As per RFC 6347 cookie must be stateless. This is not the case in here!
|
||||
//This should be fixed if we see that dos attack would be an issue.
|
||||
//this is proposed solution in RFC: Cookie = HMAC(Secret, Client-IP, Client-Parameters)
|
||||
//Secret is generated here and oftenly changed to prevent statistical attack
|
||||
simple_cookie_t *p_cookie = (simple_cookie_t *)ctx;
|
||||
|
||||
/* Not using additional info */
|
||||
(void)info;
|
||||
(void)ilen;
|
||||
|
||||
if ((size_t)(end - *p) < COOKIE_SIMPLE_LEN) {
|
||||
return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Use a simple random number of length COOKIE_SIMPLE_LEN bytes */
|
||||
get_random(NULL, p_cookie->value, COOKIE_SIMPLE_LEN);
|
||||
memcpy(*p, p_cookie->value, COOKIE_SIMPLE_LEN);
|
||||
p_cookie->len = COOKIE_SIMPLE_LEN;
|
||||
*p += COOKIE_SIMPLE_LEN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int simple_cookie_check(void *ctx,
|
||||
const unsigned char *cookie, size_t clen,
|
||||
const unsigned char *info, size_t ilen)
|
||||
{
|
||||
simple_cookie_t *p_cookie = (simple_cookie_t *)ctx;
|
||||
|
||||
/* Not using additional info */
|
||||
(void)info;
|
||||
(void)ilen;
|
||||
|
||||
if ((p_cookie->len == 0) ||
|
||||
(clen != p_cookie->len) ||
|
||||
(memcmp(cookie, p_cookie->value, p_cookie->len) != 0)) {
|
||||
return -1; /* This is what it is in mbedtls... */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**** Key export function ****/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
static int export_key_block(void *ctx,
|
||||
const unsigned char *mk, const unsigned char *kb,
|
||||
size_t maclen, size_t keylen, size_t ivlen)
|
||||
{
|
||||
key_block_t *p_key_block = (key_block_t *)ctx;
|
||||
|
||||
/* Not using master key */
|
||||
(void)mk;
|
||||
|
||||
/* Sanity check MAC and key lengths */
|
||||
if ((maclen != 0) || (((2 * keylen) + (2 * ivlen)) != KEY_BLOCK_LEN)) {
|
||||
return -1; /* Something seriously wrong! */
|
||||
}
|
||||
|
||||
/* Copy the key block we are using */
|
||||
/* No need to skip over MAC keys, MAC len must be 0 if we are here */
|
||||
memcpy(p_key_block->value, kb /* + (2 * maclen)*/, (2 * keylen) + (2 * ivlen));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int coap_security_handler_configure_keys( coap_security_t *sec, coap_security_keys_t keys )
|
||||
{
|
||||
int ret = -1;
|
||||
switch( sec->_conn_mode ){
|
||||
case Certificate:{
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
if( mbedtls_x509_crt_parse( &sec->_cacert, keys._server_cert,
|
||||
keys._server_cert_len ) < 0 ){
|
||||
break;
|
||||
}
|
||||
if( mbedtls_x509_crt_parse( &sec->_owncert, keys._pub_cert_or_identifier,
|
||||
keys._pub_len ) < 0 ){
|
||||
break;
|
||||
}
|
||||
if( mbedtls_pk_parse_key(&sec->_pkey, keys._priv, keys._priv_len, NULL, 0) < 0){
|
||||
break;
|
||||
}
|
||||
//TODO: If needed in server mode, this won't work
|
||||
if( 0 != mbedtls_ssl_conf_own_cert(&sec->_conf, &sec->_owncert, &sec->_pkey) ){
|
||||
break;
|
||||
}
|
||||
//TODO: use MBEDTLS_SSL_VERIFY_REQUIRED instead of optional
|
||||
mbedtls_ssl_conf_authmode( &sec->_conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
|
||||
mbedtls_ssl_conf_ca_chain( &sec->_conf, &sec->_cacert, NULL );
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case PSK: {
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
||||
if( 0 != mbedtls_ssl_conf_psk(&sec->_conf, keys._priv, keys._priv_len, keys._pub_cert_or_identifier, keys._pub_len) ){
|
||||
break;
|
||||
}
|
||||
mbedtls_ssl_conf_ciphersuites(&sec->_conf, PSK_SUITES);
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ECJPAKE: {
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
if( mbedtls_ssl_set_hs_ecjpake_password(&sec->_ssl, keys._priv, keys._priv_len) != 0 ){
|
||||
return -1;
|
||||
}
|
||||
mbedtls_ssl_conf_ciphersuites(&sec->_conf, ECJPAKE_SUITES);
|
||||
|
||||
//NOTE: If thread starts supporting PSK in other modes, then this will be needed!
|
||||
mbedtls_ssl_conf_export_keys_cb(&sec->_conf,
|
||||
export_key_block,
|
||||
&sec->_keyblk);
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int coap_security_handler_connect(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys){
|
||||
int ret = -1;
|
||||
|
||||
if( !sec ){
|
||||
return ret;
|
||||
}
|
||||
sec->_is_blocking = true;
|
||||
|
||||
int endpoint = MBEDTLS_SSL_IS_CLIENT;
|
||||
if( is_server ){
|
||||
endpoint = MBEDTLS_SSL_IS_SERVER;
|
||||
}
|
||||
|
||||
int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
|
||||
if( sock_mode == TLS ){
|
||||
mode = MBEDTLS_SSL_TRANSPORT_STREAM;
|
||||
}
|
||||
|
||||
if( ( mbedtls_ssl_config_defaults( &sec->_conf,
|
||||
endpoint,
|
||||
mode, 0 ) ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio( &sec->_ssl, sec,
|
||||
f_send, f_recv, NULL );
|
||||
|
||||
mbedtls_ssl_set_timer_cb( &sec->_ssl, sec, set_timer,
|
||||
get_timer );
|
||||
|
||||
if( coap_security_handler_configure_keys( sec, keys ) != 0 ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_SSL_SRV_C
|
||||
mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write,
|
||||
simple_cookie_check,
|
||||
&sec->_cookie);
|
||||
#endif
|
||||
|
||||
sec->_is_started = true;
|
||||
|
||||
do {
|
||||
ret = mbedtls_ssl_handshake_step( &sec->_ssl );
|
||||
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ){ //cookie check failed
|
||||
if( is_server ){
|
||||
mbedtls_ssl_session_reset(&sec->_ssl);
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
if( mbedtls_ssl_set_hs_ecjpake_password(&sec->_ssl, keys._priv, keys._priv_len) != 0 ){
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
ret = MBEDTLS_ERR_SSL_WANT_READ; //needed to keep doing
|
||||
}else{
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
ret == MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
|
||||
if( ret != 0){
|
||||
ret = -1;
|
||||
}else{
|
||||
if( mbedtls_ssl_get_verify_result( &sec->_ssl ) != 0 )
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int coap_security_handler_connect_non_blocking(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys, uint32_t timeout_min, uint32_t timeout_max)
|
||||
{
|
||||
|
||||
if( !sec ){
|
||||
return -1;
|
||||
}
|
||||
sec->_is_blocking = false;
|
||||
|
||||
int endpoint = MBEDTLS_SSL_IS_CLIENT;
|
||||
if( is_server ){
|
||||
endpoint = MBEDTLS_SSL_IS_SERVER;
|
||||
}
|
||||
|
||||
int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
|
||||
if( sock_mode == TLS ){
|
||||
mode = MBEDTLS_SSL_TRANSPORT_STREAM;
|
||||
}
|
||||
|
||||
if( ( mbedtls_ssl_config_defaults( &sec->_conf,
|
||||
endpoint,
|
||||
mode, 0 ) ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!timeout_max && !timeout_min){
|
||||
mbedtls_ssl_conf_handshake_timeout( &sec->_conf, DTLS_HANDSHAKE_TIMEOUT_MIN, DTLS_HANDSHAKE_TIMEOUT_MAX );
|
||||
}
|
||||
else{
|
||||
mbedtls_ssl_conf_handshake_timeout( &sec->_conf, timeout_min, timeout_max );
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng( &sec->_conf, mbedtls_ctr_drbg_random, &sec->_ctr_drbg );
|
||||
|
||||
if( ( mbedtls_ssl_setup( &sec->_ssl, &sec->_conf ) ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio( &sec->_ssl, sec,
|
||||
f_send, f_recv, NULL );
|
||||
|
||||
mbedtls_ssl_set_timer_cb( &sec->_ssl, sec, set_timer,
|
||||
get_timer );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
//TODO: Figure out better way!!!
|
||||
//Password should never be stored in multiple places!!!
|
||||
if( is_server && keys._priv_len > 0){
|
||||
memcpy(sec->_pw, keys._priv, keys._priv_len);
|
||||
sec->_pw_len = keys._priv_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( coap_security_handler_configure_keys( sec, keys ) != 0 ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_SSL_SRV_C
|
||||
mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write,
|
||||
simple_cookie_check,
|
||||
&sec->_cookie);
|
||||
#endif
|
||||
|
||||
mbedtls_ssl_conf_min_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
|
||||
mbedtls_ssl_conf_max_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
|
||||
|
||||
sec->_is_started = true;
|
||||
|
||||
int ret = mbedtls_ssl_handshake_step( &sec->_ssl );
|
||||
if( ret == 0 ){
|
||||
ret = mbedtls_ssl_handshake_step( &sec->_ssl );
|
||||
if( is_server && 0 == ret){
|
||||
ret = coap_security_handler_continue_connecting( sec );
|
||||
}
|
||||
}
|
||||
|
||||
if( ret >= 0){
|
||||
ret = 1;
|
||||
}else{
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int coap_security_handler_continue_connecting(coap_security_t *sec){
|
||||
int ret = -1;
|
||||
|
||||
while( ret != MBEDTLS_ERR_SSL_WANT_READ ){
|
||||
ret = mbedtls_ssl_handshake_step( &sec->_ssl );
|
||||
|
||||
if( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED == ret){
|
||||
mbedtls_ssl_session_reset(&sec->_ssl);
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
if( mbedtls_ssl_set_hs_ecjpake_password(&sec->_ssl, sec->_pw, sec->_pw_len) != 0 ){
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
else if(ret && (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)){
|
||||
return ret;
|
||||
}
|
||||
|
||||
if( sec->_ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int coap_security_handler_send_message(coap_security_t *sec, unsigned char *message, size_t len){
|
||||
int ret=-1;
|
||||
|
||||
if( sec ){
|
||||
do ret = mbedtls_ssl_write( &sec->_ssl, (unsigned char *) message, len );
|
||||
while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
ret == MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||
}
|
||||
|
||||
return ret; //bytes written
|
||||
}
|
||||
|
||||
int coap_security_send_close_alert(coap_security_t *sec)
|
||||
{
|
||||
if( !sec ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!mbedtls_ssl_close_notify(&sec->_ssl)){
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int coap_security_handler_read(coap_security_t *sec, unsigned char* buffer, size_t len){
|
||||
int ret=-1;
|
||||
int max_loops = 100;
|
||||
|
||||
if( sec && buffer ){
|
||||
memset( buffer, 0, len );
|
||||
do {
|
||||
ret = mbedtls_ssl_read( &sec->_ssl, buffer, len );
|
||||
} while( (ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
ret == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
&& --max_loops);
|
||||
}
|
||||
return ret; //bytes read
|
||||
}
|
||||
|
||||
/**** Timer functions ****/
|
||||
|
||||
/**
|
||||
* Set timer function.
|
||||
* Called back by mbedtls when it wants to set a timer.
|
||||
* Accepts an intermediate and a final delay in milliseconds
|
||||
* If the final delay is 0, cancels the running timer.
|
||||
* TODO - might be better to use an event timer in conjunction with
|
||||
* CoAP tasklet
|
||||
*/
|
||||
static void set_timer(void *sec_obj, uint32_t int_ms, uint32_t fin_ms)
|
||||
{
|
||||
coap_security_t *sec = (coap_security_t *)sec_obj;
|
||||
if( sec->_start_timer_cb ){
|
||||
sec->_start_timer_cb( sec->_timer_id, int_ms, fin_ms);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timer function.
|
||||
* Called back by mbedtls when it wants to get a timer state.
|
||||
* Returns the state of the current timer
|
||||
* TODO - might be better to use an event timer in conjunction with
|
||||
* CoAP tasklet
|
||||
*/
|
||||
static int get_timer(void *sec_obj)
|
||||
{
|
||||
coap_security_t *sec = (coap_security_t *)sec_obj;
|
||||
if( sec->_timer_status_cb ){
|
||||
return sec->_timer_status_cb(sec->_timer_id);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f_send( void *ctx, const unsigned char *buf, size_t len){
|
||||
coap_security_t *sec = (coap_security_t *)ctx;
|
||||
return sec->_send_cb(sec->_socket_id, sec->_handle, buf, len);
|
||||
}
|
||||
|
||||
int f_recv(void *ctx, unsigned char *buf, size_t len){
|
||||
coap_security_t *sec = (coap_security_t *)ctx;
|
||||
return sec->_receive_cb(sec->_socket_id, buf, len);
|
||||
}
|
||||
|
||||
int entropy_poll( void *ctx, unsigned char *output, size_t len,
|
||||
size_t *olen )
|
||||
{
|
||||
(void)ctx;
|
||||
//TODO: change to more secure random
|
||||
randLIB_seed_random();
|
||||
char *c = (char*)ns_dyn_mem_temporary_alloc(len);
|
||||
if( !c ){
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
memset(c, 0, len);
|
||||
for(uint16_t i=0; i < len; i++){
|
||||
*(c + i) = (char)randLIB_get_8bit();
|
||||
}
|
||||
memmove(output, c, len);
|
||||
*olen = len;
|
||||
|
||||
ns_dyn_mem_free(c);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif // COAP_SECURITY_AVAILABLE
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "coap_service_api.h"
|
||||
#include "coap_message_handler.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_scheduler.h"
|
||||
#include "eventOS_event_timer.h"
|
||||
#include "common_functions.h"
|
||||
#include "coap_connection_handler.h"
|
||||
#include "net_interface.h"
|
||||
#include "coap_service_api_internal.h"
|
||||
#include "coap_message_handler.h"
|
||||
|
||||
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr);
|
||||
|
||||
typedef struct uri_registration {
|
||||
char *uri_ptr;
|
||||
uint16_t uri_len;
|
||||
uint8_t allowed_method;
|
||||
coap_service_request_recv_cb *request_recv_cb;
|
||||
ns_list_link_t link;
|
||||
} uri_registration_t;
|
||||
|
||||
typedef NS_LIST_HEAD(uri_registration_t, link) uri_registration_list_t;
|
||||
|
||||
typedef struct coap_service {
|
||||
coap_service_security_done_cb *coap_security_done_cb;
|
||||
coap_service_security_start_cb *security_start_cb;
|
||||
coap_service_virtual_socket_send_cb *virtual_socket_send_cb;
|
||||
uri_registration_list_t uri_list;
|
||||
coap_conn_handler_t *conn_handler;
|
||||
int8_t interface_id;
|
||||
int8_t service_id;
|
||||
int8_t listen_socket;
|
||||
uint8_t service_options;
|
||||
ns_list_link_t link;
|
||||
} coap_service_t;
|
||||
|
||||
#define TRACE_GROUP "ThSA"
|
||||
|
||||
static NS_LIST_DEFINE(instance_list, coap_service_t, link);
|
||||
static int8_t tasklet_id = -1;
|
||||
coap_msg_handler_t *coap_service_handle = NULL;
|
||||
static uint32_t coap_ticks = 1;
|
||||
|
||||
#define COAP_TICK_TIMER 0xf1
|
||||
|
||||
static uri_registration_t *uri_registration_find(coap_service_t *this, const void *uri_ptr, uint16_t uri_len)
|
||||
{
|
||||
ns_list_foreach(uri_registration_t, cur_ptr, &this->uri_list) {
|
||||
if (cur_ptr->uri_len == uri_len && memcmp(cur_ptr->uri_ptr, uri_ptr, uri_len) == 0) {
|
||||
return cur_ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static coap_service_t *service_find(int8_t service_id)
|
||||
{
|
||||
coap_service_t *this = NULL;
|
||||
ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
|
||||
if (cur_ptr->service_id == service_id) {
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static coap_service_t *service_find_by_socket(int8_t socket_id)
|
||||
{
|
||||
coap_service_t *this = NULL;
|
||||
ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
|
||||
if( coap_connection_handler_socket_belongs_to(cur_ptr->conn_handler, socket_id) ){
|
||||
this = cur_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static coap_service_t *service_find_by_uri(uint8_t socket_id, uint8_t *uri_ptr, uint16_t uri_len)
|
||||
{
|
||||
ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
|
||||
if (coap_connection_handler_socket_belongs_to(cur_ptr->conn_handler, socket_id) && uri_registration_find(cur_ptr, uri_ptr, uri_len)) {
|
||||
return cur_ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Coap handling functions
|
||||
*/
|
||||
static void *own_alloc(uint16_t size)
|
||||
{
|
||||
if (size) {
|
||||
return ns_dyn_mem_temporary_alloc(size);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void own_free(void *ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
ns_dyn_mem_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr, void *param)
|
||||
{
|
||||
coap_service_t *this;
|
||||
coap_transaction_t *transaction_ptr = coap_message_handler_transaction_valid(param);
|
||||
ns_address_t dest_addr;
|
||||
|
||||
if (!transaction_ptr || !data_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tr_debug("Service %d, CoAP TX Function - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
|
||||
|
||||
this = service_find(transaction_ptr->service_id);
|
||||
if (!this) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&(dest_addr.address), address_ptr->addr_ptr, 16);
|
||||
dest_addr.identifier = address_ptr->port;
|
||||
dest_addr.type = ADDRESS_IPV6;
|
||||
|
||||
if (-2 == coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
|
||||
data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS)) {
|
||||
transaction_ptr->data_ptr = ns_dyn_mem_alloc(data_len);
|
||||
if (!transaction_ptr->data_ptr) {
|
||||
tr_debug("coap tx out of memory");
|
||||
return 0;
|
||||
|
||||
}
|
||||
memcpy(transaction_ptr->data_ptr, data_ptr, data_len);
|
||||
transaction_ptr->data_len = data_len;
|
||||
} else if (transaction_ptr->resp_cb == NULL ) {
|
||||
transaction_delete(transaction_ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void service_event_handler(arm_event_s *event)
|
||||
{
|
||||
if (event->event_type == ARM_LIB_TASKLET_INIT_EVENT) {
|
||||
tr_debug("service tasklet initialised");
|
||||
/*initialize coap service and listen socket*/
|
||||
}
|
||||
if (event->event_type == ARM_LIB_SYSTEM_TIMER_EVENT && event->event_id == COAP_TICK_TIMER) {
|
||||
coap_message_handler_exec(coap_service_handle, coap_ticks++);
|
||||
if(coap_ticks && !coap_ticks % SECURE_SESSION_CLEAN_INTERVAL){
|
||||
coap_connection_handler_exec(coap_ticks);
|
||||
}
|
||||
}
|
||||
eventOS_event_timer_request((uint8_t)COAP_TICK_TIMER, ARM_LIB_SYSTEM_TIMER_EVENT, tasklet_id, 1000);
|
||||
}
|
||||
|
||||
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr)
|
||||
{
|
||||
coap_service_t *this;
|
||||
if (!coap_message || !transaction_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Message is request, find correct handle
|
||||
this = service_find_by_uri(socket_id, coap_message->uri_path_ptr, coap_message->uri_path_len);
|
||||
if (!this) {
|
||||
tr_debug("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
|
||||
if (coap_message->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
|
||||
coap_message_handler_response_send(coap_service_handle, transaction_ptr->service_id, COAP_SERVICE_OPTIONS_NONE, coap_message,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_FOUND, COAP_CT_NONE, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
|
||||
if (uri_reg_ptr && uri_reg_ptr->request_recv_cb) {
|
||||
tr_debug("Service %d, call request recv cb uri %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
|
||||
|
||||
if ((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS ) {//TODO Add secure bypass option
|
||||
// Service has secure bypass active TODO this is not defined in interface
|
||||
// this check can be removed I think
|
||||
transaction_ptr->options = COAP_REQUEST_OPTIONS_SECURE_BYPASS;
|
||||
}
|
||||
transaction_ptr->service_id = this->service_id;
|
||||
return uri_reg_ptr->request_recv_cb(this->service_id, transaction_ptr->remote_address, transaction_ptr->remote_port, coap_message);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int recv_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *data_ptr = NULL;
|
||||
uint16_t data_len = 0;
|
||||
|
||||
if (!data || !len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_ptr = own_alloc(len);
|
||||
|
||||
if (!data_ptr) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(data_ptr, data, len);
|
||||
data_len = len;
|
||||
tr_debug("service recv socket data len %d ", data_len);
|
||||
|
||||
//parse coap message what CoAP to use
|
||||
int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback);
|
||||
own_free(data_ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int send_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *data_ptr, int data_len)
|
||||
{
|
||||
coap_service_t *this = service_find_by_socket(socket_id);
|
||||
if (this && this->virtual_socket_send_cb) {
|
||||
tr_debug("send to virtual socket");
|
||||
return this->virtual_socket_send_cb(this->service_id, (uint8_t*)address, port, data_ptr, data_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40])
|
||||
{
|
||||
//TODO: this is not enough if shared socket. Inform all!
|
||||
coap_service_t *this = service_find_by_socket(socket_id);
|
||||
if (this && this->coap_security_done_cb) { // secure done callback
|
||||
this->coap_security_done_cb(this->service_id, address, keyblock);
|
||||
}
|
||||
|
||||
//TODO: send all unsend transactions if more than 1
|
||||
coap_transaction_t *transaction_ptr = coap_message_handler_find_transaction(address, port);
|
||||
if (transaction_ptr && transaction_ptr->data_ptr) {
|
||||
tr_debug("send delayed packet");
|
||||
ns_address_t dest_addr;
|
||||
memcpy(dest_addr.address, address, 16);
|
||||
dest_addr.identifier = port;
|
||||
dest_addr.type = ADDRESS_IPV6;
|
||||
|
||||
coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
|
||||
transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS);
|
||||
ns_dyn_mem_free(transaction_ptr->data_ptr);
|
||||
transaction_ptr->data_ptr = NULL;
|
||||
transaction_ptr->data_len = 0;
|
||||
if (transaction_ptr->resp_cb == NULL) {
|
||||
transaction_delete(transaction_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get_passwd_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len)
|
||||
{
|
||||
coap_service_t *this = service_find_by_socket(socket_id);
|
||||
if (this && this->security_start_cb) {
|
||||
return this->security_start_cb(this->service_id, address, port, pw_ptr, pw_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options,
|
||||
coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb)
|
||||
{
|
||||
(void) interface_id;
|
||||
|
||||
coap_service_t *this = ns_dyn_mem_alloc(sizeof(coap_service_t));
|
||||
if (!this) {
|
||||
return -1;
|
||||
}
|
||||
memset(this, 0, sizeof(coap_service_t));
|
||||
tr_debug("service init interface %d, port %d, options %d", interface_id, listen_port, service_options);
|
||||
|
||||
int8_t id = 1;// get unique id
|
||||
while (service_find(id) && id < 127) {
|
||||
id++;
|
||||
}
|
||||
this->service_id = id;
|
||||
this->service_options = service_options;
|
||||
|
||||
this->security_start_cb = start_ptr;
|
||||
this->coap_security_done_cb = coap_security_done_cb;
|
||||
|
||||
if (tasklet_id == -1) {
|
||||
tr_debug("service tasklet init");
|
||||
tasklet_id = eventOS_event_handler_create(&service_event_handler, ARM_LIB_TASKLET_INIT_EVENT);
|
||||
}
|
||||
|
||||
this->conn_handler = connection_handler_create(recv_cb, send_cb, get_passwd_cb, sec_done_cb);
|
||||
if(!this->conn_handler){
|
||||
ns_dyn_mem_free(this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 > coap_connection_handler_open_connection(this->conn_handler, listen_port, ((this->service_options & COAP_SERVICE_OPTIONS_EPHEMERAL_PORT) == COAP_SERVICE_OPTIONS_EPHEMERAL_PORT),
|
||||
((this->service_options & COAP_SERVICE_OPTIONS_SECURE) == COAP_SERVICE_OPTIONS_SECURE),
|
||||
((this->service_options & COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET) != COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET),
|
||||
((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS))){
|
||||
ns_dyn_mem_free(this->conn_handler);
|
||||
ns_dyn_mem_free(this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!coap_service_handle) {
|
||||
coap_service_handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
}
|
||||
if (!coap_service_handle) {
|
||||
tr_error("coap service alloc failed");
|
||||
//TODO proper handling
|
||||
}
|
||||
|
||||
ns_list_add_to_start(&instance_list, this);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void coap_service_delete(int8_t service_id)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
if (!this) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->conn_handler){
|
||||
connection_handler_destroy(this->conn_handler);
|
||||
}
|
||||
|
||||
//TODO clear all transactions
|
||||
ns_list_foreach_safe(uri_registration_t, cur_ptr, &this->uri_list) {
|
||||
ns_dyn_mem_free(cur_ptr->uri_ptr);
|
||||
ns_list_remove(&this->uri_list, cur_ptr);
|
||||
ns_dyn_mem_free(cur_ptr);
|
||||
}
|
||||
|
||||
ns_list_remove(&instance_list, this);
|
||||
ns_dyn_mem_free(this);
|
||||
return;
|
||||
}
|
||||
|
||||
extern void coap_service_close_secure_connection(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
if (!this || !destination_addr_ptr) {
|
||||
return;
|
||||
}
|
||||
if (this->conn_handler){
|
||||
connection_handler_close_secure_connection(this->conn_handler, destination_addr_ptr, port);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t coap_service_virtual_socket_recv(int8_t service_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
tr_debug("Service %d, virtual socket received", service_id);
|
||||
if (!this) {
|
||||
return -1;
|
||||
}
|
||||
return coap_connection_handler_virtual_recv(this->conn_handler, source_addr_ptr, port, data_ptr, data_len);
|
||||
}
|
||||
|
||||
int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_service_virtual_socket_send_cb *send_method_ptr)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
tr_debug("register virtual socket cb");
|
||||
if (!this) {
|
||||
return -1;
|
||||
}
|
||||
this->virtual_socket_send_cb = send_method_ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_service_register_uri(int8_t service_id, const char *uri, uint8_t allowed_method, coap_service_request_recv_cb *request_recv_cb)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
uri_registration_t *uri_reg_ptr;
|
||||
char *uri_ptr = NULL;
|
||||
uint16_t uri_len;
|
||||
tr_debug("Service %d, Uri registration uri: %s", service_id, uri);
|
||||
if (!this || !uri) {
|
||||
return -1;
|
||||
}
|
||||
uri_len = strlen(uri);
|
||||
|
||||
uri_reg_ptr = uri_registration_find(this, uri, uri_len);
|
||||
if (!uri_reg_ptr) {
|
||||
uri_reg_ptr = ns_dyn_mem_alloc(sizeof(uri_registration_t));
|
||||
if( !uri_reg_ptr ){
|
||||
tr_error("Uri registration failed, OOM");
|
||||
return -2;
|
||||
}
|
||||
uri_reg_ptr->uri_ptr = NULL;
|
||||
} else {
|
||||
ns_dyn_mem_free(uri_reg_ptr->uri_ptr);
|
||||
ns_list_remove(&this->uri_list, uri_reg_ptr);
|
||||
}
|
||||
|
||||
uri_ptr = ns_dyn_mem_alloc(uri_len);
|
||||
if (!uri_ptr) {
|
||||
ns_dyn_mem_free(uri_reg_ptr);
|
||||
tr_error("Uri registration failed, OOM");
|
||||
return -2;
|
||||
}
|
||||
|
||||
uri_reg_ptr->uri_ptr = memcpy(uri_ptr, uri, uri_len);
|
||||
uri_reg_ptr->uri_len = uri_len;
|
||||
uri_reg_ptr->request_recv_cb = request_recv_cb;
|
||||
uri_reg_ptr->allowed_method = allowed_method;
|
||||
ns_list_add_to_start(&this->uri_list, uri_reg_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_service_unregister_uri(int8_t service_id, const char *uri)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
uri_registration_t *uri_reg_ptr;
|
||||
tr_debug("Service %d, Uri unregistration uri: %s", service_id, uri);
|
||||
if (!this || !uri) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uri_reg_ptr = uri_registration_find(this, uri, strlen(uri));
|
||||
if (!uri_reg_ptr) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
ns_dyn_mem_free(uri_reg_ptr->uri_ptr);
|
||||
ns_list_remove(&this->uri_list, uri_reg_ptr);
|
||||
ns_dyn_mem_free(uri_reg_ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t coap_service_request_send(int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16], uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri,
|
||||
sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_service_response_recv *request_response_cb){
|
||||
//TODO: coap_service_response_recv is an ugly cast, this should be refactored away + sn_coap_hdr_s MUST NOT be exposed to users of coap-service!
|
||||
//Callback would be still needed, but where to store callback?
|
||||
return coap_message_handler_request_send(coap_service_handle, service_id, options, destination_addr, destination_port, msg_type, msg_code, uri, cont_type, payload_ptr, payload_len, request_response_cb);
|
||||
}
|
||||
|
||||
int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len){
|
||||
return coap_message_handler_response_send(coap_service_handle, service_id, options, request_ptr, message_code, content_type, payload_ptr, payload_len);
|
||||
}
|
||||
|
||||
int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max)
|
||||
{
|
||||
coap_service_t *this = service_find(service_id);
|
||||
if(!this){
|
||||
return -1;
|
||||
}
|
||||
|
||||
return coap_connection_handler_set_timeout(this->conn_handler, min, max);
|
||||
}
|
||||
|
||||
uint32_t coap_service_get_internal_timer_ticks(void)
|
||||
{
|
||||
return coap_ticks;
|
||||
}
|
||||
|
||||
uint16_t coap_service_id_find_by_socket(int8_t socket_id)
|
||||
{
|
||||
coap_service_t *this = service_find_by_socket(socket_id);
|
||||
|
||||
return this ? this->service_id:0;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __COAP_CONNECTION_HANDLER_H__
|
||||
#define __COAP_CONNECTION_HANDLER_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "ns_address.h"
|
||||
#include "coap_service_api_internal.h"
|
||||
|
||||
#define MAX_SECURE_SESSION_COUNT 3
|
||||
#define CLOSED_SECURE_SESSION_TIMEOUT 3600 // Seconds
|
||||
#define OPEN_SECURE_SESSION_TIMEOUT 18000 // Seconds
|
||||
#define SECURE_SESSION_CLEAN_INTERVAL 60 // Seconds
|
||||
|
||||
struct internal_socket_s;
|
||||
|
||||
typedef int send_to_socket_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *, int);
|
||||
typedef int receive_from_socket_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int);
|
||||
typedef int get_pw_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len);
|
||||
typedef void security_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);
|
||||
|
||||
typedef struct coap_conn_handler_s{
|
||||
struct internal_socket_s *socket;
|
||||
|
||||
receive_from_socket_cb *_recv_cb;
|
||||
send_to_socket_cb *_send_cb;
|
||||
get_pw_cb *_get_password_cb;
|
||||
security_done_cb *_security_done_cb;
|
||||
} coap_conn_handler_t;
|
||||
|
||||
coap_conn_handler_t *connection_handler_create(receive_from_socket_cb *recv_from_cb,
|
||||
send_to_socket_cb *send_to_cb,
|
||||
get_pw_cb *pw_cb,
|
||||
security_done_cb *done_cb);
|
||||
|
||||
void connection_handler_destroy( coap_conn_handler_t *handler );
|
||||
|
||||
void connection_handler_close_secure_connection( coap_conn_handler_t *handler, uint8_t destination_addr_ptr[static 16], uint16_t port );
|
||||
|
||||
int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec);
|
||||
|
||||
//If returns -2, it means security was started and data was not send
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t src_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec);
|
||||
|
||||
int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);
|
||||
|
||||
bool coap_connection_handler_socket_belongs_to(coap_conn_handler_t *handler, int8_t socket_id);
|
||||
|
||||
int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_t min, uint32_t max);
|
||||
|
||||
void coap_connection_handler_exec(uint32_t time);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __COAP_MESSAGE_HANDLER_H__
|
||||
#define __COAP_MESSAGE_HANDLER_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "sn_coap_header.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "ns_list.h"
|
||||
|
||||
#define TRANSACTION_LIFETIME 180
|
||||
|
||||
/**
|
||||
* \brief Service message response receive callback.
|
||||
*
|
||||
* Function that handles CoAP service message receiving and parsing
|
||||
*
|
||||
* \param msg_id Id number of the current message.
|
||||
* \param response_ptr Pointer to CoAP header structure.
|
||||
*
|
||||
* \return 0 for success / -1 for failure
|
||||
*/
|
||||
typedef int coap_message_handler_response_recv(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *response_ptr);
|
||||
|
||||
typedef struct coap_msg_handler_s {
|
||||
void *(*sn_coap_service_malloc)(uint16_t);
|
||||
void (*sn_coap_service_free)(void *);
|
||||
|
||||
uint8_t (*sn_coap_tx_callback)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *);
|
||||
|
||||
struct coap_s *coap;
|
||||
} coap_msg_handler_t;
|
||||
|
||||
typedef struct coap_transaction {
|
||||
uint8_t remote_address[16];
|
||||
uint8_t local_address[16];
|
||||
uint8_t token[4];
|
||||
uint32_t create_time;
|
||||
uint16_t remote_port;
|
||||
uint16_t msg_id;
|
||||
uint16_t data_len;
|
||||
int8_t service_id;
|
||||
uint8_t options;
|
||||
uint8_t *data_ptr;
|
||||
bool client_request: 1;
|
||||
|
||||
coap_message_handler_response_recv *resp_cb;
|
||||
ns_list_link_t link;
|
||||
} coap_transaction_t;
|
||||
|
||||
|
||||
extern coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
|
||||
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *));
|
||||
|
||||
extern int8_t coap_message_handler_destroy(coap_msg_handler_t *handle);
|
||||
|
||||
extern coap_transaction_t *coap_message_handler_transaction_valid(coap_transaction_t *tr_ptr);
|
||||
|
||||
extern coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port);
|
||||
|
||||
extern int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
|
||||
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *));
|
||||
|
||||
extern uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16],
|
||||
uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri, sn_coap_content_format_e cont_type,
|
||||
const uint8_t *payload_ptr, uint16_t payload_len, coap_message_handler_response_recv *request_response_cb);
|
||||
|
||||
extern int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code,
|
||||
sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len);
|
||||
|
||||
extern int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time);
|
||||
|
||||
extern void transaction_delete(coap_transaction_t *this);
|
||||
|
||||
extern void transactions_delete_all(uint8_t *address_ptr, uint16_t port);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __COAP_SECURITY_HANDLER_H__
|
||||
#define __COAP_SECURITY_HANDLER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef NS_USE_EXTERNAL_MBED_TLS
|
||||
#include "mbedtls/ssl.h"
|
||||
#ifdef MBEDTLS_SSL_TLS_C
|
||||
#define COAP_SECURITY_AVAILABLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define COOKIE_SIMPLE_LEN 8
|
||||
typedef struct simple_cookie {
|
||||
unsigned char value[COOKIE_SIMPLE_LEN];
|
||||
size_t len;
|
||||
} simple_cookie_t;
|
||||
|
||||
#define KEY_BLOCK_LEN 40
|
||||
typedef struct key_block {
|
||||
unsigned char value[KEY_BLOCK_LEN];
|
||||
} key_block_t;
|
||||
|
||||
typedef int send_cb(int8_t socket_id, void *handle, const void *buf, size_t);
|
||||
typedef int receive_cb(int8_t socket_id, unsigned char *, size_t);
|
||||
typedef void start_timer_cb(int8_t timer_id, uint32_t min, uint32_t fin);
|
||||
typedef int timer_status_cb(int8_t timer_id);
|
||||
|
||||
#define DTLS_HANDSHAKE_TIMEOUT_MIN 25000
|
||||
#define DTLS_HANDSHAKE_TIMEOUT_MAX 201000
|
||||
|
||||
typedef enum {
|
||||
DTLS = 0,
|
||||
TLS = 1
|
||||
}SecureSocketMode;
|
||||
|
||||
typedef enum {
|
||||
Certificate,
|
||||
PSK,
|
||||
ECJPAKE
|
||||
}SecureConnectionMode;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *_server_cert;
|
||||
uint8_t _server_cert_len;
|
||||
unsigned char *_pub_cert_or_identifier;
|
||||
uint8_t _pub_len;
|
||||
unsigned char *_priv;
|
||||
uint8_t _priv_len;
|
||||
} coap_security_keys_t;
|
||||
|
||||
typedef struct coap_security_s coap_security_t;
|
||||
|
||||
#ifdef COAP_SECURITY_AVAILABLE
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle,
|
||||
SecureConnectionMode mode,
|
||||
send_cb *send_cb,
|
||||
receive_cb *receive_cb,
|
||||
start_timer_cb *start_timer_cb,
|
||||
timer_status_cb *timer_status_cb);
|
||||
|
||||
void coap_security_destroy(coap_security_t *sec);
|
||||
|
||||
int coap_security_handler_connect(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys);
|
||||
|
||||
int coap_security_handler_connect_non_blocking(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys, uint32_t timeout_min, uint32_t timeout_max);
|
||||
|
||||
int coap_security_handler_continue_connecting(coap_security_t *sec);
|
||||
|
||||
int coap_security_handler_send_message(coap_security_t *sec, unsigned char *message, size_t len);
|
||||
|
||||
int coap_security_send_close_alert(coap_security_t *sec);
|
||||
|
||||
int coap_security_handler_read(coap_security_t *sec, unsigned char* buffer, size_t len);
|
||||
|
||||
bool coap_security_handler_is_started(const coap_security_t *sec);
|
||||
|
||||
const void *coap_security_handler_keyblock(const coap_security_t *sec);
|
||||
|
||||
#else
|
||||
|
||||
/* Dummy definitions, including needed error codes */
|
||||
#define MBEDTLS_ERR_SSL_TIMEOUT (-1)
|
||||
#define MBEDTLS_ERR_SSL_WANT_READ (-2)
|
||||
#define MBEDTLS_ERR_SSL_WANT_WRITE (-3)
|
||||
#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE (-4)
|
||||
|
||||
#define coap_security_create(socket_id, timer_id, handle, \
|
||||
mode, send_cb, receive_cb, start_timer_cb, timer_status_cb) ((coap_security_t *) 0)
|
||||
#define coap_security_destroy(sec) ((void) 0)
|
||||
#define coap_security_handler_connect(sec, is_server, sock_mode, keys) (-1)
|
||||
#define coap_security_handler_connect_non_blocking(sec, is_server, sock_mode, keys, timeout_min, timeout_max) (-1)
|
||||
#define coap_security_handler_continue_connecting(sec) (-1)
|
||||
#define coap_security_handler_send_message(sec, message, len) (-1)
|
||||
#define coap_security_send_close_alert(sec) (-1)
|
||||
#define coap_security_handler_read(sec, buffer, len) (-1)
|
||||
#define coap_security_handler_is_started(sec) false
|
||||
#define coap_security_handler_keyblock(sec) ((void *) 0)
|
||||
|
||||
#endif /* COAP_SECURITY_AVAILABLE */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __COAP_SERVICE_API_INTERNAL_H__
|
||||
#define __COAP_SERVICE_API_INTERNAL_H__
|
||||
|
||||
#include "coap_message_handler.h"
|
||||
|
||||
|
||||
extern coap_msg_handler_t *coap_service_handle;
|
||||
|
||||
uint32_t coap_service_get_internal_timer_ticks(void);
|
||||
|
||||
uint16_t coap_service_id_find_by_socket(int8_t socket_id);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
#scan for folders having "Makefile" in them and remove 'this' to prevent loop
|
||||
ifeq ($(OS),Windows_NT)
|
||||
all:
|
||||
clean:
|
||||
else
|
||||
DIRS := $(filter-out ./, $(sort $(dir $(shell find . -name 'Makefile'))))
|
||||
|
||||
all:
|
||||
for dir in $(DIRS); do \
|
||||
cd $$dir; make gcov; cd ..;\
|
||||
done
|
||||
|
||||
clean:
|
||||
for dir in $(DIRS); do \
|
||||
cd $$dir; make clean; cd ..;\
|
||||
done
|
||||
rm -rf stub/*gcov stub/*gcda stubs/*o
|
||||
rm -rf results/*
|
||||
rm -rf coverages/*
|
||||
rm -rf results
|
||||
rm -rf coverages
|
||||
endif
|
||||
|
|
@ -0,0 +1,562 @@
|
|||
#---------
|
||||
#
|
||||
# MakefileWorker.mk
|
||||
#
|
||||
# Include this helper file in your makefile
|
||||
# It makes
|
||||
# A static library
|
||||
# A test executable
|
||||
#
|
||||
# See this example for parameter settings
|
||||
# examples/Makefile
|
||||
#
|
||||
#----------
|
||||
# Inputs - these variables describe what to build
|
||||
#
|
||||
# INCLUDE_DIRS - Directories used to search for include files.
|
||||
# This generates a -I for each directory
|
||||
# SRC_DIRS - Directories containing source file to built into the library
|
||||
# SRC_FILES - Specific source files to build into library. Helpful when not all code
|
||||
# in a directory can be built for test (hopefully a temporary situation)
|
||||
# TEST_SRC_DIRS - Directories containing unit test code build into the unit test runner
|
||||
# These do not go in a library. They are explicitly included in the test runner
|
||||
# TEST_SRC_FILES - Specific source files to build into the unit test runner
|
||||
# These do not go in a library. They are explicitly included in the test runner
|
||||
# MOCKS_SRC_DIRS - Directories containing mock source files to build into the test runner
|
||||
# These do not go in a library. They are explicitly included in the test runner
|
||||
#----------
|
||||
# You can adjust these variables to influence how to build the test target
|
||||
# and where to put and name outputs
|
||||
# See below to determine defaults
|
||||
# COMPONENT_NAME - the name of the thing being built
|
||||
# TEST_TARGET - name the test executable. By default it is
|
||||
# $(COMPONENT_NAME)_tests
|
||||
# Helpful if you want 1 > make files in the same directory with different
|
||||
# executables as output.
|
||||
# CPPUTEST_HOME - where CppUTest home dir found
|
||||
# TARGET_PLATFORM - Influences how the outputs are generated by modifying the
|
||||
# CPPUTEST_OBJS_DIR and CPPUTEST_LIB_DIR to use a sub-directory under the
|
||||
# normal objs and lib directories. Also modifies where to search for the
|
||||
# CPPUTEST_LIB to link against.
|
||||
# CPPUTEST_OBJS_DIR - a directory where o and d files go
|
||||
# CPPUTEST_LIB_DIR - a directory where libs go
|
||||
# CPPUTEST_ENABLE_DEBUG - build for debug
|
||||
# CPPUTEST_USE_MEM_LEAK_DETECTION - Links with overridden new and delete
|
||||
# CPPUTEST_USE_STD_CPP_LIB - Set to N to keep the standard C++ library out
|
||||
# of the test harness
|
||||
# CPPUTEST_USE_GCOV - Turn on coverage analysis
|
||||
# Clean then build with this flag set to Y, then 'make gcov'
|
||||
# CPPUTEST_MAPFILE - generate a map file
|
||||
# CPPUTEST_WARNINGFLAGS - overly picky by default
|
||||
# OTHER_MAKEFILE_TO_INCLUDE - a hook to use this makefile to make
|
||||
# other targets. Like CSlim, which is part of fitnesse
|
||||
# CPPUTEST_USE_VPATH - Use Make's VPATH functionality to support user
|
||||
# specification of source files and directories that aren't below
|
||||
# the user's Makefile in the directory tree, like:
|
||||
# SRC_DIRS += ../../lib/foo
|
||||
# It defaults to N, and shouldn't be necessary except in the above case.
|
||||
#----------
|
||||
#
|
||||
# Other flags users can initialize to sneak in their settings
|
||||
# CPPUTEST_CXXFLAGS - flags for the C++ compiler
|
||||
# CPPUTEST_CPPFLAGS - flags for the C++ AND C preprocessor
|
||||
# CPPUTEST_CFLAGS - flags for the C complier
|
||||
# CPPUTEST_LDFLAGS - Linker flags
|
||||
#----------
|
||||
|
||||
# Some behavior is weird on some platforms. Need to discover the platform.
|
||||
|
||||
# Platforms
|
||||
UNAME_OUTPUT = "$(shell uname -a)"
|
||||
MACOSX_STR = Darwin
|
||||
MINGW_STR = MINGW
|
||||
CYGWIN_STR = CYGWIN
|
||||
LINUX_STR = Linux
|
||||
SUNOS_STR = SunOS
|
||||
UNKNWOWN_OS_STR = Unknown
|
||||
|
||||
# Compilers
|
||||
CC_VERSION_OUTPUT ="$(shell $(CXX) -v 2>&1)"
|
||||
CLANG_STR = clang
|
||||
SUNSTUDIO_CXX_STR = SunStudio
|
||||
|
||||
UNAME_OS = $(UNKNWOWN_OS_STR)
|
||||
|
||||
ifeq ($(findstring $(MINGW_STR),$(UNAME_OUTPUT)),$(MINGW_STR))
|
||||
UNAME_OS = $(MINGW_STR)
|
||||
endif
|
||||
|
||||
ifeq ($(findstring $(CYGWIN_STR),$(UNAME_OUTPUT)),$(CYGWIN_STR))
|
||||
UNAME_OS = $(CYGWIN_STR)
|
||||
endif
|
||||
|
||||
ifeq ($(findstring $(LINUX_STR),$(UNAME_OUTPUT)),$(LINUX_STR))
|
||||
UNAME_OS = $(LINUX_STR)
|
||||
endif
|
||||
|
||||
ifeq ($(findstring $(MACOSX_STR),$(UNAME_OUTPUT)),$(MACOSX_STR))
|
||||
UNAME_OS = $(MACOSX_STR)
|
||||
#lion has a problem with the 'v' part of -a
|
||||
UNAME_OUTPUT = "$(shell uname -pmnrs)"
|
||||
endif
|
||||
|
||||
ifeq ($(findstring $(SUNOS_STR),$(UNAME_OUTPUT)),$(SUNOS_STR))
|
||||
UNAME_OS = $(SUNOS_STR)
|
||||
|
||||
SUNSTUDIO_CXX_ERR_STR = CC -flags
|
||||
ifeq ($(findstring $(SUNSTUDIO_CXX_ERR_STR),$(CC_VERSION_OUTPUT)),$(SUNSTUDIO_CXX_ERR_STR))
|
||||
CC_VERSION_OUTPUT ="$(shell $(CXX) -V 2>&1)"
|
||||
COMPILER_NAME = $(SUNSTUDIO_CXX_STR)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(findstring $(CLANG_STR),$(CC_VERSION_OUTPUT)),$(CLANG_STR))
|
||||
COMPILER_NAME = $(CLANG_STR)
|
||||
endif
|
||||
|
||||
#Kludge for mingw, it does not have cc.exe, but gcc.exe will do
|
||||
ifeq ($(UNAME_OS),$(MINGW_STR))
|
||||
CC := gcc
|
||||
endif
|
||||
|
||||
#And another kludge. Exception handling in gcc 4.6.2 is broken when linking the
|
||||
# Standard C++ library as a shared library. Unbelievable.
|
||||
ifeq ($(UNAME_OS),$(MINGW_STR))
|
||||
CPPUTEST_LDFLAGS += -static
|
||||
endif
|
||||
ifeq ($(UNAME_OS),$(CYGWIN_STR))
|
||||
CPPUTEST_LDFLAGS += -static
|
||||
endif
|
||||
|
||||
|
||||
#Kludge for MacOsX gcc compiler on Darwin9 who can't handle pendantic
|
||||
ifeq ($(UNAME_OS),$(MACOSX_STR))
|
||||
ifeq ($(findstring Version 9,$(UNAME_OUTPUT)),Version 9)
|
||||
CPPUTEST_PEDANTIC_ERRORS = N
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef COMPONENT_NAME
|
||||
COMPONENT_NAME = name_this_in_the_makefile
|
||||
endif
|
||||
|
||||
# Debug on by default
|
||||
ifndef CPPUTEST_ENABLE_DEBUG
|
||||
CPPUTEST_ENABLE_DEBUG = Y
|
||||
endif
|
||||
|
||||
# new and delete for memory leak detection on by default
|
||||
ifndef CPPUTEST_USE_MEM_LEAK_DETECTION
|
||||
CPPUTEST_USE_MEM_LEAK_DETECTION = Y
|
||||
endif
|
||||
|
||||
# Use the standard C library
|
||||
ifndef CPPUTEST_USE_STD_C_LIB
|
||||
CPPUTEST_USE_STD_C_LIB = Y
|
||||
endif
|
||||
|
||||
# Use the standard C++ library
|
||||
ifndef CPPUTEST_USE_STD_CPP_LIB
|
||||
CPPUTEST_USE_STD_CPP_LIB = Y
|
||||
endif
|
||||
|
||||
# Use gcov, off by default
|
||||
ifndef CPPUTEST_USE_GCOV
|
||||
CPPUTEST_USE_GCOV = N
|
||||
endif
|
||||
|
||||
ifndef CPPUTEST_PEDANTIC_ERRORS
|
||||
CPPUTEST_PEDANTIC_ERRORS = Y
|
||||
endif
|
||||
|
||||
# Default warnings
|
||||
ifndef CPPUTEST_WARNINGFLAGS
|
||||
CPPUTEST_WARNINGFLAGS = -Wall -Wextra -Wshadow -Wswitch-default -Wswitch-enum -Wconversion
|
||||
ifeq ($(CPPUTEST_PEDANTIC_ERRORS), Y)
|
||||
# CPPUTEST_WARNINGFLAGS += -pedantic-errors
|
||||
CPPUTEST_WARNINGFLAGS += -pedantic
|
||||
endif
|
||||
ifeq ($(UNAME_OS),$(LINUX_STR))
|
||||
CPPUTEST_WARNINGFLAGS += -Wsign-conversion
|
||||
endif
|
||||
CPPUTEST_CXX_WARNINGFLAGS = -Woverloaded-virtual
|
||||
CPPUTEST_C_WARNINGFLAGS = -Wstrict-prototypes
|
||||
endif
|
||||
|
||||
#Wonderful extra compiler warnings with clang
|
||||
ifeq ($(COMPILER_NAME),$(CLANG_STR))
|
||||
# -Wno-disabled-macro-expansion -> Have to disable the macro expansion warning as the operator new overload warns on that.
|
||||
# -Wno-padded -> I sort-of like this warning but if there is a bool at the end of the class, it seems impossible to remove it! (except by making padding explicit)
|
||||
# -Wno-global-constructors Wno-exit-time-destructors -> Great warnings, but in CppUTest it is impossible to avoid as the automatic test registration depends on the global ctor and dtor
|
||||
# -Wno-weak-vtables -> The TEST_GROUP macro declares a class and will automatically inline its methods. Thats ok as they are only in one translation unit. Unfortunately, the warning can't detect that, so it must be disabled.
|
||||
CPPUTEST_CXX_WARNINGFLAGS += -Weverything -Wno-disabled-macro-expansion -Wno-padded -Wno-global-constructors -Wno-exit-time-destructors -Wno-weak-vtables
|
||||
CPPUTEST_C_WARNINGFLAGS += -Weverything -Wno-padded
|
||||
endif
|
||||
|
||||
# Uhm. Maybe put some warning flags for SunStudio here?
|
||||
ifeq ($(COMPILER_NAME),$(SUNSTUDIO_CXX_STR))
|
||||
CPPUTEST_CXX_WARNINGFLAGS =
|
||||
CPPUTEST_C_WARNINGFLAGS =
|
||||
endif
|
||||
|
||||
# Default dir for temporary files (d, o)
|
||||
ifndef CPPUTEST_OBJS_DIR
|
||||
ifndef TARGET_PLATFORM
|
||||
CPPUTEST_OBJS_DIR = objs
|
||||
else
|
||||
CPPUTEST_OBJS_DIR = objs/$(TARGET_PLATFORM)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Default dir for the outout library
|
||||
ifndef CPPUTEST_LIB_DIR
|
||||
ifndef TARGET_PLATFORM
|
||||
CPPUTEST_LIB_DIR = lib
|
||||
else
|
||||
CPPUTEST_LIB_DIR = lib/$(TARGET_PLATFORM)
|
||||
endif
|
||||
endif
|
||||
|
||||
# No map by default
|
||||
ifndef CPPUTEST_MAP_FILE
|
||||
CPPUTEST_MAP_FILE = N
|
||||
endif
|
||||
|
||||
# No extentions is default
|
||||
ifndef CPPUTEST_USE_EXTENSIONS
|
||||
CPPUTEST_USE_EXTENSIONS = N
|
||||
endif
|
||||
|
||||
# No VPATH is default
|
||||
ifndef CPPUTEST_USE_VPATH
|
||||
CPPUTEST_USE_VPATH := N
|
||||
endif
|
||||
# Make empty, instead of 'N', for usage in $(if ) conditionals
|
||||
ifneq ($(CPPUTEST_USE_VPATH), Y)
|
||||
CPPUTEST_USE_VPATH :=
|
||||
endif
|
||||
|
||||
ifndef TARGET_PLATFORM
|
||||
#CPPUTEST_LIB_LINK_DIR = $(CPPUTEST_HOME)/lib
|
||||
CPPUTEST_LIB_LINK_DIR = /usr/lib/x86_64-linux-gnu
|
||||
else
|
||||
CPPUTEST_LIB_LINK_DIR = $(CPPUTEST_HOME)/lib/$(TARGET_PLATFORM)
|
||||
endif
|
||||
|
||||
# --------------------------------------
|
||||
# derived flags in the following area
|
||||
# --------------------------------------
|
||||
|
||||
# Without the C library, we'll need to disable the C++ library and ...
|
||||
ifeq ($(CPPUTEST_USE_STD_C_LIB), N)
|
||||
CPPUTEST_USE_STD_CPP_LIB = N
|
||||
CPPUTEST_USE_MEM_LEAK_DETECTION = N
|
||||
CPPUTEST_CPPFLAGS += -DCPPUTEST_STD_C_LIB_DISABLED
|
||||
CPPUTEST_CPPFLAGS += -nostdinc
|
||||
endif
|
||||
|
||||
CPPUTEST_CPPFLAGS += -DCPPUTEST_COMPILATION
|
||||
|
||||
ifeq ($(CPPUTEST_USE_MEM_LEAK_DETECTION), N)
|
||||
CPPUTEST_CPPFLAGS += -DCPPUTEST_MEM_LEAK_DETECTION_DISABLED
|
||||
else
|
||||
ifndef CPPUTEST_MEMLEAK_DETECTOR_NEW_MACRO_FILE
|
||||
CPPUTEST_MEMLEAK_DETECTOR_NEW_MACRO_FILE = -include $(CPPUTEST_HOME)/include/CppUTest/MemoryLeakDetectorNewMacros.h
|
||||
endif
|
||||
ifndef CPPUTEST_MEMLEAK_DETECTOR_MALLOC_MACRO_FILE
|
||||
CPPUTEST_MEMLEAK_DETECTOR_MALLOC_MACRO_FILE = -include $(CPPUTEST_HOME)/include/CppUTest/MemoryLeakDetectorMallocMacros.h
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CPPUTEST_ENABLE_DEBUG), Y)
|
||||
CPPUTEST_CXXFLAGS += -g
|
||||
CPPUTEST_CFLAGS += -g
|
||||
CPPUTEST_LDFLAGS += -g
|
||||
endif
|
||||
|
||||
ifeq ($(CPPUTEST_USE_STD_CPP_LIB), N)
|
||||
CPPUTEST_CPPFLAGS += -DCPPUTEST_STD_CPP_LIB_DISABLED
|
||||
ifeq ($(CPPUTEST_USE_STD_C_LIB), Y)
|
||||
CPPUTEST_CXXFLAGS += -nostdinc++
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef $(GMOCK_HOME)
|
||||
GTEST_HOME = $(GMOCK_HOME)/gtest
|
||||
CPPUTEST_CPPFLAGS += -I$(GMOCK_HOME)/include
|
||||
GMOCK_LIBRARY = $(GMOCK_HOME)/lib/.libs/libgmock.a
|
||||
LD_LIBRARIES += $(GMOCK_LIBRARY)
|
||||
CPPUTEST_CPPFLAGS += -DINCLUDE_GTEST_TESTS
|
||||
CPPUTEST_WARNINGFLAGS =
|
||||
CPPUTEST_CPPFLAGS += -I$(GTEST_HOME)/include -I$(GTEST_HOME)
|
||||
GTEST_LIBRARY = $(GTEST_HOME)/lib/.libs/libgtest.a
|
||||
LD_LIBRARIES += $(GTEST_LIBRARY)
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(CPPUTEST_USE_GCOV), Y)
|
||||
CPPUTEST_CXXFLAGS += -fprofile-arcs -ftest-coverage
|
||||
CPPUTEST_CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
endif
|
||||
|
||||
CPPUTEST_CXXFLAGS += $(CPPUTEST_WARNINGFLAGS) $(CPPUTEST_CXX_WARNINGFLAGS)
|
||||
CPPUTEST_CPPFLAGS += $(CPPUTEST_WARNINGFLAGS)
|
||||
CPPUTEST_CXXFLAGS += $(CPPUTEST_MEMLEAK_DETECTOR_NEW_MACRO_FILE)
|
||||
CPPUTEST_CPPFLAGS += $(CPPUTEST_MEMLEAK_DETECTOR_MALLOC_MACRO_FILE)
|
||||
CPPUTEST_CFLAGS += $(CPPUTEST_C_WARNINGFLAGS)
|
||||
|
||||
TARGET_MAP = $(COMPONENT_NAME).map.txt
|
||||
ifeq ($(CPPUTEST_MAP_FILE), Y)
|
||||
CPPUTEST_LDFLAGS += -Wl,-map,$(TARGET_MAP)
|
||||
endif
|
||||
|
||||
# Link with CppUTest lib
|
||||
CPPUTEST_LIB = $(CPPUTEST_LIB_LINK_DIR)/libCppUTest.a
|
||||
|
||||
ifeq ($(CPPUTEST_USE_EXTENSIONS), Y)
|
||||
CPPUTEST_LIB += $(CPPUTEST_LIB_LINK_DIR)/libCppUTestExt.a
|
||||
endif
|
||||
|
||||
ifdef CPPUTEST_STATIC_REALTIME
|
||||
LD_LIBRARIES += -lrt
|
||||
endif
|
||||
|
||||
TARGET_LIB = \
|
||||
$(CPPUTEST_LIB_DIR)/lib$(COMPONENT_NAME).a
|
||||
|
||||
ifndef TEST_TARGET
|
||||
ifndef TARGET_PLATFORM
|
||||
TEST_TARGET = $(COMPONENT_NAME)_tests
|
||||
else
|
||||
TEST_TARGET = $(COMPONENT_NAME)_$(TARGET_PLATFORM)_tests
|
||||
endif
|
||||
endif
|
||||
|
||||
#Helper Functions
|
||||
get_src_from_dir = $(wildcard $1/*.cpp) $(wildcard $1/*.cc) $(wildcard $1/*.c)
|
||||
get_dirs_from_dirspec = $(wildcard $1)
|
||||
get_src_from_dir_list = $(foreach dir, $1, $(call get_src_from_dir,$(dir)))
|
||||
__src_to = $(subst .c,$1, $(subst .cc,$1, $(subst .cpp,$1,$(if $(CPPUTEST_USE_VPATH),$(notdir $2),$2))))
|
||||
src_to = $(addprefix $(CPPUTEST_OBJS_DIR)/,$(call __src_to,$1,$2))
|
||||
src_to_o = $(call src_to,.o,$1)
|
||||
src_to_d = $(call src_to,.d,$1)
|
||||
src_to_gcda = $(call src_to,.gcda,$1)
|
||||
src_to_gcno = $(call src_to,.gcno,$1)
|
||||
time = $(shell date +%s)
|
||||
delta_t = $(eval minus, $1, $2)
|
||||
debug_print_list = $(foreach word,$1,echo " $(word)";) echo;
|
||||
|
||||
#Derived
|
||||
STUFF_TO_CLEAN += $(TEST_TARGET) $(TEST_TARGET).exe $(TARGET_LIB) $(TARGET_MAP)
|
||||
|
||||
SRC += $(call get_src_from_dir_list, $(SRC_DIRS)) $(SRC_FILES)
|
||||
OBJ = $(call src_to_o,$(SRC))
|
||||
|
||||
STUFF_TO_CLEAN += $(OBJ)
|
||||
|
||||
TEST_SRC += $(call get_src_from_dir_list, $(TEST_SRC_DIRS)) $(TEST_SRC_FILES)
|
||||
TEST_OBJS = $(call src_to_o,$(TEST_SRC))
|
||||
STUFF_TO_CLEAN += $(TEST_OBJS)
|
||||
|
||||
|
||||
MOCKS_SRC += $(call get_src_from_dir_list, $(MOCKS_SRC_DIRS))
|
||||
MOCKS_OBJS = $(call src_to_o,$(MOCKS_SRC))
|
||||
STUFF_TO_CLEAN += $(MOCKS_OBJS)
|
||||
|
||||
ALL_SRC = $(SRC) $(TEST_SRC) $(MOCKS_SRC)
|
||||
|
||||
# If we're using VPATH
|
||||
ifeq ($(CPPUTEST_USE_VPATH), Y)
|
||||
# gather all the source directories and add them
|
||||
VPATH += $(sort $(dir $(ALL_SRC)))
|
||||
# Add the component name to the objs dir path, to differentiate between same-name objects
|
||||
CPPUTEST_OBJS_DIR := $(addsuffix /$(COMPONENT_NAME),$(CPPUTEST_OBJS_DIR))
|
||||
endif
|
||||
|
||||
#Test coverage with gcov
|
||||
GCOV_OUTPUT = gcov_output.txt
|
||||
GCOV_REPORT = gcov_report.txt
|
||||
GCOV_ERROR = gcov_error.txt
|
||||
GCOV_GCDA_FILES = $(call src_to_gcda, $(ALL_SRC))
|
||||
GCOV_GCNO_FILES = $(call src_to_gcno, $(ALL_SRC))
|
||||
TEST_OUTPUT = $(TEST_TARGET).txt
|
||||
STUFF_TO_CLEAN += \
|
||||
$(GCOV_OUTPUT)\
|
||||
$(GCOV_REPORT)\
|
||||
$(GCOV_REPORT).html\
|
||||
$(GCOV_ERROR)\
|
||||
$(GCOV_GCDA_FILES)\
|
||||
$(GCOV_GCNO_FILES)\
|
||||
$(TEST_OUTPUT)
|
||||
|
||||
#The gcda files for gcov need to be deleted before each run
|
||||
#To avoid annoying messages.
|
||||
GCOV_CLEAN = $(SILENCE)rm -f $(GCOV_GCDA_FILES) $(GCOV_OUTPUT) $(GCOV_REPORT) $(GCOV_ERROR)
|
||||
RUN_TEST_TARGET = $(SILENCE) $(GCOV_CLEAN) ; echo "Running $(TEST_TARGET)"; ./$(TEST_TARGET) $(CPPUTEST_EXE_FLAGS) -ojunit
|
||||
|
||||
ifeq ($(CPPUTEST_USE_GCOV), Y)
|
||||
|
||||
ifeq ($(COMPILER_NAME),$(CLANG_STR))
|
||||
LD_LIBRARIES += --coverage
|
||||
else
|
||||
LD_LIBRARIES += -lgcov
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
INCLUDES_DIRS_EXPANDED = $(call get_dirs_from_dirspec, $(INCLUDE_DIRS))
|
||||
INCLUDES += $(foreach dir, $(INCLUDES_DIRS_EXPANDED), -I$(dir))
|
||||
MOCK_DIRS_EXPANDED = $(call get_dirs_from_dirspec, $(MOCKS_SRC_DIRS))
|
||||
INCLUDES += $(foreach dir, $(MOCK_DIRS_EXPANDED), -I$(dir))
|
||||
|
||||
CPPUTEST_CPPFLAGS += $(INCLUDES) $(CPPUTESTFLAGS)
|
||||
|
||||
DEP_FILES = $(call src_to_d, $(ALL_SRC))
|
||||
STUFF_TO_CLEAN += $(DEP_FILES) $(PRODUCTION_CODE_START) $(PRODUCTION_CODE_END)
|
||||
STUFF_TO_CLEAN += $(STDLIB_CODE_START) $(MAP_FILE) cpputest_*.xml junit_run_output
|
||||
|
||||
# We'll use the CPPUTEST_CFLAGS etc so that you can override AND add to the CppUTest flags
|
||||
CFLAGS = $(CPPUTEST_CFLAGS) $(CPPUTEST_ADDITIONAL_CFLAGS)
|
||||
CPPFLAGS = $(CPPUTEST_CPPFLAGS) $(CPPUTEST_ADDITIONAL_CPPFLAGS)
|
||||
CXXFLAGS = $(CPPUTEST_CXXFLAGS) $(CPPUTEST_ADDITIONAL_CXXFLAGS)
|
||||
LDFLAGS = $(CPPUTEST_LDFLAGS) $(CPPUTEST_ADDITIONAL_LDFLAGS)
|
||||
|
||||
# Don't consider creating the archive a warning condition that does STDERR output
|
||||
ARFLAGS := $(ARFLAGS)c
|
||||
|
||||
DEP_FLAGS=-MMD -MP
|
||||
|
||||
# Some macros for programs to be overridden. For some reason, these are not in Make defaults
|
||||
RANLIB = ranlib
|
||||
|
||||
# Targets
|
||||
|
||||
.PHONY: all
|
||||
all: start $(TEST_TARGET)
|
||||
$(RUN_TEST_TARGET)
|
||||
|
||||
.PHONY: start
|
||||
start: $(TEST_TARGET)
|
||||
$(SILENCE)START_TIME=$(call time)
|
||||
|
||||
.PHONY: all_no_tests
|
||||
all_no_tests: $(TEST_TARGET)
|
||||
|
||||
.PHONY: flags
|
||||
flags:
|
||||
@echo
|
||||
@echo "OS ${UNAME_OS}"
|
||||
@echo "Compile C and C++ source with CPPFLAGS:"
|
||||
@$(call debug_print_list,$(CPPFLAGS))
|
||||
@echo "Compile C++ source with CXXFLAGS:"
|
||||
@$(call debug_print_list,$(CXXFLAGS))
|
||||
@echo "Compile C source with CFLAGS:"
|
||||
@$(call debug_print_list,$(CFLAGS))
|
||||
@echo "Link with LDFLAGS:"
|
||||
@$(call debug_print_list,$(LDFLAGS))
|
||||
@echo "Link with LD_LIBRARIES:"
|
||||
@$(call debug_print_list,$(LD_LIBRARIES))
|
||||
@echo "Create libraries with ARFLAGS:"
|
||||
@$(call debug_print_list,$(ARFLAGS))
|
||||
|
||||
TEST_DEPS = $(TEST_OBJS) $(MOCKS_OBJS) $(PRODUCTION_CODE_START) $(TARGET_LIB) $(USER_LIBS) $(PRODUCTION_CODE_END) $(CPPUTEST_LIB) $(STDLIB_CODE_START)
|
||||
test-deps: $(TEST_DEPS)
|
||||
|
||||
$(TEST_TARGET): $(TEST_DEPS)
|
||||
@echo Linking $@
|
||||
$(SILENCE)$(CXX) -o $@ $^ $(LD_LIBRARIES) $(LDFLAGS)
|
||||
|
||||
$(TARGET_LIB): $(OBJ)
|
||||
@echo Building archive $@
|
||||
$(SILENCE)mkdir -p $(dir $@)
|
||||
$(SILENCE)$(AR) $(ARFLAGS) $@ $^
|
||||
$(SILENCE)$(RANLIB) $@
|
||||
|
||||
test: $(TEST_TARGET)
|
||||
$(RUN_TEST_TARGET) | tee $(TEST_OUTPUT)
|
||||
|
||||
vtest: $(TEST_TARGET)
|
||||
$(RUN_TEST_TARGET) -v | tee $(TEST_OUTPUT)
|
||||
|
||||
$(CPPUTEST_OBJS_DIR)/%.o: %.cc
|
||||
@echo compiling $(notdir $<)
|
||||
$(SILENCE)mkdir -p $(dir $@)
|
||||
$(SILENCE)$(COMPILE.cpp) $(DEP_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
$(CPPUTEST_OBJS_DIR)/%.o: %.cpp
|
||||
@echo compiling $(notdir $<)
|
||||
$(SILENCE)mkdir -p $(dir $@)
|
||||
$(SILENCE)$(COMPILE.cpp) $(DEP_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
$(CPPUTEST_OBJS_DIR)/%.o: %.c
|
||||
@echo compiling $(notdir $<)
|
||||
$(SILENCE)mkdir -p $(dir $@)
|
||||
$(SILENCE)$(COMPILE.c) $(DEP_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
ifneq "$(MAKECMDGOALS)" "clean"
|
||||
-include $(DEP_FILES)
|
||||
endif
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@echo Making clean
|
||||
$(SILENCE)$(RM) $(STUFF_TO_CLEAN)
|
||||
$(SILENCE)rm -rf gcov objs #$(CPPUTEST_OBJS_DIR)
|
||||
$(SILENCE)rm -rf $(CPPUTEST_LIB_DIR)
|
||||
$(SILENCE)find . -name "*.gcno" | xargs rm -f
|
||||
$(SILENCE)find . -name "*.gcda" | xargs rm -f
|
||||
|
||||
#realclean gets rid of all gcov, o and d files in the directory tree
|
||||
#not just the ones made by this makefile
|
||||
.PHONY: realclean
|
||||
realclean: clean
|
||||
$(SILENCE)rm -rf gcov
|
||||
$(SILENCE)find . -name "*.gdcno" | xargs rm -f
|
||||
$(SILENCE)find . -name "*.[do]" | xargs rm -f
|
||||
|
||||
gcov: test
|
||||
ifeq ($(CPPUTEST_USE_VPATH), Y)
|
||||
$(SILENCE)gcov --object-directory $(CPPUTEST_OBJS_DIR) $(SRC) >> $(GCOV_OUTPUT) 2>> $(GCOV_ERROR)
|
||||
else
|
||||
$(SILENCE)for d in $(SRC_DIRS) ; do \
|
||||
gcov --object-directory $(CPPUTEST_OBJS_DIR)/$$d $$d/*.c $$d/*.cpp >> $(GCOV_OUTPUT) 2>>$(GCOV_ERROR) ; \
|
||||
done
|
||||
$(SILENCE)for f in $(SRC_FILES) ; do \
|
||||
gcov --object-directory $(CPPUTEST_OBJS_DIR)/$$f $$f >> $(GCOV_OUTPUT) 2>>$(GCOV_ERROR) ; \
|
||||
done
|
||||
endif
|
||||
# $(CPPUTEST_HOME)/scripts/filterGcov.sh $(GCOV_OUTPUT) $(GCOV_ERROR) $(GCOV_REPORT) $(TEST_OUTPUT)
|
||||
/usr/share/cpputest/scripts/filterGcov.sh $(GCOV_OUTPUT) $(GCOV_ERROR) $(GCOV_REPORT) $(TEST_OUTPUT)
|
||||
$(SILENCE)cat $(GCOV_REPORT)
|
||||
$(SILENCE)mkdir -p gcov
|
||||
$(SILENCE)mv *.gcov gcov
|
||||
$(SILENCE)mv gcov_* gcov
|
||||
@echo "See gcov directory for details"
|
||||
|
||||
.PHONEY: format
|
||||
format:
|
||||
$(CPPUTEST_HOME)/scripts/reformat.sh $(PROJECT_HOME_DIR)
|
||||
|
||||
.PHONEY: debug
|
||||
debug:
|
||||
@echo
|
||||
@echo "Target Source files:"
|
||||
@$(call debug_print_list,$(SRC))
|
||||
@echo "Target Object files:"
|
||||
@$(call debug_print_list,$(OBJ))
|
||||
@echo "Test Source files:"
|
||||
@$(call debug_print_list,$(TEST_SRC))
|
||||
@echo "Test Object files:"
|
||||
@$(call debug_print_list,$(TEST_OBJS))
|
||||
@echo "Mock Source files:"
|
||||
@$(call debug_print_list,$(MOCKS_SRC))
|
||||
@echo "Mock Object files:"
|
||||
@$(call debug_print_list,$(MOCKS_OBJS))
|
||||
@echo "All Input Dependency files:"
|
||||
@$(call debug_print_list,$(DEP_FILES))
|
||||
@echo Stuff to clean:
|
||||
@$(call debug_print_list,$(STUFF_TO_CLEAN))
|
||||
@echo Includes:
|
||||
@$(call debug_print_list,$(INCLUDES))
|
||||
|
||||
-include $(OTHER_MAKEFILE_TO_INCLUDE)
|
|
@ -0,0 +1,26 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_connection_handler_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_connection_handler.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_connection_handlertest.cpp \
|
||||
test_coap_connection_handler.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/ns_timer_stub.c \
|
||||
../stub/timeout_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/socket_api_stub.c \
|
||||
../stub/coap_security_handler_stub.c \
|
||||
../stub/coap_service_api_stub.c \
|
||||
../stub/coap_message_handler_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -DHAVE_THREAD
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
#include "CppUTest/TestHarness.h"
|
||||
#include "test_coap_connection_handler.h"
|
||||
|
||||
TEST_GROUP(coap_connection_handler)
|
||||
{
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void teardown()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST(coap_connection_handler, test_connection_handler_create)
|
||||
{
|
||||
CHECK(test_connection_handler_create());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_connection_handler_destroy)
|
||||
{
|
||||
CHECK(test_connection_handler_destroy());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_coap_connection_handler_open_connection)
|
||||
{
|
||||
CHECK(test_coap_connection_handler_open_connection());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_coap_connection_handler_send_data)
|
||||
{
|
||||
CHECK(test_coap_connection_handler_send_data());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_coap_connection_handler_virtual_recv)
|
||||
{
|
||||
CHECK(test_coap_connection_handler_virtual_recv());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_coap_connection_handler_socket_belongs_to)
|
||||
{
|
||||
CHECK(test_coap_connection_handler_socket_belongs_to());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_timer_callbacks)
|
||||
{
|
||||
CHECK(test_timer_callbacks());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_socket_api_callbacks)
|
||||
{
|
||||
CHECK(test_socket_api_callbacks());
|
||||
}
|
||||
|
||||
TEST(coap_connection_handler, test_security_callbacks)
|
||||
{
|
||||
CHECK(test_security_callbacks());
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "CppUTest/CommandLineTestRunner.h"
|
||||
#include "CppUTest/TestPlugin.h"
|
||||
#include "CppUTest/TestRegistry.h"
|
||||
#include "CppUTestExt/MockSupportPlugin.h"
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
return CommandLineTestRunner::RunAllTests(ac, av);
|
||||
}
|
||||
|
||||
IMPORT_TEST_GROUP(coap_connection_handler);
|
||||
|
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "test_coap_connection_handler.h"
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "nsdynmemLIB_stub.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "coap_connection_handler.h"
|
||||
#include "coap_security_handler_stub.h"
|
||||
#include "ns_timer_stub.h"
|
||||
#include "socket_api.h"
|
||||
#include "socket_api_stub.h"
|
||||
#include "net_interface.h"
|
||||
|
||||
int send_to_sock_cb(int8_t socket_id, uint8_t address, uint16_t port, const unsigned char *a, int b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int receive_from_sock_cb(int8_t socket_id, uint8_t address, uint16_t port, unsigned char *a, int b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_passwd_cb(int8_t socket_id, uint8_t address, uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool test_connection_handler_create()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
if( NULL != connection_handler_create(NULL, NULL, NULL, NULL) )
|
||||
return false;
|
||||
|
||||
if( NULL != connection_handler_create(&receive_from_sock_cb, NULL, NULL, NULL) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, NULL, NULL, NULL);
|
||||
if( NULL == handler )
|
||||
return false;
|
||||
ns_dyn_mem_free(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_connection_handler_destroy()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, NULL, NULL, NULL);
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_connection_handler_open_connection()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, NULL, NULL, NULL);
|
||||
|
||||
if( -1 != coap_connection_handler_open_connection(NULL, 0,false,false,false,false) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_open_connection(handler, 0,false,false,false,false) )
|
||||
return false;
|
||||
|
||||
ns_dyn_mem_free(handler);
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
if( -1 != coap_connection_handler_open_connection(handler, 0,true,true,true,false) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 0,true,true,true,false) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,true,true) )
|
||||
return false;
|
||||
|
||||
//open second one
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler2 = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler2, 22,false,true,true,true) )
|
||||
return false;
|
||||
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 23,false,false,false,false) )
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler2);
|
||||
connection_handler_destroy(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_connection_handler_send_data()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
if( -1 != coap_connection_handler_send_data(NULL, NULL, ns_in6addr_any, NULL, 0, false))
|
||||
return false;
|
||||
|
||||
ns_address_t addr;
|
||||
memset(addr.address, 1, 16);
|
||||
addr.identifier = 22;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 4;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,false,false) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
free(coap_security_handler_stub.sec_obj);
|
||||
coap_security_handler_stub.sec_obj = NULL;
|
||||
|
||||
//NON SECURE HERE -->
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,false,false,false) )
|
||||
return false;
|
||||
|
||||
|
||||
if( 1 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,false,true,false) )
|
||||
return false;
|
||||
|
||||
socket_api_stub.int8_value = 7;
|
||||
if( 7 != coap_connection_handler_send_data(handler, &addr, ns_in6addr_any, NULL, 0, true))
|
||||
return false;
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
//<-- NON SECURE HERE
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_connection_handler_virtual_recv()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
if( -1 != coap_connection_handler_virtual_recv(NULL,buf, 12, NULL, 0) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,true,false) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_virtual_recv(handler,buf, 12, NULL, 0) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( -1 != coap_connection_handler_virtual_recv(handler,buf, 12, NULL, 0) )
|
||||
return false;
|
||||
|
||||
ns_timer_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( -1 != coap_connection_handler_virtual_recv(handler,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
//handler->socket->data still in memory
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
ns_timer_stub.int8_value = -1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( -1 != coap_connection_handler_virtual_recv(handler,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
ns_timer_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( -1 != coap_connection_handler_virtual_recv(handler,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler2 = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, &get_passwd_cb, &sec_done_cb);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler2, 24,false,true,true,false) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 0 != coap_connection_handler_virtual_recv(handler2,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_security_handler_stub.int_value = 0;
|
||||
if( 0 != coap_connection_handler_virtual_recv(handler2,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 0 != coap_connection_handler_virtual_recv(handler2,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_security_handler_stub.int_value = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
|
||||
if( 0 != coap_connection_handler_virtual_recv(handler2,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler2);
|
||||
|
||||
free(coap_security_handler_stub.sec_obj);
|
||||
coap_security_handler_stub.sec_obj = NULL;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler3 = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, &get_passwd_cb, &sec_done_cb);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler3, 26,false,false,true,false) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 0 != coap_connection_handler_virtual_recv(handler3,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_connection_handler_socket_belongs_to()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
if( false != coap_connection_handler_socket_belongs_to(NULL, 2) )
|
||||
return false;
|
||||
|
||||
socket_api_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,true,false) )
|
||||
return false;
|
||||
|
||||
if( true != coap_connection_handler_socket_belongs_to(handler, 0) )
|
||||
return false;
|
||||
|
||||
if( false != coap_connection_handler_socket_belongs_to(handler, 3) )
|
||||
return false;
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_timer_callbacks()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,true,false) )
|
||||
return false;
|
||||
|
||||
//handler->socket->data still in memory
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
ns_timer_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
ns_timer_stub.int8_value = 5;
|
||||
if( -1 != coap_connection_handler_virtual_recv(handler,buf, 12, &buf, 1) )
|
||||
return false;
|
||||
|
||||
//Note next tests will affect ns_timer test (cycle & cycle_count
|
||||
if( coap_security_handler_stub.start_timer_cb ){
|
||||
coap_security_handler_stub.start_timer_cb(1, 0, 0);
|
||||
|
||||
coap_security_handler_stub.start_timer_cb(1, 1, 2);
|
||||
}
|
||||
|
||||
if( coap_security_handler_stub.timer_status_cb ){
|
||||
if( -1 != coap_security_handler_stub.timer_status_cb(4) )
|
||||
return false;
|
||||
|
||||
if( 0 != coap_security_handler_stub.timer_status_cb(1) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ns_timer_stub.cb ){
|
||||
ns_timer_stub.cb(4, 0);
|
||||
|
||||
ns_timer_stub.cb(5, 0);
|
||||
|
||||
coap_security_handler_stub.int_value = MBEDTLS_ERR_SSL_TIMEOUT;
|
||||
|
||||
ns_timer_stub.cb(5, 0);
|
||||
coap_security_handler_stub.int_value = 0;
|
||||
}
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
free(coap_security_handler_stub.sec_obj);
|
||||
coap_security_handler_stub.sec_obj = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_socket_api_callbacks()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
|
||||
socket_callback_t *sckt_data = (socket_callback_t *)malloc(sizeof(socket_callback_t));
|
||||
memset(sckt_data, 0, sizeof(socket_callback_t));
|
||||
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
socket_api_stub.int8_value = 0;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,false,true,false) )
|
||||
return false;
|
||||
|
||||
if( socket_api_stub.recv_cb ){
|
||||
sckt_data->event_type = SOCKET_DATA;
|
||||
sckt_data->d_len = 1;
|
||||
socket_api_stub.int8_value = -1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
socket_api_stub.int8_value = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
}
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler2 = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, &get_passwd_cb, &sec_done_cb);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler2, 22,false,true,true,false) )
|
||||
return false;
|
||||
|
||||
if( socket_api_stub.recv_cb ){
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
socket_api_stub.int8_value = 1;
|
||||
sckt_data->socket_id = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
socket_api_stub.int8_value = 1;
|
||||
sckt_data->socket_id = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
socket_api_stub.int8_value = 1;
|
||||
sckt_data->socket_id = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
|
||||
coap_security_handler_stub.int_value = 4;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
socket_api_stub.int8_value = 1;
|
||||
sckt_data->socket_id = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
|
||||
coap_security_handler_stub.int_value = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
socket_api_stub.int8_value = 1;
|
||||
sckt_data->socket_id = 1;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
}
|
||||
|
||||
connection_handler_destroy(handler2);
|
||||
|
||||
free(coap_security_handler_stub.sec_obj);
|
||||
coap_security_handler_stub.sec_obj = NULL;
|
||||
|
||||
free(sckt_data);
|
||||
sckt_data = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_security_callbacks()
|
||||
{
|
||||
coap_security_handler_stub.counter = -1;
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
|
||||
socket_callback_t *sckt_data = (socket_callback_t *)malloc(sizeof(socket_callback_t));
|
||||
memset(sckt_data, 0, sizeof(socket_callback_t));
|
||||
|
||||
coap_security_handler_stub.sec_obj = coap_security_handler_stub_alloc();
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_conn_handler_t *handler = connection_handler_create(&receive_from_sock_cb, &send_to_sock_cb, NULL, NULL);
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_connection_handler_open_connection(handler, 22,false,true,true,false) )
|
||||
return false;
|
||||
|
||||
if( socket_api_stub.recv_cb ){
|
||||
sckt_data->event_type = SOCKET_DATA;
|
||||
sckt_data->d_len = 1;
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
socket_api_stub.int8_value = 1;
|
||||
sckt_data->socket_id = 0;
|
||||
socket_api_stub.recv_cb(sckt_data);
|
||||
}
|
||||
|
||||
if( coap_security_handler_stub.send_cb ){
|
||||
coap_security_handler_stub.send_cb(0, buf, 22, &buf, 16);
|
||||
}
|
||||
if( coap_security_handler_stub.receive_cb ){
|
||||
coap_security_handler_stub.receive_cb(0, &buf, 16);
|
||||
}
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
free(coap_security_handler_stub.sec_obj);
|
||||
coap_security_handler_stub.sec_obj = NULL;
|
||||
|
||||
free(sckt_data);
|
||||
sckt_data = NULL;
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef TEST_COAP_CONNECTION_HANDLER_H
|
||||
#define TEST_COAP_CONNECTION_HANDLER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool test_connection_handler_create();
|
||||
|
||||
bool test_connection_handler_destroy();
|
||||
|
||||
bool test_coap_connection_handler_open_connection();
|
||||
|
||||
bool test_coap_connection_handler_send_data();
|
||||
|
||||
bool test_coap_connection_handler_virtual_recv();
|
||||
|
||||
bool test_coap_connection_handler_socket_belongs_to();
|
||||
|
||||
bool test_timer_callbacks();
|
||||
|
||||
bool test_socket_api_callbacks();
|
||||
|
||||
bool test_security_callbacks();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TEST_COAP_CONNECTION_HANDLER_H
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_message_handler_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_message_handler.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_message_handlertest.cpp \
|
||||
test_coap_message_handler.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/sn_coap_protocol_stub.c \
|
||||
../stub/sn_coap_parser_stub.c \
|
||||
../stub/sn_coap_builder_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/randLIB_stub.c \
|
||||
../stub/coap_service_api_stub.c \
|
||||
../stub/socket_api_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
#include "CppUTest/TestHarness.h"
|
||||
#include "test_coap_message_handler.h"
|
||||
|
||||
TEST_GROUP(coap_message_handler)
|
||||
{
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void teardown()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_init)
|
||||
{
|
||||
CHECK(test_coap_message_handler_init());
|
||||
}
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_destroy)
|
||||
{
|
||||
CHECK(test_coap_message_handler_destroy());
|
||||
}
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_find_transaction)
|
||||
{
|
||||
CHECK(test_coap_message_handler_find_transaction());
|
||||
}
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_coap_msg_process)
|
||||
{
|
||||
CHECK(test_coap_message_handler_coap_msg_process());
|
||||
}
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_request_send)
|
||||
{
|
||||
CHECK(test_coap_message_handler_request_send());
|
||||
}
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_response_send)
|
||||
{
|
||||
CHECK(test_coap_message_handler_response_send());
|
||||
}
|
||||
|
||||
TEST(coap_message_handler, test_coap_message_handler_exec)
|
||||
{
|
||||
CHECK(test_coap_message_handler_exec());
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "CppUTest/CommandLineTestRunner.h"
|
||||
#include "CppUTest/TestPlugin.h"
|
||||
#include "CppUTest/TestRegistry.h"
|
||||
#include "CppUTestExt/MockSupportPlugin.h"
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
return CommandLineTestRunner::RunAllTests(ac, av);
|
||||
}
|
||||
|
||||
IMPORT_TEST_GROUP(coap_message_handler);
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "test_coap_message_handler.h"
|
||||
#include <string.h>
|
||||
#include "coap_message_handler.h"
|
||||
#include "sn_coap_protocol_stub.h"
|
||||
#include "nsdynmemLIB_stub.h"
|
||||
#include "sn_coap_builder_stub.h"
|
||||
#include "sn_coap_parser_stub.h"
|
||||
#include "socket_api.h"
|
||||
|
||||
int retCounter = 0;
|
||||
int retValue = 0;
|
||||
|
||||
static void *own_alloc(uint16_t size)
|
||||
{
|
||||
if( retCounter > 0 ){
|
||||
retCounter--;
|
||||
return malloc(size);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void own_free(void *ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr, void *param)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resp_recv(int8_t service_id, uint16_t msg_id, sn_coap_hdr_s *response_ptr){
|
||||
return retValue;
|
||||
}
|
||||
|
||||
int16_t process_cb(int8_t a, sn_coap_hdr_s *b, coap_transaction_t *c)
|
||||
{
|
||||
return retValue;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_init()
|
||||
{
|
||||
if( NULL != coap_message_handler_init(NULL, NULL, NULL) )
|
||||
return false;
|
||||
if( NULL != coap_message_handler_init(&own_alloc, NULL, NULL) )
|
||||
return false;
|
||||
if( NULL != coap_message_handler_init(&own_alloc, &own_free, NULL) )
|
||||
return false;
|
||||
if( NULL != coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function) )
|
||||
return false;
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
if( NULL != coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function) )
|
||||
return false;
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
free(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_destroy()
|
||||
{
|
||||
if( -1 != coap_message_handler_destroy(NULL) )
|
||||
return false;
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
|
||||
if( 0 != coap_message_handler_destroy(handle) )
|
||||
return false;
|
||||
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_find_transaction()
|
||||
{
|
||||
if( NULL != coap_message_handler_find_transaction(NULL, 0))
|
||||
return false;
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
char uri[3];
|
||||
uri[0] = "r";
|
||||
uri[1] = "s";
|
||||
uri[2] = "\0";
|
||||
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv))
|
||||
return false;
|
||||
|
||||
if( NULL == coap_message_handler_find_transaction(&buf, 24))
|
||||
return false;
|
||||
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
coap_message_handler_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_coap_msg_process()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, ns_in6addr_any, NULL, 0, NULL))
|
||||
return false;
|
||||
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = NULL;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
sn_coap_protocol_stub.expectedHeader->coap_status = 66;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
|
||||
sn_coap_protocol_stub.expectedHeader->msg_code = 1;
|
||||
retValue = 0;
|
||||
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
retValue = -1;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
|
||||
sn_coap_protocol_stub.expectedHeader->msg_code = 333;
|
||||
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
|
||||
sn_coap_protocol_stub.expectedHeader->msg_code = 333;
|
||||
|
||||
char uri[3];
|
||||
uri[0] = "r";
|
||||
uri[1] = "s";
|
||||
uri[2] = "\0";
|
||||
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv))
|
||||
return false;
|
||||
|
||||
sn_coap_protocol_stub.expectedHeader->msg_id = 2;
|
||||
// sn_coap_protocol_stub.expectedHeader->token_ptr = (uint8_t*)malloc(4);
|
||||
// memset(sn_coap_protocol_stub.expectedHeader->token_ptr, 1, 4);
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
// free(sn_coap_protocol_stub.expectedHeader->token_ptr);
|
||||
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
coap_message_handler_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_request_send()
|
||||
{
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
char uri[3];
|
||||
uri[0] = "r";
|
||||
uri[1] = "s";
|
||||
uri[2] = "\0";
|
||||
if( 0 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, NULL))
|
||||
return false;
|
||||
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 0 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, NULL))
|
||||
return false;
|
||||
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 0 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, NULL))
|
||||
return false;
|
||||
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 0 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, NULL))
|
||||
return false;
|
||||
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv))
|
||||
return false;
|
||||
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
coap_message_handler_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_response_send()
|
||||
{
|
||||
if( -1 != coap_message_handler_response_send(NULL, 2, 0, NULL, 1,3,NULL, 0))
|
||||
return false;
|
||||
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
sn_coap_hdr_s *header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(header, 0, sizeof(sn_coap_hdr_s));
|
||||
|
||||
if( -2 != coap_message_handler_response_send(handle, 2, 0, header, 1,3,NULL, 0))
|
||||
return false;
|
||||
|
||||
uint8_t buf[16];
|
||||
memset(&buf, 1, 16);
|
||||
char uri[3];
|
||||
uri[0] = "r";
|
||||
uri[1] = "s";
|
||||
uri[2] = "\0";
|
||||
sn_coap_builder_stub.expectedUint16 = 1;
|
||||
nsdynmemlib_stub.returnCounter = 3;
|
||||
if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv))
|
||||
return false;
|
||||
|
||||
header->msg_id = 2;
|
||||
sn_coap_builder_stub.expectedUint16 = 2;
|
||||
coap_transaction_t * tx = coap_message_handler_find_transaction(&buf, 24);
|
||||
if( tx ){
|
||||
tx->client_request = false;
|
||||
}
|
||||
sn_coap_builder_stub.expectedHeader = NULL;
|
||||
if( -1 != coap_message_handler_response_send(handle, 2, 0, header, 1,3,NULL, 0))
|
||||
return false;
|
||||
|
||||
sn_coap_builder_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_builder_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
nsdynmemlib_stub.returnCounter = 0;
|
||||
if( -1 != coap_message_handler_response_send(handle, 2, 0, header, 1,3,NULL, 0))
|
||||
return false;
|
||||
|
||||
sn_coap_builder_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(sn_coap_builder_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 0 != coap_message_handler_response_send(handle, 2, 0, header, 1,3,NULL, 0))
|
||||
return false;
|
||||
|
||||
// free(header);
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
coap_message_handler_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_message_handler_exec()
|
||||
{
|
||||
if( -1 != coap_message_handler_exec(NULL, 0))
|
||||
return false;
|
||||
retCounter = 1;
|
||||
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
|
||||
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
|
||||
coap_msg_handler_t *handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
|
||||
if( 0 != coap_message_handler_exec(handle, 0))
|
||||
return false;
|
||||
|
||||
free(sn_coap_protocol_stub.expectedCoap);
|
||||
sn_coap_protocol_stub.expectedCoap = NULL;
|
||||
coap_message_handler_destroy(handle);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef TEST_COAP_MESSAGE_HANDLER_H
|
||||
#define TEST_COAP_MESSAGE_HANDLER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool test_coap_message_handler_init();
|
||||
bool test_coap_message_handler_destroy();
|
||||
bool test_coap_message_handler_find_transaction();
|
||||
bool test_coap_message_handler_coap_msg_process();
|
||||
bool test_coap_message_handler_request_send();
|
||||
bool test_coap_message_handler_response_send();
|
||||
bool test_coap_message_handler_exec();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TEST_COAP_MESSAGE_HANDLER_H
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_security_handler_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_security_handler.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_security_handlertest.cpp \
|
||||
test_coap_security_handler.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/ns_timer_stub.c \
|
||||
../stub/mbedtls_stub.c \
|
||||
../stub/randLIB_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/socket_api_stub.c \
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -DMBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED -DMBEDTLS_ECJPAKE_C -DMBEDTLS_SHA256_C -DMBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
#include "CppUTest/TestHarness.h"
|
||||
#include "test_coap_security_handler.h"
|
||||
#include "mbedtls_stub.h"
|
||||
#include "nsdynmemLIB_stub.h"
|
||||
|
||||
TEST_GROUP(coap_security_handler)
|
||||
{
|
||||
void setup()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 0;
|
||||
mbedtls_stub.useCounter = false;
|
||||
}
|
||||
|
||||
void teardown()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST(coap_security_handler, test_thread_security_create)
|
||||
{
|
||||
CHECK(test_thread_security_create());
|
||||
}
|
||||
|
||||
TEST(coap_security_handler, test_thread_security_destroy)
|
||||
{
|
||||
CHECK(test_thread_security_destroy());
|
||||
}
|
||||
|
||||
TEST(coap_security_handler, test_coap_security_handler_connect)
|
||||
{
|
||||
CHECK(test_coap_security_handler_connect());
|
||||
}
|
||||
|
||||
TEST(coap_security_handler, test_coap_security_handler_continue_connecting)
|
||||
{
|
||||
CHECK(test_coap_security_handler_continue_connecting());
|
||||
}
|
||||
|
||||
TEST(coap_security_handler, test_coap_security_handler_send_message)
|
||||
{
|
||||
CHECK(test_coap_security_handler_send_message());
|
||||
}
|
||||
|
||||
TEST(coap_security_handler, test_thread_security_send_close_alert)
|
||||
{
|
||||
CHECK(test_thread_security_send_close_alert());
|
||||
}
|
||||
|
||||
TEST(coap_security_handler, test_coap_security_handler_read)
|
||||
{
|
||||
CHECK(test_coap_security_handler_read());
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "CppUTest/CommandLineTestRunner.h"
|
||||
#include "CppUTest/TestPlugin.h"
|
||||
#include "CppUTest/TestRegistry.h"
|
||||
#include "CppUTestExt/MockSupportPlugin.h"
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
return CommandLineTestRunner::RunAllTests(ac, av);
|
||||
}
|
||||
|
||||
IMPORT_TEST_GROUP(coap_security_handler);
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "test_coap_security_handler.h"
|
||||
#include "coap_security_handler.h"
|
||||
#include <string.h>
|
||||
#include "nsdynmemLIB_stub.h"
|
||||
#include "mbedtls_stub.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
|
||||
static int send_to_socket(int8_t socket_id, void *handle, const unsigned char *buf, size_t len)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void start_timer_callback(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int timer_status_callback(int8_t timer_id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool test_thread_security_create()
|
||||
{
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, NULL) )
|
||||
return false;
|
||||
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
mbedtls_stub.expected_int = -1;
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.expected_int = 0;
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = -1;
|
||||
if( NULL != coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_thread_security_destroy()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_security_handler_connect()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
unsigned char pw = "pwd";
|
||||
coap_security_keys_t keys;
|
||||
keys._priv = &pw;
|
||||
keys._priv_len = 3;
|
||||
if( -1 != coap_security_handler_connect_non_blocking(NULL, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
mbedtls_stub.useCounter = true;
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = -1;
|
||||
mbedtls_stub.retArray[1] = -1;
|
||||
mbedtls_stub.retArray[2] = -1;
|
||||
mbedtls_stub.retArray[3] = -1;
|
||||
mbedtls_stub.retArray[4] = -1;
|
||||
mbedtls_stub.retArray[5] = MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
|
||||
mbedtls_stub.retArray[6] = -1;
|
||||
mbedtls_stub.retArray[7] = -1;
|
||||
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = 0;
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
// mbedtls_stub.retArray[0] = 0;
|
||||
mbedtls_stub.retArray[1] = 0;
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
simple_cookie_t c;
|
||||
memset(&c, 0, sizeof(simple_cookie_t));
|
||||
mbedtls_stub.cookie_obj = &c;
|
||||
memset(&mbedtls_stub.cookie_value, 1, 8);
|
||||
mbedtls_stub.cookie_len = 2;
|
||||
mbedtls_stub.counter = 0;
|
||||
// mbedtls_stub.retArray[0] = 0;
|
||||
// mbedtls_stub.retArray[1] = 0;
|
||||
mbedtls_stub.retArray[2] = 0;
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
c.len = 8;
|
||||
memset(&c.value, 1, 8);
|
||||
mbedtls_stub.cookie_obj = &c;
|
||||
memset(&mbedtls_stub.cookie_value, 1, 8);
|
||||
|
||||
mbedtls_stub.cookie_len = 8;
|
||||
mbedtls_stub.counter = 0;
|
||||
// mbedtls_stub.retArray[0] = 0;
|
||||
// mbedtls_stub.retArray[1] = 0;
|
||||
// mbedtls_stub.retArray[2] = 0;
|
||||
mbedtls_stub.retArray[3] = 0;
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
// mbedtls_stub.retArray[0] = 0;
|
||||
// mbedtls_stub.retArray[1] = 0;
|
||||
// mbedtls_stub.retArray[2] = 0;
|
||||
// mbedtls_stub.retArray[3] = 0;
|
||||
mbedtls_stub.retArray[4] = 0;
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
// mbedtls_stub.retArray[0] = 0;
|
||||
// mbedtls_stub.retArray[1] = 0;
|
||||
// mbedtls_stub.retArray[2] = 0;
|
||||
// mbedtls_stub.retArray[3] = 0;
|
||||
// mbedtls_stub.retArray[4] = 0;
|
||||
mbedtls_stub.retArray[6] = 0;
|
||||
mbedtls_stub.retArray[7] = 0;
|
||||
if( 1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[5] = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
|
||||
|
||||
if( -1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[5] = HANDSHAKE_FINISHED_VALUE;
|
||||
|
||||
if( 1 != coap_security_handler_connect_non_blocking(handle, true, DTLS, keys, 0, 1) )
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_security_handler_continue_connecting()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.useCounter = true;
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
|
||||
mbedtls_stub.retArray[1] = -1;
|
||||
mbedtls_stub.retArray[2] = -1;
|
||||
|
||||
if( -1 != coap_security_handler_continue_connecting(handle) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
|
||||
mbedtls_stub.retArray[1] = 0;
|
||||
mbedtls_stub.retArray[2] = 0;
|
||||
|
||||
if( 1 != coap_security_handler_continue_connecting(handle) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
|
||||
|
||||
if( MBEDTLS_ERR_SSL_BAD_HS_FINISHED != coap_security_handler_continue_connecting(handle) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = MBEDTLS_ERR_SSL_WANT_READ;
|
||||
|
||||
if( 1 != coap_security_handler_continue_connecting(handle) )
|
||||
return false;
|
||||
|
||||
mbedtls_stub.counter = 0;
|
||||
mbedtls_stub.retArray[0] = HANDSHAKE_FINISHED_VALUE_RETURN_ZERO;
|
||||
|
||||
if( 0 != coap_security_handler_continue_connecting(handle) )
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_security_handler_send_message()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_security_handler_send_message(NULL, NULL, 0))
|
||||
return false;
|
||||
|
||||
mbedtls_stub.expected_int = 6;
|
||||
unsigned char cbuf[6];
|
||||
if( 6 != coap_security_handler_send_message(handle, &cbuf, 6))
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_thread_security_send_close_alert()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_security_send_close_alert(NULL))
|
||||
return false;
|
||||
|
||||
mbedtls_stub.expected_int = 0;
|
||||
if( 0 != coap_security_send_close_alert(handle))
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_security_handler_read()
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,NULL,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, &timer_status_callback);
|
||||
if( NULL == handle )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_security_handler_read(NULL, NULL, 0))
|
||||
return false;
|
||||
|
||||
mbedtls_stub.expected_int = 6;
|
||||
unsigned char cbuf[6];
|
||||
if( 6 != coap_security_handler_read(handle, &cbuf, 6))
|
||||
return false;
|
||||
|
||||
coap_security_destroy(handle);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef TEST_COAP_SECURITY_HANDLER_H
|
||||
#define TEST_COAP_SECURITY_HANDLER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
bool test_thread_security_create();
|
||||
|
||||
bool test_thread_security_destroy();
|
||||
|
||||
bool test_coap_security_handler_connect();
|
||||
|
||||
bool test_coap_security_handler_continue_connecting();
|
||||
|
||||
bool test_coap_security_handler_send_message();
|
||||
|
||||
bool test_thread_security_send_close_alert();
|
||||
|
||||
bool test_coap_security_handler_read();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TEST_COAP_SECURITY_HANDLER_H
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
include ../makefile_defines.txt
|
||||
|
||||
COMPONENT_NAME = coap_service_api_unit
|
||||
|
||||
#This must be changed manually
|
||||
SRC_FILES = \
|
||||
../../../../source/coap_service_api.c
|
||||
|
||||
TEST_SRC_FILES = \
|
||||
main.cpp \
|
||||
coap_service_apitest.cpp \
|
||||
test_coap_service_api.c \
|
||||
../stub/mbed_trace_stub.c \
|
||||
../stub/ns_list_stub.c \
|
||||
../stub/system_timer_stub.c \
|
||||
../stub/nsdynmemLIB_stub.c \
|
||||
../stub/eventOS_event_stub.c \
|
||||
../stub/coap_connection_handler_stub.c \
|
||||
../stub/coap_message_handler_stub.c \
|
||||
../stub/common_functions_stub.c
|
||||
|
||||
include ../MakefileWorker.mk
|
||||
|
||||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
#include "CppUTest/TestHarness.h"
|
||||
#include "test_coap_service_api.h"
|
||||
|
||||
TEST_GROUP(coap_service_api)
|
||||
{
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void teardown()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST(coap_service_api, test_coap_service_initialize)
|
||||
{
|
||||
CHECK(test_coap_service_initialize());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_delete)
|
||||
{
|
||||
CHECK(test_coap_service_delete());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_virtual_socket_recv)
|
||||
{
|
||||
CHECK(test_coap_service_virtual_socket_recv());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_virtual_socket_set_cb)
|
||||
{
|
||||
CHECK(test_coap_service_virtual_socket_set_cb());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_register_uri)
|
||||
{
|
||||
CHECK(test_coap_service_register_uri());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_unregister_uri)
|
||||
{
|
||||
CHECK(test_coap_service_unregister_uri());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_request_send)
|
||||
{
|
||||
CHECK(test_coap_service_request_send());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_service_response_send)
|
||||
{
|
||||
CHECK(test_coap_service_response_send());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_coap_callbacks)
|
||||
{
|
||||
CHECK(test_coap_callbacks());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_eventOS_callbacks)
|
||||
{
|
||||
CHECK(test_eventOS_callbacks());
|
||||
}
|
||||
|
||||
TEST(coap_service_api, test_conn_handler_callbacks)
|
||||
{
|
||||
CHECK(test_conn_handler_callbacks());
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "CppUTest/CommandLineTestRunner.h"
|
||||
#include "CppUTest/TestPlugin.h"
|
||||
#include "CppUTest/TestRegistry.h"
|
||||
#include "CppUTestExt/MockSupportPlugin.h"
|
||||
int main(int ac, char** av)
|
||||
{
|
||||
return CommandLineTestRunner::RunAllTests(ac, av);
|
||||
}
|
||||
|
||||
IMPORT_TEST_GROUP(coap_service_api);
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "test_coap_service_api.h"
|
||||
#include <string.h>
|
||||
#include "coap_service_api.h"
|
||||
#include "nsdynmemLIB_stub.h"
|
||||
#include "coap_connection_handler_stub.h"
|
||||
#include "coap_message_handler_stub.h"
|
||||
#include "eventOS_event_stub.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "net_interface.h"
|
||||
|
||||
int sec_done_cb(int8_t service_id, uint8_t address[static 16], uint8_t keyblock[static 40]){
|
||||
return 2;
|
||||
}
|
||||
|
||||
int sec_start_cb(int8_t service_id, uint8_t address[static 16], uint16_t port, uint8_t* pw, uint8_t *pw_len)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int request_recv_cb(int8_t service_id, uint8_t source_address[static 16], uint16_t source_port, sn_coap_hdr_s *request_ptr)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int virtual_sock_send_cb(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port, const uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool test_coap_service_initialize()
|
||||
{
|
||||
if( -1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
if( -1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
thread_conn_handler_stub.int_value = -1;
|
||||
if( -1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
thread_conn_handler_stub.int_value = 0;
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 2 != coap_service_initialize(3, 4, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
coap_service_delete(2);
|
||||
coap_service_delete(1);
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_delete()
|
||||
{
|
||||
coap_service_delete(1);
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
coap_service_delete(1);
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_virtual_socket_recv()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
if( -1 != coap_service_virtual_socket_recv(1, &buf, 10, NULL, 0) )
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.int_value = 5;
|
||||
if( 5 != coap_service_virtual_socket_recv(1, &buf, 10, NULL, 0) )
|
||||
return false;
|
||||
|
||||
coap_service_delete(1);
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
thread_conn_handler_stub.int_value = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_virtual_socket_set_cb()
|
||||
{
|
||||
if( -1 != coap_service_virtual_socket_set_cb(1, NULL) )
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
if( 0 != coap_service_virtual_socket_set_cb(1, NULL) )
|
||||
return false;
|
||||
|
||||
coap_service_delete(1);
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_register_uri()
|
||||
{
|
||||
if( -1 != coap_service_register_uri(1, "as", 1, &request_recv_cb))
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
if( -2 != coap_service_register_uri(1, "as", 1, &request_recv_cb) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( -2 != coap_service_register_uri(1, "as", 1, &request_recv_cb) )
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_service_register_uri(1, "as", 1, &request_recv_cb) )
|
||||
return false;
|
||||
|
||||
coap_service_delete(1);
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_unregister_uri()
|
||||
{
|
||||
if( -1 != coap_service_unregister_uri(1, "as"))
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
thread_conn_handler_stub.int_value = 0;
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_service_register_uri(1, "as", 1, &request_recv_cb) )
|
||||
return false;
|
||||
|
||||
if( -2 != coap_service_unregister_uri(1, "ts") )
|
||||
return false;
|
||||
|
||||
if( 0 != coap_service_unregister_uri(1, "as") )
|
||||
return false;
|
||||
|
||||
coap_service_delete(1);
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_request_send()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
coap_message_handler_stub.uint16_value = 6;
|
||||
if( 6 != coap_service_request_send(0,0,&buf,0,0,0,NULL, 0,NULL,0,NULL))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_service_response_send()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
coap_message_handler_stub.int8_value = 6;
|
||||
if( 6 != coap_service_response_send(0,0,NULL, 65, 0,NULL, 0))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_coap_callbacks()
|
||||
{
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
coap_message_handler_stub.coap_ptr = (coap_msg_handler_t *)malloc(sizeof(coap_msg_handler_t));
|
||||
memset(coap_message_handler_stub.coap_ptr, 0, sizeof(coap_msg_handler_t));
|
||||
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
if( 0 != coap_message_handler_stub.coap_ptr->sn_coap_service_malloc(0))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
void *handle = coap_message_handler_stub.coap_ptr->sn_coap_service_malloc(5);
|
||||
if( 0 == handle )
|
||||
return false;
|
||||
|
||||
coap_message_handler_stub.coap_ptr->sn_coap_service_free(handle);
|
||||
|
||||
//coap_tx_function
|
||||
uint8_t data[14];
|
||||
memset(&data, 3, 14);
|
||||
sn_nsdl_addr_s addr;
|
||||
addr.addr_len = 2;
|
||||
addr.port = 4;
|
||||
addr.addr_ptr = &data;
|
||||
if( 255 != coap_message_handler_stub.coap_ptr->sn_coap_tx_callback(NULL, 0, &addr, NULL))
|
||||
return false;
|
||||
|
||||
coap_transaction_t *tr = (coap_transaction_t *)malloc(sizeof(coap_transaction_t));
|
||||
memset(tr, 0, sizeof(coap_transaction_t));
|
||||
|
||||
if( 255 != coap_message_handler_stub.coap_ptr->sn_coap_tx_callback(&data, 0, &addr, tr))
|
||||
return false;
|
||||
|
||||
tr->service_id = 1;
|
||||
thread_conn_handler_stub.int_value = -2;
|
||||
if( 255 != coap_message_handler_stub.coap_ptr->sn_coap_tx_callback(&data, 0, &addr, tr))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 255 != coap_message_handler_stub.coap_ptr->sn_coap_tx_callback(&data, 2, &addr, tr))
|
||||
return false;
|
||||
|
||||
free(tr->data_ptr);
|
||||
free(tr);
|
||||
|
||||
coap_service_delete(1);
|
||||
|
||||
free( coap_message_handler_stub.coap_ptr );
|
||||
coap_message_handler_stub.coap_ptr = NULL;
|
||||
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define COAP_TICK_TIMER 0xf1 //MUST BE SAME AS IN coap_service_api.c
|
||||
bool test_eventOS_callbacks()
|
||||
{
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 1 != coap_service_initialize(1, 2, 0, NULL, NULL ))
|
||||
return false;
|
||||
|
||||
if( eventOs_event_stub.event_ptr ){
|
||||
arm_event_s event;
|
||||
event.event_type = ARM_LIB_TASKLET_INIT_EVENT;
|
||||
eventOs_event_stub.event_ptr(&event);
|
||||
|
||||
event.event_type = ARM_LIB_SYSTEM_TIMER_EVENT;
|
||||
event.event_id = COAP_TICK_TIMER;
|
||||
eventOs_event_stub.event_ptr(&event);
|
||||
}
|
||||
|
||||
coap_service_delete(1);
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_conn_handler_callbacks()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
thread_conn_handler_stub.handler_obj = (coap_conn_handler_t*)malloc(sizeof(coap_conn_handler_t));
|
||||
memset(thread_conn_handler_stub.handler_obj, 0, sizeof(coap_conn_handler_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 1 != coap_service_initialize(1, 2, COAP_SERVICE_OPTIONS_SECURE_BYPASS, &sec_start_cb, &sec_done_cb ))
|
||||
return false;
|
||||
|
||||
if( thread_conn_handler_stub.send_to_sock_cb ){
|
||||
thread_conn_handler_stub.bool_value = true;
|
||||
coap_service_virtual_socket_set_cb(1, &virtual_sock_send_cb);
|
||||
if( 2 != thread_conn_handler_stub.send_to_sock_cb(1, buf, 12, NULL, 0))
|
||||
return false;
|
||||
thread_conn_handler_stub.bool_value = false;
|
||||
if( -1 != thread_conn_handler_stub.send_to_sock_cb(1, buf, 12, NULL, 0))
|
||||
return false;
|
||||
}
|
||||
|
||||
if( thread_conn_handler_stub.receive_from_sock_cb ){
|
||||
coap_message_handler_stub.int16_value = 2;
|
||||
if( -1 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, NULL, 0))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
uint8_t * ptr = ns_dyn_mem_alloc(5);
|
||||
memset(ptr, 3, 5);
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( 2 != thread_conn_handler_stub.receive_from_sock_cb(1, buf, 12, NULL, ptr, 5))
|
||||
return false;
|
||||
ns_dyn_mem_free(ptr);
|
||||
coap_message_handler_stub.int16_value = 0;
|
||||
|
||||
//This could be moved to own test function,
|
||||
//but thread_conn_handler_stub.receive_from_sock_cb must be called successfully
|
||||
if( coap_message_handler_stub.cb ){
|
||||
if( -1 != coap_message_handler_stub.cb(1, NULL, NULL) )
|
||||
return false;
|
||||
|
||||
sn_coap_hdr_s * coap = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
|
||||
memset(coap, 0, sizeof(sn_coap_hdr_s));
|
||||
|
||||
uint8_t uri[2] = "as";
|
||||
coap->uri_path_ptr = &uri;
|
||||
coap->uri_path_len=2;
|
||||
|
||||
if( -1 != coap_message_handler_stub.cb(1, coap, NULL) )
|
||||
return false;
|
||||
|
||||
thread_conn_handler_stub.bool_value = true;
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
if( 0 != coap_service_register_uri(1, "as", 1, &request_recv_cb) )
|
||||
return false;
|
||||
|
||||
if( -1 != coap_message_handler_stub.cb(1, coap, NULL) )
|
||||
return false;
|
||||
|
||||
coap_transaction_t *tr = (coap_transaction_t *)malloc(sizeof(coap_transaction_t));
|
||||
memset(tr, 0, sizeof(coap_transaction_t));
|
||||
|
||||
if( 2 != coap_message_handler_stub.cb(1, coap, tr) )
|
||||
return false;
|
||||
|
||||
free(tr);
|
||||
tr = NULL;
|
||||
|
||||
thread_conn_handler_stub.bool_value = false;
|
||||
free(coap);
|
||||
coap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(thread_conn_handler_stub.get_passwd_cb){
|
||||
thread_conn_handler_stub.bool_value = true;
|
||||
if( 2 != thread_conn_handler_stub.get_passwd_cb(1, buf, 12, NULL, 0))
|
||||
return false;
|
||||
thread_conn_handler_stub.bool_value = false;
|
||||
if( -1 != thread_conn_handler_stub.get_passwd_cb(1, buf, 12, NULL, 0))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(thread_conn_handler_stub.sec_done_cb){
|
||||
uint8_t block[40];
|
||||
thread_conn_handler_stub.bool_value = true;
|
||||
|
||||
coap_transaction_t *tr = (coap_transaction_t *)malloc(sizeof(coap_transaction_t));
|
||||
memset(tr, 0, sizeof(coap_transaction_t));
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
tr->data_ptr = ns_dyn_mem_alloc(1);
|
||||
tr->data_len = 1;
|
||||
coap_message_handler_stub.coap_tx_ptr = tr;
|
||||
|
||||
thread_conn_handler_stub.sec_done_cb(1, buf, 12, block);
|
||||
|
||||
free(tr);
|
||||
coap_message_handler_stub.coap_tx_ptr = NULL;
|
||||
|
||||
thread_conn_handler_stub.bool_value = false;
|
||||
|
||||
}
|
||||
|
||||
coap_service_delete(1);
|
||||
free( thread_conn_handler_stub.handler_obj );
|
||||
thread_conn_handler_stub.handler_obj = NULL;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef TEST_COAP_SERVICE_API_H
|
||||
#define TEST_COAP_SERVICE_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool test_coap_service_initialize();
|
||||
|
||||
bool test_coap_service_delete();
|
||||
|
||||
bool test_coap_service_virtual_socket_recv();
|
||||
|
||||
bool test_coap_service_virtual_socket_set_cb();
|
||||
|
||||
bool test_coap_service_register_uri();
|
||||
|
||||
bool test_coap_service_unregister_uri();
|
||||
|
||||
bool test_coap_service_request_send();
|
||||
|
||||
bool test_coap_service_response_send();
|
||||
|
||||
bool test_coap_callbacks();
|
||||
|
||||
bool test_eventOS_callbacks();
|
||||
|
||||
bool test_conn_handler_callbacks();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TEST_COAP_SERVICE_API_H
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#--- Inputs ----#
|
||||
CPPUTEST_HOME = /usr
|
||||
CPPUTEST_USE_EXTENSIONS = Y
|
||||
CPPUTEST_USE_VPATH = Y
|
||||
CPPUTEST_USE_GCOV = Y
|
||||
CPP_PLATFORM = gcc
|
||||
|
||||
INCLUDE_DIRS =\
|
||||
.\
|
||||
../stub\
|
||||
../../../../coap-service/\
|
||||
../../../../source/include/\
|
||||
../../../../yotta_modules/mbedtls/ \
|
||||
../../../../yotta_modules/sal-stack-nanostack/nanostack/ \
|
||||
../../../../yotta_modules/nanostack-randlib/mbed-client-randlib/ \
|
||||
../../../../yotta_modules/nanostack-libservice/ \
|
||||
../../../../yotta_modules/nanostack-libservice/mbed-client-libservice/ \
|
||||
../../../../yotta_modules/mbed-client-c/nsdl-c/ \
|
||||
../../../../yotta_modules/mbed-client-c/source/libCoap/src/include/ \
|
||||
../../../../yotta_modules/sal-stack-nanostack-eventloop/nanostack-event-loop/ \
|
||||
../../../../yotta_modules/sal-stack-nanostack-eventloop/source/ \
|
||||
../../../../yotta_modules/mbed-trace/ \
|
||||
../../../../../nanostack/nanostack/\
|
||||
../../../../../libService/libService/\
|
||||
../../../../../nsdl-c/nsdl-c/\
|
||||
../../../../../nsdl-c/source/libCoap/src/include/\
|
||||
../../../../../event-loop/nanostack-event-loop/\
|
||||
../../../../../event-loop/source/ \
|
||||
../../../../../mbedtls/include/ \
|
||||
../../../../../mbedtls/include/mbedtls/ \
|
||||
/usr/include\
|
||||
$(CPPUTEST_HOME)/include\
|
||||
|
||||
CPPUTESTFLAGS = -D__thumb2__ -w
|
||||
CPPUTEST_CFLAGS += -std=gnu99 -DNS_USE_EXTERNAL_MBED_TLS
|
||||
|
||||
#if you need to use -std=c++11 or c++0x you need to uncomment this
|
||||
#CPPUTESTFLAGS += -DCPPUTEST_STD_CPP_LIB_DISABLED
|
||||
#CPPUTEST_CXXFLAGS += -std=gnu++0x
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
echo
|
||||
echo Build Coap-service unit tests
|
||||
echo
|
||||
|
||||
# Remember to add new test folder to Makefile
|
||||
make clean
|
||||
make all
|
||||
|
||||
echo
|
||||
echo Create results
|
||||
echo
|
||||
mkdir results
|
||||
find ./ -name '*.xml' | xargs cp -t ./results/
|
||||
|
||||
echo
|
||||
echo Create coverage document
|
||||
echo
|
||||
mkdir coverages
|
||||
cd coverages
|
||||
|
||||
lcov -q -d ../. -c -o app.info
|
||||
lcov -q -r app.info "/test*" -o app.info
|
||||
lcov -q -r app.info "/usr*" -o app.info
|
||||
lcov -q -r app.info "/libService*" -o app.info
|
||||
lcov -q -r app.info "/yotta_modules*" -o app.info
|
||||
genhtml -q --no-branch-coverage app.info
|
||||
cd ..
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo Have a nice bug hunt!
|
||||
echo
|
||||
echo
|
||||
echo
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "coap_connection_handler.h"
|
||||
#include "coap_security_handler.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "socket_api.h"
|
||||
#include "net_interface.h"
|
||||
#include "eventOS_callback_timer.h"
|
||||
#include "coap_connection_handler_stub.h"
|
||||
|
||||
thread_conn_handler_stub_def thread_conn_handler_stub;
|
||||
|
||||
int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t address[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
return thread_conn_handler_stub.int_value;
|
||||
}
|
||||
|
||||
coap_conn_handler_t *connection_handler_create(int (*recv_cb)(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *, int),
|
||||
int (*send_cb)(int8_t socket_id, uint8_t const address[static 16], uint16_t port, const void *, int),
|
||||
int (*pw_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len),
|
||||
void(*done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static KEY_BLOCK_LEN]) )
|
||||
{
|
||||
thread_conn_handler_stub.send_to_sock_cb = send_cb;
|
||||
thread_conn_handler_stub.receive_from_sock_cb = recv_cb;
|
||||
thread_conn_handler_stub.get_passwd_cb = pw_cb;
|
||||
thread_conn_handler_stub.sec_done_cb = done_cb;
|
||||
return thread_conn_handler_stub.handler_obj;
|
||||
}
|
||||
|
||||
void connection_handler_destroy(coap_conn_handler_t *handler)
|
||||
{
|
||||
|
||||
}
|
||||
void connection_handler_close_secure_connection( coap_conn_handler_t *handler, uint8_t destination_addr_ptr[static 16], uint16_t port )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool is_real_socket, bool bypassSec)
|
||||
{
|
||||
return thread_conn_handler_stub.int_value;
|
||||
}
|
||||
|
||||
int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_address_t *dest_addr, const uint8_t dst_address[static 16], uint8_t *data_ptr, uint16_t data_len, bool bypass_link_sec)
|
||||
{
|
||||
return thread_conn_handler_stub.int_value;
|
||||
}
|
||||
|
||||
bool coap_connection_handler_socket_belongs_to(coap_conn_handler_t *handler, int8_t socket_id)
|
||||
{
|
||||
return thread_conn_handler_stub.bool_value;
|
||||
}
|
||||
|
||||
int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_t min, uint32_t max)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void coap_connection_handler_exec(uint32_t time)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __COAP_CONNECTION_HANDLER_STUB_H__
|
||||
#define __COAP_CONNECTION_HANDLER_STUB_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "coap_connection_handler.h"
|
||||
|
||||
typedef struct {
|
||||
int int_value;
|
||||
bool bool_value;
|
||||
coap_conn_handler_t *handler_obj;
|
||||
|
||||
int (*send_to_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const void *, int);
|
||||
int (*receive_from_sock_cb)(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len);
|
||||
int (*get_passwd_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t *pw_len);
|
||||
void (*sec_done_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]);
|
||||
|
||||
} thread_conn_handler_stub_def;
|
||||
|
||||
extern thread_conn_handler_stub_def thread_conn_handler_stub;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "coap_message_handler_stub.h"
|
||||
|
||||
coap_message_handler_stub_def coap_message_handler_stub;
|
||||
|
||||
coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
|
||||
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *))
|
||||
{
|
||||
if(coap_message_handler_stub.coap_ptr){
|
||||
coap_message_handler_stub.coap_ptr->sn_coap_service_malloc = used_malloc_func_ptr;
|
||||
coap_message_handler_stub.coap_ptr->sn_coap_service_free = used_free_func_ptr;
|
||||
coap_message_handler_stub.coap_ptr->sn_coap_tx_callback = used_tx_callback_ptr;
|
||||
}
|
||||
return coap_message_handler_stub.coap_ptr;
|
||||
}
|
||||
|
||||
void transaction_delete(coap_transaction_t *this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void transactions_delete_all(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
|
||||
}
|
||||
int8_t coap_message_handler_destroy(coap_msg_handler_t *handle)
|
||||
{
|
||||
return coap_message_handler_stub.int8_value;
|
||||
}
|
||||
|
||||
coap_transaction_t *coap_message_handler_transaction_valid(coap_transaction_t *tr_ptr)
|
||||
{
|
||||
return coap_message_handler_stub.coap_ptr;
|
||||
}
|
||||
|
||||
coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port)
|
||||
{
|
||||
return coap_message_handler_stub.coap_tx_ptr;
|
||||
}
|
||||
|
||||
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
|
||||
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
|
||||
{
|
||||
coap_message_handler_stub.cb = cb;
|
||||
return coap_message_handler_stub.int16_value;
|
||||
}
|
||||
|
||||
uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options,
|
||||
const uint8_t destination_addr[static 16], uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code,
|
||||
const char *uri, sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_message_handler_response_recv *request_response_cb)
|
||||
{
|
||||
return coap_message_handler_stub.uint16_value;
|
||||
}
|
||||
|
||||
int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code,sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len)
|
||||
{
|
||||
return coap_message_handler_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time)
|
||||
{
|
||||
return coap_message_handler_stub.int8_value;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __COAP_MESSAGE_HANDLER_STUB_H__
|
||||
#define __COAP_MESSAGE_HANDLER_STUB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "coap_message_handler.h"
|
||||
|
||||
typedef struct {
|
||||
int8_t int8_value;
|
||||
int16_t int16_value;
|
||||
uint16_t uint16_value;
|
||||
coap_msg_handler_t *coap_ptr;
|
||||
coap_transaction_t *coap_tx_ptr;
|
||||
int16_t (*cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *);
|
||||
} coap_message_handler_stub_def;
|
||||
|
||||
extern coap_message_handler_stub_def coap_message_handler_stub;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __COAP_MESSAGE_HANDLER_STUB_H__
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_connection_handler.h"
|
||||
#include "coap_security_handler_stub.h"
|
||||
|
||||
thread_sec_def coap_security_handler_stub;
|
||||
|
||||
struct coap_security_s {
|
||||
bool _is_started;
|
||||
};
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle, SecureConnectionMode mode,
|
||||
int (*send_cb)(int8_t socket_id, void *handle, const void *, size_t),
|
||||
int (*receive_cb)(int8_t socket_id, unsigned char *, size_t),
|
||||
void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin),
|
||||
int (*timer_status_cb)(int8_t timer_id))
|
||||
{
|
||||
coap_security_handler_stub.send_cb = send_cb;
|
||||
coap_security_handler_stub.receive_cb = receive_cb;
|
||||
coap_security_handler_stub.start_timer_cb = start_timer_cb;
|
||||
coap_security_handler_stub.timer_status_cb = timer_status_cb;
|
||||
return coap_security_handler_stub.sec_obj;
|
||||
}
|
||||
|
||||
coap_security_t *coap_security_handler_stub_alloc(void)
|
||||
{
|
||||
return calloc(1, sizeof(coap_security_t));
|
||||
}
|
||||
|
||||
|
||||
void coap_security_destroy(coap_security_t *sec)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int coap_security_handler_connect_non_blocking(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys, uint32_t timeout_min, uint32_t timeout_max)
|
||||
{
|
||||
sec->_is_started = true;
|
||||
if( coap_security_handler_stub.counter >= 0){
|
||||
return coap_security_handler_stub.values[coap_security_handler_stub.counter--];
|
||||
}
|
||||
return coap_security_handler_stub.int_value;
|
||||
}
|
||||
|
||||
int coap_security_handler_continue_connecting(coap_security_t *sec)
|
||||
{
|
||||
if( coap_security_handler_stub.counter >= 0){
|
||||
return coap_security_handler_stub.values[coap_security_handler_stub.counter--];
|
||||
}
|
||||
|
||||
return coap_security_handler_stub.int_value;
|
||||
}
|
||||
|
||||
|
||||
int coap_security_handler_send_message(coap_security_t *sec, unsigned char *message, size_t len)
|
||||
{
|
||||
if( coap_security_handler_stub.counter >= 0){
|
||||
return coap_security_handler_stub.values[coap_security_handler_stub.counter--];
|
||||
}
|
||||
return coap_security_handler_stub.int_value;
|
||||
}
|
||||
|
||||
int coap_security_send_close_alert(coap_security_t *sec)
|
||||
{
|
||||
if( coap_security_handler_stub.counter >= 0){
|
||||
return coap_security_handler_stub.values[coap_security_handler_stub.counter--];
|
||||
}
|
||||
return coap_security_handler_stub.int_value;
|
||||
}
|
||||
|
||||
int coap_security_handler_read(coap_security_t *sec, unsigned char* buffer, size_t len)
|
||||
{
|
||||
if( coap_security_handler_stub.counter >= 0){
|
||||
return coap_security_handler_stub.values[coap_security_handler_stub.counter--];
|
||||
}
|
||||
return coap_security_handler_stub.int_value;
|
||||
}
|
||||
|
||||
bool coap_security_handler_is_started(const coap_security_t *sec)
|
||||
{
|
||||
return sec->_is_started;
|
||||
}
|
||||
|
||||
const void *coap_security_handler_keyblock(const coap_security_t *sec)
|
||||
{
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __COAP_SECURITY_HANDLER_STUB_H__
|
||||
#define __COAP_SECURITY_HANDLER_STUB_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "coap_security_handler.h"
|
||||
|
||||
typedef struct tsh{
|
||||
coap_security_t *sec_obj;
|
||||
int int_value;
|
||||
int counter;
|
||||
int values[10];
|
||||
|
||||
int (*send_cb)(int8_t socket_id, const uint8_t *address_ptr, uint16_t port, const void *, size_t);
|
||||
int (*receive_cb)(int8_t socket_id, unsigned char *, size_t);
|
||||
void (*start_timer_cb)(int8_t timer_id, uint32_t min, uint32_t fin);
|
||||
int (*timer_status_cb)(int8_t timer_id);
|
||||
} thread_sec_def;
|
||||
|
||||
extern thread_sec_def coap_security_handler_stub;
|
||||
|
||||
coap_security_t *coap_security_handler_stub_alloc(void);
|
||||
|
||||
#endif //__COAP_SECURITY_HANDLER_STUB_H__
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "coap_service_api.h"
|
||||
#include "coap_message_handler.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_scheduler.h"
|
||||
#include "eventOS_event_timer.h"
|
||||
#include "common_functions.h"
|
||||
#include "net_interface.h"
|
||||
|
||||
coap_msg_handler_t *coap_service_handle = NULL;
|
||||
|
||||
int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options,
|
||||
coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void coap_service_delete(int8_t service_id)
|
||||
{
|
||||
}
|
||||
|
||||
int16_t coap_service_virtual_socket_recv(int8_t service_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_service_virtual_socket_send_cb *send_method_ptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_service_register_uri(int8_t service_id, const char *uri, uint8_t allowed_method, coap_service_request_recv_cb *request_recv_cb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_service_unregister_uri(int8_t service_id, const char *uri)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t coap_service_request_send(int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16], uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri, sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_service_response_recv *request_response_cb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t coap_service_get_internal_timer_ticks(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t coap_service_id_find_by_socket(int8_t socket_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "ns_types.h"
|
||||
|
||||
uint16_t common_read_16_bit(const uint8_t data_buf[__static 2])
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ns_types.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_event_stub.h"
|
||||
|
||||
eventOs_event_stub_def eventOs_event_stub;
|
||||
|
||||
int8_t eventOS_event_send(arm_event_s *event)
|
||||
{
|
||||
return eventOs_event_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uint8_t init_event_type)
|
||||
{
|
||||
eventOs_event_stub.event_ptr = handler_func_ptr;
|
||||
return eventOs_event_stub.int8_value;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __EVENTOS_EVENT_STUB_H__
|
||||
#define __EVENTOS_EVENT_STUB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "eventOS_event.h"
|
||||
|
||||
typedef struct {
|
||||
void (*event_ptr)(arm_event_s *);
|
||||
int8_t int8_value;
|
||||
} eventOs_event_stub_def;
|
||||
|
||||
extern eventOs_event_stub_def eventOs_event_stub;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __EVENTOS_EVENT_STUB_H__
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef YOTTA_CFG_MBED_TRACE
|
||||
#define YOTTA_CFG_MBED_TRACE 1
|
||||
#define YOTTA_CFG_MBED_TRACE_FEA_IPV6 1
|
||||
#endif
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
#if YOTTA_CFG_MBED_TRACE_FEA_IPV6 == 1
|
||||
#include "mbed-client-libservice/ip6string.h"
|
||||
#include "mbed-client-libservice/common_functions.h"
|
||||
#endif
|
||||
|
||||
|
||||
int mbed_trace_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void mbed_trace_free(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mbed_trace_buffer_sizes(int lineLength, int tmpLength)
|
||||
{
|
||||
}
|
||||
|
||||
void mbed_trace_config_set(uint8_t config)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t mbed_trace_config_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbed_trace_prefix_function_set(char *(*pref_f)(size_t))
|
||||
{
|
||||
}
|
||||
|
||||
void mbed_trace_suffix_function_set(char *(*suffix_f)(void))
|
||||
{
|
||||
}
|
||||
|
||||
void mbed_trace_print_function_set(void (*printf)(const char *))
|
||||
{
|
||||
}
|
||||
|
||||
void mbed_trace_cmdprint_function_set(void (*printf)(const char *))
|
||||
{
|
||||
}
|
||||
|
||||
void mbed_trace_exclude_filters_set(char *filters)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char *mbed_trace_exclude_filters_get(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *mbed_trace_include_filters_get(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mbed_trace_include_filters_set(char *filters)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
|
||||
const char *mbed_trace_last(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Helping functions */
|
||||
#define tmp_data_left() m_trace.tmp_data_length-(m_trace.tmp_data_ptr-m_trace.tmp_data)
|
||||
#if YOTTA_CFG_MBED_TRACE_FEA_IPV6 == 1
|
||||
char *mbed_trace_ipv6(const void *addr_ptr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif //YOTTA_CFG_MBED_TRACE_FEA_IPV6
|
||||
|
||||
char *mbed_trace_array(const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "mbedtls_stub.h"
|
||||
|
||||
mbedtls_stub_def mbedtls_stub;
|
||||
|
||||
//From ssl.h
|
||||
int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
if( mbedtls_stub.useCounter ){
|
||||
|
||||
if( mbedtls_stub.retArray[mbedtls_stub.counter] == HANDSHAKE_FINISHED_VALUE ||
|
||||
mbedtls_stub.retArray[mbedtls_stub.counter] == HANDSHAKE_FINISHED_VALUE_RETURN_ZERO){
|
||||
|
||||
ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
|
||||
if(mbedtls_stub.retArray[mbedtls_stub.counter] == HANDSHAKE_FINISHED_VALUE_RETURN_ZERO)
|
||||
return 0;
|
||||
}
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_close_notify( mbedtls_ssl_context *a )
|
||||
{
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_init( mbedtls_ssl_context *a ){
|
||||
|
||||
}
|
||||
void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_config_init( mbedtls_ssl_config *a ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *a, uint32_t b, uint32_t c)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_free( mbedtls_ssl_context *a ){
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *a,
|
||||
mbedtls_x509_crt *b,
|
||||
mbedtls_pk_context *c ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *a, int c ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *a,
|
||||
mbedtls_x509_crt *b,
|
||||
mbedtls_x509_crl *c ){
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *a,
|
||||
const unsigned char *b, size_t c,
|
||||
const unsigned char *d, size_t e ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_config_defaults( mbedtls_ssl_config *a,
|
||||
int b, int c, int d){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_rng( mbedtls_ssl_config *a,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *b ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *a,
|
||||
const int *b)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_ssl_setup( mbedtls_ssl_context *a,
|
||||
const mbedtls_ssl_config *b ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
|
||||
void *p_bio,
|
||||
int (*f_send)(void *, const unsigned char *, size_t),
|
||||
int (*f_recv)(void *, unsigned char *, size_t),
|
||||
int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) ){
|
||||
if( p_bio != NULL ){
|
||||
if( f_send )
|
||||
f_send( p_bio, NULL, 0 );
|
||||
if( f_recv )
|
||||
f_recv( p_bio, NULL, 0 );
|
||||
if( f_recv_timeout )
|
||||
f_recv_timeout( p_bio, NULL, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *a,
|
||||
void *ctx,
|
||||
void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms),
|
||||
int (*f_get_timer)(void *) ){
|
||||
f_set_timer(ctx, 1, 2);
|
||||
f_get_timer(ctx);
|
||||
if(mbedtls_stub.invalidate_timer){
|
||||
f_set_timer(ctx, 0, 0);
|
||||
}
|
||||
f_get_timer(ctx);
|
||||
}
|
||||
|
||||
int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *a ){
|
||||
return mbedtls_stub.uint32_value;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_read( mbedtls_ssl_context *a, unsigned char *b, size_t c){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_write( mbedtls_ssl_context *a, const unsigned char *b, size_t c ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//From crt_drbg.h
|
||||
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *a,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *b,
|
||||
const unsigned char *c,
|
||||
size_t d ){
|
||||
return mbedtls_stub.crt_expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *a ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *a ){
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_ctr_drbg_random_with_add( void *a,
|
||||
unsigned char *b, size_t c,
|
||||
const unsigned char *d, size_t e ){
|
||||
return mbedtls_stub.crt_expected_int;
|
||||
}
|
||||
|
||||
int mbedtls_ctr_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len ){
|
||||
return mbedtls_stub.crt_expected_int;
|
||||
}
|
||||
|
||||
//From x509_crt.h
|
||||
void mbedtls_x509_crt_init( mbedtls_x509_crt *a ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_x509_crt_free( mbedtls_x509_crt *a ){
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_x509_crt_parse( mbedtls_x509_crt *a, const unsigned char *b, size_t c ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
//From entropy.h
|
||||
void mbedtls_entropy_init( mbedtls_entropy_context *a ){
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_entropy_free( mbedtls_entropy_context *ctx ){
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_entropy_func( void *a, unsigned char *b, size_t c ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
int mbedtls_entropy_add_source( mbedtls_entropy_context *a,
|
||||
mbedtls_entropy_f_source_ptr f_source, void *b,
|
||||
size_t c, int d ){
|
||||
unsigned char buf[2];
|
||||
size_t len;
|
||||
f_source(NULL, buf, 1, &len);
|
||||
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
//From pk.h
|
||||
int mbedtls_pk_parse_key( mbedtls_pk_context *a,
|
||||
const unsigned char *b, size_t c,
|
||||
const unsigned char *d, size_t e ){
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_pk_init( mbedtls_pk_context *ctx )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_pk_free( mbedtls_pk_context *ctx )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_config_free( mbedtls_ssl_config *a)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *pw,
|
||||
size_t pw_len )
|
||||
{
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
|
||||
mbedtls_ssl_cookie_write_t *f_cookie_write,
|
||||
mbedtls_ssl_cookie_check_t *f_cookie_check,
|
||||
void *p_cookie )
|
||||
{
|
||||
if( mbedtls_stub.cookie_obj && f_cookie_check && mbedtls_stub.cookie_len > 0 ){
|
||||
f_cookie_check(mbedtls_stub.cookie_obj, &mbedtls_stub.cookie_value, mbedtls_stub.cookie_len, NULL, 0);
|
||||
}
|
||||
if( mbedtls_stub.cookie_obj && f_cookie_write && mbedtls_stub.cookie_len > 0 ){
|
||||
unsigned char out[16];
|
||||
unsigned char *ptr = &out;
|
||||
f_cookie_write(mbedtls_stub.cookie_obj, &ptr, ptr+mbedtls_stub.cookie_len, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
|
||||
mbedtls_ssl_export_keys_t *f_export_keys,
|
||||
void *p_export_keys )
|
||||
{
|
||||
if( f_export_keys && p_export_keys){
|
||||
unsigned char value[40];
|
||||
memset(&value, 1, 40);
|
||||
f_export_keys(p_export_keys, &value, "", 0, 0,0); //failure case
|
||||
|
||||
f_export_keys(p_export_keys, &value, "", 0, 20,0); //success case
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
if( mbedtls_stub.useCounter ){
|
||||
return mbedtls_stub.retArray[mbedtls_stub.counter++];
|
||||
}
|
||||
return mbedtls_stub.expected_int;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBEDTLS_STUB_H
|
||||
#define MBEDTLS_STUB_H
|
||||
|
||||
#define MBEDTLS_SSL_EXPORT_KEYS
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
|
||||
|
||||
#define HANDSHAKE_FINISHED_VALUE 8888
|
||||
#define HANDSHAKE_FINISHED_VALUE_RETURN_ZERO 8889
|
||||
|
||||
typedef struct {
|
||||
int crt_expected_int;
|
||||
bool useCounter;
|
||||
int counter;
|
||||
int retArray[20];
|
||||
int expected_int;
|
||||
uint32_t uint32_value;
|
||||
bool invalidate_timer;
|
||||
void *cookie_obj;
|
||||
unsigned char cookie_value[8];
|
||||
size_t cookie_len;
|
||||
} mbedtls_stub_def;
|
||||
|
||||
extern mbedtls_stub_def mbedtls_stub;
|
||||
|
||||
#endif // MBEDTLS_STUB_H
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#define NS_LIST_FN extern
|
||||
|
||||
#include "ns_list.h"
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_timer.h"
|
||||
#include "ns_timer_stub.h"
|
||||
#include "eventOS_callback_timer.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include "platform/arm_hal_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
|
||||
ns_timer_stub_def ns_timer_stub;
|
||||
|
||||
int8_t ns_timer_init(void)
|
||||
{
|
||||
return ns_timer_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_register(void (*timer_interrupt_handler)(int8_t, uint16_t))
|
||||
{
|
||||
ns_timer_stub.cb = timer_interrupt_handler;
|
||||
return ns_timer_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_unregister(int8_t ns_timer_id)
|
||||
{
|
||||
return ns_timer_stub.int8_value;
|
||||
}
|
||||
|
||||
|
||||
int8_t ns_timer_sleep(void)
|
||||
{
|
||||
return ns_timer_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_start(int8_t ns_timer_id, uint16_t slots)
|
||||
{
|
||||
return ns_timer_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_stop(int8_t ns_timer_id)
|
||||
{
|
||||
return ns_timer_stub.int8_value;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __NS_TIMER_STUB_H__
|
||||
#define __NS_TIMER_STUB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int8_t int8_value;
|
||||
void (*cb)(int8_t, uint16_t);
|
||||
} ns_timer_stub_def;
|
||||
|
||||
extern ns_timer_stub_def ns_timer_stub;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __NS_TIMER_STUB_H__
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "nsdynmemLIB_stub.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <nsdynmemLIB.h>
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
nsdynmemlib_stub_data_t nsdynmemlib_stub;
|
||||
|
||||
void ns_dyn_mem_init(uint8_t *heap, uint16_t h_size, void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
void *ns_dyn_mem_alloc(int16_t alloc_size)
|
||||
{
|
||||
if (nsdynmemlib_stub.returnCounter > 0)
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter--;
|
||||
return malloc(alloc_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(nsdynmemlib_stub.expectedPointer);
|
||||
}
|
||||
}
|
||||
|
||||
void *ns_dyn_mem_temporary_alloc(int16_t alloc_size)
|
||||
{
|
||||
if (nsdynmemlib_stub.returnCounter > 0)
|
||||
{
|
||||
nsdynmemlib_stub.returnCounter--;
|
||||
return malloc(alloc_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(nsdynmemlib_stub.expectedPointer);
|
||||
}
|
||||
}
|
||||
|
||||
void ns_dyn_mem_free(void *block)
|
||||
{
|
||||
free(block);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __NSDYNMEMLIB_STUB_H__
|
||||
#define __NSDYNMEMLIB_STUB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t returnCounter;
|
||||
void* expectedPointer;
|
||||
} nsdynmemlib_stub_data_t;
|
||||
|
||||
extern nsdynmemlib_stub_data_t nsdynmemlib_stub;
|
||||
|
||||
|
||||
void *ns_dyn_mem_alloc(int16_t alloc_size);
|
||||
void *ns_dyn_mem_temporary_alloc(int16_t alloc_size);
|
||||
void ns_dyn_mem_free(void *block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include "randLIB.h"
|
||||
#include "platform/arm_hal_random.h"
|
||||
|
||||
#if ((RAND_MAX+1) & RAND_MAX) != 0
|
||||
#error "RAND_MAX isn't 2^n-1 :("
|
||||
#endif
|
||||
|
||||
int counter = 1;
|
||||
|
||||
void randLIB_seed_random(void)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t randLIB_get_8bit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t randLIB_get_16bit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t randLIB_get_32bit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *randLIB_get_n_bytes_random(void *data_ptr, uint8_t count)
|
||||
{
|
||||
if(data_ptr && count > 0){
|
||||
*((int*)data_ptr) = counter++%255;
|
||||
}
|
||||
return data_ptr;
|
||||
}
|
||||
|
||||
uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t randLIB_randomise_base(uint32_t base, uint16_t min_factor, uint16_t max_factor)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_coap_builder.c
|
||||
*
|
||||
* \brief CoAP Message builder
|
||||
*
|
||||
* Functionality: Builds CoAP message
|
||||
*
|
||||
*/
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * INCLUDE FILES * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "sn_coap_builder_stub.h"
|
||||
|
||||
sn_coap_builder_stub_def sn_coap_builder_stub;
|
||||
|
||||
sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
|
||||
{
|
||||
return sn_coap_builder_stub.expectedHeader;
|
||||
}
|
||||
|
||||
int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr)
|
||||
{
|
||||
return sn_coap_builder_stub.expectedInt16;
|
||||
}
|
||||
|
||||
uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr)
|
||||
{
|
||||
return sn_coap_builder_stub.expectedUint16;
|
||||
}
|
||||
|
||||
int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number)
|
||||
{
|
||||
return sn_coap_builder_stub.expectedInt16;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __SN_COAP_BUILDER_STUB_H__
|
||||
#define __SN_COAP_BUILDER_STUB_H__
|
||||
|
||||
typedef struct {
|
||||
int16_t expectedInt16;
|
||||
uint16_t expectedUint16;
|
||||
sn_coap_hdr_s *expectedHeader;
|
||||
} sn_coap_builder_stub_def;
|
||||
|
||||
extern sn_coap_builder_stub_def sn_coap_builder_stub;
|
||||
|
||||
#endif //__SN_COAP_BUILDER_STUB_H__
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
*\file sn_coap_parser.c
|
||||
*
|
||||
* \brief CoAP Header parser
|
||||
*
|
||||
* Functionality: Parses CoAP Header
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "sn_coap_parser_stub.h"
|
||||
|
||||
sn_coap_parser_def sn_coap_parser_stub;
|
||||
|
||||
sn_coap_hdr_s *sn_coap_parser(struct coap_s *handle, uint16_t packet_data_len, uint8_t *packet_data_ptr, coap_version_e *coap_version_ptr)
|
||||
{
|
||||
return sn_coap_parser_stub.expectedHeader;
|
||||
}
|
||||
|
||||
void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr)
|
||||
{
|
||||
if (freed_coap_msg_ptr != NULL) {
|
||||
if (freed_coap_msg_ptr->uri_path_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->uri_path_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->token_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->token_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr != NULL) {
|
||||
if (freed_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->proxy_uri_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->etag_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->uri_host_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->location_path_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->location_query_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->uri_query_ptr);
|
||||
}
|
||||
|
||||
free(freed_coap_msg_ptr->options_list_ptr);
|
||||
}
|
||||
|
||||
free(freed_coap_msg_ptr);
|
||||
freed_coap_msg_ptr = NULL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __SN_COAP_PARSER_STUB_H__
|
||||
#define __SN_COAP_PARSER_STUB_H__
|
||||
|
||||
#include "sn_coap_header.h"
|
||||
|
||||
typedef struct {
|
||||
sn_coap_hdr_s *expectedHeader;
|
||||
} sn_coap_parser_def;
|
||||
|
||||
extern sn_coap_parser_def sn_coap_parser_stub;
|
||||
|
||||
#endif //__SN_COAP_PARSER_STUB_H__
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For libary malloc() */
|
||||
#include <string.h> /* For memset() and memcpy() */
|
||||
#ifdef __linux__
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "sn_coap_header_internal.h"
|
||||
#include "sn_coap_protocol_internal.h"
|
||||
#include "sn_coap_protocol_stub.h"
|
||||
|
||||
uint16_t sn_coap_block_data_size = 0;
|
||||
|
||||
uint8_t sn_coap_resending_queue_msgs = 0;
|
||||
uint8_t sn_coap_resending_queue_bytes = 0;
|
||||
uint8_t sn_coap_resending_count = 0;
|
||||
uint8_t sn_coap_resending_intervall = 0;
|
||||
|
||||
uint8_t sn_coap_duplication_buffer_size = 0;
|
||||
|
||||
sn_coap_protocol_stub_def sn_coap_protocol_stub;
|
||||
|
||||
int8_t sn_coap_protocol_destroy(struct coap_s *handle)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedInt8;
|
||||
}
|
||||
|
||||
struct coap_s *sn_coap_protocol_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
|
||||
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *),
|
||||
int8_t (*used_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *param))
|
||||
{
|
||||
if( sn_coap_protocol_stub.expectedCoap ){
|
||||
sn_coap_protocol_stub.expectedCoap->sn_coap_protocol_free = used_free_func_ptr;
|
||||
sn_coap_protocol_stub.expectedCoap->sn_coap_protocol_malloc = used_malloc_func_ptr;
|
||||
sn_coap_protocol_stub.expectedCoap->sn_coap_rx_callback = used_rx_callback_ptr;
|
||||
sn_coap_protocol_stub.expectedCoap->sn_coap_tx_callback = used_tx_callback_ptr;
|
||||
}
|
||||
return sn_coap_protocol_stub.expectedCoap;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_set_block_size(struct coap_s *handle, uint16_t block_size)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedInt8;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_set_duplicate_buffer_size(struct coap_s *handle, uint8_t size)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedInt8;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_set_retransmission_parameters(struct coap_s *handle, uint8_t resending_count, uint8_t resending_intervall)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedInt8;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_set_retransmission_buffer(struct coap_s *handle, uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedInt8;
|
||||
}
|
||||
|
||||
void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr,
|
||||
uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, void *param)
|
||||
{
|
||||
//TODO: check if needed here
|
||||
src_coap_msg_ptr->msg_id = 2;
|
||||
return sn_coap_protocol_stub.expectedInt16;
|
||||
}
|
||||
|
||||
sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr, void *param)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedHeader;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedInt8;
|
||||
}
|
||||
|
||||
coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len)
|
||||
{
|
||||
return sn_coap_protocol_stub.expectedSendMsg;
|
||||
}
|
||||
|
||||
int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __SN_COAP_PROTOCOL_STUB_H__
|
||||
#define __SN_COAP_PROTOCOL_STUB_H__
|
||||
|
||||
#include "sn_coap_header_internal.h"
|
||||
#include "sn_coap_protocol_internal.h"
|
||||
|
||||
typedef struct {
|
||||
int8_t expectedInt8;
|
||||
int16_t expectedInt16;
|
||||
struct coap_s *expectedCoap;
|
||||
sn_coap_hdr_s *expectedHeader;
|
||||
coap_send_msg_s *expectedSendMsg;
|
||||
} sn_coap_protocol_stub_def;
|
||||
|
||||
extern sn_coap_protocol_stub_def sn_coap_protocol_stub;
|
||||
|
||||
#endif //__SN_COAP_PROTOCOL_STUB_H__
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "socket_api.h"
|
||||
#include "socket_api_stub.h"
|
||||
|
||||
socket_api_stub_data_t socket_api_stub;
|
||||
const uint8_t ns_in6addr_any[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
int8_t socket_raw_open(void (*passed_fptr)(void *))
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_open(uint8_t protocol, uint16_t identifier, void (*passed_fptr)(void *))
|
||||
{
|
||||
socket_api_stub.recv_cb = passed_fptr;
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t socket_close(int8_t socket)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_listen(int8_t socket, uint8_t backlog)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_connect(int8_t socket, ns_address_t *address, uint8_t randomly_take_src_number)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_bind(int8_t socket, const ns_address_t *address)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int16_t socket_read(int8_t socket, ns_address_t *address, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
if( address ){
|
||||
memset(&address->address, 0, 16);
|
||||
address->identifier = 0;
|
||||
}
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_read_session_address(int8_t socket, ns_address_t *address)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_setsockopt(int8_t socket, uint8_t level, uint8_t opt_name, const void *opt_value, uint16_t opt_len)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
int8_t socket_getsockopt(int8_t socket, uint8_t level, uint8_t opt_name, void *opt_value, uint16_t *opt_len)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int8_t socket_sendmsg(int8_t socket, const ns_msghdr_t *msg, int flags)
|
||||
{
|
||||
if( socket_api_stub.counter >= 0){
|
||||
return socket_api_stub.values[socket_api_stub.counter--];
|
||||
}
|
||||
|
||||
return socket_api_stub.int8_value;
|
||||
}
|
||||
|
||||
int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ns_cmsghdr_t *NS_CMSG_NXTHDR(const ns_msghdr_t *msgh, const ns_cmsghdr_t *cmsg)
|
||||
{
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2015 ARM Limited. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __SOCKET_API_STUB_H__
|
||||
#define __SOCKET_API_STUB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct {
|
||||
void (*recv_cb)(void *);
|
||||
int8_t int8_value;
|
||||
int counter;
|
||||
int values[10];
|
||||
} socket_api_stub_data_t;
|
||||
|
||||
extern socket_api_stub_data_t socket_api_stub;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__SOCKET_API_STUB_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
#include "ns_types.h"
|
||||
#include "timer_sys.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include "ns_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_callback_timer.h"
|
||||
|
||||
#ifndef ST_MAX
|
||||
#define ST_MAX 6
|
||||
#endif
|
||||
|
||||
#define TIMER_SYS_TICK_PERIOD 100
|
||||
|
||||
void timer_sys_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void timer_sys_disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int8_t timer_sys_wakeup(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t timer_get_runtime_ticks(void) // only used in dev_stats_internal.c
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int8_t eventOS_event_timer_request(uint8_t snmessage, uint8_t event_type, int8_t tasklet_id, uint32_t time)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t eventOS_event_timer_cancel(uint8_t snmessage, int8_t tasklet_id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t eventOS_event_timer_shortest_active_timer(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void system_timer_tick_update(uint32_t ticks)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "eventOS_event_timer.h"
|
||||
|
||||
// Timeout structure, already typedefed to timeout_t
|
||||
struct timeout_entry_t {
|
||||
uint8_t id;
|
||||
};
|
||||
|
||||
static timeout_t timeout_stub;
|
||||
|
||||
timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg)
|
||||
{
|
||||
return &timeout_stub;
|
||||
}
|
||||
|
||||
void eventOS_timeout_cancel(timeout_t *t)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2015 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
# not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# * http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
echo
|
||||
echo "Creating report"
|
||||
echo
|
||||
|
||||
echo '<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml-stylesheet type="text/xsl" href="junit_xsl.xslt"?>
|
||||
<list>' >> lcov/index.xml
|
||||
|
||||
for f in lcov/results/*.xml
|
||||
do
|
||||
name=${f##*/}
|
||||
echo '<entry name="results/'"$name"'" />'>> lcov/index.xml
|
||||
done
|
||||
|
||||
echo '</list>' >> lcov/index.xml
|
||||
|
||||
echo
|
||||
echo "Report created to lcov/index.xml (outputs html)"
|
||||
echo
|
Loading…
Reference in New Issue