mirror of https://github.com/ARMmbed/mbed-os.git
This commit includes
Replacing with source code replicated from respective repositories including mbed-client - TAG mbed-os-5.0-rc1 mbed-client-c - TAG mbed-os-5.0-rc1 mbed-client-classic - TAG mbed-os-5.0-rc2 mbed-client-mbed-tls - TAG mbed-os-5.0-rc1 mbed-client-randlib - TAG mbed-os-5.0-rc1 coap-service - TAG mbed-os-5.0-rc1 Adding CONTRIBUTING.md file explaining how to submit patches for any of the components belonging to FEATURE_CLIENTpull/2249/head
parent
359dc05f28
commit
effa193386
|
|
@ -0,0 +1,83 @@
|
|||
# How to contribute
|
||||
|
||||
This directory structure is entirely generated or copied from another repositories. Do not send patches against it, they cannot be accepted because all code will be entirely overwritten on next release.
|
||||
|
||||
Instead follow these instructions to send and test your contributions against master repositories.
|
||||
|
||||
## Directory structure
|
||||
|
||||
This directory consist of following modules
|
||||
|
||||
* [mbed-client](#mbed-client)
|
||||
* [mbed-client-c](#mbed-client-c)
|
||||
* [mbed-client-mbed-tls](#mbed-client-mbed-tls)
|
||||
* [mbed-client-classic](#mbed-client-classic)
|
||||
* [mbed-client-randlib](#mbed-client-randlib)
|
||||
* [coap-service](#coap-service)
|
||||
|
||||
|
||||
## mbed-client
|
||||
|
||||
mbed-cient is copied from master repository from here: https://github.com/ARMmbed/mbed-client
|
||||
|
||||
To replace the copied version with master repository follow these steps:
|
||||
|
||||
* Remove mbed-client directory: `rm -rf mbed-client`
|
||||
* Clone from the master: `git clone git@github.com:ARMmbed/mbed-client.git`
|
||||
|
||||
Now you have mbed-client directory replaced with Git repository cloned from original. You can build and test your changes against it and send patches normally to Github as a pull requests.
|
||||
|
||||
## mbed-client-c
|
||||
|
||||
mbed-client-c is copied from master repository from here: https://github.com/ARMmbed/mbed-client-c
|
||||
|
||||
To replace the copied version with master repository follow these steps:
|
||||
|
||||
* Remove mbed-client-c directory: `rm -rf mbed-client-c`
|
||||
* Clone from the master: `git clone git@github.com:ARMmbed/mbed-client-c.git`
|
||||
|
||||
Now you have mbed-client-c directory replaced with Git repository cloned from original. You can build and test your changes against it and send patches normally to Github as a pull requests.
|
||||
|
||||
## mbed-client-classic
|
||||
|
||||
mbed-client-classic is copied from master repository from here: https://github.com/ARMmbed/mbed-client-classic
|
||||
|
||||
To replace the copied version with master repository follow these steps:
|
||||
|
||||
* Remove mbed-client-classic directory: `rm -rf mbed-client-classic`
|
||||
* Clone from the master: `git clone git@github.com:ARMmbed/mbed-client-classic.git`
|
||||
|
||||
Now you have mbed-client-classic directory replaced with Git repository cloned from original. You can build and test your changes against it and send patches normally to Github as a pull requests.
|
||||
|
||||
## mbed-client-mbed-tls
|
||||
|
||||
mbed-client-mbed-tls is copied from master repository from here: https://github.com/ARMmbed/mbed-client-mbed-tls
|
||||
|
||||
To replace the copied version with master repository follow these steps:
|
||||
|
||||
* Remove mbed-client-mbed-tls directory: `rm -rf mbed-client-mbed-tls`
|
||||
* Clone from the master: `git clone git@github.com:ARMmbed/mbed-client-mbed-tls.git`
|
||||
|
||||
Now you have mbed-client-mbed-tls directory replaced with Git repository cloned from original. You can build and test your changes against it and send patches normally to Github as a pull requests.
|
||||
|
||||
## mbed-client-randlib
|
||||
|
||||
mbed-client-randlib is copied from master repository from here: https://github.com/ARMmbed/mbed-client-randlib
|
||||
|
||||
To replace the copied version with master repository follow these steps:
|
||||
|
||||
* Remove mbed-client-randlib directory: `rm -rf mbed-client-randlib`
|
||||
* Clone from the master: `git clone git@github.com:ARMmbed/mbed-client-randlib.git`
|
||||
|
||||
Now you have mbed-client-randlib directory replaced with Git repository cloned from original. You can build and test your changes against it and send patches normally to Github as a pull requests.
|
||||
|
||||
## coap-service
|
||||
|
||||
coap-service is copied from master repository from here: https://github.com/ARMmbed/coap-service
|
||||
|
||||
To replace the copied version with master repository follow these steps:
|
||||
|
||||
* Remove coap-service directory: `rm -rf coap-service`
|
||||
* Clone from the master: `git clone git@github.com:ARMmbed/coap-service.git`
|
||||
|
||||
Now you have coap-service directory replaced with Git repository cloned from original. You can build and test your changes against it and send patches normally to Github as a pull requests.
|
||||
|
|
@ -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,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.1",
|
||||
"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": "^2.0.0",
|
||||
"sal-stack-nanostack": "^5.0.0",
|
||||
"mbedtls": "^2.0.0"
|
||||
},
|
||||
"targetDependencies": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/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
|
||||
|
||||
yt target x86-linux-native
|
||||
yt up
|
||||
make -f Makefile.test test
|
||||
make -f Makefile.test test clean
|
||||
|
|
@ -0,0 +1,797 @@
|
|||
/*
|
||||
* 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;
|
||||
int8_t listen_socket;
|
||||
|
||||
ns_address_t dest_addr;
|
||||
size_t data_len;
|
||||
uint8_t *data;
|
||||
|
||||
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
|
||||
|
||||
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 send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, 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(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);
|
||||
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, 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->sec_handler = coap_security_create(parent->listen_socket, this->timer.id, address_ptr, port, ECJPAKE,
|
||||
&send_to_socket, &receive_from_socket, &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, 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->sec_handler->_remote_port == port &&
|
||||
memcmp(cur_ptr->sec_handler->_remote_address, address_ptr, 16) == 0) {
|
||||
this = cur_ptr;
|
||||
// hack_save_remote_address(address_ptr, port);
|
||||
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->listen_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->listen_socket = socket_open(SOCKET_UDP, listen_port, recv_sckt_msg);
|
||||
}else{
|
||||
this->listen_socket = socket_open(SOCKET_UDP, listen_port, secure_recv_sckt_msg);
|
||||
}
|
||||
// Socket create failed
|
||||
if(this->listen_socket < 0){
|
||||
ns_dyn_mem_free(this);
|
||||
return NULL;
|
||||
}
|
||||
// XXX API for this? May want to get clever to do recommended first query = 1 hop, retries = whole PAN
|
||||
socket_setsockopt(this->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &(const int16_t) {
|
||||
16
|
||||
}, sizeof(int16_t));
|
||||
}else{
|
||||
this->listen_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_free(this->listen_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->listen_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 int send_to_socket(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *buf, size_t len)
|
||||
{
|
||||
internal_socket_t *sock = int_socket_find_by_socket_id(socket_id);
|
||||
if(!sock){
|
||||
return -1;
|
||||
}
|
||||
if(!sock->real_socket){
|
||||
//In this case all clients will have socket_id -1 and socket will not have a real address
|
||||
//so sock->dest_addr cannot be used here
|
||||
int ret = sock->parent->_send_cb(sock->listen_socket, address_ptr, port, 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->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(sock->listen_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
|
||||
int ret = socket_sendto(sock->listen_socket, &sock->dest_addr, (unsigned char*)buf, len);
|
||||
if( ret < 0 )
|
||||
return ret;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int receive_from_socket(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)
|
||||
{
|
||||
sock->data_len = 0;
|
||||
if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) {
|
||||
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;
|
||||
}
|
||||
sock->data_len = socket_read(sckt_data->socket_id, src_address, sock->data, sckt_data->d_len);
|
||||
}
|
||||
if( sock->data_len < 1){
|
||||
ns_dyn_mem_free(sock->data);
|
||||
sock->data = NULL;
|
||||
sock->data_len = 0;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if( sock && read_data(sckt_data, sock, &src_address) == 0 ){
|
||||
secure_session_t *session = secure_session_find(sock, src_address.address, src_address.identifier);
|
||||
|
||||
// Create session
|
||||
if( !session ){
|
||||
memcpy( sock->dest_addr.address, src_address.address, 16 );
|
||||
sock->dest_addr.identifier = src_address.identifier;
|
||||
sock->dest_addr.type = src_address.type;
|
||||
session = secure_session_create(sock, src_address.address, src_address.identifier);
|
||||
}
|
||||
if( !session ){
|
||||
tr_err("secure_recv_sckt_msg session creation failed - OOM");
|
||||
return;
|
||||
}
|
||||
session->last_contact_time = coap_service_get_internal_timer_ticks();
|
||||
// Start handshake
|
||||
if( !session->sec_handler->_is_started ){
|
||||
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
|
||||
uint8_t pw_len;
|
||||
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_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->listen_socket, src_address.address,
|
||||
src_address.identifier,
|
||||
session->sec_handler->_keyblk.value);
|
||||
}
|
||||
}
|
||||
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 ){
|
||||
ns_dyn_mem_free(data);
|
||||
secure_session_delete( session );
|
||||
}else{
|
||||
if( sock->parent->_recv_cb ){
|
||||
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, 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;
|
||||
if( sock && read_data(sckt_data, sock, &src_address) == 0 ){
|
||||
if(sock->parent && sock->parent->_recv_cb){
|
||||
sock->parent->_recv_cb(sock->listen_socket, src_address.address, src_address.identifier, 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( !session->sec_handler->_is_started ){
|
||||
uint8_t *pw = (uint8_t *)ns_dyn_mem_alloc(64);
|
||||
uint8_t pw_len;
|
||||
if( sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->listen_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->listen_socket,
|
||||
address, port,
|
||||
session->sec_handler->_keyblk.value);
|
||||
}
|
||||
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 ){
|
||||
ns_dyn_mem_free(data);
|
||||
secure_session_delete( session );
|
||||
return 0;
|
||||
}else{
|
||||
if( sock->parent->_recv_cb ){
|
||||
sock->parent->_recv_cb(sock->listen_socket, address, port, data, len);
|
||||
}
|
||||
ns_dyn_mem_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if( sock->parent->_recv_cb ){
|
||||
sock->parent->_recv_cb(sock->listen_socket, address, port, 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, ns_address_t *dest_addr, 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;
|
||||
memcpy(handler->socket->dest_addr.address, dest_addr->address, 16);
|
||||
handler->socket->dest_addr.identifier = dest_addr->identifier;
|
||||
handler->socket->dest_addr.type = dest_addr->type;
|
||||
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();
|
||||
memcpy( handler->socket->dest_addr.address, dest_addr->address, 16 );
|
||||
handler->socket->dest_addr.identifier = dest_addr->identifier;
|
||||
handler->socket->dest_addr.type = dest_addr->type;
|
||||
uint8_t *pw = (uint8_t *)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->listen_socket, 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->listen_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->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &opt_name, sizeof(int));
|
||||
socket_setsockopt(handler->socket->listen_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
|
||||
return socket_sendto(handler->socket->listen_socket, dest_addr, 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->listen_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,398 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_message_handler.h"
|
||||
#include "sn_coap_protocol.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
|
||||
ns_list_add_to_start(&request_list, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
static void transaction_delete(coap_transaction_t *this)
|
||||
{
|
||||
if (this) {
|
||||
ns_list_remove(&request_list, this);
|
||||
if(this->data_ptr){
|
||||
ns_dyn_mem_free(this->data_ptr);
|
||||
}
|
||||
ns_dyn_mem_free(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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");
|
||||
if (!resp_ptr) {
|
||||
return -1;
|
||||
}
|
||||
if( resp_ptr->token_ptr ){
|
||||
this = transaction_find_client_by_token(resp_ptr->token_ptr);
|
||||
}
|
||||
if (this && this->resp_cb) {
|
||||
this->resp_cb(this->service_id, address_ptr->addr_ptr, address_ptr->port, NULL);
|
||||
}
|
||||
transaction_delete(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void coap_service_build_content_format(sn_coap_hdr_s *header, sn_coap_content_format_e format);
|
||||
|
||||
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, uint8_t source_addr_ptr[static 16], uint16_t port,
|
||||
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 = 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;
|
||||
}
|
||||
if (coap_message->msg_code > 0 && coap_message->msg_code < 32) {
|
||||
|
||||
//TODO Sorry
|
||||
|
||||
coap_transaction_t *transaction_ptr = transaction_create();
|
||||
if (transaction_ptr) {
|
||||
|
||||
transaction_ptr->msg_id = coap_message->msg_id;
|
||||
transaction_ptr->client_request = false;// this is server transaction
|
||||
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
|
||||
}
|
||||
} else {
|
||||
//response find by MSG id
|
||||
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);
|
||||
if (this->resp_cb) {
|
||||
this->resp_cb(this->service_id, source_addr_ptr, port, coap_message);
|
||||
}
|
||||
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
|
||||
transaction_delete(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);
|
||||
coap_service_build_content_format(&request, 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){
|
||||
own_free(request.content_type_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(request.content_type_ptr);
|
||||
own_free(data_ptr);
|
||||
if(request_response_cb == NULL){
|
||||
//No response expected
|
||||
return 0;
|
||||
}
|
||||
return transaction_ptr->msg_id;
|
||||
}
|
||||
|
||||
//TODO: refactor this to use nsdl
|
||||
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...
|
||||
coap_service_build_content_format(response, 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);
|
||||
//TODO deallocate stuff i quess
|
||||
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);
|
||||
transaction_delete(transaction_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;
|
||||
}
|
||||
return sn_coap_protocol_exec(handle->coap, current_time);
|
||||
}
|
||||
|
||||
static void coap_service_build_content_format(sn_coap_hdr_s *header, sn_coap_content_format_e format)
|
||||
{
|
||||
if (format == COAP_CT_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always alloc - CoAP library needs a non-NULL pointer to trigger writing
|
||||
* of a zero-length option, and it will free the pointer later.
|
||||
*/
|
||||
header->content_type_ptr = own_alloc(2);
|
||||
if (!header->content_type_ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (format == 0) { /* text/plain */
|
||||
header->content_type_len = 0;
|
||||
} else if (format <= 0xff) {
|
||||
header->content_type_ptr[0] = format;
|
||||
header->content_type_len = 1;
|
||||
} else {
|
||||
header->content_type_ptr[0] = format >> 8;
|
||||
header->content_type_ptr[1] = format & 0xff;
|
||||
header->content_type_len = 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "coap_connection_handler.h"
|
||||
#include "coap_security_handler.h"
|
||||
#include "randLIB.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
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, uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode,
|
||||
send_cb *send_cb,
|
||||
receive_cb *receive_cb,
|
||||
start_timer_cb *start_timer_cb,
|
||||
timer_status_cb *timer_status_cb)
|
||||
{
|
||||
if( !address_ptr || send_cb == NULL || receive_cb == NULL || start_timer_cb == NULL || timer_status_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->_remote_port = port;
|
||||
memcpy(this->_remote_address, address_ptr, 16);
|
||||
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 = send_cb;
|
||||
this->_receive_cb = receive_cb;
|
||||
this->_start_timer_cb = start_timer_cb;
|
||||
this->_timer_status_cb = timer_status_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;
|
||||
}
|
||||
|
||||
//TODO: Only needed for server type?
|
||||
mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write,
|
||||
simple_cookie_check,
|
||||
&sec->_cookie);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//Only needed for server type?
|
||||
mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write,
|
||||
simple_cookie_check,
|
||||
&sec->_cookie);
|
||||
|
||||
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->_remote_address, sec->_remote_port, 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 );
|
||||
}
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
static int16_t coap_service_coap_msg_process(int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len);
|
||||
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", transaction_ptr->service_id);
|
||||
|
||||
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, 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;
|
||||
}
|
||||
|
||||
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 ){
|
||||
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_warn("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
|
||||
if (transaction_ptr && 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 int16_t coap_service_coap_msg_process(int8_t socket_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len)
|
||||
{
|
||||
return coap_message_handler_coap_msg_process( coap_service_handle, socket_id, source_addr_ptr, port, data_ptr, data_len, &coap_msg_process_callback);
|
||||
}
|
||||
|
||||
static int recv_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *data_ptr = NULL;
|
||||
uint16_t data_len = 0;
|
||||
|
||||
data_ptr = own_alloc(len);
|
||||
|
||||
if (!data_ptr || len < 1) {
|
||||
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_service_coap_msg_process(socket_id, address, port, data_ptr, data_len);
|
||||
own_free(data_ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int send_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *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, address, port, data_ptr, data_len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//static void sec_conn_closed_cb(int8_t socket_id)
|
||||
//{
|
||||
// coap_service_t *this = service_find_by_socket(socket_id);
|
||||
|
||||
// tr_debug("Secure socket was closed by end device");
|
||||
//}
|
||||
|
||||
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 refactor this away. There should be no transaction_ptr(s) before done_cb has been called
|
||||
//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->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;
|
||||
//TODO: who deletes transaction incase no response is required
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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, uint8_t address[static 16], uint16_t port, const unsigned char *, int);
|
||||
typedef int receive_from_socket_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, 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, ns_address_t *dest_addr, 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,84 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
/**
|
||||
* \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];
|
||||
uint16_t remote_port;
|
||||
uint8_t token[4];
|
||||
uint16_t msg_id;
|
||||
int8_t service_id;
|
||||
uint8_t options;
|
||||
bool client_request: 1;
|
||||
uint8_t *data_ptr;
|
||||
uint16_t data_len;
|
||||
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, uint8_t source_addr_ptr[static 16], uint16_t port,
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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>
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
|
||||
#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, uint8_t *address_ptr, uint16_t port, const unsigned char *, 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 {
|
||||
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 _remote_address[16];
|
||||
uint16_t _remote_port;
|
||||
|
||||
uint8_t _pw[64];
|
||||
uint8_t _pw_len;
|
||||
|
||||
bool _is_blocking;
|
||||
int8_t _socket_id;
|
||||
int8_t _timer_id;
|
||||
send_cb *_send_cb;
|
||||
receive_cb *_receive_cb;
|
||||
start_timer_cb *_start_timer_cb;
|
||||
timer_status_cb *_timer_status_cb;
|
||||
|
||||
} coap_security_t;
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port,
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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__
|
||||
|
||||
|
||||
uint32_t coap_service_get_internal_timer_ticks(void);
|
||||
|
||||
#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,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,469 @@
|
|||
/*
|
||||
* 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, 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, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
connection_handler_destroy(handler);
|
||||
|
||||
coap_security_handler_stub.sec_obj = (coap_security_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 22;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 1, 16 );
|
||||
|
||||
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, NULL, 0, true))
|
||||
return false;
|
||||
|
||||
if( -1 != coap_connection_handler_send_data(handler, &addr, 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, 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, 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_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 55;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 4, 16 );
|
||||
|
||||
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;
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 12;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 1, 16 );
|
||||
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_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
coap_security_handler_stub.sec_obj->_remote_port = 55;
|
||||
memset(coap_security_handler_stub.sec_obj->_remote_address, 4, 16 );
|
||||
coap_security_handler_stub.sec_obj->_timer_id = 5;
|
||||
|
||||
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_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
|
||||
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_t *)malloc(sizeof(coap_security_t));
|
||||
memset(coap_security_handler_stub.sec_obj, 0, sizeof(coap_security_t));
|
||||
|
||||
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,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,300 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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, 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, 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, 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 = -1;
|
||||
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, NULL, 0, process_cb))
|
||||
return false;
|
||||
|
||||
nsdynmemlib_stub.returnCounter = 1;
|
||||
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, 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, 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, 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 = 1;
|
||||
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 = 2;
|
||||
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,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,286 @@
|
|||
/*
|
||||
* 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, uint8_t *address_ptr, uint16_t port, 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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
if( NULL != coap_security_create(1,2,&buf,12,ECJPAKE,&send_to_socket, &receive_from_socket, &start_timer_callback, NULL) )
|
||||
return false;
|
||||
|
||||
if( NULL != coap_security_create(1,2,&buf,12,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,&buf,12,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,&buf,12,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,&buf,12,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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,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()
|
||||
{
|
||||
uint8_t buf[16];
|
||||
nsdynmemlib_stub.returnCounter = 2;
|
||||
mbedtls_stub.crt_expected_int = 0;
|
||||
coap_security_t *handle = coap_security_create(1,2,&buf,12,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,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, 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, 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
|
||||
|
||||
#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 address[static 16], uint16_t port, unsigned char *, int),
|
||||
int (*send_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, const unsigned char *, 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, ns_address_t *dest_addr, 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 unsigned char *, int);
|
||||
int (*receive_from_sock_cb)(int8_t socket_id, uint8_t address[static 16], uint16_t port, unsigned char *, int);
|
||||
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,58 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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, uint8_t source_addr_ptr[static 16], uint16_t port,
|
||||
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,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 __COAP_MESSAGE_HANDLER_STUB_H__
|
||||
#define __COAP_MESSAGE_HANDLER_STUB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.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,74 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, uint8_t *address_ptr, uint16_t port, SecureConnectionMode mode,
|
||||
int (*send_cb)(int8_t socket_id, uint8_t *address_ptr, uint16_t port, const unsigned char *, 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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, uint8_t *address_ptr, uint16_t port, const unsigned char *, 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;
|
||||
|
||||
#endif //__COAP_SECURITY_HANDLER_STUB_H__
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary)
|
||||
{
|
||||
if(data_ptr && eight_bit_boundary > 0){
|
||||
data_ptr[0] = counter++%255;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,95 @@
|
|||
/*
|
||||
* 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->content_type_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->content_type_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr != NULL) {
|
||||
if (freed_coap_msg_ptr->options_list_ptr->max_age_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->max_age_ptr);
|
||||
}
|
||||
|
||||
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->uri_port_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->uri_port_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->observe_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->observe_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->uri_query_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->block2_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->block2_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->block1_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->block1_ptr);
|
||||
}
|
||||
if (freed_coap_msg_ptr->options_list_ptr->accept_ptr != NULL) {
|
||||
free(freed_coap_msg_ptr->options_list_ptr->accept_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,96 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -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,118 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
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_free(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)
|
||||
{
|
||||
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_close(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_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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
* text=auto
|
||||
*.uvproj eol=lf
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
*.o
|
||||
*.a
|
||||
*.d
|
||||
*.eww
|
||||
*.bak
|
||||
*.dep
|
||||
*.Scr
|
||||
*.uvgui.*
|
||||
build/
|
||||
*.dep
|
||||
*.ewd
|
||||
*.ewt
|
||||
Debug
|
||||
Release
|
||||
settings
|
||||
*_release
|
||||
Obj
|
||||
*_output
|
||||
Backup*
|
||||
*.r43
|
||||
*.htm
|
||||
*.uvgui.*
|
||||
*.lib
|
||||
*.crf
|
||||
*.uvopt
|
||||
*.out
|
||||
docs/
|
||||
yotta_modules
|
||||
yotta_targets
|
||||
test/nsdl-c/unittest/coverages
|
||||
test/nsdl-c/unittest/results
|
||||
.yotta.json
|
||||
coverage/
|
||||
lcov/
|
||||
upload.tar.gz
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
test/*
|
||||
unittest/*
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# need unity.h:
|
||||
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,51 @@
|
|||
#
|
||||
# Makefile.test for combined NSDL+COAP library 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 '.*/stubs/.*' -e '.*/mbed-client-c/.*' -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)
|
||||
@genhtml -q $(COVERAGEFILE) --show-details --output-directory lcov/html
|
||||
@echo mbed-client-c module 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,2 @@
|
|||
The mbed Device C Client Library provides a simple and efficient way to create mbed Device Client in
|
||||
C.
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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,20 @@
|
|||
{
|
||||
"name": "mbed-client-c",
|
||||
"version": "2.7.7",
|
||||
"description": "Nanostack NSDL and COAP library",
|
||||
"keywords": [
|
||||
"coap",
|
||||
"nanostack"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"extraIncludes": [
|
||||
"nsdl-c",
|
||||
"source/libNsdl/src/include",
|
||||
"source/libCoap/src/include"
|
||||
],
|
||||
"dependencies": {
|
||||
"nanostack-libservice": "^3.0.0",
|
||||
"mbed-trace": ">=0.2.0,<2.0.0"
|
||||
},
|
||||
"targetDependencies": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,398 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_coap_header.h
|
||||
*
|
||||
* \brief CoAP C-library User header interface header file
|
||||
*/
|
||||
|
||||
#ifndef SN_COAP_HEADER_H_
|
||||
#define SN_COAP_HEADER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Handle structure */
|
||||
struct coap_s;
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Version
|
||||
*/
|
||||
typedef enum coap_version_ {
|
||||
COAP_VERSION_1 = 0x40,
|
||||
COAP_VERSION_UNKNOWN = 0xFF
|
||||
} coap_version_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Message type, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_msg_type_ {
|
||||
COAP_MSG_TYPE_CONFIRMABLE = 0x00, /**< Reliable Request messages */
|
||||
COAP_MSG_TYPE_NON_CONFIRMABLE = 0x10, /**< Non-reliable Request and Response messages */
|
||||
COAP_MSG_TYPE_ACKNOWLEDGEMENT = 0x20, /**< Response to a Confirmable Request */
|
||||
COAP_MSG_TYPE_RESET = 0x30 /**< Answer a Bad Request */
|
||||
} sn_coap_msg_type_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Message code, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_msg_code_ {
|
||||
COAP_MSG_CODE_EMPTY = 0,
|
||||
COAP_MSG_CODE_REQUEST_GET = 1,
|
||||
COAP_MSG_CODE_REQUEST_POST = 2,
|
||||
COAP_MSG_CODE_REQUEST_PUT = 3,
|
||||
COAP_MSG_CODE_REQUEST_DELETE = 4,
|
||||
|
||||
COAP_MSG_CODE_RESPONSE_CREATED = 65,
|
||||
COAP_MSG_CODE_RESPONSE_DELETED = 66,
|
||||
COAP_MSG_CODE_RESPONSE_VALID = 67,
|
||||
COAP_MSG_CODE_RESPONSE_CHANGED = 68,
|
||||
COAP_MSG_CODE_RESPONSE_CONTENT = 69,
|
||||
COAP_MSG_CODE_RESPONSE_CONTINUE = 95,
|
||||
COAP_MSG_CODE_RESPONSE_BAD_REQUEST = 128,
|
||||
COAP_MSG_CODE_RESPONSE_UNAUTHORIZED = 129,
|
||||
COAP_MSG_CODE_RESPONSE_BAD_OPTION = 130,
|
||||
COAP_MSG_CODE_RESPONSE_FORBIDDEN = 131,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_FOUND = 132,
|
||||
COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED = 133,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE = 134,
|
||||
COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE = 136,
|
||||
COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED = 140,
|
||||
COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE = 141,
|
||||
COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT = 143,
|
||||
COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR = 160,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_IMPLEMENTED = 161,
|
||||
COAP_MSG_CODE_RESPONSE_BAD_GATEWAY = 162,
|
||||
COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE = 163,
|
||||
COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT = 164,
|
||||
COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED = 165
|
||||
} sn_coap_msg_code_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Option number, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_option_numbers_ {
|
||||
COAP_OPTION_IF_MATCH = 1,
|
||||
COAP_OPTION_URI_HOST = 3,
|
||||
COAP_OPTION_ETAG = 4,
|
||||
COAP_OPTION_IF_NONE_MATCH = 5,
|
||||
COAP_OPTION_OBSERVE = 6,
|
||||
COAP_OPTION_URI_PORT = 7,
|
||||
COAP_OPTION_LOCATION_PATH = 8,
|
||||
COAP_OPTION_URI_PATH = 11,
|
||||
COAP_OPTION_CONTENT_FORMAT = 12,
|
||||
COAP_OPTION_MAX_AGE = 14,
|
||||
COAP_OPTION_URI_QUERY = 15,
|
||||
COAP_OPTION_ACCEPT = 17,
|
||||
COAP_OPTION_LOCATION_QUERY = 20,
|
||||
COAP_OPTION_BLOCK2 = 23,
|
||||
COAP_OPTION_BLOCK1 = 27,
|
||||
COAP_OPTION_SIZE2 = 28,
|
||||
COAP_OPTION_PROXY_URI = 35,
|
||||
COAP_OPTION_PROXY_SCHEME = 39,
|
||||
COAP_OPTION_SIZE1 = 60
|
||||
// 128 = (Reserved)
|
||||
// 132 = (Reserved)
|
||||
// 136 = (Reserved)
|
||||
} sn_coap_option_numbers_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Content Format codes
|
||||
*/
|
||||
typedef enum sn_coap_content_format_ {
|
||||
COAP_CT_NONE = -1,
|
||||
COAP_CT_TEXT_PLAIN = 0,
|
||||
COAP_CT_LINK_FORMAT = 40,
|
||||
COAP_CT_XML = 41,
|
||||
COAP_CT_OCTET_STREAM = 42,
|
||||
COAP_CT_EXI = 47,
|
||||
COAP_CT_JSON = 50
|
||||
} sn_coap_content_format_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP status, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_status_ {
|
||||
COAP_STATUS_OK = 0, /**< Default value is OK */
|
||||
COAP_STATUS_PARSER_ERROR_IN_HEADER = 1, /**< CoAP will send Reset message to invalid message sender */
|
||||
COAP_STATUS_PARSER_DUPLICATED_MSG = 2, /**< CoAP will send Acknowledgement message to duplicated message sender */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING = 3, /**< User will get whole message after all message blocks received.
|
||||
User must release messages with this status. */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_ACK = 4, /**< Acknowledgement for sent Blockwise message received */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED = 5, /**< Blockwise message received but not supported by compiling switch */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED = 6, /**< Blockwise message fully received and returned to app.
|
||||
User must take care of releasing whole payload of the blockwise messages */
|
||||
COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED = 7 /**< When re-transmissions have been done and ACK not received, CoAP library calls
|
||||
RX callback with this status */
|
||||
} sn_coap_status_e;
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief Structure for CoAP Options
|
||||
*/
|
||||
typedef struct sn_coap_options_list_ {
|
||||
|
||||
uint8_t max_age_len; /**< 0-4 bytes. */
|
||||
uint8_t *max_age_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint16_t proxy_uri_len; /**< 1-1034 bytes. */
|
||||
uint8_t *proxy_uri_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint8_t etag_len; /**< 1-8 bytes. Repeatable */
|
||||
uint8_t *etag_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint16_t uri_host_len; /**< 1-255 bytes. */
|
||||
uint8_t *uri_host_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint16_t location_path_len; /**< 0-255 bytes. Repeatable */
|
||||
uint8_t *location_path_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint8_t uri_port_len; /**< 0-2 bytes. */
|
||||
uint8_t *uri_port_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint16_t location_query_len; /**< 0-255 bytes. Repeatable */
|
||||
uint8_t *location_query_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint8_t observe;
|
||||
uint8_t observe_len; /**< 0-2 bytes. */
|
||||
uint8_t *observe_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint8_t accept_len; /**< 0-2 bytes. Repeatable */
|
||||
uint8_t *accept_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint16_t uri_query_len; /**< 1-255 bytes. Repeatable */
|
||||
uint8_t *uri_query_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint8_t block1_len; /**< 0-3 bytes. */
|
||||
uint8_t *block1_ptr; /**< Not for User */
|
||||
|
||||
uint8_t block2_len; /**< 0-3 bytes. */
|
||||
uint8_t *block2_ptr; /**< Not for User */
|
||||
|
||||
uint8_t size1_len; /**< 0-4 bytes. */
|
||||
uint8_t *size1_ptr; /**< Not for User */
|
||||
|
||||
uint8_t size2_len; /**< 0-4 bytes. */
|
||||
uint8_t *size2_ptr; /**< Not for User */
|
||||
} sn_coap_options_list_s;
|
||||
|
||||
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
|
||||
/* !!! Main CoAP message struct !!! */
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
|
||||
|
||||
/**
|
||||
* \brief Main CoAP message struct
|
||||
*/
|
||||
typedef struct sn_coap_hdr_ {
|
||||
sn_coap_status_e coap_status; /**< Used for telling to User special cases when parsing message */
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * Header * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
sn_coap_msg_type_e msg_type; /**< Confirmable, Non-Confirmable, Acknowledgement or Reset */
|
||||
sn_coap_msg_code_e msg_code; /**< Empty: 0; Requests: 1-31; Responses: 64-191 */
|
||||
uint16_t msg_id; /**< Message ID. Parser sets parsed message ID, builder sets message ID of built coap message */
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * Options * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
/* Here are most often used Options */
|
||||
|
||||
uint16_t uri_path_len; /**< 0-255 bytes. Repeatable. */
|
||||
uint8_t *uri_path_ptr; /**< Must be set to NULL if not used. E.g: temp1/temp2 */
|
||||
|
||||
uint8_t token_len; /**< 1-8 bytes. */
|
||||
uint8_t *token_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
uint8_t content_type_len; /**< 0-2 bytes. */
|
||||
uint8_t *content_type_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
/* Here are not so often used Options */
|
||||
sn_coap_options_list_s *options_list_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * Payload * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
uint16_t payload_len; /**< Must be set to zero if not used */
|
||||
uint8_t *payload_ptr; /**< Must be set to NULL if not used */
|
||||
} sn_coap_hdr_s;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* * * * EXTERNAL FUNCTION PROTOTYPES * * * */
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
/**
|
||||
* \fn 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)
|
||||
*
|
||||
* \brief Parses CoAP message from given Packet data
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param packet_data_len is length of given Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *packet_data_ptr is source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *coap_version_ptr is destination for parsed CoAP specification version
|
||||
*
|
||||
* \return Return value is pointer to parsed CoAP message.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Failure in given pointer (= NULL)\n
|
||||
* -Failure in memory allocation (malloc() returns NULL)
|
||||
*/
|
||||
extern 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);
|
||||
|
||||
/**
|
||||
* \fn void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr)
|
||||
*
|
||||
* \brief Releases memory of given CoAP message
|
||||
*
|
||||
* Note!!! Does not release Payload part
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param *freed_coap_msg_ptr is pointer to released CoAP message
|
||||
*/
|
||||
extern void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr)
|
||||
*
|
||||
* \brief Builds an outgoing message buffer from a CoAP header structure.
|
||||
*
|
||||
* \param *dst_packet_data_ptr is pointer to allocated destination to built CoAP packet
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to source structure for building Packet data
|
||||
*
|
||||
* \return Return value is byte count of built Packet data. In failure cases:\n
|
||||
* -1 = Failure in given CoAP header structure\n
|
||||
* -2 = Failure in given pointer (= NULL)
|
||||
*/
|
||||
extern int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr)
|
||||
*
|
||||
* \brief Calculates needed Packet data memory size for given CoAP message
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to data which needed Packet
|
||||
* data length is calculated
|
||||
*
|
||||
* \return Return value is count of needed memory as bytes for build Packet data
|
||||
* Null if failed
|
||||
*/
|
||||
extern uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_size)
|
||||
*
|
||||
* \brief Builds an outgoing message buffer from a CoAP header structure.
|
||||
*
|
||||
* \param *dst_packet_data_ptr is pointer to allocated destination to built CoAP packet
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to source structure for building Packet data
|
||||
*
|
||||
* \param blockwise_payload_size Blockwise message maximum payload size
|
||||
*
|
||||
* \return Return value is byte count of built Packet data. In failure cases:\n
|
||||
* -1 = Failure in given CoAP header structure\n
|
||||
* -2 = Failure in given pointer (= NULL)
|
||||
*/
|
||||
extern int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size);
|
||||
|
||||
/**
|
||||
* \fn uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
|
||||
*
|
||||
* \brief Calculates needed Packet data memory size for given CoAP message
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to data which needed Packet
|
||||
* data length is calculated
|
||||
* \param blockwise_payload_size Blockwise message maximum payload size
|
||||
*
|
||||
* \return Return value is count of needed memory as bytes for build Packet data
|
||||
* Null if failed
|
||||
*/
|
||||
extern uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size);
|
||||
|
||||
/**
|
||||
* \fn sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
|
||||
*
|
||||
* \brief Prepares generic response packet from a request packet. This function allocates memory for the resulting sn_coap_hdr_s
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param *coap_packet_ptr The request packet pointer
|
||||
* \param msg_code response messages code
|
||||
*
|
||||
* \return *coap_packet_ptr The allocated and pre-filled response packet pointer
|
||||
* NULL Error in parsing the request
|
||||
*
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code);
|
||||
|
||||
/**
|
||||
* \brief Initialise a message structure to empty
|
||||
*
|
||||
* \param *coap_msg_ptr is pointer to CoAP message to initialise
|
||||
*
|
||||
* \return Return value is pointer passed in
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_parser_init_message(sn_coap_hdr_s *coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \brief Allocate an empty message structure
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \return Return value is pointer to an empty CoAP message.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Failure in given pointer (= NULL)\n
|
||||
* -Failure in memory allocation (malloc() returns NULL)
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_parser_alloc_message(struct coap_s *handle);
|
||||
|
||||
/**
|
||||
* \brief Allocate an empty options structure
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param *coap_msg_ptr is pointer to CoAP message that will contain the options
|
||||
*
|
||||
* If the message already has a pointer to an option structure, that pointer
|
||||
* is returned, rather than a new structure being allocated.
|
||||
*
|
||||
* \return Return value is pointer to the CoAP options structure.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Failure in given pointer (= NULL)\n
|
||||
* -Failure in memory allocation (malloc() returns NULL)
|
||||
*/
|
||||
extern sn_coap_options_list_s *sn_coap_parser_alloc_options(struct coap_s *handle, sn_coap_hdr_s *coap_msg_ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SN_COAP_HEADER_H_ */
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_coap_protocol.h
|
||||
*
|
||||
* \brief CoAP C-library User protocol interface header file
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_PROTOCOL_H_
|
||||
#define SN_COAP_PROTOCOL_H_
|
||||
|
||||
#include "sn_coap_header.h"
|
||||
|
||||
/**
|
||||
* \fn 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)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *),
|
||||
int8_t (*used_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *)
|
||||
*
|
||||
* \brief Initializes CoAP Protocol part. When using libNsdl, sn_nsdl_init() calls this function.
|
||||
*
|
||||
* \param *used_malloc_func_ptr is function pointer for used memory allocation function.
|
||||
*
|
||||
* \param *used_free_func_ptr is function pointer for used memory free function.
|
||||
*
|
||||
* \param *used_tx_callback_ptr function callback pointer to tx function for sending coap messages
|
||||
*
|
||||
* \param *used_rx_callback_ptr used to return CoAP header struct with status COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED
|
||||
* when re-sendings exceeded. If set to NULL, no error message is returned.
|
||||
*
|
||||
* \return Pointer to handle when success
|
||||
* Null if failed
|
||||
*/
|
||||
|
||||
extern 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 *));
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_destroy(void)
|
||||
*
|
||||
* \brief Frees all memory from CoAP protocol part
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \return Return value is always 0
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_destroy(struct coap_s *handle);
|
||||
|
||||
/**
|
||||
* \fn 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)
|
||||
*
|
||||
* \brief Builds Packet data from given CoAP header structure to be sent
|
||||
*
|
||||
* \param *dst_addr_ptr is pointer to destination address where CoAP message
|
||||
* will be sent (CoAP builder needs that information for message resending purposes)
|
||||
*
|
||||
* \param *dst_packet_data_ptr is pointer to destination of built Packet data
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to source of built Packet data
|
||||
*
|
||||
* \param param void pointer that will be passed to tx/rx function callback when those are called.
|
||||
*
|
||||
* \return Return value is byte count of built Packet data.\n
|
||||
* Note: If message is blockwised, all payload is not sent at the same time\n
|
||||
* In failure cases:\n
|
||||
* -1 = Failure in CoAP header structure\n
|
||||
* -2 = Failure in given pointer (= NULL)\n
|
||||
* -3 = Failure in Reset message\ŋ
|
||||
* If there is not enough memory (or User given limit exceeded) for storing
|
||||
* resending messages, situation is ignored.
|
||||
*/
|
||||
extern 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);
|
||||
|
||||
/**
|
||||
* \fn 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)
|
||||
*
|
||||
* \brief Parses received CoAP message from given Packet data
|
||||
*
|
||||
* \param *src_addr_ptr is pointer to source address of received CoAP message
|
||||
* (CoAP parser needs that information for Message acknowledgement)
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param packet_data_len is length of given Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *packet_data_ptr is pointer to source of Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param param void pointer that will be passed to tx/rx function callback when those are called.
|
||||
*
|
||||
* \return Return value is pointer to parsed CoAP message structure. This structure includes also coap_status field.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Given NULL pointer\n
|
||||
* -Failure in parsed header of non-confirmable message\ŋ
|
||||
* -Out of memory (malloc() returns NULL)
|
||||
*/
|
||||
extern 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 *);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time)
|
||||
*
|
||||
* \brief Sends CoAP messages from re-sending queue, if there is any.
|
||||
* Cleans also old messages from the duplication list and from block receiving list
|
||||
*
|
||||
* This function can be called e.g. once in a second but also more frequently.
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param current_time is System time in seconds. This time is
|
||||
* used for message re-sending timing and to identify old saved data.
|
||||
*
|
||||
* \return 0 if success
|
||||
* -1 if failed
|
||||
*/
|
||||
|
||||
extern int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_block_size(uint16_t block_size)
|
||||
*
|
||||
* \brief If block transfer is enabled, this function changes the block size.
|
||||
*
|
||||
* \param uint16_t block_size maximum size of CoAP payload. Valid sizes are 16, 32, 64, 128, 256, 512 and 1024 bytes
|
||||
* \return 0 = success
|
||||
* -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_block_size(struct coap_s *handle, uint16_t block_size);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_duplicate_buffer_size(uint8_t message_count)
|
||||
*
|
||||
* \brief If dublicate message detection is enabled, this function changes buffer size.
|
||||
*
|
||||
* \param uint8_t message_count max number of messages saved for duplicate control
|
||||
* \return 0 = success
|
||||
* -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_duplicate_buffer_size(struct coap_s *handle, uint8_t message_count);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_retransmission_parameters(uint8_t resending_count, uint8_t resending_intervall)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function changes resending count and interval.
|
||||
*
|
||||
* \param uint8_t resending_count max number of resendings for message
|
||||
* \param uint8_t resending_intervall message resending intervall in seconds
|
||||
* \return 0 = success, -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_retransmission_parameters(struct coap_s *handle,
|
||||
uint8_t resending_count, uint8_t resending_interval);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_retransmission_buffer(uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function changes message retransmission queue size.
|
||||
* Set size to '0' to disable feature. If both are set to '0', then re-sendings are disabled.
|
||||
*
|
||||
* \param uint8_t buffer_size_messages queue size - maximum number of messages to be saved to queue
|
||||
* \param uint8_t buffer_size_bytes queue size - maximum size of messages saved to queue
|
||||
* \return 0 = success, -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_retransmission_buffer(struct coap_s *handle,
|
||||
uint8_t buffer_size_messages, uint16_t buffer_size_bytes);
|
||||
|
||||
/**
|
||||
* \fn void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle)
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function removes all messages from the retransmission queue.
|
||||
*/
|
||||
extern void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle);
|
||||
|
||||
#endif /* SN_COAP_PROTOCOL_H_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_nsdl.h
|
||||
*
|
||||
* \brief libNsdl generic header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SN_NSDL_H_
|
||||
#define SN_NSDL_H_
|
||||
|
||||
/* * * Common * * */
|
||||
|
||||
#define SN_NSDL_SUCCESS 0
|
||||
#define SN_NSDL_FAILURE (-1)
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Used protocol
|
||||
*/
|
||||
typedef enum sn_nsdl_capab_ {
|
||||
SN_NSDL_PROTOCOL_HTTP = 0x01, /**< Unsupported */
|
||||
SN_NSDL_PROTOCOL_HTTPS = 0x02, /**< Unsupported */
|
||||
SN_NSDL_PROTOCOL_COAP = 0x04 /**< Supported */
|
||||
} sn_nsdl_capab_e;
|
||||
|
||||
/**
|
||||
* \brief Address type of given address
|
||||
*/
|
||||
typedef enum sn_nsdl_addr_type_ {
|
||||
SN_NSDL_ADDRESS_TYPE_IPV6 = 0x01, /**< Supported */
|
||||
SN_NSDL_ADDRESS_TYPE_IPV4 = 0x02, /**< Supported */
|
||||
SN_NSDL_ADDRESS_TYPE_HOSTNAME = 0x03, /**< Unsupported */
|
||||
SN_NSDL_ADDRESS_TYPE_NONE = 0xFF
|
||||
} sn_nsdl_addr_type_e;
|
||||
|
||||
|
||||
#define SN_NDSL_RESOURCE_NOT_REGISTERED 0
|
||||
#define SN_NDSL_RESOURCE_REGISTERING 1
|
||||
#define SN_NDSL_RESOURCE_REGISTERED 2
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief Address structure of Packet data
|
||||
*/
|
||||
typedef struct sn_nsdl_addr_ {
|
||||
sn_nsdl_addr_type_e type;
|
||||
|
||||
uint8_t addr_len;
|
||||
uint8_t *addr_ptr;
|
||||
|
||||
uint16_t port;
|
||||
|
||||
} sn_nsdl_addr_s;
|
||||
|
||||
/**
|
||||
* \brief Used for creating manually registration message with sn_coap_register()
|
||||
*/
|
||||
typedef struct registration_info_ {
|
||||
uint8_t *endpoint_ptr; /**< Endpoint name */
|
||||
uint8_t endpoint_len;
|
||||
|
||||
uint8_t *endpoint_type_ptr; /**< Endpoint type */
|
||||
uint8_t endpoint_type_len;
|
||||
|
||||
uint8_t *links_ptr; /**< Resource registration string */
|
||||
uint16_t links_len;
|
||||
|
||||
} registration_info_t;
|
||||
|
||||
#endif /* SN_NSDL_H_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,684 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_nsdl_lib.h
|
||||
*
|
||||
* \brief NanoService Devices Library header file
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SN_NSDL_LIB_H_
|
||||
#define SN_NSDL_LIB_H_
|
||||
|
||||
#include "ns_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SN_NSDL_ENDPOINT_NOT_REGISTERED 0
|
||||
#define SN_NSDL_ENDPOINT_IS_REGISTERED 1
|
||||
|
||||
/* Handle structure */
|
||||
struct nsdl_s;
|
||||
|
||||
/**
|
||||
* \brief Received device server security
|
||||
*/
|
||||
typedef enum omalw_server_security_ {
|
||||
SEC_NOT_SET = -1,
|
||||
PSK = 0,
|
||||
RPK = 1,
|
||||
CERTIFICATE = 2,
|
||||
NO_SEC = 3
|
||||
} omalw_server_security_t;
|
||||
|
||||
/**
|
||||
* \brief Endpoint binding and mode
|
||||
*/
|
||||
typedef enum sn_nsdl_oma_binding_and_mode_ {
|
||||
BINDING_MODE_NOT_SET = 0,
|
||||
BINDING_MODE_U = 0x01,
|
||||
BINDING_MODE_Q = 0x02,
|
||||
BINDING_MODE_S = 0x04
|
||||
} sn_nsdl_oma_binding_and_mode_t;
|
||||
|
||||
/**
|
||||
* \brief Endpoint registration mode.
|
||||
* If REGISTER_WITH_RESOURCES, endpoint sends list of all resources during registration.
|
||||
* If REGISTER_WITH_TEMPLATE, endpoint sends registration without resource list. Device server must have
|
||||
* correctly configured template.
|
||||
*/
|
||||
typedef enum sn_nsdl_registration_mode_ {
|
||||
REGISTER_WITH_RESOURCES = 0,
|
||||
REGISTER_WITH_TEMPLATE
|
||||
} sn_nsdl_registration_mode_t;
|
||||
|
||||
|
||||
typedef struct omalw_certificate_list_ {
|
||||
uint8_t certificate_chain_len;
|
||||
uint8_t *certificate_ptr[2];
|
||||
uint16_t certificate_len[2];
|
||||
uint8_t *own_private_key_ptr;
|
||||
uint16_t own_private_key_len;
|
||||
} omalw_certificate_list_t;
|
||||
|
||||
/**
|
||||
* \brief Endpoint registration parameters
|
||||
*/
|
||||
typedef struct sn_nsdl_ep_parameters_ {
|
||||
uint8_t *endpoint_name_ptr; /**< Endpoint name */
|
||||
uint8_t endpoint_name_len;
|
||||
|
||||
uint8_t *domain_name_ptr; /**< Domain to register. If null, NSP uses default domain */
|
||||
uint8_t domain_name_len;
|
||||
|
||||
uint8_t *type_ptr; /**< Endpoint type */
|
||||
uint8_t type_len;
|
||||
|
||||
uint8_t *lifetime_ptr; /**< Endpoint lifetime in seconds. eg. "1200" = 1200 seconds */
|
||||
uint8_t lifetime_len;
|
||||
|
||||
sn_nsdl_registration_mode_t ds_register_mode; /**< Defines registration mode */
|
||||
sn_nsdl_oma_binding_and_mode_t binding_and_mode; /**< Defines endpoints binding and mode */
|
||||
|
||||
uint8_t *location_ptr; /**< Endpoint location in server, optional parameter,default is NULL */
|
||||
uint8_t location_len;
|
||||
|
||||
} sn_nsdl_ep_parameters_s;
|
||||
|
||||
/**
|
||||
* \brief For internal use
|
||||
*/
|
||||
typedef struct sn_nsdl_sent_messages_ {
|
||||
uint16_t msg_id_number;
|
||||
uint8_t message_type;
|
||||
ns_list_link_t link;
|
||||
} sn_nsdl_sent_messages_s;
|
||||
|
||||
/**
|
||||
* \brief Includes resource path
|
||||
*/
|
||||
typedef struct sn_grs_resource_ {
|
||||
uint8_t pathlen;
|
||||
uint8_t *path;
|
||||
} sn_grs_resource_s;
|
||||
|
||||
/**
|
||||
* \brief Table of created resources
|
||||
*/
|
||||
typedef struct sn_grs_resource_list_ {
|
||||
uint8_t res_count; /**< Number of resources */
|
||||
sn_grs_resource_s *res;
|
||||
} sn_grs_resource_list_s;
|
||||
|
||||
/**
|
||||
* \brief Resource access rights
|
||||
*/
|
||||
typedef enum sn_grs_resource_acl_ {
|
||||
SN_GRS_GET_ALLOWED = 0x01 ,
|
||||
SN_GRS_PUT_ALLOWED = 0x02,
|
||||
SN_GRS_POST_ALLOWED = 0x04,
|
||||
SN_GRS_DELETE_ALLOWED = 0x08
|
||||
} sn_grs_resource_acl_e;
|
||||
|
||||
|
||||
typedef enum sn_nsdl_oma_device_error_ {
|
||||
NO_ERROR = 0,
|
||||
LOW_BATTERY_POWER = 1,
|
||||
EXTERNAL_POWER_SUPPLY_OFF = 2,
|
||||
GPS_MODULE_FAILURE = 3,
|
||||
LOW_RECEIVED_SIGNAL_STRENGTH = 4,
|
||||
OUT_OF_MEMORY = 5,
|
||||
SMS_FAILURE = 6,
|
||||
IP_CONN_FAILURE = 7,
|
||||
PERIPHERAL_MALFUNCTION = 8
|
||||
} sn_nsdl_oma_device_error_t;
|
||||
|
||||
/**
|
||||
* \brief Defines the resource mode
|
||||
*/
|
||||
typedef enum sn_nsdl_resource_mode_ {
|
||||
SN_GRS_STATIC, /**< Static resources have some value that doesn't change */
|
||||
SN_GRS_DYNAMIC, /**< Dynamic resources are handled in application. Therefore one must give function callback pointer to them */
|
||||
SN_GRS_DIRECTORY /**< Directory resources are unused and unsupported */
|
||||
} sn_nsdl_resource_mode_e;
|
||||
|
||||
/**
|
||||
* \brief Resource registration parameters
|
||||
*/
|
||||
typedef struct sn_nsdl_resource_parameters_ {
|
||||
uint8_t *resource_type_ptr;
|
||||
uint16_t resource_type_len;
|
||||
|
||||
uint8_t *interface_description_ptr;
|
||||
uint16_t interface_description_len;
|
||||
|
||||
uint8_t coap_content_type;
|
||||
|
||||
uint8_t mime_content_type;
|
||||
|
||||
uint8_t observable;
|
||||
|
||||
uint8_t registered;
|
||||
|
||||
} sn_nsdl_resource_parameters_s;
|
||||
|
||||
/**
|
||||
* \brief Defines parameters for the resource.
|
||||
*/
|
||||
typedef struct sn_nsdl_resource_info_ {
|
||||
sn_nsdl_resource_parameters_s *resource_parameters_ptr;
|
||||
|
||||
sn_nsdl_resource_mode_e mode; /**< STATIC etc.. */
|
||||
|
||||
uint16_t pathlen; /**< Address */
|
||||
uint8_t *path;
|
||||
|
||||
uint16_t resourcelen; /**< 0 if dynamic resource, resource information in static resource */
|
||||
uint8_t *resource; /**< NULL if dynamic resource */
|
||||
|
||||
sn_grs_resource_acl_e access;
|
||||
|
||||
uint8_t (*sn_grs_dyn_res_callback)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *, sn_nsdl_capab_e);
|
||||
|
||||
ns_list_link_t link;
|
||||
|
||||
uint8_t publish_uri;
|
||||
|
||||
} sn_nsdl_resource_info_s;
|
||||
|
||||
/**
|
||||
* \brief Defines OMA device object parameters.
|
||||
*/
|
||||
typedef struct sn_nsdl_oma_device_ {
|
||||
sn_nsdl_oma_device_error_t error_code; /**< Error code. Mandatory. Can be more than one */
|
||||
uint8_t (*sn_oma_device_boot_callback)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *, sn_nsdl_capab_e); /**< Device boot callback function. If defined, this is called when reset request is received */
|
||||
|
||||
} sn_nsdl_oma_device_t;
|
||||
|
||||
/**
|
||||
* \brief Defines OMAlw server information
|
||||
*/
|
||||
typedef struct sn_nsdl_oma_server_info_ {
|
||||
sn_nsdl_addr_s *omalw_address_ptr;
|
||||
omalw_server_security_t omalw_server_security;
|
||||
|
||||
} sn_nsdl_oma_server_info_t;
|
||||
|
||||
/**
|
||||
* \brief Defines endpoint parameters to OMA bootstrap.
|
||||
*/
|
||||
typedef struct sn_nsdl_bs_ep_info_ {
|
||||
void (*oma_bs_status_cb)(sn_nsdl_oma_server_info_t *); /**< Callback for OMA bootstrap status */
|
||||
sn_nsdl_oma_device_t *device_object; /**< OMA LWM2M mandatory device resources */
|
||||
void (*oma_bs_status_cb_handle)(sn_nsdl_oma_server_info_t *,
|
||||
struct nsdl_s *); /**< Callback for OMA bootstrap status with nsdl handle */
|
||||
} sn_nsdl_bs_ep_info_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \fn struct nsdl_s *sn_nsdl_init (uint8_t (*sn_nsdl_tx_cb)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *),
|
||||
* uint8_t (*sn_nsdl_rx_cb)(sn_coap_hdr_s *, sn_nsdl_addr_s *),
|
||||
* sn_nsdl_mem_s *sn_memory)
|
||||
*
|
||||
* \brief Initialization function for NSDL library. Initializes NSDL, GRS, HTTP and CoAP.
|
||||
*
|
||||
* \param *sn_nsdl_tx_callback A callback function for sending messages.
|
||||
*
|
||||
* \param *sn_nsdl_rx_callback A callback function for parsed messages. If received message is not CoAP protocol message (eg. ACK), message for GRS (GET, PUT, POST, DELETE) or
|
||||
* reply for some DS messages (register message etc.), rx callback will be called.
|
||||
*
|
||||
* \param *sn_memory Memory structure which includes function pointers to the allocation and free functions.
|
||||
*
|
||||
* \return pointer to created handle structure. NULL if failed
|
||||
*/
|
||||
struct nsdl_s *sn_nsdl_init(uint8_t (*sn_nsdl_tx_cb)(struct nsdl_s *, sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *),
|
||||
uint8_t (*sn_nsdl_rx_cb)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *),
|
||||
void *(*sn_nsdl_alloc)(uint16_t), void (*sn_nsdl_free)(void *));
|
||||
|
||||
/**
|
||||
* \fn extern uint16_t sn_nsdl_register_endpoint(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr);
|
||||
*
|
||||
* \brief Registers endpoint to mbed Device Server.
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *endpoint_info_ptr Contains endpoint information.
|
||||
*
|
||||
* \return registration message ID, 0 if failed
|
||||
*/
|
||||
extern uint16_t sn_nsdl_register_endpoint(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr);
|
||||
|
||||
/**
|
||||
* \fn extern uint16_t sn_nsdl_unregister_endpoint(struct nsdl_s *handle)
|
||||
*
|
||||
* \brief Sends unregister-message to mbed Device Server.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*
|
||||
* \return unregistration message ID, 0 if failed
|
||||
*/
|
||||
extern uint16_t sn_nsdl_unregister_endpoint(struct nsdl_s *handle);
|
||||
|
||||
/**
|
||||
* \fn extern uint16_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint8_t lt_len);
|
||||
*
|
||||
* \brief Update the registration with mbed Device Server.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *lt_ptr Pointer to lifetime value string in ascii form, eg. "1200"
|
||||
* \param lt_len Length of the lifetime string
|
||||
*
|
||||
* \return registration update message ID, 0 if failed
|
||||
*/
|
||||
extern uint16_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint8_t lt_len);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_set_endpoint_location(struct nsdl_s *handle, uint8_t *location_ptr, uint8_t location_len);
|
||||
*
|
||||
* \brief Sets the location receievd from Device Server.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *lt_ptr Pointer to location value string , eg. "s322j4k"
|
||||
* \param lt_len Length of the location string
|
||||
*
|
||||
* \return success, 0 if failed -1
|
||||
*/
|
||||
extern int8_t sn_nsdl_set_endpoint_location(struct nsdl_s *handle, uint8_t *location_ptr, uint8_t location_len);
|
||||
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_is_ep_registered(struct nsdl_s *handle)
|
||||
*
|
||||
* \brief Checks if endpoint is registered.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*
|
||||
* \return 1 Endpoint registration is done successfully
|
||||
* \return 0 Endpoint is not registered
|
||||
*/
|
||||
extern int8_t sn_nsdl_is_ep_registered(struct nsdl_s *handle);
|
||||
|
||||
/**
|
||||
* \fn extern void sn_nsdl_nsp_lost(struct nsdl_s *handle);
|
||||
*
|
||||
* \brief A function to inform mbed Device C client library if application detects a fault in mbed Device Server registration.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*
|
||||
* After calling this function sn_nsdl_is_ep_registered() will return "not registered".
|
||||
*/
|
||||
extern void sn_nsdl_nsp_lost(struct nsdl_s *handle);
|
||||
|
||||
/**
|
||||
* \fn extern uint16_t sn_nsdl_send_observation_notification(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len,
|
||||
* uint8_t *payload_ptr, uint16_t payload_len,
|
||||
* uint8_t *observe_ptr, uint8_t observe_len,
|
||||
* sn_coap_msg_type_e message_type, uint8_t content_type)
|
||||
*
|
||||
*
|
||||
* \brief Sends observation message to mbed Device Server
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *token_ptr Pointer to token to be used
|
||||
* \param token_len Token length
|
||||
* \param *payload_ptr Pointer to payload to be sent
|
||||
* \param payload_len Payload length
|
||||
* \param *observe_ptr Pointer to observe number to be sent
|
||||
* \param observe_len Observe number len
|
||||
* \param message_type Observation message type (confirmable or non-confirmable)
|
||||
* \param content_type Observation message payload contetnt type
|
||||
*
|
||||
* \return !0 Success, observation messages message ID
|
||||
* \return 0 Failure
|
||||
*/
|
||||
extern uint16_t sn_nsdl_send_observation_notification(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len,
|
||||
uint8_t *payload_ptr, uint16_t payload_len,
|
||||
uint8_t *observe_ptr, uint8_t observe_len,
|
||||
sn_coap_msg_type_e message_type,
|
||||
uint8_t content_type);
|
||||
|
||||
/**
|
||||
* \fn extern uint16_t sn_nsdl_send_observation_notification_with_uri_path(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len,
|
||||
* uint8_t *payload_ptr, uint16_t payload_len,
|
||||
* uint8_t *observe_ptr, uint8_t observe_len,
|
||||
* sn_coap_msg_type_e message_type, uint8_t content_type,
|
||||
* uint8_t *uri_path_ptr,
|
||||
* uint16_t uri_path_len)
|
||||
*
|
||||
*
|
||||
* \brief Sends observation message to mbed Device Server with uri path
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *token_ptr Pointer to token to be used
|
||||
* \param token_len Token length
|
||||
* \param *payload_ptr Pointer to payload to be sent
|
||||
* \param payload_len Payload length
|
||||
* \param *observe_ptr Pointer to observe number to be sent
|
||||
* \param observe_len Observe number len
|
||||
* \param message_type Observation message type (confirmable or non-confirmable)
|
||||
* \param content_type Observation message payload contetnt type
|
||||
* \param uri_path_ptr Pointer to uri path to be sent
|
||||
* \param uri_path_len Uri path len
|
||||
*
|
||||
* \return !0 Success, observation messages message ID
|
||||
* \return 0 Failure
|
||||
*/
|
||||
extern uint16_t sn_nsdl_send_observation_notification_with_uri_path(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len,
|
||||
uint8_t *payload_ptr, uint16_t payload_len,
|
||||
uint8_t *observe_ptr, uint8_t observe_len,
|
||||
sn_coap_msg_type_e message_type,
|
||||
uint8_t content_type,
|
||||
uint8_t *uri_path_ptr,
|
||||
uint16_t uri_path_len);
|
||||
|
||||
/**
|
||||
* \fn extern uint32_t sn_nsdl_get_version(void)
|
||||
*
|
||||
* \brief Version query function.
|
||||
*
|
||||
* Used to retrieve the version information from the mbed Device C Client library.
|
||||
*
|
||||
* \return Pointer to library version string
|
||||
*/
|
||||
extern char *sn_nsdl_get_version(void);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src)
|
||||
*
|
||||
* \brief To push CoAP packet to mbed Device C Client library
|
||||
*
|
||||
* Used to push an CoAP packet to mbed Device C Client library for processing.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*
|
||||
* \param *packet Pointer to a uint8_t array containing the packet (including the CoAP headers).
|
||||
* After successful execution this array may contain the response packet.
|
||||
*
|
||||
* \param *packet_len Pointer to length of the packet. After successful execution this array may contain the length
|
||||
* of the response packet.
|
||||
*
|
||||
* \param *src Pointer to packet source address information. After successful execution this array may contain
|
||||
* the destination address of the response packet.
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_exec(struct nsdl_s *handle, uint32_t time);
|
||||
*
|
||||
* \brief CoAP retransmission function.
|
||||
*
|
||||
* Used to give execution time for the mbed Device C Client library for retransmissions.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*
|
||||
* \param time Time in seconds.
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_exec(struct nsdl_s *handle, uint32_t time);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_create_resource(struct nsdl_s *handle, sn_nsdl_resource_info_s *res);
|
||||
*
|
||||
* \brief Resource creating function.
|
||||
*
|
||||
* Used to create a static or dynamic CoAP resource.
|
||||
*
|
||||
* \param *res Pointer to a structure of type sn_nsdl_resource_info_t that contains the information
|
||||
* about the resource.
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
* \return -2 Resource already exists
|
||||
* \return -3 Invalid path
|
||||
* \return -4 List adding failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_create_resource(struct nsdl_s *handle, sn_nsdl_resource_info_s *res);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_update_resource(sn_nsdl_resource_info_s *res)
|
||||
*
|
||||
* \brief Resource updating function.
|
||||
*
|
||||
* Used to update the direct value of a static resource, the callback function pointer of a dynamic resource
|
||||
* and access rights of the recource.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *res Pointer to a structure of type sn_nsdl_resource_info_t that contains the information
|
||||
* about the resource. Only the pathlen and path elements are evaluated along with
|
||||
* either resourcelen and resource or the function pointer.
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_update_resource(struct nsdl_s *handle, sn_nsdl_resource_info_s *res);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_delete_resource(struct nsdl_s *handle, uint8_t pathlen, uint8_t *path)
|
||||
*
|
||||
* \brief Resource delete function.
|
||||
*
|
||||
* Used to delete a resource. If resource has a subresources, these all must also be removed.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param pathlen Contains the length of the path that is to be deleted (excluding possible trailing "\0").
|
||||
* \param *path_ptr A pointer to an array containing the path.
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return -1 Failure (No such resource)
|
||||
*/
|
||||
extern int8_t sn_nsdl_delete_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path);
|
||||
|
||||
/**
|
||||
* \fn extern sn_nsdl_resource_info_s *sn_nsdl_get_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path)
|
||||
*
|
||||
* \brief Resource get function.
|
||||
*
|
||||
* Used to get a resource.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param pathlen Contains the length of the path that is to be returned (excluding possible trailing '\0').
|
||||
* \param *path A pointer to an array containing the path.
|
||||
*
|
||||
* \return !NULL Success, pointer to a sn_nsdl_resource_info_s that contains the resource information\n
|
||||
* \return NULL Failure
|
||||
*/
|
||||
extern sn_nsdl_resource_info_s *sn_nsdl_get_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path);
|
||||
|
||||
/**
|
||||
* \fn extern sn_grs_resource_list_s *sn_nsdl_list_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path)
|
||||
*
|
||||
* \brief Resource list function.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param pathlen Contains the length of the target path (excluding possible trailing '\0').
|
||||
* The length value is not examined if the path itself is a NULL pointer.
|
||||
* \param *path A pointer to an array containing the path or a NULL pointer.
|
||||
*
|
||||
* \return !NULL A pointer to a sn_grs_resource_list_s structure containing the resource listing.
|
||||
* \return NULL Failure with an unspecified error
|
||||
*/
|
||||
sn_grs_resource_list_s *sn_nsdl_list_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path);
|
||||
|
||||
/**
|
||||
* \fn extern void sn_nsdl_free_resource_list(struct nsdl_s *handle, sn_grs_resource_list_s *list)
|
||||
*
|
||||
* \brief Free a resource list obtained from sn_nsdl_list_resource()
|
||||
*
|
||||
* \param list The list to free, or NULL.
|
||||
*/
|
||||
void sn_nsdl_free_resource_list(struct nsdl_s *handle, sn_grs_resource_list_s *list);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_send_coap_message(struct nsdl_s *handle, sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr);
|
||||
*
|
||||
* \brief Send an outgoing CoAP request.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \param *address_ptr Pointer to source address struct
|
||||
* \param *coap_hdr_ptr Pointer to CoAP message to be sent
|
||||
*
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_send_coap_message(struct nsdl_s *handle, sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type);
|
||||
*
|
||||
* \brief This function is used to set the mbed Device Server address given by an application.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \return 0 Success
|
||||
* \return -1 Failed to indicate that internal address pointer is not allocated (call nsdl_init() first).
|
||||
*/
|
||||
extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_destroy(struct nsdl_s *handle);
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
* \brief This function releases all allocated memory in mbed Device C Client library.
|
||||
*/
|
||||
extern int8_t sn_nsdl_destroy(struct nsdl_s *handle);
|
||||
|
||||
/**
|
||||
* \fn extern uint16_t sn_nsdl_oma_bootstrap(struct nsdl_s *handle, sn_nsdl_addr_s *bootstrap_address_ptr, sn_nsdl_ep_parameters_s *endpoint_info_ptr, sn_nsdl_bs_ep_info_t *bootstrap_endpoint_info_ptr);
|
||||
*
|
||||
* \brief Starts OMA bootstrap process
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*
|
||||
* \return bootstrap message ID, 0 if failed
|
||||
*/
|
||||
extern uint16_t sn_nsdl_oma_bootstrap(struct nsdl_s *handle, sn_nsdl_addr_s *bootstrap_address_ptr, sn_nsdl_ep_parameters_s *endpoint_info_ptr, sn_nsdl_bs_ep_info_t *bootstrap_endpoint_info_ptr);
|
||||
|
||||
/**
|
||||
* \fn extern omalw_certificate_list_t *sn_nsdl_get_certificates(struct nsdl_s *handle);
|
||||
*
|
||||
* \brief Get pointer to received device server certificates
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*/
|
||||
extern omalw_certificate_list_t *sn_nsdl_get_certificates(struct nsdl_s *handle);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_update_certificates(struct nsdl_s *handle, omalw_certificate_list_t* certificate_ptr, uint8_t certificate_chain);
|
||||
*
|
||||
* \brief Updates certificate pointers to resource server.
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*/
|
||||
extern int8_t sn_nsdl_update_certificates(struct nsdl_s *handle, omalw_certificate_list_t *certificate_ptr, uint8_t certificate_chain);
|
||||
|
||||
/**
|
||||
* \fn extern int8_t sn_nsdl_create_oma_device_object(struct nsdl_s *handle, sn_nsdl_oma_device_t *device_object_ptr);
|
||||
*
|
||||
* \brief Creates new device object resource
|
||||
*
|
||||
* \param *handle Pointer to nsdl-library handle
|
||||
*/
|
||||
extern int8_t sn_nsdl_create_oma_device_object(struct nsdl_s *handle, sn_nsdl_oma_device_t *device_object_ptr);
|
||||
|
||||
/**
|
||||
* \fn sn_coap_hdr_s *sn_nsdl_build_response(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
|
||||
*
|
||||
* \brief Prepares generic response packet from a request packet. This function allocates memory for the resulting sn_coap_hdr_s
|
||||
*
|
||||
* \param *handle Pointer to library handle
|
||||
* \param *coap_packet_ptr The request packet pointer
|
||||
* \param msg_code response messages code
|
||||
*
|
||||
* \return *coap_packet_ptr The allocated and pre-filled response packet pointer
|
||||
* NULL Error in parsing the request
|
||||
*
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_nsdl_build_response(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code);
|
||||
|
||||
/**
|
||||
* \fn void sn_nsdl_release_allocated_coap_msg_mem(struct nsdl_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr)
|
||||
*
|
||||
* \brief Releases memory of given CoAP message
|
||||
*
|
||||
* Note!!! Does not release Payload part
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param *freed_coap_msg_ptr is pointer to released CoAP message
|
||||
*/
|
||||
extern void sn_nsdl_release_allocated_coap_msg_mem(struct nsdl_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_nsdl_set_retransmission_parameters(struct nsdl_s *handle, uint8_t resending_count, uint8_t resending_intervall)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function changes resending count and interval.
|
||||
*
|
||||
* \param *handle Pointer to library handle
|
||||
* \param uint8_t resending_count max number of resendings for message
|
||||
* \param uint8_t resending_intervall message resending intervall in seconds
|
||||
* \return 0 = success, -1 = failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_set_retransmission_parameters(struct nsdl_s *handle, uint8_t resending_count, uint8_t resending_interval);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_nsdl_set_retransmission_buffer(struct nsdl_s *handle, uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function changes message retransmission queue size.
|
||||
* Set size to '0' to disable feature. If both are set to '0', then re-sendings are disabled.
|
||||
*
|
||||
* \param *handle Pointer to library handle
|
||||
* \param uint8_t buffer_size_messages queue size - maximum number of messages to be saved to queue
|
||||
* \param uint8_t buffer_size_bytes queue size - maximum size of messages saved to queue
|
||||
* \return 0 = success, -1 = failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_set_retransmission_buffer(struct nsdl_s *handle,
|
||||
uint8_t buffer_size_messages, uint16_t buffer_size_bytes);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_nsdl_set_block_size(struct nsdl_s *handle, uint16_t block_size)
|
||||
*
|
||||
* \brief If block transfer is enabled, this function changes the block size.
|
||||
*
|
||||
* \param *handle Pointer to library handle
|
||||
* \param uint16_t block_size maximum size of CoAP payload. Valid sizes are 16, 32, 64, 128, 256, 512 and 1024 bytes
|
||||
* \return 0 = success, -1 = failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_set_block_size(struct nsdl_s *handle, uint16_t block_size);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_nsdl_set_duplicate_buffer_size(struct nsdl_s *handle,uint8_t message_count)
|
||||
*
|
||||
* \brief If dublicate message detection is enabled, this function changes buffer size.
|
||||
*
|
||||
* \param *handle Pointer to library handle
|
||||
* \param uint8_t message_count max number of messages saved for duplicate control
|
||||
* \return 0 = success, -1 = failure
|
||||
*/
|
||||
extern int8_t sn_nsdl_set_duplicate_buffer_size(struct nsdl_s *handle, uint8_t message_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SN_NSDL_LIB_H_ */
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/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 mbed Client C unit tests"
|
||||
echo
|
||||
|
||||
yt target x86-linux-native
|
||||
yt up
|
||||
make -f Makefile.test test
|
||||
#make -f Makefile.test test clean
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
# Execute script with root path where to find binaries.
|
||||
# For example ./run_unit_tests_with_valgrind.sh ./build/x86-linux-native-coverage/test/mbedclient/
|
||||
|
||||
input="binaries.txt"
|
||||
valgrind_logs="valgrind_logs"
|
||||
rm -rf $valgrind_logs
|
||||
mkdir $valgrind_logs
|
||||
find $1 -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print > $input
|
||||
while file= read -r binary
|
||||
do
|
||||
valgrind --track-origins=yes --xml=yes --xml-file="${valgrind_logs}/valgrind_$(basename $binary).xml" "$binary"
|
||||
|
||||
done < "$input"
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_coap_header_internal.h
|
||||
*
|
||||
* \brief Header file for CoAP Header part
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_HEADER_INTERNAL_H_
|
||||
#define SN_COAP_HEADER_INTERNAL_H_
|
||||
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * DEFINES * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
#define COAP_VERSION COAP_VERSION_1 /* Tells which IETF CoAP specification version the CoAP message supports. */
|
||||
/* This value is written to CoAP message header part. */
|
||||
|
||||
/* CoAP Header defines */
|
||||
#define COAP_HEADER_LENGTH 4 /* Fixed Header length of CoAP message as bytes */
|
||||
#define COAP_HEADER_VERSION_MASK 0xC0
|
||||
#define COAP_HEADER_MSG_TYPE_MASK 0x30
|
||||
#define COAP_HEADER_TOKEN_LENGTH_MASK 0x0F
|
||||
#define COAP_HEADER_MSG_ID_MSB_SHIFT 8
|
||||
|
||||
/* CoAP Options defines */
|
||||
#define COAP_OPTIONS_OPTION_NUMBER_SHIFT 4
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief This structure is returned by sn_coap_exec() for sending
|
||||
*/
|
||||
typedef struct sn_nsdl_transmit_ {
|
||||
sn_nsdl_addr_s *dst_addr_ptr;
|
||||
|
||||
sn_nsdl_capab_e protocol;
|
||||
|
||||
uint16_t packet_len;
|
||||
uint8_t *packet_ptr;
|
||||
uint8_t *uri_path_ptr;
|
||||
uint8_t uri_path_len;
|
||||
} sn_nsdl_transmit_s;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* * * * EXTERNAL FUNCTION PROTOTYPES * * * */
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
extern int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_version_e coap_version);
|
||||
|
||||
#endif /* SN_COAP_HEADER_INTERNAL_H_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_coap_protocol_internal.h
|
||||
*
|
||||
* \brief Header file for CoAP Protocol part
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SN_COAP_PROTOCOL_INTERNAL_H_
|
||||
#define SN_COAP_PROTOCOL_INTERNAL_H_
|
||||
|
||||
#include "ns_list.h"
|
||||
#include "sn_coap_header_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * DEFINES * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
/* * For Message resending * */
|
||||
#define ENABLE_RESENDINGS 1 /**< Enable / Disable resending from library in building */
|
||||
|
||||
#define SN_COAP_RESENDING_MAX_COUNT 3 /**< Default number of re-sendings */
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS 2 /**< Default re-sending queue size - defines how many messages can be stored. Setting this to 0 disables feature */
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES 0 /**< Default re-sending queue size - defines size of the re-sending buffer. Setting this to 0 disables feature */
|
||||
#define DEFAULT_RESPONSE_TIMEOUT 10 /**< Default re-sending timeout as seconds */
|
||||
|
||||
/* These parameters sets maximum values application can set with API */
|
||||
#define SN_COAP_MAX_ALLOWED_RESENDING_COUNT 6 /**< Maximum allowed count of re-sending */
|
||||
#define SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_MSGS 6 /**< Maximum allowed number of saved re-sending messages */
|
||||
#define SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_BYTES 512 /**< Maximum allowed size of re-sending buffer */
|
||||
#define SN_COAP_MAX_ALLOWED_RESPONSE_TIMEOUT 40 /**< Maximum allowed re-sending timeout */
|
||||
|
||||
#define RESPONSE_RANDOM_FACTOR 1 /**< Resending random factor, value is specified in IETF CoAP specification */
|
||||
|
||||
/* * For Message duplication detecting * */
|
||||
|
||||
/* Init value for the maximum count of messages to be stored for duplication detection */
|
||||
/* Setting of this value to 0 will disable duplication check, also reduce use of ROM memory */
|
||||
|
||||
// Keep the old flag to maintain backward compatibility
|
||||
#ifndef SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT 0
|
||||
#endif
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT YOTTA_CFG_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT MBED_CONF_MBED_CLIENT_SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Maximum allowed number of saved messages for duplicate searching */
|
||||
#define SN_COAP_MAX_ALLOWED_DUPLICATION_MESSAGE_COUNT 6
|
||||
|
||||
/* Maximum time in seconds of messages to be stored for duplication detection */
|
||||
#define SN_COAP_DUPLICATION_MAX_TIME_MSGS_STORED 60 /* RESPONSE_TIMEOUT * RESPONSE_RANDOM_FACTOR * (2 ^ MAX_RETRANSMIT - 1) + the expected maximum round trip time */
|
||||
|
||||
/* * For Message blockwising * */
|
||||
|
||||
/* Init value for the maximum payload size to be sent and received at one blockwise message */
|
||||
/* Setting of this value to 0 will disable this feature, and also reduce use of ROM memory */
|
||||
/* Note: Current Coap implementation supports Blockwise transfers specification version draft-ietf-core-block-03 */
|
||||
/* Note: This define is common for both received and sent Blockwise messages */
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE MBED_CONF_MBED_CLIENT_SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 0 /**< Must be 2^x and x is at least 4. Suitable values: 0, 16, 32, 64, 128, 256, 512 and 1024 */
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED
|
||||
#define SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED 10 /**< Maximum time in seconds of data (messages and payload) to be stored for blockwising */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
|
||||
|
||||
|
||||
/* Structure which is stored to Linked list for message sending purposes */
|
||||
typedef struct coap_send_msg_ {
|
||||
uint8_t resending_counter; /* Tells how many times message is still tried to resend */
|
||||
uint32_t resending_time; /* Tells next resending time */
|
||||
|
||||
sn_nsdl_transmit_s *send_msg_ptr;
|
||||
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
void *param; /* Extra parameter that will be passed to TX/RX callback functions */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_send_msg_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_send_msg_s, link) coap_send_msg_list_t;
|
||||
|
||||
/* Structure which is stored to Linked list for message duplication detection purposes */
|
||||
typedef struct coap_duplication_info_ {
|
||||
uint32_t timestamp; /* Tells when duplication information is stored to Linked list */
|
||||
|
||||
uint8_t addr_len;
|
||||
uint8_t *addr_ptr;
|
||||
uint16_t port;
|
||||
|
||||
uint16_t msg_id;
|
||||
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_duplication_info_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_duplication_info_s, link) coap_duplication_info_list_t;
|
||||
|
||||
/* Structure which is stored to Linked list for blockwise messages sending purposes */
|
||||
typedef struct coap_blockwise_msg_ {
|
||||
uint32_t timestamp; /* Tells when Blockwise message is stored to Linked list */
|
||||
|
||||
sn_coap_hdr_s *coap_msg_ptr;
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_blockwise_msg_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_blockwise_msg_s, link) coap_blockwise_msg_list_t;
|
||||
|
||||
/* Structure which is stored to Linked list for blockwise messages receiving purposes */
|
||||
typedef struct coap_blockwise_payload_ {
|
||||
uint32_t timestamp; /* Tells when Payload is stored to Linked list */
|
||||
|
||||
uint8_t addr_len;
|
||||
uint8_t *addr_ptr;
|
||||
uint16_t port;
|
||||
|
||||
uint16_t payload_len;
|
||||
uint8_t *payload_ptr;
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_blockwise_payload_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_blockwise_payload_s, link) coap_blockwise_payload_list_t;
|
||||
|
||||
struct coap_s {
|
||||
void *(*sn_coap_protocol_malloc)(uint16_t);
|
||||
void (*sn_coap_protocol_free)(void *);
|
||||
|
||||
uint8_t (*sn_coap_tx_callback)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *);
|
||||
int8_t (*sn_coap_rx_callback)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *);
|
||||
|
||||
#if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
|
||||
coap_send_msg_list_t linked_list_resent_msgs; /* Active resending messages are stored to this Linked list */
|
||||
uint16_t count_resent_msgs;
|
||||
#endif
|
||||
|
||||
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
|
||||
coap_duplication_info_list_t linked_list_duplication_msgs; /* Messages for duplicated messages detection is stored to this Linked list */
|
||||
uint16_t count_duplication_msgs;
|
||||
#endif
|
||||
|
||||
#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwise is not used at all, this part of code will not be compiled */
|
||||
coap_blockwise_msg_list_t linked_list_blockwise_sent_msgs; /* Blockwise message to to be sent is stored to this Linked list */
|
||||
coap_blockwise_payload_list_t linked_list_blockwise_received_payloads; /* Blockwise payload to to be received is stored to this Linked list */
|
||||
#endif
|
||||
|
||||
uint32_t system_time; /* System time seconds */
|
||||
uint16_t sn_coap_block_data_size;
|
||||
uint8_t sn_coap_resending_queue_msgs;
|
||||
uint8_t sn_coap_resending_queue_bytes;
|
||||
uint8_t sn_coap_resending_count;
|
||||
uint8_t sn_coap_resending_intervall;
|
||||
uint8_t sn_coap_duplication_buffer_size;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SN_COAP_PROTOCOL_INTERNAL_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file sn_coap_header_check.c
|
||||
*
|
||||
* \brief CoAP Header validity checker
|
||||
*
|
||||
* Functionality: Checks validity of CoAP Header
|
||||
*
|
||||
*/
|
||||
|
||||
/* * * * INCLUDE FILES * * * */
|
||||
#include "ns_types.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "sn_coap_header_internal.h"
|
||||
#include "sn_coap_protocol_internal.h"
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_version_e coap_version)
|
||||
*
|
||||
* \brief Checks validity of given Header
|
||||
*
|
||||
* \param *src_coap_msg_ptr is source for building Packet data
|
||||
* \param coap_version is version of used CoAP specification
|
||||
*
|
||||
* \return Return value is status of validity check. In ok cases 0 and in
|
||||
* failure cases -1
|
||||
*/
|
||||
int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_version_e coap_version)
|
||||
{
|
||||
/* * Check validity of CoAP Version * */
|
||||
if (coap_version != COAP_VERSION_1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* * Check validity of Message type * */
|
||||
switch (src_coap_msg_ptr->msg_type) {
|
||||
case COAP_MSG_TYPE_CONFIRMABLE:
|
||||
case COAP_MSG_TYPE_NON_CONFIRMABLE:
|
||||
case COAP_MSG_TYPE_ACKNOWLEDGEMENT:
|
||||
case COAP_MSG_TYPE_RESET:
|
||||
break; /* Ok cases */
|
||||
default:
|
||||
return -1; /* Failed case */
|
||||
}
|
||||
|
||||
/* * Check validity of Message code * */
|
||||
switch (src_coap_msg_ptr->msg_code) {
|
||||
case COAP_MSG_CODE_EMPTY:
|
||||
case COAP_MSG_CODE_REQUEST_GET:
|
||||
case COAP_MSG_CODE_REQUEST_POST:
|
||||
case COAP_MSG_CODE_REQUEST_PUT:
|
||||
case COAP_MSG_CODE_REQUEST_DELETE:
|
||||
case COAP_MSG_CODE_RESPONSE_CREATED:
|
||||
case COAP_MSG_CODE_RESPONSE_DELETED:
|
||||
case COAP_MSG_CODE_RESPONSE_VALID:
|
||||
case COAP_MSG_CODE_RESPONSE_CHANGED:
|
||||
case COAP_MSG_CODE_RESPONSE_CONTENT:
|
||||
case COAP_MSG_CODE_RESPONSE_BAD_REQUEST:
|
||||
case COAP_MSG_CODE_RESPONSE_UNAUTHORIZED:
|
||||
case COAP_MSG_CODE_RESPONSE_BAD_OPTION:
|
||||
case COAP_MSG_CODE_RESPONSE_FORBIDDEN:
|
||||
case COAP_MSG_CODE_RESPONSE_NOT_FOUND:
|
||||
case COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED:
|
||||
case COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE:
|
||||
case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE:
|
||||
case COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED:
|
||||
case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE:
|
||||
case COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT:
|
||||
case COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR:
|
||||
case COAP_MSG_CODE_RESPONSE_NOT_IMPLEMENTED:
|
||||
case COAP_MSG_CODE_RESPONSE_BAD_GATEWAY:
|
||||
case COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE:
|
||||
case COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT:
|
||||
case COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED:
|
||||
case COAP_MSG_CODE_RESPONSE_CONTINUE:
|
||||
break; /* Ok cases */
|
||||
default:
|
||||
return -1; /* Failed case */
|
||||
}
|
||||
|
||||
/* Success */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,843 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*\file sn_coap_parser.c
|
||||
*
|
||||
* \brief CoAP Header parser
|
||||
*
|
||||
* Functionality: Parses CoAP Header
|
||||
*
|
||||
*/
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * INCLUDE FILES * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* For memset() and memcpy() */
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "sn_coap_header_internal.h"
|
||||
#include "sn_coap_protocol_internal.h"
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * */
|
||||
/* * * * LOCAL FUNCTION PROTOTYPES * * * */
|
||||
/* * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
static void sn_coap_parser_header_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, coap_version_e *coap_version_ptr);
|
||||
static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, uint8_t *packet_data_start_ptr, uint16_t packet_len);
|
||||
static int8_t sn_coap_parser_options_parse_multiple_options(struct coap_s *handle, uint8_t **packet_data_pptr, uint16_t packet_left_len, uint8_t **dst_pptr, uint16_t *dst_len_ptr, sn_coap_option_numbers_e option, uint16_t option_number_len);
|
||||
static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_t *packet_data_ptr, uint16_t packet_left_len, sn_coap_option_numbers_e option, uint16_t option_number_len);
|
||||
static int8_t sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *packet_data_start_ptr, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr);
|
||||
|
||||
sn_coap_hdr_s *sn_coap_parser_init_message(sn_coap_hdr_s *coap_msg_ptr)
|
||||
{
|
||||
/* * * * Check given pointer * * * */
|
||||
if (coap_msg_ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX not technically legal to memset pointers to 0 */
|
||||
memset(coap_msg_ptr, 0x00, sizeof(sn_coap_hdr_s));
|
||||
|
||||
return coap_msg_ptr;
|
||||
}
|
||||
|
||||
sn_coap_hdr_s *sn_coap_parser_alloc_message(struct coap_s *handle)
|
||||
{
|
||||
sn_coap_hdr_s *returned_coap_msg_ptr;
|
||||
|
||||
/* * * * Check given pointer * * * */
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* * * * Allocate memory for returned CoAP message and initialize allocated memory with with default values * * * */
|
||||
returned_coap_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_coap_hdr_s));
|
||||
|
||||
return sn_coap_parser_init_message(returned_coap_msg_ptr);
|
||||
}
|
||||
|
||||
sn_coap_options_list_s *sn_coap_parser_alloc_options(struct coap_s *handle, sn_coap_hdr_s *coap_msg_ptr)
|
||||
{
|
||||
/* * * * Check given pointers * * * */
|
||||
if (handle == NULL || coap_msg_ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* * * * If the message already has options, return them * * * */
|
||||
if (coap_msg_ptr->options_list_ptr) {
|
||||
return coap_msg_ptr->options_list_ptr;
|
||||
}
|
||||
|
||||
/* * * * Allocate memory for options and initialize allocated memory with with default values * * * */
|
||||
coap_msg_ptr->options_list_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
|
||||
|
||||
if (coap_msg_ptr->options_list_ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX not technically legal to memset pointers to 0 */
|
||||
memset(coap_msg_ptr->options_list_ptr, 0x00, sizeof(sn_coap_options_list_s));
|
||||
|
||||
return coap_msg_ptr->options_list_ptr;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
uint8_t *data_temp_ptr = packet_data_ptr;
|
||||
sn_coap_hdr_s *parsed_and_returned_coap_msg_ptr = NULL;
|
||||
|
||||
/* * * * Check given pointer * * * */
|
||||
if (packet_data_ptr == NULL || packet_data_len < 4 || handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* * * * Allocate and initialize CoAP message * * * */
|
||||
parsed_and_returned_coap_msg_ptr = sn_coap_parser_alloc_message(handle);
|
||||
|
||||
if (parsed_and_returned_coap_msg_ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* * * * Header parsing, move pointer over the header... * * * */
|
||||
sn_coap_parser_header_parse(&data_temp_ptr, parsed_and_returned_coap_msg_ptr, coap_version_ptr);
|
||||
|
||||
/* * * * Options parsing, move pointer over the options... * * * */
|
||||
if (sn_coap_parser_options_parse(handle, &data_temp_ptr, parsed_and_returned_coap_msg_ptr, packet_data_ptr, packet_data_len) != 0) {
|
||||
parsed_and_returned_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_ERROR_IN_HEADER;
|
||||
return parsed_and_returned_coap_msg_ptr;
|
||||
}
|
||||
|
||||
/* * * * Payload parsing * * * */
|
||||
if (sn_coap_parser_payload_parse(packet_data_len, packet_data_ptr, &data_temp_ptr, parsed_and_returned_coap_msg_ptr) == -1) {
|
||||
parsed_and_returned_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_ERROR_IN_HEADER;
|
||||
return parsed_and_returned_coap_msg_ptr;
|
||||
}
|
||||
|
||||
/* * * * Return parsed CoAP message * * * * */
|
||||
return parsed_and_returned_coap_msg_ptr;
|
||||
}
|
||||
|
||||
void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr)
|
||||
{
|
||||
if (handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr != NULL) {
|
||||
if (freed_coap_msg_ptr->uri_path_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->uri_path_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->token_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->token_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->content_type_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->content_type_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr != NULL) {
|
||||
if (freed_coap_msg_ptr->options_list_ptr->max_age_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->max_age_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->proxy_uri_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->etag_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->uri_host_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->location_path_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->uri_port_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->uri_port_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->location_query_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->observe_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->observe_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->uri_query_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->block2_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->block2_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->block1_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->block1_ptr);
|
||||
}
|
||||
if (freed_coap_msg_ptr->options_list_ptr->accept_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->accept_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->size1_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->size1_ptr);
|
||||
}
|
||||
|
||||
if (freed_coap_msg_ptr->options_list_ptr->size2_ptr != NULL) {
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr->size2_ptr);
|
||||
}
|
||||
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr->options_list_ptr);
|
||||
}
|
||||
|
||||
handle->sn_coap_protocol_free(freed_coap_msg_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn static void sn_coap_parser_header_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, coap_version_e *coap_version_ptr)
|
||||
*
|
||||
* \brief Parses CoAP message's Header part from given Packet data
|
||||
*
|
||||
* \param **packet_data_ptr is source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *dst_coap_msg_ptr is destination for parsed CoAP message
|
||||
*
|
||||
* \param *coap_version_ptr is destination for parsed CoAP specification version
|
||||
*/
|
||||
static void sn_coap_parser_header_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, coap_version_e *coap_version_ptr)
|
||||
{
|
||||
/* Parse CoAP Version and message type*/
|
||||
*coap_version_ptr = (coap_version_e)(**packet_data_pptr & COAP_HEADER_VERSION_MASK);
|
||||
dst_coap_msg_ptr->msg_type = (sn_coap_msg_type_e)(**packet_data_pptr & COAP_HEADER_MSG_TYPE_MASK);
|
||||
(*packet_data_pptr) += 1;
|
||||
|
||||
/* Parse Message code */
|
||||
dst_coap_msg_ptr->msg_code = (sn_coap_msg_code_e) **packet_data_pptr;
|
||||
(*packet_data_pptr) += 1;
|
||||
|
||||
/* Parse Message ID */
|
||||
dst_coap_msg_ptr->msg_id = *(*packet_data_pptr + 1);
|
||||
dst_coap_msg_ptr->msg_id += **packet_data_pptr << COAP_HEADER_MSG_ID_MSB_SHIFT;
|
||||
(*packet_data_pptr) += 2;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn static uint8_t sn_coap_parser_options_parse(uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr)
|
||||
*
|
||||
* \brief Parses CoAP message's Options part from given Packet data
|
||||
*
|
||||
* \param **packet_data_pptr is source of Packet data to be parsed to CoAP message
|
||||
* \param *dst_coap_msg_ptr is destination for parsed CoAP message
|
||||
*
|
||||
* \return Return value is 0 in ok case and -1 in failure case
|
||||
*/
|
||||
static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr, uint8_t *packet_data_start_ptr, uint16_t packet_len)
|
||||
{
|
||||
uint8_t previous_option_number = 0;
|
||||
uint8_t i = 0;
|
||||
int8_t ret_status = 0;
|
||||
uint16_t message_left = 0;
|
||||
|
||||
/* Parse token, if exists */
|
||||
dst_coap_msg_ptr->token_len = *packet_data_start_ptr & COAP_HEADER_TOKEN_LENGTH_MASK;
|
||||
|
||||
if (dst_coap_msg_ptr->token_len) {
|
||||
if ((dst_coap_msg_ptr->token_len > 8) || dst_coap_msg_ptr->token_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst_coap_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(dst_coap_msg_ptr->token_len);
|
||||
|
||||
if (dst_coap_msg_ptr->token_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->token_ptr, *packet_data_pptr, dst_coap_msg_ptr->token_len);
|
||||
(*packet_data_pptr) += dst_coap_msg_ptr->token_len;
|
||||
}
|
||||
|
||||
message_left = packet_len - ((*packet_data_pptr) - packet_data_start_ptr);
|
||||
|
||||
/* Loop all Options */
|
||||
while (message_left && (**packet_data_pptr != 0xff)) {
|
||||
|
||||
/* Get option length WITHOUT extensions */
|
||||
uint16_t option_len = (**packet_data_pptr & 0x0F);
|
||||
|
||||
/* Option number length 15 is reserved for the future use - ERROR */
|
||||
if (option_len == 15) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Resolve option delta */
|
||||
uint16_t option_number = (**packet_data_pptr >> COAP_OPTIONS_OPTION_NUMBER_SHIFT);
|
||||
|
||||
if (option_number == 13) {
|
||||
option_number = *(*packet_data_pptr + 1) + 13;
|
||||
(*packet_data_pptr)++;
|
||||
} else if (option_number == 14) {
|
||||
option_number = *(*packet_data_pptr + 2);
|
||||
option_number += (*(*packet_data_pptr + 1) << 8) + 269;
|
||||
(*packet_data_pptr) += 2;
|
||||
}
|
||||
/* Option number 15 reserved for payload marker. This is handled as a error! */
|
||||
else if (option_number == 15) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add previous option to option delta and get option number */
|
||||
option_number += previous_option_number;
|
||||
|
||||
/* Add possible option length extension to resolve full length of the option */
|
||||
if (option_len == 13) {
|
||||
option_len = *(*packet_data_pptr + 1) + 13;
|
||||
(*packet_data_pptr)++;
|
||||
} else if (option_len == 14) {
|
||||
option_len = *(*packet_data_pptr + 2);
|
||||
option_len += (*(*packet_data_pptr + 1) << 8) + 269;
|
||||
(*packet_data_pptr) += 2;
|
||||
}
|
||||
|
||||
|
||||
/* * * Parse option itself * * */
|
||||
/* Some options are handled independently in own functions */
|
||||
previous_option_number = option_number;
|
||||
/* Allocate options_list_ptr if needed */
|
||||
switch (option_number) {
|
||||
case COAP_OPTION_MAX_AGE:
|
||||
case COAP_OPTION_PROXY_URI:
|
||||
case COAP_OPTION_ETAG:
|
||||
case COAP_OPTION_URI_HOST:
|
||||
case COAP_OPTION_LOCATION_PATH:
|
||||
case COAP_OPTION_URI_PORT:
|
||||
case COAP_OPTION_LOCATION_QUERY:
|
||||
case COAP_OPTION_OBSERVE:
|
||||
case COAP_OPTION_URI_QUERY:
|
||||
case COAP_OPTION_BLOCK2:
|
||||
case COAP_OPTION_BLOCK1:
|
||||
case COAP_OPTION_ACCEPT:
|
||||
case COAP_OPTION_SIZE1:
|
||||
case COAP_OPTION_SIZE2:
|
||||
if (sn_coap_parser_alloc_options(handle, dst_coap_msg_ptr) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Parse option */
|
||||
switch (option_number) {
|
||||
case COAP_OPTION_CONTENT_FORMAT:
|
||||
if ((option_len > 2) || (dst_coap_msg_ptr->content_type_ptr)) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->content_type_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (option_len) {
|
||||
dst_coap_msg_ptr->content_type_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->content_type_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->content_type_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
}
|
||||
break;
|
||||
|
||||
case COAP_OPTION_MAX_AGE:
|
||||
if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->max_age_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->max_age_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (option_len) {
|
||||
dst_coap_msg_ptr->options_list_ptr->max_age_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->max_age_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->max_age_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
}
|
||||
break;
|
||||
|
||||
case COAP_OPTION_PROXY_URI:
|
||||
if ((option_len > 1034) || (option_len < 1) || dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->proxy_uri_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_ETAG:
|
||||
/* This is managed independently because User gives this option in one character table */
|
||||
|
||||
ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr,
|
||||
message_left,
|
||||
&dst_coap_msg_ptr->options_list_ptr->etag_ptr,
|
||||
(uint16_t *)&dst_coap_msg_ptr->options_list_ptr->etag_len,
|
||||
COAP_OPTION_ETAG, option_len);
|
||||
if (ret_status >= 0) {
|
||||
i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case COAP_OPTION_URI_HOST:
|
||||
if ((option_len > 255) || (option_len < 1) || dst_coap_msg_ptr->options_list_ptr->uri_host_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->uri_host_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->uri_host_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->uri_host_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->uri_host_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_LOCATION_PATH:
|
||||
if (dst_coap_msg_ptr->options_list_ptr->location_path_ptr) {
|
||||
return -1;
|
||||
}
|
||||
/* This is managed independently because User gives this option in one character table */
|
||||
ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left,
|
||||
&dst_coap_msg_ptr->options_list_ptr->location_path_ptr, &dst_coap_msg_ptr->options_list_ptr->location_path_len,
|
||||
COAP_OPTION_LOCATION_PATH, option_len);
|
||||
if (ret_status >= 0) {
|
||||
i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case COAP_OPTION_URI_PORT:
|
||||
if ((option_len > 2) || dst_coap_msg_ptr->options_list_ptr->uri_port_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->uri_port_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (option_len) {
|
||||
dst_coap_msg_ptr->options_list_ptr->uri_port_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->uri_port_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->uri_port_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
}
|
||||
break;
|
||||
|
||||
case COAP_OPTION_LOCATION_QUERY:
|
||||
ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left,
|
||||
&dst_coap_msg_ptr->options_list_ptr->location_query_ptr, &dst_coap_msg_ptr->options_list_ptr->location_query_len,
|
||||
COAP_OPTION_LOCATION_QUERY, option_len);
|
||||
if (ret_status >= 0) {
|
||||
i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_URI_PATH:
|
||||
ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left,
|
||||
&dst_coap_msg_ptr->uri_path_ptr, &dst_coap_msg_ptr->uri_path_len,
|
||||
COAP_OPTION_URI_PATH, option_len);
|
||||
if (ret_status >= 0) {
|
||||
i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_OBSERVE:
|
||||
if ((option_len > 2) || dst_coap_msg_ptr->options_list_ptr->observe_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->observe = 1;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (option_len) {
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->observe_len = option_len;
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->observe_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->observe_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->observe_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_URI_QUERY:
|
||||
ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left,
|
||||
&dst_coap_msg_ptr->options_list_ptr->uri_query_ptr, &dst_coap_msg_ptr->options_list_ptr->uri_query_len,
|
||||
COAP_OPTION_URI_QUERY, option_len);
|
||||
if (ret_status >= 0) {
|
||||
i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_BLOCK2:
|
||||
if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->block2_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->block2_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->block2_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->block2_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->block2_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_BLOCK1:
|
||||
if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->block1_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->block1_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
dst_coap_msg_ptr->options_list_ptr->block1_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->block1_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->block1_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_ACCEPT:
|
||||
ret_status = sn_coap_parser_options_parse_multiple_options(handle, packet_data_pptr, message_left,
|
||||
&dst_coap_msg_ptr->options_list_ptr->accept_ptr, (uint16_t *)&dst_coap_msg_ptr->options_list_ptr->accept_len,
|
||||
COAP_OPTION_ACCEPT, option_len);
|
||||
if (ret_status >= 0) {
|
||||
i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COAP_OPTION_SIZE1:
|
||||
if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->size1_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->size1_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (option_len) {
|
||||
dst_coap_msg_ptr->options_list_ptr->size1_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->size1_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->size1_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
}
|
||||
break;
|
||||
|
||||
case COAP_OPTION_SIZE2:
|
||||
if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->size2_ptr) {
|
||||
return -1;
|
||||
}
|
||||
dst_coap_msg_ptr->options_list_ptr->size2_len = option_len;
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (option_len) {
|
||||
dst_coap_msg_ptr->options_list_ptr->size2_ptr = handle->sn_coap_protocol_malloc(option_len);
|
||||
|
||||
if (dst_coap_msg_ptr->options_list_ptr->size2_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst_coap_msg_ptr->options_list_ptr->size2_ptr, *packet_data_pptr, option_len);
|
||||
(*packet_data_pptr) += option_len;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for overflow */
|
||||
if ((*packet_data_pptr - packet_data_start_ptr) > packet_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
message_left = packet_len - (*packet_data_pptr - packet_data_start_ptr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \fn static int8_t sn_coap_parser_options_parse_multiple_options(uint8_t **packet_data_pptr, uint8_t options_count_left, uint8_t *previous_option_number_ptr, uint8_t **dst_pptr,
|
||||
* uint16_t *dst_len_ptr, sn_coap_option_numbers_e option, uint16_t option_number_len)
|
||||
*
|
||||
* \brief Parses CoAP message's Uri-query options
|
||||
*
|
||||
* \param **packet_data_pptr is source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *dst_coap_msg_ptr is destination for parsed CoAP message
|
||||
*
|
||||
* \param options_count_left tells how many options are unhandled in Packet data
|
||||
*
|
||||
* \param *previous_option_number_ptr is pointer to used and returned previous Option number
|
||||
*
|
||||
* \return Return value is count of Uri-query optios parsed. In failure case -1 is returned.
|
||||
*/
|
||||
static int8_t sn_coap_parser_options_parse_multiple_options(struct coap_s *handle, uint8_t **packet_data_pptr, uint16_t packet_left_len, uint8_t **dst_pptr, uint16_t *dst_len_ptr, sn_coap_option_numbers_e option, uint16_t option_number_len)
|
||||
{
|
||||
int16_t uri_query_needed_heap = sn_coap_parser_options_count_needed_memory_multiple_option(*packet_data_pptr, packet_left_len, option, option_number_len);
|
||||
uint8_t *temp_parsed_uri_query_ptr = NULL;
|
||||
uint8_t returned_option_counter = 0;
|
||||
|
||||
if (uri_query_needed_heap == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uri_query_needed_heap) {
|
||||
*dst_pptr = (uint8_t *) handle->sn_coap_protocol_malloc(uri_query_needed_heap);
|
||||
|
||||
if (*dst_pptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*dst_len_ptr = uri_query_needed_heap;
|
||||
|
||||
temp_parsed_uri_query_ptr = *dst_pptr;
|
||||
|
||||
/* Loop all Uri-Query options */
|
||||
while ((temp_parsed_uri_query_ptr - *dst_pptr) < uri_query_needed_heap) {
|
||||
/* Check if this is first Uri-Query option */
|
||||
if (returned_option_counter > 0) {
|
||||
/* Uri-Query is modified to following format: temp1'\0'temp2'\0'temp3 i.e. */
|
||||
/* Uri-Path is modified to following format: temp1\temp2\temp3 i.e. */
|
||||
if (option == COAP_OPTION_URI_QUERY || option == COAP_OPTION_LOCATION_QUERY || option == COAP_OPTION_ETAG || option == COAP_OPTION_ACCEPT) {
|
||||
memset(temp_parsed_uri_query_ptr, '&', 1);
|
||||
} else if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) {
|
||||
memset(temp_parsed_uri_query_ptr, '/', 1);
|
||||
}
|
||||
|
||||
temp_parsed_uri_query_ptr++;
|
||||
}
|
||||
|
||||
returned_option_counter++;
|
||||
|
||||
(*packet_data_pptr)++;
|
||||
|
||||
if (((temp_parsed_uri_query_ptr - *dst_pptr) + option_number_len) > uri_query_needed_heap) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(temp_parsed_uri_query_ptr, *packet_data_pptr, option_number_len);
|
||||
|
||||
(*packet_data_pptr) += option_number_len;
|
||||
temp_parsed_uri_query_ptr += option_number_len;
|
||||
|
||||
if ((temp_parsed_uri_query_ptr - *dst_pptr) >= uri_query_needed_heap || ((**packet_data_pptr >> COAP_OPTIONS_OPTION_NUMBER_SHIFT) != 0)) {
|
||||
return returned_option_counter;
|
||||
}
|
||||
|
||||
option_number_len = (**packet_data_pptr & 0x0F);
|
||||
if (option_number_len == 13) {
|
||||
option_number_len = *(*packet_data_pptr + 1) + 13;
|
||||
(*packet_data_pptr)++;
|
||||
} else if (option_number_len == 14) {
|
||||
option_number_len = *(*packet_data_pptr + 2);
|
||||
option_number_len += (*(*packet_data_pptr + 1) << 8) + 269;
|
||||
(*packet_data_pptr) += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return returned_option_counter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \fn static uint16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_t *packet_data_ptr, uint8_t options_count_left, uint8_t previous_option_number, sn_coap_option_numbers_e option, uint16_t option_number_len)
|
||||
*
|
||||
* \brief Counts needed memory for uri query option
|
||||
*
|
||||
* \param *packet_data_ptr is start of source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param options_count_left tells how many options are unhandled in Packet data
|
||||
*
|
||||
* \param previous_option_number is previous Option number
|
||||
*
|
||||
* \param sn_coap_option_numbers_e option option number to be calculated
|
||||
*
|
||||
* \param uint16_t option_number_len length of the first option part
|
||||
*/
|
||||
static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_t *packet_data_ptr, uint16_t packet_left_len, sn_coap_option_numbers_e option, uint16_t option_number_len)
|
||||
{
|
||||
uint16_t ret_value = 0;
|
||||
uint16_t i = 1;
|
||||
|
||||
/* Loop all Uri-Query options */
|
||||
while (i < packet_left_len) {
|
||||
if (option == COAP_OPTION_LOCATION_PATH && option_number_len > 255) {
|
||||
return -1;
|
||||
}
|
||||
if (option == COAP_OPTION_URI_PATH && option_number_len > 255) {
|
||||
return -1;
|
||||
}
|
||||
if (option == COAP_OPTION_URI_QUERY && option_number_len > 255) {
|
||||
return -1;
|
||||
}
|
||||
if (option == COAP_OPTION_LOCATION_QUERY && option_number_len > 255) {
|
||||
return -1;
|
||||
}
|
||||
if (option == COAP_OPTION_ACCEPT && option_number_len > 2) {
|
||||
return -1;
|
||||
}
|
||||
if (option == COAP_OPTION_ETAG && option_number_len > 8) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
i += option_number_len;
|
||||
ret_value += option_number_len + 1; /* + 1 is for separator */
|
||||
if(ret_value >= packet_left_len)
|
||||
break;
|
||||
|
||||
if(ret_value >= packet_left_len)
|
||||
break;
|
||||
|
||||
if( i == packet_left_len )
|
||||
break;
|
||||
|
||||
if ((*(packet_data_ptr + i) >> COAP_OPTIONS_OPTION_NUMBER_SHIFT) != 0) {
|
||||
return (ret_value - 1); /* -1 because last Part path does not include separator */
|
||||
}
|
||||
|
||||
option_number_len = (*(packet_data_ptr + i) & 0x0F);
|
||||
|
||||
if (option_number_len == 13) {
|
||||
i++;
|
||||
option_number_len = *(packet_data_ptr + i) + 13;
|
||||
} else if (option_number_len == 14) {
|
||||
option_number_len = *(packet_data_ptr + i + 2);
|
||||
option_number_len += (*(packet_data_ptr + i + 1) << 8) + 269;
|
||||
i += 2;
|
||||
} else if (option_number_len == 15) {
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
if (ret_value != 0) {
|
||||
return (ret_value - 1); /* -1 because last Part path does not include separator */
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn static void sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *packet_data_ptr, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr)
|
||||
*
|
||||
* \brief Parses CoAP message's Payload part from given Packet data
|
||||
*
|
||||
* \param packet_data_len is length of given Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *packet_data_ptr is start of source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param **packet_data_pptr is source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *dst_coap_msg_ptr is destination for parsed CoAP message
|
||||
*****************************************************************************/
|
||||
static int8_t sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *packet_data_start_ptr, uint8_t **packet_data_pptr, sn_coap_hdr_s *dst_coap_msg_ptr)
|
||||
{
|
||||
/* If there is payload */
|
||||
if ((*packet_data_pptr - packet_data_start_ptr) < packet_data_len) {
|
||||
if (**packet_data_pptr == 0xff) {
|
||||
(*packet_data_pptr)++;
|
||||
/* Parse Payload length */
|
||||
dst_coap_msg_ptr->payload_len = packet_data_len - (*packet_data_pptr - packet_data_start_ptr);
|
||||
|
||||
/* The presence of a marker followed by a zero-length payload MUST be processed as a message format error */
|
||||
if (dst_coap_msg_ptr->payload_len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse Payload by setting CoAP message's payload_ptr to point Payload in Packet data */
|
||||
dst_coap_msg_ptr->payload_ptr = *packet_data_pptr;
|
||||
}
|
||||
/* No payload marker.. */
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2011-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 GRS_H_
|
||||
#define GRS_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define SN_GRS_RESOURCE_ALREADY_EXISTS -2
|
||||
#define SN_GRS_INVALID_PATH -3
|
||||
#define SN_GRS_LIST_ADDING_FAILURE -4
|
||||
#define SN_GRS_RESOURCE_UPDATED -5
|
||||
|
||||
#define ACCESS_DENIED -6
|
||||
|
||||
#define SN_GRS_DELETE_METHOD 0
|
||||
#define SN_GRS_SEARCH_METHOD 1
|
||||
|
||||
#define SN_GRS_DEFAULT_ACCESS 0x0F
|
||||
|
||||
#define SN_NDSL_RESOURCE_NOT_REGISTERED 0
|
||||
#define SN_NDSL_RESOURCE_REGISTERING 1
|
||||
#define SN_NDSL_RESOURCE_REGISTERED 2
|
||||
|
||||
/***** Structs *****/
|
||||
|
||||
typedef struct sn_grs_version_ {
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint8_t build;
|
||||
} sn_grs_version_s;
|
||||
|
||||
typedef NS_LIST_HEAD(sn_nsdl_resource_info_s, link) resource_list_t;
|
||||
|
||||
struct grs_s {
|
||||
struct coap_s *coap;
|
||||
|
||||
uint16_t resource_root_count;
|
||||
resource_list_t resource_root_list;
|
||||
|
||||
void *(*sn_grs_alloc)(uint16_t);
|
||||
void (*sn_grs_free)(void *);
|
||||
uint8_t (*sn_grs_tx_callback)(struct nsdl_s *, sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *);
|
||||
int8_t (*sn_grs_rx_callback)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *);
|
||||
};
|
||||
|
||||
|
||||
struct nsdl_s {
|
||||
struct grs_s *grs;
|
||||
|
||||
uint8_t *oma_bs_address_ptr; /* Bootstrap address pointer. If null, no bootstrap in use */
|
||||
uint8_t oma_bs_address_len; /* Bootstrap address length */
|
||||
uint16_t oma_bs_port; /* Bootstrap port */
|
||||
void (*sn_nsdl_oma_bs_done_cb)(sn_nsdl_oma_server_info_t *server_info_ptr); /* Callback to inform application when bootstrap is done */
|
||||
sn_nsdl_ep_parameters_s *ep_information_ptr; // Endpoint parameters, Name, Domain etc..
|
||||
sn_nsdl_oma_server_info_t *nsp_address_ptr; // NSP server address information
|
||||
uint8_t sn_nsdl_endpoint_registered;
|
||||
|
||||
uint16_t register_msg_id;
|
||||
uint16_t unregister_msg_id;
|
||||
|
||||
void *(*sn_nsdl_alloc)(uint16_t);
|
||||
void (*sn_nsdl_free)(void *);
|
||||
uint8_t (*sn_nsdl_tx_callback)(struct nsdl_s *, sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *);
|
||||
uint8_t (*sn_nsdl_rx_callback)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *);
|
||||
void (*sn_nsdl_oma_bs_done_cb_handle)(sn_nsdl_oma_server_info_t *server_info_ptr,
|
||||
struct nsdl_s *handle); /* Callback to inform application when bootstrap is done with nsdl handle */
|
||||
uint16_t update_register_msg_id;
|
||||
uint16_t register_msg_len;
|
||||
uint16_t update_register_msg_len;
|
||||
uint16_t bootstrap_msg_id;
|
||||
bool handle_bootstrap_msg;
|
||||
};
|
||||
|
||||
/***** Function prototypes *****/
|
||||
/**
|
||||
* \fn extern grs_s *sn_grs_init (uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t,
|
||||
* sn_nsdl_addr_s *), uint8_t (*sn_grs_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *),
|
||||
* sn_grs_mem_s *sn_memory)
|
||||
*
|
||||
* \brief GRS library initialize function.
|
||||
*
|
||||
* This function initializes GRS and CoAP.
|
||||
*
|
||||
* \param sn_grs_tx_callback A function pointer to a transmit callback function. Should return 1 when succeed, 0 when failed
|
||||
* \param *sn_grs_rx_callback_ptr A function pointer to a receiving callback function. If received packet is not for GRS, it will be passed to
|
||||
* upper level (NSDL) to be proceed.
|
||||
* \param sn_memory A pointer to a structure containing the platform specific functions for memory allocation and free.
|
||||
*
|
||||
* \return success pointer to handle, failure = NULL
|
||||
*
|
||||
*/
|
||||
extern struct grs_s *sn_grs_init(uint8_t (*sn_grs_tx_callback_ptr)(struct nsdl_s *, sn_nsdl_capab_e , uint8_t *, uint16_t,
|
||||
sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *), void *(*sn_grs_alloc)(uint16_t), void (*sn_grs_free)(void *));
|
||||
|
||||
extern const sn_nsdl_resource_info_s *sn_grs_get_first_resource(struct grs_s *handle);
|
||||
extern const sn_nsdl_resource_info_s *sn_grs_get_next_resource(struct grs_s *handle, const sn_nsdl_resource_info_s *sn_grs_current_resource);
|
||||
extern int8_t sn_grs_process_coap(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *src);
|
||||
extern sn_nsdl_resource_info_s *sn_grs_search_resource(struct grs_s *handle, uint16_t pathlen, uint8_t *path, uint8_t search_method);
|
||||
extern int8_t sn_grs_destroy(struct grs_s *handle);
|
||||
extern sn_grs_resource_list_s *sn_grs_list_resource(struct grs_s *handle, uint16_t pathlen, uint8_t *path);
|
||||
extern void sn_grs_free_resource_list(struct grs_s *handle, sn_grs_resource_list_s *list);
|
||||
extern int8_t sn_grs_update_resource(struct grs_s *handle, sn_nsdl_resource_info_s *res);
|
||||
extern int8_t sn_grs_send_coap_message(struct nsdl_s *handle, sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr);
|
||||
extern int8_t sn_grs_create_resource(struct grs_s *handle, sn_nsdl_resource_info_s *res);
|
||||
extern int8_t sn_grs_delete_resource(struct grs_s *handle, uint16_t pathlen, uint8_t *path);
|
||||
extern void sn_grs_mark_resources_as_registered(struct nsdl_s *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GRS_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,15 @@
|
|||
# NB external pthreads dependency!!
|
||||
find_package (Threads)
|
||||
add_executable(multithread-linux-test
|
||||
"main.c"
|
||||
"mbed_client.c"
|
||||
)
|
||||
target_link_libraries(multithread-linux-test
|
||||
mbed-client-c
|
||||
)
|
||||
|
||||
target_link_libraries(multithread-linux-test
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 _ARGUMENTS_
|
||||
#define _ARGUMENTS_
|
||||
#include "resource_generation_help.h"
|
||||
|
||||
#ifdef MACOSX
|
||||
// ----------------------------------------
|
||||
// Mac OS X
|
||||
#ifdef __DARWIN_UNIX03
|
||||
typedef unsigned short port_t;
|
||||
#else
|
||||
#include <mach/port.h>
|
||||
#endif // __DARWIN_UNIX03
|
||||
typedef unsigned long ipaddr_t;
|
||||
#endif
|
||||
|
||||
/* Argument variables */
|
||||
uint16_t arg_port, arg_sport, arg_dport; //0-65535
|
||||
char arg_dst[64];
|
||||
|
||||
#endif /* _ARGUMENTS_ */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "sn_nsdl_lib.h"
|
||||
#include "ns_list.h"
|
||||
#include "arguments.h"
|
||||
|
||||
#define NUMTHREADS 10
|
||||
|
||||
extern int register_endpoint(int port, sn_nsdl_ep_parameters_s *endpoint_ptr, int thread_id);
|
||||
void stop_pgm(char *s)
|
||||
{
|
||||
perror(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *own_alloc(uint16_t size)
|
||||
{
|
||||
if(size) {
|
||||
return malloc(size);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void own_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void arg_init(void)
|
||||
{
|
||||
memcpy(arg_dst,"::1",32); //default localhost
|
||||
arg_sport=5683;
|
||||
arg_dport=5683;
|
||||
}
|
||||
|
||||
|
||||
void usage_show(void)
|
||||
{
|
||||
printf("Usage:\n\n"
|
||||
|
||||
"multithread-linux-test [-d 127.0.0.1] \n"
|
||||
"-d NSP IPv4 address (default = ::1)\n"
|
||||
"-dp NSP port number (default = 5683)\n");
|
||||
}
|
||||
|
||||
/* function to be executed by the new thread */
|
||||
void* create_endpoint(void *arg)
|
||||
{
|
||||
int index = *((int *) arg);
|
||||
int port = 8100 + index;
|
||||
sn_nsdl_ep_parameters_s *endpoint_ptr;
|
||||
uint8_t endpoint_type[] = {"type"};
|
||||
uint8_t lifetime_ptr[] = {"120"};
|
||||
char str[10];
|
||||
sprintf(str, "THREAD_%d", index);
|
||||
endpoint_ptr = own_alloc(sizeof(sn_nsdl_ep_parameters_s));
|
||||
if(endpoint_ptr)
|
||||
{
|
||||
memset(endpoint_ptr, 0, sizeof(sn_nsdl_ep_parameters_s));
|
||||
endpoint_ptr->endpoint_name_ptr = str;
|
||||
endpoint_ptr->endpoint_name_len = strlen(str);
|
||||
endpoint_ptr->type_ptr = endpoint_type;
|
||||
endpoint_ptr->type_len = sizeof(endpoint_type)-1;
|
||||
endpoint_ptr->lifetime_ptr = lifetime_ptr;
|
||||
endpoint_ptr->lifetime_len = sizeof(lifetime_ptr)-1;
|
||||
}
|
||||
register_endpoint(port, endpoint_ptr, index);
|
||||
if(endpoint_ptr) {
|
||||
own_free(endpoint_ptr);
|
||||
endpoint_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint8_t i;
|
||||
arg_init();
|
||||
|
||||
if (argc<1)
|
||||
{
|
||||
usage_show();
|
||||
}
|
||||
else
|
||||
{
|
||||
i=1; //argv[0] is the command itself
|
||||
|
||||
argc--; //get the real number of arguments
|
||||
while (i<=argc)
|
||||
{
|
||||
//check arguments
|
||||
if (!(strcmp("-h",argv[i])))
|
||||
{
|
||||
usage_show();
|
||||
stop_pgm("");
|
||||
}
|
||||
else if (!(strcmp("-d",argv[i])))
|
||||
{
|
||||
if (i++==argc) stop_pgm("Argument missed for option -d\n");
|
||||
memcpy(arg_dst,argv[i],strlen((const char*)argv[i])+1);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (!(strcmp("-p",argv[i])))
|
||||
{
|
||||
if (i++==argc) stop_pgm("Argument missed for option -p\n");
|
||||
arg_port=atoi(argv[i]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (!(strcmp("-dp",argv[i])))
|
||||
{
|
||||
if (i++==argc) stop_pgm("Argument missed for option -dp\n");
|
||||
arg_dport=atoi(argv[i]);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage_show();
|
||||
stop_pgm("\n--- Argument error ---\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pthread_t threads[NUMTHREADS];
|
||||
for (int index = 0; index < NUMTHREADS; index++) {
|
||||
pthread_create(&threads[index], NULL, create_endpoint, (void *) &index);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMTHREADS; i) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,518 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h> /* For SIGIGN and SIGINT */
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "sn_nsdl.h"
|
||||
#include "sn_coap_header.h"
|
||||
#include "sn_coap_protocol.h"
|
||||
#include "sn_nsdl_lib.h"
|
||||
#include "ns_list.h"
|
||||
#include "sn_grs.h"
|
||||
#include "arguments.h"
|
||||
#include "resource_generation_help.h"
|
||||
|
||||
#define BUFLEN 1024
|
||||
|
||||
/* Resource paths and values */
|
||||
static uint8_t res_manufacturer[] = {"3/0/0"};
|
||||
static uint8_t res_manufacturer_val[] = {"ARM"};
|
||||
static uint8_t res_model_number[] = {"3/0/1"};
|
||||
static uint8_t res_model_number_val[] = {"1.00"};
|
||||
|
||||
static uint8_t res_temp[] = {"3303/0/temp"};
|
||||
static uint8_t res_type_test[] = {"t"};
|
||||
|
||||
struct thread_data_struct {
|
||||
struct nsdl_s *handle;
|
||||
struct sockaddr_in sa_dst;
|
||||
struct sockaddr_in sa_src;
|
||||
int sock_server;
|
||||
socklen_t slen_sa_dst;
|
||||
int thread_id;
|
||||
sn_nsdl_ep_parameters_s *endpoint_ptr;
|
||||
sn_nsdl_addr_s received_packet_address;
|
||||
ns_list_link_t link;
|
||||
bool registered;
|
||||
uint32_t ns_system_time;
|
||||
uint8_t delayed_token[8];
|
||||
uint8_t delayed_token_len;
|
||||
sn_coap_msg_type_e delayed_msg_type;
|
||||
uint8_t delayed_response_cnt;
|
||||
uint8_t res_temp_val[16];
|
||||
};
|
||||
typedef struct thread_data_struct thread_data_struct_s;
|
||||
|
||||
extern void stop_pgm();
|
||||
extern void *own_alloc(uint16_t size);
|
||||
extern void own_free(void* ptr);
|
||||
|
||||
/* Function templates */
|
||||
int register_endpoint(int port, sn_nsdl_ep_parameters_s *endpoint, int thread_id);
|
||||
uint8_t tx_function(struct nsdl_s *handle, sn_nsdl_capab_e protocol , uint8_t *data, uint16_t len, sn_nsdl_addr_s *address);
|
||||
uint8_t rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_header, sn_nsdl_addr_s *address);
|
||||
static void ctrl_c_handle_function();
|
||||
typedef void (*signalhandler_t)(int);
|
||||
void coap_exec_poll_function(int thread_id);
|
||||
int16_t receive_msg(thread_data_struct_s *data_item, uint8_t *buf);
|
||||
uint8_t general_resource_cb(struct nsdl_s *handle, sn_coap_hdr_s *coap_ptr, sn_nsdl_addr_s *address, sn_nsdl_capab_e protocol);
|
||||
int8_t compare_uripaths(sn_coap_hdr_s *coap_header, const uint8_t *uri_path_to_compare);
|
||||
void send_ack(struct nsdl_s *handle, sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address);
|
||||
|
||||
/* CoAP related globals*/
|
||||
uint8_t text_plain = COAP_CT_TEXT_PLAIN;
|
||||
uint8_t link_format = COAP_CT_LINK_FORMAT;
|
||||
|
||||
/* Resource related globals*/
|
||||
uint8_t *reg_location = 0;
|
||||
int8_t reg_location_len;
|
||||
|
||||
/* List containing thread specific data */
|
||||
typedef NS_LIST_HEAD(thread_data_struct_s, link) thread_data_struct_t;
|
||||
static thread_data_struct_t NS_LIST_NAME_INIT(data_list);
|
||||
|
||||
/*****************************************************/
|
||||
/* This is called from main to start the CoAP server */
|
||||
/*****************************************************/
|
||||
int register_endpoint(int port, sn_nsdl_ep_parameters_s *endpoint, int thread_id)
|
||||
{
|
||||
printf("Register endpoint, port: %d, thread id: %d\n", port, thread_id);
|
||||
thread_data_struct_s *data_item = NULL;
|
||||
uint8_t nsp_addr[16];
|
||||
pthread_t coap_exec_thread;
|
||||
uint8_t received_address[4];
|
||||
uint8_t buf[BUFLEN];
|
||||
int16_t rcv_size=0;
|
||||
|
||||
data_item = malloc(sizeof(thread_data_struct_s));
|
||||
data_item->slen_sa_dst = sizeof(data_item->sa_dst);
|
||||
memset(&data_item->received_packet_address, 0, sizeof(sn_nsdl_addr_s));
|
||||
memset(&data_item->sa_dst, 0, sizeof(struct sockaddr_in));
|
||||
memset(&data_item->sa_src, 0, sizeof(struct sockaddr_in));
|
||||
data_item->received_packet_address.addr_ptr = received_address;
|
||||
data_item->endpoint_ptr = endpoint;
|
||||
data_item->registered = false;
|
||||
data_item->thread_id = thread_id;
|
||||
data_item->ns_system_time = 1;
|
||||
data_item->delayed_token_len = 0;
|
||||
data_item->delayed_response_cnt = 0;
|
||||
|
||||
/* Initial values for temperature */
|
||||
char temp[10];
|
||||
if (thread_id >= 9) {
|
||||
sprintf(temp, "25.%d", thread_id);
|
||||
} else {
|
||||
sprintf(temp, "2%d.0", thread_id);
|
||||
}
|
||||
strcpy(data_item->res_temp_val,temp);
|
||||
|
||||
sn_nsdl_resource_info_s *resource_ptr = 0;
|
||||
|
||||
if (signal(SIGINT, (signalhandler_t)ctrl_c_handle_function) == SIG_ERR) {
|
||||
printf("Error with SIGINT: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open the server socket*/
|
||||
if ((data_item->sock_server=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) ==-1 ) {
|
||||
stop_pgm("socket() error");
|
||||
}
|
||||
|
||||
/* Init the listen port addr*/
|
||||
memset((char *) &data_item->sa_src, 0, sizeof(data_item->sa_src));
|
||||
data_item->sa_src.sin_family = AF_INET;
|
||||
data_item->sa_src.sin_port = htons(port);
|
||||
|
||||
/* Listen to the port */
|
||||
data_item->sa_src.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(data_item->sock_server, (struct sockaddr *) &data_item->sa_src, sizeof(data_item->sa_src) ) == -1) {
|
||||
stop_pgm("bind() error");
|
||||
}
|
||||
|
||||
data_item->handle = sn_nsdl_init(&tx_function, &rx_function, &own_alloc, &own_free);
|
||||
inet_pton(AF_INET, arg_dst, &nsp_addr);
|
||||
|
||||
set_NSP_address(data_item->handle, nsp_addr, arg_dport, SN_NSDL_ADDRESS_TYPE_IPV4);
|
||||
ns_list_add_to_start(&data_list, data_item);
|
||||
|
||||
pthread_create(&coap_exec_thread, NULL, (void *)coap_exec_poll_function, data_item->thread_id);
|
||||
|
||||
resource_ptr = own_alloc(sizeof(sn_nsdl_resource_info_s));
|
||||
if(!resource_ptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(resource_ptr, 0, sizeof(sn_nsdl_resource_info_s));
|
||||
resource_ptr->resource_parameters_ptr = own_alloc(sizeof(sn_nsdl_resource_parameters_s));
|
||||
if(!resource_ptr->resource_parameters_ptr) {
|
||||
own_free(resource_ptr);
|
||||
return 0;
|
||||
}
|
||||
memset(resource_ptr->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s));
|
||||
|
||||
/* Create resources */
|
||||
CREATE_STATIC_RESOURCE(resource_ptr, sizeof(res_manufacturer)-1, (uint8_t*) res_manufacturer, sizeof(res_type_test)-1,
|
||||
(uint8_t*)res_type_test, (uint8_t*) res_manufacturer_val,
|
||||
sizeof(res_manufacturer_val)-1, data_item->handle);
|
||||
|
||||
CREATE_STATIC_RESOURCE(resource_ptr, sizeof(res_model_number)-1, (uint8_t*) res_model_number, sizeof(res_type_test)-1,
|
||||
(uint8_t*)res_type_test, (uint8_t*) res_model_number_val,
|
||||
sizeof(res_model_number_val)-1, data_item->handle);
|
||||
|
||||
CREATE_DYNAMIC_RESOURCE(resource_ptr, sizeof(res_temp)-1, (uint8_t*) res_temp, sizeof(res_type_test)-1,
|
||||
(uint8_t*)res_type_test, 0, &general_resource_cb, data_item->handle)
|
||||
|
||||
/* Start registration */
|
||||
if(sn_nsdl_register_endpoint(data_item->handle, data_item->endpoint_ptr) == SN_NSDL_FAILURE) {
|
||||
printf("NSP registration failed, thread:%d\n", data_item->thread_id);
|
||||
}
|
||||
|
||||
/* Free resource_ptr */
|
||||
if(resource_ptr->resource_parameters_ptr) {
|
||||
own_free(resource_ptr->resource_parameters_ptr);
|
||||
}
|
||||
if(resource_ptr) {
|
||||
own_free(resource_ptr);
|
||||
}
|
||||
|
||||
/* Main loop. */
|
||||
/* Listen and process incoming messages */
|
||||
while (1)
|
||||
{
|
||||
usleep(100);
|
||||
memset(buf, 0, BUFLEN);
|
||||
rcv_size = receive_msg(data_item,buf);
|
||||
if(rcv_size > 0) {
|
||||
sn_nsdl_process_coap(data_item->handle, buf, rcv_size, &data_item->received_packet_address);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t receive_msg(thread_data_struct_s *data_item, uint8_t *buf)
|
||||
{
|
||||
char rcv_in_addr[32];
|
||||
int16_t rcv_size=0;
|
||||
|
||||
memset(rcv_in_addr,0,32);
|
||||
|
||||
if ((rcv_size=recvfrom(data_item->sock_server, buf, BUFLEN, 0,
|
||||
(struct sockaddr *)&data_item->sa_dst, (socklen_t*)&data_item->slen_sa_dst))==-1) {
|
||||
stop_pgm("recvfrom()");
|
||||
}
|
||||
else {
|
||||
inet_ntop(AF_INET, &(data_item->sa_dst.sin_addr),rcv_in_addr,INET_ADDRSTRLEN);
|
||||
data_item->received_packet_address.port = ntohs(data_item->sa_dst.sin_port);
|
||||
data_item->received_packet_address.type = SN_NSDL_ADDRESS_TYPE_IPV4;
|
||||
data_item->received_packet_address.addr_len = 4;
|
||||
memcpy(data_item->received_packet_address.addr_ptr, &data_item->sa_dst.sin_addr, 4);
|
||||
printf("\nRX %s.%d [%d B] - thread id: %d\n", rcv_in_addr, ntohs(data_item->sa_dst.sin_port), rcv_size, data_item->thread_id);
|
||||
}
|
||||
return rcv_size;
|
||||
}
|
||||
|
||||
/* Function needed for libCoap protocol. */
|
||||
uint8_t tx_function(struct nsdl_s *handle, sn_nsdl_capab_e protocol,
|
||||
uint8_t *data, uint16_t len, sn_nsdl_addr_s *address)
|
||||
{
|
||||
/* Set NSP address and port */
|
||||
thread_data_struct_s *data_item = NULL;
|
||||
ns_list_foreach(thread_data_struct_s, item, &data_list) {
|
||||
if (item->handle == handle) {
|
||||
data_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (data_item != NULL) {
|
||||
printf("TX function - thread id: %d\n", data_item->thread_id);
|
||||
ns_list_remove(&data_list, data_item);
|
||||
data_item->sa_dst.sin_family = AF_INET;
|
||||
data_item->sa_dst.sin_port = htons(address->port);
|
||||
memcpy(&data_item->sa_dst.sin_addr, address->addr_ptr, address->addr_len);
|
||||
ns_list_add_to_end(&data_list, data_item);
|
||||
|
||||
int ret = sendto(data_item->sock_server,
|
||||
data,
|
||||
len,
|
||||
0,
|
||||
(const struct sockaddr *)&data_item->sa_dst,
|
||||
data_item->slen_sa_dst);
|
||||
if (ret == -1) {
|
||||
stop_pgm("sendto() failed");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* RX function for libNsdl. Passes CoAP responses sent from application to this function. Also response to registration message */
|
||||
uint8_t rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_header, sn_nsdl_addr_s *address)
|
||||
{
|
||||
if(!coap_header)
|
||||
return 0;
|
||||
|
||||
thread_data_struct_s *data_item = NULL;
|
||||
ns_list_foreach(thread_data_struct_s, item, &data_list) {
|
||||
if (item->handle == handle) {
|
||||
data_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!data_item)
|
||||
return 0;
|
||||
printf("\nRX callback mid:%d, thread id: %d\n", coap_header->msg_id, data_item->thread_id);
|
||||
|
||||
/* If message is response to NSP registration */
|
||||
if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CREATED &&
|
||||
!data_item->registered) {
|
||||
reg_location_len = coap_header->options_list_ptr->location_path_len;
|
||||
if(reg_location)
|
||||
free(reg_location);
|
||||
reg_location = malloc(reg_location_len);
|
||||
|
||||
if(!reg_location) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(reg_location, coap_header->options_list_ptr->location_path_ptr, reg_location_len);
|
||||
printf("Registered to NSP: ");
|
||||
for(int i = 0; i < reg_location_len; i++)
|
||||
printf("%c", *(reg_location+i));
|
||||
printf("\n");
|
||||
|
||||
data_item->registered = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ctrl_c_handle_function()
|
||||
{
|
||||
printf("Pressed ctrl-c\n");
|
||||
ns_list_foreach(thread_data_struct_s, item, &data_list) {
|
||||
if (item->handle) {
|
||||
sn_nsdl_unregister_endpoint(item->handle);
|
||||
}
|
||||
}
|
||||
if(reg_location)
|
||||
own_free(reg_location);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void coap_exec_poll_function(int thread_id)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
sn_coap_hdr_s coap_header;
|
||||
|
||||
while(1)
|
||||
{
|
||||
sleep(1);
|
||||
thread_data_struct_s *data_item = NULL;
|
||||
ns_list_foreach(thread_data_struct_s, item, &data_list) {
|
||||
if (item->thread_id == thread_id) {
|
||||
data_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (data_item) {
|
||||
/* nsdl execution function, must be called at least once / second. System time must be increased every second. */
|
||||
/* Cleans saved and unused data from libraries. Recommend to run this in same thread with other nsdl - functions */
|
||||
sn_nsdl_exec(data_item->handle, data_item->ns_system_time);
|
||||
data_item->ns_system_time++;
|
||||
|
||||
/* Check if reregistration needed */
|
||||
if(!(data_item->ns_system_time % (uint32_t)30) && data_item->ns_system_time)
|
||||
{
|
||||
printf("Update registration - thread id: %d\n", data_item->thread_id);
|
||||
sn_nsdl_update_registration(data_item->handle, data_item->endpoint_ptr->lifetime_ptr, data_item->endpoint_ptr->lifetime_len);
|
||||
}
|
||||
|
||||
/* Send delayed response to request */
|
||||
/* This is just example. When receiving request to sen/temp, application send ack and after few seconds value for this resource */
|
||||
if(data_item->delayed_response_cnt == 1) {
|
||||
printf("Delayed response - thread: %d\n", data_item->thread_id);
|
||||
memset(&coap_header, 0, sizeof(sn_coap_hdr_s));
|
||||
|
||||
if(data_item->delayed_msg_type == COAP_MSG_TYPE_CONFIRMABLE)
|
||||
coap_header.msg_type = COAP_MSG_TYPE_CONFIRMABLE;
|
||||
else if(data_item->delayed_msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE)
|
||||
coap_header.msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
|
||||
|
||||
coap_header.msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
|
||||
|
||||
if(data_item->delayed_token_len)
|
||||
{
|
||||
coap_header.token_len = data_item->delayed_token_len;
|
||||
coap_header.token_ptr = data_item->delayed_token;
|
||||
data_item->delayed_token_len = 0;
|
||||
}
|
||||
|
||||
coap_header.payload_len = sizeof(data_item->res_temp_val) - 1;
|
||||
coap_header.payload_ptr = data_item->res_temp_val;
|
||||
|
||||
sn_nsdl_send_coap_message(data_item->handle, &data_item->received_packet_address, &coap_header);
|
||||
|
||||
data_item->delayed_response_cnt = 0;
|
||||
|
||||
}
|
||||
else if(data_item->delayed_response_cnt > 1) {
|
||||
data_item->delayed_response_cnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is callback for other DYNAMIC resources */
|
||||
uint8_t general_resource_cb(struct nsdl_s *handle, sn_coap_hdr_s *received_coap_ptr,
|
||||
sn_nsdl_addr_s *address, sn_nsdl_capab_e protocol)
|
||||
{
|
||||
sn_coap_hdr_s *coap_res_ptr = 0;
|
||||
thread_data_struct_s *data_item = NULL;
|
||||
ns_list_foreach(thread_data_struct_s, item, &data_list) {
|
||||
if (item->handle == handle) {
|
||||
data_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!data_item) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) {
|
||||
printf("\nGeneral callback - thread id: %d\n", data_item->thread_id);
|
||||
coap_res_ptr = sn_nsdl_build_response(data_item->handle, received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);
|
||||
coap_res_ptr->content_type_ptr = &text_plain;
|
||||
coap_res_ptr->content_type_len = sizeof(text_plain);
|
||||
|
||||
/* Temperature resource */
|
||||
/* This makes delayed response, first ack and after that real value */
|
||||
if(compare_uripaths(received_coap_ptr, res_temp))
|
||||
{
|
||||
send_ack(data_item->handle,received_coap_ptr, &data_item->received_packet_address);
|
||||
if(coap_res_ptr->token_ptr) {
|
||||
own_free(coap_res_ptr->token_ptr);
|
||||
}
|
||||
if(coap_res_ptr->options_list_ptr) {
|
||||
own_free(coap_res_ptr->options_list_ptr);
|
||||
}
|
||||
own_free(coap_res_ptr);
|
||||
return 0;
|
||||
}
|
||||
sn_nsdl_send_coap_message(data_item->handle, address, coap_res_ptr);
|
||||
}
|
||||
else if (received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) {
|
||||
if (received_coap_ptr->payload_ptr && received_coap_ptr->payload_len < 16) {
|
||||
ns_list_remove(&data_list, data_item);
|
||||
memcpy(data_item->res_temp_val,received_coap_ptr->payload_ptr, received_coap_ptr->payload_len);
|
||||
printf("Update resource value to %s, thread id: %d\n", data_item->res_temp_val, data_item->thread_id);
|
||||
ns_list_add_to_end(&data_list, data_item);
|
||||
}
|
||||
coap_res_ptr = sn_nsdl_build_response(data_item->handle, received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED);
|
||||
sn_nsdl_send_coap_message(data_item->handle, address, coap_res_ptr);
|
||||
}
|
||||
/* Method not supported */
|
||||
else {
|
||||
printf("Method not supported\n");
|
||||
coap_res_ptr = sn_coap_build_response(handle->grs->coap, received_coap_ptr, COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED);
|
||||
sn_nsdl_send_coap_message(handle, address, coap_res_ptr);
|
||||
}
|
||||
|
||||
if(coap_res_ptr->token_ptr) {
|
||||
own_free(coap_res_ptr->token_ptr);
|
||||
}
|
||||
|
||||
if(coap_res_ptr->options_list_ptr) {
|
||||
own_free(coap_res_ptr->options_list_ptr);
|
||||
}
|
||||
own_free(coap_res_ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t compare_uripaths(sn_coap_hdr_s *coap_header, const uint8_t *uri_path_to_compare)
|
||||
{
|
||||
if(memcmp(coap_header->uri_path_ptr,&uri_path_to_compare[0], coap_header->uri_path_len) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_ack(struct nsdl_s *handle, sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address/*, sn_nsdl_addr_s *received_packet_address*/)
|
||||
{
|
||||
printf("Send acknowledgement\n");
|
||||
sn_coap_hdr_s *coap_res_ptr = 0;
|
||||
uint16_t message_len = 0;
|
||||
uint8_t *message_ptr;
|
||||
thread_data_struct_s *data_item = NULL;
|
||||
ns_list_foreach(thread_data_struct_s, item, &data_list) {
|
||||
if (item->handle == handle) {
|
||||
data_item = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (data_item) {
|
||||
if (received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET)
|
||||
{
|
||||
if (received_coap_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
|
||||
coap_res_ptr = own_alloc(sizeof(sn_coap_hdr_s));
|
||||
if(!coap_res_ptr) {
|
||||
return;
|
||||
}
|
||||
memset(coap_res_ptr, 0x00, sizeof(sn_coap_hdr_s));
|
||||
coap_res_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
|
||||
coap_res_ptr->msg_code = COAP_MSG_CODE_EMPTY;
|
||||
coap_res_ptr->msg_id = received_coap_ptr->msg_id;
|
||||
data_item->delayed_msg_type = COAP_MSG_TYPE_CONFIRMABLE;
|
||||
}
|
||||
else {
|
||||
data_item->delayed_msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
|
||||
}
|
||||
|
||||
if(received_coap_ptr->token_len) {
|
||||
memset(data_item->delayed_token, 0, 8);
|
||||
data_item->delayed_token_len = received_coap_ptr->token_len;
|
||||
memcpy(data_item->delayed_token, received_coap_ptr->token_ptr, received_coap_ptr->token_len);
|
||||
}
|
||||
data_item->delayed_response_cnt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(coap_res_ptr) {
|
||||
message_len = sn_coap_builder_calc_needed_packet_data_size(coap_res_ptr);
|
||||
message_ptr = own_alloc(message_len);
|
||||
if(!message_ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
sn_coap_builder(message_ptr, coap_res_ptr);
|
||||
tx_function(handle,SN_NSDL_PROTOCOL_COAP, message_ptr, message_len, address);
|
||||
|
||||
/* Free memory */
|
||||
if(coap_res_ptr) {
|
||||
own_free(coap_res_ptr);
|
||||
}
|
||||
own_free(message_ptr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "multithread-linux-test",
|
||||
"version": "1.0.0",
|
||||
"description": "Example application how to use mbed-client-c library",
|
||||
"private": true,
|
||||
"keywords": [],
|
||||
"author": "Antti Yli-Tokola <antti.yli-tokola@arm.com>",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"mbed-client-c": "^2.0.0"
|
||||
},
|
||||
"bin": "./"
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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 RESOURCE_GENERATION_HELP_H_
|
||||
#define RESOURCE_GENERATION_HELP_H_
|
||||
|
||||
/*
|
||||
* A helper macro to create a static resoure
|
||||
*/
|
||||
#define CREATE_STATIC_RESOURCE(resource_structure, pt_len, pt, rpp_len, rpp_ptr, rsc, rsc_len, handle) \
|
||||
{ \
|
||||
resource_structure->access = (sn_grs_resource_acl_e)0xff; \
|
||||
resource_structure->mode = SN_GRS_STATIC; \
|
||||
resource_structure->pathlen = pt_len; \
|
||||
resource_structure->path = pt; \
|
||||
resource_structure->resource_parameters_ptr->resource_type_len = rpp_len; \
|
||||
resource_structure->resource_parameters_ptr->resource_type_ptr = rpp_ptr; \
|
||||
resource_structure->resource = rsc; \
|
||||
resource_structure->resourcelen = rsc_len; \
|
||||
sn_nsdl_create_resource(handle,resource_structure); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A helper macro to create a dynamic resoure
|
||||
*/
|
||||
#define CREATE_DYNAMIC_RESOURCE(resource_structure, pt_len, pt, rpp_len, rpp_ptr, is_observable, callback_ptr, handle) \
|
||||
{ \
|
||||
resource_structure->access = (sn_grs_resource_acl_e)0xff; \
|
||||
resource_structure->resource = 0; \
|
||||
resource_structure->resourcelen = 0; \
|
||||
resource_structure->sn_grs_dyn_res_callback = callback_ptr; \
|
||||
resource_structure->mode = SN_GRS_DYNAMIC; \
|
||||
resource_structure->pathlen = pt_len; \
|
||||
resource_structure->path = pt; \
|
||||
resource_structure->resource_parameters_ptr->resource_type_len = rpp_len; \
|
||||
resource_structure->resource_parameters_ptr->resource_type_ptr = rpp_ptr; \
|
||||
resource_structure->resource_parameters_ptr->observable = is_observable; \
|
||||
sn_nsdl_create_resource(handle,resource_structure); \
|
||||
}
|
||||
|
||||
#define INIT_REGISTER_NSDL_ENDPOINT(endpoint_structure, name, typename_ptr, lifetime_ptr) \
|
||||
{ \
|
||||
if(!endpoint_structure) \
|
||||
{ \
|
||||
endpoint_structure = own_alloc(sizeof(sn_nsdl_ep_parameters_s)); \
|
||||
} \
|
||||
if(endpoint_structure) \
|
||||
{ \
|
||||
memset(endpoint_structure, 0, sizeof(sn_nsdl_ep_parameters_s)); \
|
||||
endpoint_structure->endpoint_name_ptr = name; \
|
||||
endpoint_structure->endpoint_name_len = sizeof(name)-1; \
|
||||
endpoint_structure->type_ptr = typename_ptr; \
|
||||
endpoint_structure->type_len = sizeof(typename_ptr)-1; \
|
||||
endpoint_structure->lifetime_ptr = lifetime_ptr; \
|
||||
endpoint_structure->lifetime_len = sizeof(lifetime_ptr)-1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLEAN_REGISTER_NSDL_ENDPOINT(endpoint_structure) \
|
||||
{ \
|
||||
if(endpoint_structure) \
|
||||
{ \
|
||||
own_free(endpoint_structure); \
|
||||
endpoint_structure = 0; \
|
||||
} \
|
||||
} \
|
||||
|
||||
#endif /* RESOURCE_GENERATION_HELP_H_ */
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#!/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.
|
||||
|
||||
initial_values=(20.0 21.0 22.0 23.0 24.0 25.0 26.0 27.0 28.0 25.9 )
|
||||
new_values=(30.0 31.0 32.0 33.0 34.0 35.0 36.0 37.0 38.0 35.9 )
|
||||
DESTINATION=$1
|
||||
function read_default_values {
|
||||
echo "Read default values"
|
||||
for i in {0..9}
|
||||
do
|
||||
value=`curl -s -H "Authorization: Basic YWRtaW46c2VjcmV0" "http://${DESTINATION}:8080/endpoints/THREAD_${i}/3303/0/temp?sync=true"`
|
||||
echo "Thread${i} $value"
|
||||
if [ "${initial_values[$i]}" != "$value" ];
|
||||
then
|
||||
echo "Value ${initial_values[$i]} does not match to $value"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function read_new_values {
|
||||
echo "Read new values"
|
||||
for i in {0..9}
|
||||
do
|
||||
value=`curl -s -H "Authorization: Basic YWRtaW46c2VjcmV0" "http://${DESTINATION}:8080/endpoints/THREAD_${i}/3303/0/temp?sync=true"`
|
||||
echo "Thread${i} $value"
|
||||
if [ "${new_values[$i]}" != "$value" ];
|
||||
then
|
||||
echo "Value ${new_values[$i]} does not match to $value"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function post_new_values {
|
||||
echo "Post new values"
|
||||
for i in {0..9}
|
||||
do
|
||||
curl -X PUT -H "Authorization: Basic YWRtaW46c2VjcmV0" "http://${DESTINATION}:8080/endpoints/THREAD_${i}/3303/0/temp?sync=true" -d "${new_values[$i]}"
|
||||
done
|
||||
}
|
||||
|
||||
function post_default_values {
|
||||
echo "Post default values"
|
||||
for i in {0..9}
|
||||
do
|
||||
curl -X PUT -H "Authorization: Basic YWRtaW46c2VjcmV0" "http://${DESTINATION}:8080/endpoints/THREAD_${i}/3303/0/temp?sync=true" -d "${initial_values[$i]}"
|
||||
done
|
||||
}
|
||||
post_default_values
|
||||
while [ true ]; do
|
||||
read_default_values
|
||||
sleep 2
|
||||
post_new_values
|
||||
sleep 2
|
||||
read_new_values
|
||||
sleep 2
|
||||
post_default_values
|
||||
sleep 2
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue