diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7764e0c7..b477e87af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,26 +1,62 @@
## Changelog for Pelion Device Management Client
+### Release 4.9.0 (20.05.2021)
+
+### Device Management Client
+
+- Fixed a race condition in the handling of message status callback (particularly the handling of `MESSAGE_STATUS_SENT`). Previously, it was getting reported just before the operation had finished successfully.
+- Added support for TLV to single resource.
+- PUT to a resource 1/0/1 now triggers a registration update.
+- POST to a resource 1/0/4 now triggers a deregister process.
+- Removed deprecated STL APIs. These APIs and classes were removed:
+ - `SimpleM2MResource*`.
+ - `MbedCloudClient::set_device_resource_value(M2MDevice::DeviceResource resource, const std::string &value)`.
+ - `MbedCloudClient::register_update_callback(string route, SimpleM2MResourceBase* resource)`.
+- Added new API `MbedCloudClient::alert()` to send high-priority messages.
+ - In alert mode, Device Management Client halts all data sendings/active operations and waits for priority data to be sent.
+- Added new status callback API `MbedCloudClient::on_status_changed()`, which replaces these callback APIs:
+ - `MbedCloudClient::on_registered()`.
+ - `MbedCloudClient::on_unregistered()`.
+ - `MbedCloudClient::on_registration_updated()`.
+ - The old APIs are deprecated and will be removed in a future release.
+- Added option to reduce traffic in bootstrap flow:
+ - `MBED_CONF_MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE` flag added to control whether delay or piggybacked response is used. By default, piggybacked response type is used.
+ - Piggybacked response can be disabled by setting `mbed-client.bootstrap-piggybacked-response" : 0` in `mbed_app.json`.
+- Fixed register and register update content type to `COAP_CT_LINK_FORMAT` (Core Link Format).
+- Fixed a memory leak when `setup()` and `close()` were called multiple times in row.
+
+#### Device Management Update client
+
+- Removed the `need_reboot = false` option in the `fota_component_add()` API. When registering a component, the `need_reboot` option must always be `true`.
+- Fixed storage erase calculations for boards with a non-uniform sector map.
+- Fixed the FOTA defer download behaviour. Device registration update won't cause the client to resume FOTA download after the application calls the `fota_app_defer()` API.
+
+### Platform Adaptation Layer (PAL)
+
+- Added new PAL_DNS_API_VERSION 3. It's an asynchronous DNS API that can return multiple DNS results.
+ - This feature is currently implemented only for Linux platform and is disabled by default. You can enable it by defining PAL_DNS_API_VERSION=3. In future releases, this feature will be enabled by default for Linux.
+
### Release 4.8.0 (19.04.2021)
#### Device Management Client
-- Client internal timers were not using event_ids correctly. Previously, if there were two timers running at the same time, cancel might have stopped the wrong timer.
+- Client internal timers were not using event IDs correctly. Previously, if two timers were running at the same time, cancel might have stopped the wrong timer.
- Added fallback timer for asynchronous DNS requests (`PAL_DNS_API_VERSION` = 2). The client waits 10 minutes for a response to DNS query before aborting the request and raising a DNS error event.
- Improved client bootstrap recovery handling.
-- The client doesn't go sleep if update register, unregistering or reconnecting is ongoing.
+- The client doesn't go to sleep if update register, unregistering or reconnecting is ongoing.
- Added LwM2M version as part of the registration message.
- Added API to get M2MServer instance.
- tinycbor: Removed the default usage of asserts in input validation. Instead of asserting, the library returns an error if an invalid cbor input is given. Introduced a new `TINYCBOR_USE_ASSERT` flag to save on code size. This saves approximately 200 bytes.
- Deprecated the `MBED_CLIENT_USER_CONFIG_FILE` macro. An application only needs to use `MBED_CLOUD_CLIENT_USER_CONFIG_FILE`.
- Allow Write-Attributes to GET resource.
- Parent resource of resource-instance also set observable flag. Now also parent resource can be observed.
-- Added API `m2mbase::set_confirmable(bool confirmable)` to choose whether notification is sent as a confirmable or non-confirmable way. By default, the confirmable message type is used.
+- Added API `m2mbase::set_confirmable(bool confirmable)` to choose whether a notification is sent in a confirmable or nonconfirmable way. By default, the confirmable message type is used.
- M2MDevice now accepts PUT/POST requests, and you can also observe it.
-- Fixed an issue which can cause a crash if there is a lot of network traffic during the `pause()` call.
-- Don't report notification sending timeout to the application. Notification sending can't fail after the message has been created because it has its own queue for resending.
-- Removed deprecated notification delivery status APIs. Use `M2MBase::set_message_delivery_status_cb` instead.
-- Changed default content type from `COAP_CONTENT_OMA_TLV_TYPE_OLD` to` COAP_CONTENT_OMA_TLV_TYPE`.
-- Deprecated `kcm_ecdh_key_agreement()` API for psa configuration, due to `psa_set_key_enrollment_algorithm()` API deprecation in mbed-crypto.
+- Fixed an issue that could cause a crash if there were a lot of network traffic during the `pause()` call.
+- Do not report notification sending timeout to application. Notification sending can't fail once message has been because since they have own queue for resending.
+- Removed deprecated notification delivery status APIs. Use `M2MBase::set_message_delivery_status_cb`, instead.
+- Changed default content type from `COAP_CONTENT_OMA_TLV_TYPE_OLD` to `COAP_CONTENT_OMA_TLV_TYPE`.
+- Deprecated `kcm_ecdh_key_agreement()` API for PSA configuration, due to `psa_set_key_enrollment_algorithm()` API deprecation in Mbed Crypto.
#### Device Management Update client
@@ -123,7 +159,7 @@ However, the notification will still be stored internally in client and it will
* Added a compile-time check to prevent configuring the client with LIFETIME values below 60 seconds. 60 seconds is the minimum allowed.
* [Mbed OS] Changed the default storage location for update to `ARM_UCP_FLASHIAP`.
* Added support for Device Sentry feature.
-* Added new library flag `MBED_CONF_MBED_CLOUD_CLIENT_NON_PROVISIONED_SECURE_ELEMENT`, The default is `null`. Should be set to `1` if SE hasn't pre-provisioned credentials.
+* Added new library flag `MBED_CONF_MBED_CLOUD_CLIENT_NON_PROVISIONED_SECURE_ELEMENT`, The default is `null`. Should be set to `1` if SE hasn't pre-provisioned credentials.
### Release 4.4.0 (17.04.2020)
@@ -700,7 +736,7 @@ Added a temporary workaround for Cypress PSOC6 target to read each block from an
* Full support for the `device generated keys` mode. You can activate the mode using the Factory Configurator Utility (FCU) or the KCM APIs.
**Note:** Cloud Client and Mbed Cloud do not yet support this mode.
-
+
* A certificate signed request (CSR) that is generated on the device, can be created with the `Extended key usage` extension.
* A new KCM API introduced:
* `kcm_certificate_verify_with_private_key` - a self-generated certificate can be checked against a stored private key.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 22d358de6..c6283807d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -288,11 +288,19 @@ if (FOTA_ENABLE)
endif()
include_directories(${FOTA_SOURCE_DIR})
+ include_directories("${FOTA_SOURCE_DIR}/platform/linux")
FILE(GLOB FOTA_SRC
"${FOTA_SOURCE_DIR}/*.c"
"${FOTA_SOURCE_DIR}/*.cpp"
"${FOTA_SOURCE_DIR}/bspatch/*.c"
+if ( (${OS_BRAND} MATCHES "Linux"))
+ "${FOTA_SOURCE_DIR}/platform/linux/*.c*"
+else
+if ( (${OS_BRAND} MATCHES "NXP"))
+ "${FOTA_SOURCE_DIR}/platform/nxp/*.c*"
+endif
+endif
)
message("FOTA sources = \n ${FOTA_SRC}")
target_sources(mbedCloudClient PRIVATE "${FOTA_SRC}")
@@ -301,16 +309,18 @@ if (FOTA_ENABLE)
add_library(fota STATIC ${FOTA_SRC})
- if (MBED_CLOUD_CLIENT_CURL_DYNAMIC_LINK)
- include(FindPkgConfig)
- pkg_check_modules(CURL libcurl REQUIRED)
- message("curl include at: ${CURL_INCLUDE_DIRS}")
- message("curl link: ${CURL_LIBRARIES}")
- include_directories(SYSTEM ${CURL_LIBRARIES})
- target_link_libraries(fota ${CURL_LIBRARIES})
- else()
- add_dependencies(fota libcurl)
- target_link_libraries(fota libcurl)
+ if ( NOT FOTA_COAP_DOWNLOAD)
+ if (MBED_CLOUD_CLIENT_CURL_DYNAMIC_LINK)
+ include(FindPkgConfig)
+ pkg_check_modules(CURL libcurl REQUIRED)
+ message("curl include at: ${CURL_INCLUDE_DIRS}")
+ message("curl link: ${CURL_LIBRARIES}")
+ include_directories(SYSTEM ${CURL_LIBRARIES})
+ target_link_libraries(fota ${CURL_LIBRARIES})
+ else()
+ add_dependencies(fota libcurl)
+ target_link_libraries(fota libcurl)
+ endif()
endif()
add_dependencies(mbedCloudClient fota)
target_link_libraries(mbedCloudClient fota)
diff --git a/certificate-enrollment-client/source/ce_safe_renewal_internal.c b/certificate-enrollment-client/source/ce_safe_renewal_internal.c
index 43620871b..11ef25fd1 100644
--- a/certificate-enrollment-client/source/ce_safe_renewal_internal.c
+++ b/certificate-enrollment-client/source/ce_safe_renewal_internal.c
@@ -21,7 +21,7 @@
#include "ce_internal.h"
#include "est_defs.h"
#include "storage_kcm.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
const char g_lwm2m_name[] = "LWM2M";
const char g_renewal_status_file[] = "renewal_status";
diff --git a/factory-configurator-client/crypto-service/crypto-service/cs_der_certs.h b/factory-configurator-client/crypto-service/crypto-service/cs_der_certs.h
index 7bacb00a3..30d9192b1 100644
--- a/factory-configurator-client/crypto-service/crypto-service/cs_der_certs.h
+++ b/factory-configurator-client/crypto-service/crypto-service/cs_der_certs.h
@@ -26,7 +26,7 @@ extern "C" {
#include
#include "kcm_status.h"
#include "storage_kcm.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
/*
* Types certificate's attributes
diff --git a/factory-configurator-client/crypto-service/crypto-service/cs_hash.h b/factory-configurator-client/crypto-service/crypto-service/cs_hash.h
index 42ab6cebf..daa58a356 100644
--- a/factory-configurator-client/crypto-service/crypto-service/cs_hash.h
+++ b/factory-configurator-client/crypto-service/crypto-service/cs_hash.h
@@ -22,7 +22,7 @@
#include
#include "kcm_status.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#ifdef __cplusplus
extern "C" {
diff --git a/factory-configurator-client/crypto-service/crypto-service/pal_Crypto.h b/factory-configurator-client/crypto-service/crypto-service/cs_pal_crypto.h
similarity index 99%
rename from factory-configurator-client/crypto-service/crypto-service/pal_Crypto.h
rename to factory-configurator-client/crypto-service/crypto-service/cs_pal_crypto.h
index 8a8e312cf..ddda6a825 100644
--- a/factory-configurator-client/crypto-service/crypto-service/pal_Crypto.h
+++ b/factory-configurator-client/crypto-service/crypto-service/cs_pal_crypto.h
@@ -16,8 +16,8 @@
// limitations under the License.
// ----------------------------------------------------------------------------
-#ifndef _FCC_PAL_CRYPTO_H_
-#define _FCC_PAL_CRYPTO_H_
+#ifndef _CS_PAL_CRYPTO_H_
+#define _CS_PAL_CRYPTO_H_
#ifdef __cplusplus
extern "C" {
@@ -27,7 +27,7 @@ extern "C" {
#include
#include
#include
-#include
+#include "cs_pal_crypto_configuration.h"
#include "mbed-trace/mbed_trace.h"
#if !defined(MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT) || defined(MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT)
#include "pal.h"
@@ -36,7 +36,7 @@ extern "C" {
#define NULLPTR 0
typedef int32_t palStatus_t;
-/*! \file pal_Crypto.h
+/*! \file cs_pal_crypto.h
* \brief PAL cryptographic.
* This file contains cryptographic APIs and is part of the PAL service API.
*
diff --git a/factory-configurator-client/crypto-service/crypto-service/pal_crypto_configuration.h b/factory-configurator-client/crypto-service/crypto-service/cs_pal_crypto_configuration.h
similarity index 95%
rename from factory-configurator-client/crypto-service/crypto-service/pal_crypto_configuration.h
rename to factory-configurator-client/crypto-service/crypto-service/cs_pal_crypto_configuration.h
index f96776c27..871409284 100644
--- a/factory-configurator-client/crypto-service/crypto-service/pal_crypto_configuration.h
+++ b/factory-configurator-client/crypto-service/crypto-service/cs_pal_crypto_configuration.h
@@ -16,8 +16,8 @@
// limitations under the License.
// ----------------------------------------------------------------------------
-#ifndef _FCC_PAL_CRYPTO_COFIGURATION_H
-#define _FCC_PAL_CRYPTO_COFIGURATION_H
+#ifndef _CS_PAL_CRYPTO_CONFIGURATION_H
+#define _CS_PAL_CRYPTO_CONFIGURATION_H
#include "limits.h"
#ifdef PAL_USER_DEFINED_CONFIGURATION
diff --git a/factory-configurator-client/crypto-service/crypto-service/pal_plat_Crypto.h b/factory-configurator-client/crypto-service/crypto-service/cs_pal_plat_crypto.h
similarity index 99%
rename from factory-configurator-client/crypto-service/crypto-service/pal_plat_Crypto.h
rename to factory-configurator-client/crypto-service/crypto-service/cs_pal_plat_crypto.h
index cb4ff7739..031008be3 100644
--- a/factory-configurator-client/crypto-service/crypto-service/pal_plat_Crypto.h
+++ b/factory-configurator-client/crypto-service/crypto-service/cs_pal_plat_crypto.h
@@ -14,16 +14,15 @@
* limitations under the License.
*******************************************************************************/
-#ifndef _PAL_PLAT_CRYPTO_H_
-#define _PAL_PLAT_CRYPTO_H_
+#ifndef _CS_PAL_PLAT_CRYPTO_H_
+#define _CS_PAL_PLAT_CRYPTO_H_
#ifdef __cplusplus
extern "C" {
#endif
-#include "pal_Crypto.h"
-//#include "pal_crypto_configuration.h"
-/*! \file pal_plat_Crypto.h
+#include "cs_pal_crypto.h"
+/*! \file cs_pal_plat_crypto.h
* \brief PAL cryptographic - platform.
* This file contains cryptographic APIs that need to be implemented in the platform layer.
*/
diff --git a/factory-configurator-client/crypto-service/source/cs_hash.c b/factory-configurator-client/crypto-service/source/cs_hash.c
index f212a6741..378c3a5eb 100644
--- a/factory-configurator-client/crypto-service/source/cs_hash.c
+++ b/factory-configurator-client/crypto-service/source/cs_hash.c
@@ -16,7 +16,7 @@
#include "pv_error_handling.h"
#include "cs_hash.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "cs_utils.h"
#include "pv_macros.h"
diff --git a/factory-configurator-client/crypto-service/source/pal_Crypto.c b/factory-configurator-client/crypto-service/source/cs_pal_crypto.c
similarity index 99%
rename from factory-configurator-client/crypto-service/source/pal_Crypto.c
rename to factory-configurator-client/crypto-service/source/cs_pal_crypto.c
index 02b55c881..cfd901e9f 100644
--- a/factory-configurator-client/crypto-service/source/pal_Crypto.c
+++ b/factory-configurator-client/crypto-service/source/cs_pal_crypto.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#include "pv_macros.h"
#include
diff --git a/factory-configurator-client/crypto-service/source/pal_plat_Crypto.c b/factory-configurator-client/crypto-service/source/cs_pal_plat_crypto.c
similarity index 99%
rename from factory-configurator-client/crypto-service/source/pal_plat_Crypto.c
rename to factory-configurator-client/crypto-service/source/cs_pal_plat_crypto.c
index f31dbfd8a..82ed0ebda 100644
--- a/factory-configurator-client/crypto-service/source/pal_plat_Crypto.c
+++ b/factory-configurator-client/crypto-service/source/cs_pal_plat_crypto.c
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#if !defined(MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT) || defined(MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT)
#include "pal.h"
#endif
@@ -1230,7 +1230,7 @@ palStatus_t pal_plat_CtrDRBGIsSeeded(palCtrDrbgCtxHandle_t ctx)
#endif
}
-// FIXME: Currently not public in pal_plat_Crypto.h and is called from pal_plat_drbg_w_entropy_sources.c
+// FIXME: Currently not public in cs_pal_plat_crypto.h and is called from pal_plat_drbg_w_entropy_sources.c
// With a forward declaration
// This function will later be public, deprecating pal_plat_CtrDRBGSeed() (pal_plat_CtrDRBGInit will call this directly).
// Changing this requires some work - therefore not done yet
diff --git a/factory-configurator-client/crypto-service/source/pal_plat_drbg_w_entropy_sources_kv.c b/factory-configurator-client/crypto-service/source/cs_pal_plat_drbg_w_entropy_sources_kv.c
similarity index 98%
rename from factory-configurator-client/crypto-service/source/pal_plat_drbg_w_entropy_sources_kv.c
rename to factory-configurator-client/crypto-service/source/cs_pal_plat_drbg_w_entropy_sources_kv.c
index 4a417f6eb..c1c4ed228 100644
--- a/factory-configurator-client/crypto-service/source/pal_plat_drbg_w_entropy_sources_kv.c
+++ b/factory-configurator-client/crypto-service/source/cs_pal_plat_drbg_w_entropy_sources_kv.c
@@ -28,7 +28,7 @@
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/config.h"
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#ifndef FCC_NANOCLIENT_ENABLED
#if PAL_USE_HW_TRNG
#include "pal_plat_drbg_noise.h"
@@ -36,8 +36,7 @@
#endif
#include "mbed_trace.h"
#include
-#include "pal_Crypto.h"
-#include "pal_plat_Crypto.h"
+#include "cs_pal_crypto.h"
#define TRACE_GROUP "DRBG"
diff --git a/factory-configurator-client/crypto-service/source/cs_utils.c b/factory-configurator-client/crypto-service/source/cs_utils.c
index f8d692536..77da8ce76 100644
--- a/factory-configurator-client/crypto-service/source/cs_utils.c
+++ b/factory-configurator-client/crypto-service/source/cs_utils.c
@@ -17,7 +17,7 @@
#include "pv_log.h"
#include "cs_der_keys_and_csrs.h"
#include "cs_der_certs.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "pv_error_handling.h"
#include "key_slot_allocator.h"
diff --git a/factory-configurator-client/crypto-service/source/include/cs_utils.h b/factory-configurator-client/crypto-service/source/include/cs_utils.h
index 51e6ff5fc..6f65d70b0 100644
--- a/factory-configurator-client/crypto-service/source/include/cs_utils.h
+++ b/factory-configurator-client/crypto-service/source/include/cs_utils.h
@@ -19,7 +19,7 @@
#include
#include
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "kcm_status.h"
#include "kcm_defs.h"
diff --git a/factory-configurator-client/factory-configurator-client/source/factory_configurator_client.c b/factory-configurator-client/factory-configurator-client/source/factory_configurator_client.c
index 5c3c20b5f..79bf482e0 100644
--- a/factory-configurator-client/factory-configurator-client/source/factory_configurator_client.c
+++ b/factory-configurator-client/factory-configurator-client/source/factory_configurator_client.c
@@ -25,7 +25,7 @@
#ifndef FCC_NANOCLIENT_ENABLED
#include "pal.h"
#endif
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#include "fcc_utils.h"
/**
diff --git a/factory-configurator-client/factory-configurator-client/source/include/fcc_utils.h b/factory-configurator-client/factory-configurator-client/source/include/fcc_utils.h
index f8f36d623..aef648f97 100644
--- a/factory-configurator-client/factory-configurator-client/source/include/fcc_utils.h
+++ b/factory-configurator-client/factory-configurator-client/source/include/fcc_utils.h
@@ -26,7 +26,7 @@
#ifndef FCC_NANOCLIENT_ENABLED
#include "pal.h"
#endif
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#ifdef __cplusplus
extern "C" {
diff --git a/factory-configurator-client/key-config-manager/key-config-manager/kcm_defs.h b/factory-configurator-client/key-config-manager/key-config-manager/kcm_defs.h
index e635b3861..aed086812 100644
--- a/factory-configurator-client/key-config-manager/key-config-manager/kcm_defs.h
+++ b/factory-configurator-client/key-config-manager/key-config-manager/kcm_defs.h
@@ -32,8 +32,8 @@ extern "C" {
* KCM item types.
*/
typedef enum {
- KCM_PRIVATE_KEY_ITEM, //!< KCM private key item type. KCM supports ECC keys with curves defined in palGroupIndex_t (pal_Crypto.h).
- KCM_PUBLIC_KEY_ITEM, //!< KCM public key item type. KCM supports ECC keys with curves defined in palGroupIndex_t (pal_Crypto.h).
+ KCM_PRIVATE_KEY_ITEM, //!< KCM private key item type. KCM supports ECC keys with curves defined in palGroupIndex_t (cs_pal_crypto.h).
+ KCM_PUBLIC_KEY_ITEM, //!< KCM public key item type. KCM supports ECC keys with curves defined in palGroupIndex_t (cs_pal_crypto.h).
KCM_SYMMETRIC_KEY_ITEM, //!< KCM symmetric key item type.
KCM_CERTIFICATE_ITEM, //!< KCM certificate item type. Supports x509 certificates in DER format.
KCM_CONFIG_ITEM, //!< KCM configuration parameter item type.
diff --git a/factory-configurator-client/key-config-manager/source/key_config_manager.c b/factory-configurator-client/key-config-manager/source/key_config_manager.c
index 7795b1c7a..19ef6e5ee 100644
--- a/factory-configurator-client/key-config-manager/source/key_config_manager.c
+++ b/factory-configurator-client/key-config-manager/source/key_config_manager.c
@@ -22,7 +22,7 @@
#ifndef FCC_NANOCLIENT_ENABLED
#include "pal.h"
#endif
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#include "cs_utils.h"
#include "pv_macros.h"
#include "key_slot_allocator.h"
@@ -782,7 +782,7 @@ kcm_status_e kcm_generate_random(uint8_t *buffer, size_t buffer_size)
return kcm_status;
}
-
+#ifndef MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT
kcm_status_e kcm_ecdh_key_agreement(const uint8_t *private_key_name, size_t private_key_name_len, const uint8_t *peer_public_key, size_t peer_public_key_size,
uint8_t *shared_secret, size_t shared_secret_max_size, size_t *shared_secret_act_size_out)
{
@@ -830,5 +830,6 @@ kcm_status_e kcm_ecdh_key_agreement(const uint8_t *private_key_name, size_t priv
return kcm_status;
}
+#endif
diff --git a/factory-configurator-client/mbed-client-esfs/source/include/esfs.h b/factory-configurator-client/mbed-client-esfs/source/include/esfs.h
index e8b6335a0..100529731 100644
--- a/factory-configurator-client/mbed-client-esfs/source/include/esfs.h
+++ b/factory-configurator-client/mbed-client-esfs/source/include/esfs.h
@@ -18,7 +18,7 @@
#include
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
diff --git a/factory-configurator-client/psa-driver/source/psa_driver_crypto.c b/factory-configurator-client/psa-driver/source/psa_driver_crypto.c
index ed05c9624..7f4a28aed 100644
--- a/factory-configurator-client/psa-driver/source/psa_driver_crypto.c
+++ b/factory-configurator-client/psa-driver/source/psa_driver_crypto.c
@@ -75,23 +75,10 @@ static void set_generic_attr(uint32_t extra_flags, psa_key_attributes_t *psa_key
}
//Set algorithm and usage flags
-#if !defined(TARGET_LPC55S69_NS)
- /* FIXME - we should skip this if key should be generated into secure element */
- /* FIXME: currently, mbed-os has no SPM (Secure Partitioning Manager) support for LPC55S69_NS platforms.
- * that is why we mask the PSA multiple usage for those platforms, however, this workaround should be reverted once mbed-os
- * team will add the necessary implementation to support the psa_key_policy_set_enrollment_algorithm API.
- */
- // Set policy for ECDH (key agreement)
- psa_key_usage |= (PSA_KEY_USAGE_DERIVE);
-#endif
-
// set key usage
psa_set_key_usage_flags(psa_key_attr, psa_key_usage);
// set key algorithm
psa_set_key_algorithm(psa_key_attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
-#if !defined(TARGET_LPC55S69_NS)
- psa_set_key_enrollment_algorithm(psa_key_attr, PSA_ALG_ECDH);
-#endif
}
#ifdef MBED_CONF_MBED_CLOUD_CLIENT_SECURE_ELEMENT_SUPPORT
@@ -236,7 +223,7 @@ kcm_status_e psa_drv_crypto_init(void)
#ifdef MBED_CONF_MBED_CLOUD_CLIENT_SECURE_ELEMENT_SUPPORT
//Register se driver before calling to psa_crypto_init
- psa_status = psa_register_se_driver(PSA_DRIVER_SE_DRIVER_LIFETIME_VALUE, g_se_driver_info);
+ psa_status = psa_register_se_driver(PSA_DRIVER_SE_DRIVER_LOCATION_VALUE, g_se_driver_info);
SA_PV_ERR_RECOVERABLE_RETURN_IF((psa_status != PSA_SUCCESS), psa_drv_translate_to_kcm_error(psa_status), "Failed psa_register_se_driver (%" PRIu32 ")", (uint32_t)psa_status);
#endif
diff --git a/factory-configurator-client/storage/source/storage_non_psa.c b/factory-configurator-client/storage/source/storage_non_psa.c
index 26b110936..4b6ccbd9e 100644
--- a/factory-configurator-client/storage/source/storage_non_psa.c
+++ b/factory-configurator-client/storage/source/storage_non_psa.c
@@ -22,7 +22,7 @@
#include "pv_error_handling.h"
#include "fcc_malloc.h"
#include "pv_macros.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
/*The function copies certificate chain or single certificate from source to destination (inside storage)*/
static kcm_status_e copy_certificate_chain(const uint8_t *item_name, size_t item_name_len, storage_item_prefix_type_e source_item_prefix_type, storage_item_prefix_type_e destination_item_prefix_type)
diff --git a/factory-configurator-client/storage/source/storage_psa.cpp b/factory-configurator-client/storage/source/storage_psa.cpp
index 6ec06b4d7..2b5bd1a53 100644
--- a/factory-configurator-client/storage/source/storage_psa.cpp
+++ b/factory-configurator-client/storage/source/storage_psa.cpp
@@ -21,7 +21,7 @@
#include "pv_error_handling.h"
#include "storage_internal.h"
#include "pv_macros.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#ifdef TARGET_LIKE_MBED
#include "mbed.h"
#if !(defined(TARGET_TFM) && (MBED_MAJOR_VERSION > 5))
diff --git a/factory-configurator-client/storage/storage/storage_kcm.h b/factory-configurator-client/storage/storage/storage_kcm.h
index 8e925c70e..f9252f752 100644
--- a/factory-configurator-client/storage/storage/storage_kcm.h
+++ b/factory-configurator-client/storage/storage/storage_kcm.h
@@ -26,7 +26,7 @@
#if defined MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
#include "pal_sst.h"
#endif
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#ifdef __cplusplus
extern "C" {
diff --git a/fota/bspatch_fota_mbed.c b/fota/bspatch_fota_mbed.c
index 04648f6d4..741a2c54e 100644
--- a/fota/bspatch_fota_mbed.c
+++ b/fota/bspatch_fota_mbed.c
@@ -2,9 +2,9 @@
// in order to avoid collision with the ones used in UC-Hub
// (due to the nature of mbed-os source file globbing)
+#if (defined(__MBED__) || defined(__NANOSIMULATOR__)) && defined(MBED_CLOUD_CLIENT_FOTA_ENABLE)
#include "MbedCloudClientConfig.h"
-#if (defined(__MBED__) || defined(__NANOSIMULATOR__)) && defined(MBED_CLOUD_CLIENT_FOTA_ENABLE)
#include "bspatch/bspatch.c"
#include "bspatch/lz4.c"
#include "bspatch/varint.c"
diff --git a/fota/fota.c b/fota/fota.c
index d81b4bba9..337dd9769 100644
--- a/fota/fota.c
+++ b/fota/fota.c
@@ -29,7 +29,7 @@
#include "fota/fota_source.h"
#include "fota/fota_delta.h"
#include "fota/fota_app_ifs.h"
-#include "fota/fota_platform.h"
+#include "fota_platform_hooks.h"
#include "fota/fota_nvm.h"
#include "fota/fota_block_device.h"
#include "fota/fota_crypto.h"
@@ -58,7 +58,7 @@
#endif
#if defined(TARGET_LIKE_LINUX)
-#include "fota_platform_linux.h"
+#include "fota/platform/linux/fota_platform_linux.h"
#endif
#if (MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT == FOTA_RESUME_SUPPORT_RESUME) && !FOTA_HEADER_HAS_CANDIDATE_READY
@@ -76,6 +76,8 @@ static void fota_on_install_authorize(bool defer);
static bool initialized = false;
static size_t storage_available;
+static bool fota_defer_by_user = false;
+
// Multicast related variables here should not be part of the FOTA context, as they live also outside of FOTA scope
#if (MBED_CLOUD_CLIENT_FOTA_MULTICAST_SUPPORT != FOTA_MULTICAST_UNSUPPORTED)
static size_t mc_image_data_addr;
@@ -225,12 +227,11 @@ static void abort_update(int ret, const char *msg)
fota_source_report_update_result(upd_res);
fota_source_report_state(FOTA_SOURCE_STATE_IDLE, NULL, NULL);
manifest_delete();
+ fota_nvm_fw_encryption_key_delete();
} else {
fota_source_report_state(FOTA_SOURCE_STATE_PROCESSING_MANIFEST, NULL, NULL);
}
- fota_nvm_fw_encryption_key_delete();
-
const fota_component_desc_t *comp_desc;
fota_component_get_desc(fota_ctx->comp_id, &comp_desc);
fota_platform_abort_update_hook(comp_desc->name);
@@ -641,6 +642,7 @@ int fota_init(void *m2m_interface, void *resource_list)
#endif
initialized = true;
+
FOTA_TRACE_DEBUG("init complete");
return FOTA_STATUS_SUCCESS;
@@ -669,6 +671,7 @@ int fota_deinit(void)
fota_linux_deinit();
#endif
initialized = false;
+
return FOTA_STATUS_SUCCESS;
}
@@ -950,6 +953,8 @@ void fota_on_defer(int32_t status)
if (!fota_ctx) {
return; // gracefully ignore this call if update is not running
}
+ /* mark call to defer only if FOTA is active */
+ fota_defer_by_user = true; // for now we assume that defer called always by user app
if (fota_ctx->state == FOTA_STATE_AWAIT_INSTALL_AUTHORIZATION) {
FOTA_TRACE_INFO("Installation deferred by application.");
@@ -1147,7 +1152,7 @@ static int prepare_and_program_header(void)
fota_set_header_info_magic(&header_info);
header_info.fw_size = fota_ctx->fw_info->installed_size;
header_info.version = fota_ctx->fw_info->version;
- header_info.external_header_size = (uint16_t)(sizeof(fota_header_info_t) - offsetof(fota_header_info_t,internal_header_barrier));
+ header_info.external_header_size = (uint16_t)(sizeof(fota_header_info_t) - offsetof(fota_header_info_t, internal_header_barrier));
memcpy(header_info.digest, fota_ctx->fw_info->installed_digest, FOTA_CRYPTO_HASH_SIZE);
memcpy(header_info.precursor, fota_ctx->fw_info->precursor_digest, FOTA_CRYPTO_HASH_SIZE);
memcpy(header_info.vendor_data, fota_ctx->fw_info->vendor_data, FOTA_MANIFEST_VENDOR_DATA_SIZE);
@@ -1381,7 +1386,7 @@ static int analyze_resume_state(fota_state_e *next_fota_state)
static int calc_and_erase_needed_storage()
{
int ret;
- size_t storage_needed = 0, erase_size, total_erase_size;
+ size_t storage_needed = 0, erase_size, total_erase_size, end_addr;
if (fota_ctx) {
// Calculate needed space for FW data in storage:
@@ -1427,12 +1432,16 @@ static int calc_and_erase_needed_storage()
return FOTA_STATUS_INSUFFICIENT_STORAGE;
}
- ret = fota_bd_get_erase_size(fota_candidate_get_config()->storage_start_addr + storage_needed - 1, &erase_size);
+ end_addr = fota_candidate_get_config()->storage_start_addr + storage_needed;
+ ret = fota_bd_get_erase_size(end_addr - 1, &erase_size);
if (ret) {
FOTA_TRACE_ERROR("Get erase size failed %d", ret);
return ret;
}
- total_erase_size = FOTA_ALIGN_UP(storage_needed, erase_size);
+
+ // Align erase size to the end of last sector
+ total_erase_size = end_addr % erase_size ? FOTA_ALIGN_DOWN(end_addr, erase_size) + erase_size - fota_candidate_get_config()->storage_start_addr :
+ storage_needed;
FOTA_TRACE_DEBUG("Erasing storage at %zu, size %zu", fota_candidate_get_config()->storage_start_addr, total_erase_size);
ret = fota_bd_erase(fota_candidate_get_config()->storage_start_addr, total_erase_size);
if (ret) {
@@ -1655,7 +1664,7 @@ void fota_on_authorize(int32_t status)
FOTA_ASSERT(
(fota_ctx->state == FOTA_STATE_AWAIT_DOWNLOAD_AUTHORIZATION) ||
(fota_ctx->state == FOTA_STATE_AWAIT_INSTALL_AUTHORIZATION)
- )
+ );
if (fota_ctx->state == FOTA_STATE_AWAIT_INSTALL_AUTHORIZATION) {
FOTA_TRACE_INFO("Install authorization granted.");
@@ -1984,14 +1993,33 @@ void fota_on_fragment(uint8_t *buf, size_t size)
}
-void fota_on_resume(int32_t status)
+void fota_on_resume(int32_t param)
{
#if (MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT != FOTA_RESUME_UNSUPPORTED)
- (void)status; // unused
+
+ bool fota_resume_by_user = !param; // param=0 - called from user app
+ // param=1 - called from internal flow
+
if (fota_ctx) {
+ /*
+ * FOTA context exists therefore defer was not called. Got here because of internal resume event, continue update
+ */
+ FOTA_TRACE_DEBUG("FOTA already running");
return; // FOTA is already running - ignore
}
+ FOTA_TRACE_INFO("fota_on_resume - resume by %u", fota_resume_by_user);
+
+ //if we got here, there is no fota context:
+ // either defer was called or context was deleted because of internal error
+ if ((fota_defer_by_user == true) && (fota_resume_by_user == false)) {
+ /* fota was deferred by user app and resume was called from internal flow
+ * ignore the resume for now and wait for call from user app
+ */
+ FOTA_TRACE_INFO("Internal resume followed by user app defer - abort!");
+ return; // don't resume now, wait for explicit user call for resume
+ }
+
size_t manifest_size;
uint8_t *manifest = calloc(1, FOTA_MANIFEST_MAX_SIZE);
@@ -2016,6 +2044,7 @@ void fota_on_resume(int32_t status)
if (ret) {
FOTA_TRACE_ERROR("failed to load manifest from NVM (ret code %d) - update resume aborted.", ret);
}
+ fota_defer_by_user = false; //resume completed, remove the flag
#endif
}
diff --git a/fota/fota_app_ifs.c b/fota/fota_app_ifs.c
index add9ca855..ff4e72483 100644
--- a/fota/fota_app_ifs.c
+++ b/fota/fota_app_ifs.c
@@ -53,7 +53,7 @@ void fota_app_defer()
void fota_app_resume(void)
{
- fota_event_handler_defer_with_result_ignore_busy(fota_on_resume, 0);
+ fota_event_handler_defer_with_result_ignore_busy(fota_on_resume, /*fota resume by user app */ 0);
}
#if defined (FOTA_DEFAULT_APP_IFS) && FOTA_DEFAULT_APP_IFS==1
diff --git a/fota/fota_app_ifs.h b/fota/fota_app_ifs.h
index f0548a9ba..a68732018 100644
--- a/fota/fota_app_ifs.h
+++ b/fota/fota_app_ifs.h
@@ -42,13 +42,16 @@ extern "C" {
/**
* FOTA download authorization callback to be implemented by the device application.
*
- * Should be implemented by the application if it wants to authorize FOTA to start downloading the candidate image.
+ * The application must implement this callback if you want the application to authorize the FOTA client to start downloading the candidate image.
+ * The client invokes this callback for the first time when the device receives the update manifest from Device Management.
*
* FOTA expects the callback implementation to call one of these APIs:
- * - ::fota_app_authorize() - Authorize request to download image.
- * - ::fota_app_reject() - Reject request to download image and discard the manifest. The update will not be re-prompted.
- * - ::fota_app_defer() - Defer image download to a later phase. This aborts the current update attempt, while preserving the update manifest.
- * Update will be restarted on next boot. Alternatively update can be restarted by calling ::fota_app_resume().
+ * - ::fota_app_authorize() - Authorize request to download image. The download phase will proceed.
+ * - ::fota_app_reject() - Reject request to download image and discard the manifest. The client will not re-prompt the update.
+ * - ::fota_app_defer() - Defer image download to a later phase. This aborts the current image download attempt, while preserving the update manifest.
+ * Image download continues on the next boot after device registration or when the device application calls the :fota_app_resume() API.
+ * The client invokes ::fota_app_on_download_authorization when the update flow continues.
+ * Both ::fota_app_defer() and ::fota_app_resume() APIs are implemented only if the ::MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT build flag is not equal to ::FOTA_RESUME_UNSUPPORTED.
*
* \note Only required if the ::MBED_CLOUD_CLIENT_FOTA_ENABLE build flag is specified.
* \note Only required if the ::FOTA_DEFAULT_APP_IFS build flag is disabled.
@@ -69,16 +72,20 @@ int fota_app_on_download_authorization(
* Pelion FOTA install authorization callback to be implemented by the device application.
*
* Should be implemented by the application if it wants to authorize FOTA to install the update.
+ * The client invokes this callback for the first time when the device fully downloads the update candidate image.
*
* FOTA client expects the callback implementation to call one of these APIs:
* - ::fota_app_authorize() - Authorize FOTA to install the candidate image. Reboot or connectivity loss may occur during installation.
- * This phase is critical because power loss can brick the device.
+ * This phase is critical because power loss can brick the device.
* - ::fota_app_reject() - Reject request to install, and discard the update. The update will not be re-prompted.
* - ::fota_app_defer() - Defer the installation to a later phase. This marks the candidate image as valid, but the device will not reboot.
+ * For the main component, the installation proceeds automatically after the device reboots.
+ * For user components, the update flow proceeds on the next boot after device registration or when the device application calls the ::fota_app_resume() API.
+ * The application invokes the ::fota_app_on_download_authorization and ::fota_app_on_install_authorization() callbacks when the update flow proceeds.
+ * The client implements the ::fota_app_defer() and ::fota_app_resume() APIs only if the ::MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT build flag is not equal to ::FOTA_RESUME_UNSUPPORTED.
*
* \note Only required if the ::MBED_CLOUD_CLIENT_FOTA_ENABLE build flag is specified.
* \note Only required if the ::FOTA_DEFAULT_APP_IFS build flag is disabled.
- * \note After the application defers installation by calling ::fota_app_defer(), the device has to reboot before installing the candidate image. Calling ::fota_app_resume() after ::fota_app_defer() has no effect.
*
* \return ::FOTA_STATUS_SUCCESS to acknowledge that the application received the authorization callback properly.
*/
@@ -103,8 +110,14 @@ int fota_app_on_complete(int32_t status);
/**
* Resume Pelion FOTA update.
*
- * If the update process is interrupted, the application can call this function to restart the process.
- */
+ * If the update process is interrupted, the application can call this function to resume the process.
+ * This API invokes ::fota_app_on_download_authorization() CB.
+ *
+ * \note The function is implemented only if ::MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT build flag is not equal to ::FOTA_RESUME_UNSUPPORTED.
+ * \note If ::MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT build flag is equal to ::FOTA_RESUME_SUPPORT_RESTART, the update flow will restart from the beginning.
+ * \note If ::MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT build flag is equal to ::FOTA_RESUME_SUPPORT_RESUME, the update flow will resume from the point that it was interrupted.
+ *
+ */
void fota_app_resume(void);
/**
@@ -118,7 +131,7 @@ void fota_app_authorize(void);
/**
* Reject Pelion FOTA update.
*
- * FOTA client expects the ::fota_app_on_download_authorization() and ::fota_app_on_install_authorization() application callbacks to call this API.
+ * ::fota_app_on_download_authorization() and ::fota_app_on_install_authorization() application callbacks may call this API.
*
* \param[in] reason Reject reason code.
*/
@@ -127,9 +140,11 @@ void fota_app_reject(int32_t reason);
/**
* Defer Pelion FOTA update.
*
- * FOTA client resources will be released and update will be reattempted on next boot or by
- * calling the ::fota_app_resume() API.
- * FOTA client expects the ::fota_app_on_download_authorization() and ::fota_app_on_install_authorization() application callbacks to call this API.
+ * The FOTA client releases resources and reattempts the update on the next boot after device registration or when the device application calls
+ * the ::fota_app_resume() API.
+ * ::fota_app_on_download_authorization() and ::fota_app_on_install_authorization() application callbacks may call this API.
+ *
+ * \note The function is implemented only if ::MBED_CLOUD_CLIENT_FOTA_RESUME_SUPPORT build flag is not equal to ::FOTA_RESUME_UNSUPPORTED.
*/
void fota_app_defer(void);
@@ -183,12 +198,12 @@ int fota_app_on_install_candidate(const char *candidate_fs_name, const manifest_
#if defined(MBED_CLOUD_CLIENT_FOTA_LINUX_SINGLE_MAIN_FILE)
/**
- * Install MAIN application by overwriting current executable file.
+ * Install main application by overwriting current executable file.
*
- * This function will overwrite the executable file and relaunch the process.
- * The API is expected to be called from ::fota_app_on_install_candidate() application
- * callback.
- * It is only available in case of a single main file mode.
+ * This function overwrites the executable file and relaunches the process.
+ * The client expects the ::fota_app_on_install_candidate() application
+ * callback to call this API.
+ * It is only available if there is a single main file.
*
* \note This function does not validate candidate file integrity or authenticity.
*
diff --git a/fota/fota_base.h b/fota/fota_base.h
index 8575b72a3..e0c85ab56 100644
--- a/fota/fota_base.h
+++ b/fota/fota_base.h
@@ -76,7 +76,10 @@ extern "C" {
#endif
#if !defined(FOTA_HALT)
-#if defined(TARGET_LIKE_LINUX)
+#if defined(FOTA_UNIT_TEST)
+void unitest_halt(void);
+#define FOTA_HALT unitest_halt()
+#elif defined(TARGET_LIKE_LINUX)
#define FOTA_HALT assert(0)
#else
#define FOTA_HALT for(;;)
diff --git a/fota/fota_block_device.h b/fota/fota_block_device.h
index bb5d8cc22..4dd3017df 100644
--- a/fota/fota_block_device.h
+++ b/fota/fota_block_device.h
@@ -130,6 +130,17 @@ int fota_bd_get_erase_size(size_t addr, size_t *erase_size);
*/
int fota_bd_get_erase_value(int *erase_value);
+/**
+ * Pelion FOTA block device translate physical address to logical one.
+ * It is required that block device addresses will be continuous and start from 0.
+ * In most devices, this is the case and this function should simply return the physical address.
+ * Devices like like internal flash, where addresses don't start from 0. require a less trivial translation logic.
+ *
+ * \param[in] phys_addr Physical address.
+ * \return Logical address
+ */
+size_t fota_bd_physical_addr_to_logical_addr(size_t phys_addr);
+
#ifdef __cplusplus
}
#endif
diff --git a/fota/fota_candidate.c b/fota/fota_candidate.c
index 4a97bbfda..362809779 100644
--- a/fota/fota_candidate.c
+++ b/fota/fota_candidate.c
@@ -57,8 +57,6 @@ static fota_candidate_config_t fota_candidate_config = {
static candidate_contex_t *ctx = NULL;
-uint32_t fota_bd_physical_addr_to_logical_addr(uint32_t phys_addr);
-
void fota_candidate_set_config(fota_candidate_config_t *in_fota_candidate_config)
{
FOTA_ASSERT(in_fota_candidate_config->storage_size);
@@ -167,7 +165,7 @@ int fota_candidate_read_header(size_t *addr, uint32_t bd_read_size, uint32_t bd_
goto end;
}
- if (header_size < header->external_header_size + offsetof(fota_header_info_t, internal_header_barrier)){
+ if (header_size < header->external_header_size + offsetof(fota_header_info_t, internal_header_barrier)) {
*addr += FOTA_ALIGN_UP(header->external_header_size + offsetof(fota_header_info_t, internal_header_barrier), bd_prog_size);
} else {
*addr += FOTA_ALIGN_UP(header_size, bd_prog_size);
diff --git a/fota/fota_component.c b/fota/fota_component.c
index 433bbfc8a..5f9c5cd69 100644
--- a/fota/fota_component.c
+++ b/fota/fota_component.c
@@ -96,24 +96,43 @@ int fota_component_add(const fota_component_desc_info_t *comp_desc_info, const c
fota_component_desc_t *comp_table = user_comp_table;
unsigned int *num_components = &num_user_components;
- FOTA_ASSERT(comp_name);
- FOTA_ASSERT(!(comp_desc_info->support_delta && (!comp_desc_info->curr_fw_get_digest || !comp_desc_info->curr_fw_read)));
-
+ if (!comp_name) {
+ FOTA_TRACE_ERROR("Empty component name");
+ return FOTA_STATUS_INVALID_ARGUMENT;
+ }
+ if (comp_desc_info->support_delta && (!comp_desc_info->curr_fw_get_digest || !comp_desc_info->curr_fw_read)) {
+ FOTA_TRACE_ERROR("empty fields in component description");
+ return FOTA_STATUS_INVALID_ARGUMENT;
+ }
+
#ifdef FOTA_INTERNAL_COMPONENTS_SUPPORT
if (comp_name[0] == '%') {
comp_table = malloc((num_int_components + 1) * sizeof(fota_component_desc_t));
- FOTA_ASSERT(comp_table);
+ if (!comp_table) {
+ FOTA_TRACE_ERROR("comp_table wasn't allocated");
+ return FOTA_STATUS_OUT_OF_MEMORY;
+ }
memcpy(comp_table, int_comp_table, num_int_components * sizeof(fota_component_desc_t));
free(int_comp_table);
int_comp_table = comp_table;
num_components = &num_int_components;
} else {
- FOTA_ASSERT(*num_components < FOTA_NUM_COMPONENTS);
+ if (*num_components > FOTA_NUM_COMPONENTS) {
+ FOTA_TRACE_ERROR("Wrong number of components");
+ return FOTA_STATUS_INVALID_ARGUMENT;
+ }
}
#else
- FOTA_ASSERT(*num_components < FOTA_NUM_COMPONENTS);
+ if (*num_components > FOTA_NUM_COMPONENTS) {
+ FOTA_TRACE_ERROR("Wrong number of components");
+ return FOTA_STATUS_INVALID_ARGUMENT;
+ }
#endif
+ if (comp_desc_info->need_reboot == false && comp_table == user_comp_table){
+ FOTA_TRACE_ERROR("Component with need_reboot false is not supported");
+ return FOTA_STATUS_INVALID_ARGUMENT;
+ }
memcpy(&comp_table[*num_components].desc_info, comp_desc_info, sizeof(*comp_desc_info));
strncpy(comp_table[*num_components].name, comp_name, FOTA_COMPONENT_MAX_NAME_SIZE - 1);
fota_component_version_semver_to_int(comp_semver, &comp_table[*num_components].version);
@@ -136,7 +155,7 @@ void fota_component_get_desc(unsigned int comp_id, const fota_component_desc_t *
comp_id_translate(&comp_id, &comp_table, &num_components);
#endif
- FOTA_ASSERT(comp_id < num_components)
+ FOTA_ASSERT(comp_id < num_components);
*comp_desc = &comp_table[comp_id];
}
@@ -148,7 +167,7 @@ void fota_component_get_curr_version(unsigned int comp_id, fota_component_versio
#ifdef FOTA_INTERNAL_COMPONENTS_SUPPORT
comp_id_translate(&comp_id, &comp_table, &num_components);
#endif
- FOTA_ASSERT(comp_id < num_components)
+ FOTA_ASSERT(comp_id < num_components);
*version = comp_table[comp_id].version;
}
@@ -160,7 +179,7 @@ void fota_component_set_curr_version(unsigned int comp_id, fota_component_versio
#ifdef FOTA_INTERNAL_COMPONENTS_SUPPORT
comp_id_translate(&comp_id, &comp_table, &num_components);
#endif
- FOTA_ASSERT(comp_id < num_components)
+ FOTA_ASSERT(comp_id < num_components);
comp_table[comp_id].version = version;
}
diff --git a/fota/fota_component.h b/fota/fota_component.h
index 0faa86b03..f824926d4 100644
--- a/fota/fota_component.h
+++ b/fota/fota_component.h
@@ -79,6 +79,7 @@ typedef int (*fota_component_verify_install_handler_t)(const char *comp_name, co
* @param install_alignment The preferred installer fragment size. Typically equal to the flash program size.
* @param support_delta Specify whether the component supports differential (delta) update.
* @param need_reboot Specify whether the component requires system reboot after the component installation has completed.
+ Only `true` parameter is currently supported.
* @param candidate_iterate_cb A callback function the FOTA client calls for installing the candidate.
* The FOTA client calls the callback iteratively with a firmware fragment buffer pointer as an argument.
* Note: For Linux systems, this iterative callback is replaced by ::fota_app_on_install_candidate().
diff --git a/fota/fota_config.h b/fota/fota_config.h
index 19547a822..0cf376bd3 100644
--- a/fota/fota_config.h
+++ b/fota/fota_config.h
@@ -157,21 +157,12 @@ extern char *program_invocation_name;
#define MBED_CLOUD_CLIENT_FOTA_LINUX_CURR_FW_FILENAME program_invocation_name
#endif
-#if defined(FOTA_CUSTOM_CURR_FW_STRUCTURE) && FOTA_CUSTOM_CURR_FW_STRUCTURE
-#error Custom current firmware structure should not be defined in Linux targets.
-#endif
-
// No legacy bootloader here - force up to date header
#undef MBED_CLOUD_CLIENT_FOTA_FW_HEADER_VERSION
#define MBED_CLOUD_CLIENT_FOTA_FW_HEADER_VERSION 3
#endif // defined(TARGET_LIKE_LINUX)
-
-#if !defined(FOTA_CUSTOM_CURR_FW_STRUCTURE) && !defined(__MBED__) && !defined(FOTA_UNIT_TEST) && !defined(TARGET_LIKE_LINUX)
-#define FOTA_CUSTOM_CURR_FW_STRUCTURE 1
-#endif
-
// Set this flag to 1 to use custom verification logic for main app installation
#if !defined(FOTA_CUSTOM_MAIN_APP_VERIFY_INSTALL)
// Use default verification logic otherwise
@@ -261,8 +252,8 @@ extern char *program_invocation_name;
#endif
#if (MBED_CLOUD_CLIENT_FOTA_KEY_ENCRYPTION == FOTA_USE_DEVICE_KEY)
-#if (MBED_CLOUD_CLIENT_FOTA_ENCRYPTION_SUPPORT == 0) || !defined(__MBED__)
-#error FOTA_USE_DEVICE_KEY should be used only for with __MBED__ with encryption enabled
+#if (MBED_CLOUD_CLIENT_FOTA_ENCRYPTION_SUPPORT == 0) || (!(defined(MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT)) && !(defined(__MBED__)))
+#error FOTA_USE_DEVICE_KEY should be used only for with MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT or __MBED__ with encryption enabled
#endif
#endif
diff --git a/fota/fota_crypto.c b/fota/fota_crypto.c
index d4686dcba..67acd221a 100644
--- a/fota/fota_crypto.c
+++ b/fota/fota_crypto.c
@@ -557,7 +557,13 @@ int fota_verify_signature_prehashed(
mbedtls_x509_crt_init(&crt);
+/*mbedtls_x509_crt_parse_der_nocopy not supported for mbedtls 2.16.0 and lower versions,
+ use older version of x509 cert parse function */
+#if (MBEDTLS_VERSION_NUMBER < 0x02110000)
+ ret = mbedtls_x509_crt_parse_der(
+#else
ret = mbedtls_x509_crt_parse_der_nocopy(
+#endif
&crt,
update_crt_data, update_crt_size
);
diff --git a/fota/fota_curr_fw.h b/fota/fota_curr_fw.h
index 83853f80d..363541646 100644
--- a/fota/fota_curr_fw.h
+++ b/fota/fota_curr_fw.h
@@ -32,26 +32,9 @@ extern "C" {
/**
* @file fota_curr_fw.h
* \brief FOTA requires access to the currently installed firmware (FW) and the FW metadata header.
- * By default, on non-Mbed-OS targets, the FOTA library assumes a custom FW layout structure and expects that the application will implement the current FW interfaces described in this file.
- * If the FW image and the FW header reside in a memory mapped flash, you can define the ::FOTA_CUSTOM_CURR_FW_STRUCTURE=0 macro, in which case, the application only has to implement these functions:
- * uint8_t *fota_curr_fw_get_app_start_addr(void)
- * uint8_t *fota_curr_fw_get_app_header_addr(void)
+ * Support code for each platform should implement the current FW interfaces described in this file.
*/
-/**
- * Returns a pointer to the application start.
- *
- * \return Pointer to the application start.
- */
-uint8_t *fota_curr_fw_get_app_start_addr(void);
-
-/**
- * Returns a pointer to the header start.
- *
- * \return Pointers to the header start.
- */
-uint8_t *fota_curr_fw_get_app_header_addr(void);
-
/**
* Reads the header of the current firmware.
*
diff --git a/fota/fota_device_key.cpp b/fota/fota_device_key.cpp
index 7449c108a..4471205c3 100644
--- a/fota/fota_device_key.cpp
+++ b/fota/fota_device_key.cpp
@@ -23,15 +23,14 @@
#include "fota/fota_crypto_defs.h"
#include "fota/fota_status.h"
-#ifdef __MBED__
-
// fota_get_device_key_128bit in use only in case defined MBED_CLOUD_CLIENT_FOTA_KEY_ENCRYPTION == FOTA_USE_DEVICE_KEY or external legacy header
#if ((MBED_CLOUD_CLIENT_FOTA_FW_HEADER_VERSION == 2) && (MBED_CLOUD_CLIENT_FOTA_FW_HEADER_EXTERNAL == 1)) || (MBED_CLOUD_CLIENT_FOTA_KEY_ENCRYPTION == FOTA_USE_DEVICE_KEY)
+#include "kv_config.h"
#include "KVMap.h"
-#include "mbed.h"
#include "TDBStore.h"
-#include "DeviceKey.h"
+
+using namespace mbed;
extern "C" int8_t fota_get_device_key_128bit(uint8_t *key, uint32_t keyLenBytes)
{
@@ -64,5 +63,4 @@ extern "C" int8_t fota_get_device_key_128bit(uint8_t *key, uint32_t keyLenBytes)
}
#endif // #if ((MBED_CLOUD_CLIENT_FOTA_FW_HEADER_VERSION == 2) && (MBED_CLOUD_CLIENT_FOTA_FW_HEADER_EXTERNAL == 1)) || (MBED_CLOUD_CLIENT_FOTA_KEY_ENCRYPTION == FOTA_USE_DEVICE_KEY)
-#endif // #ifdef __MBED__
#endif //MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/fota_event_handler.c b/fota/fota_event_handler.c
index d70d4ef02..f457e92c8 100644
--- a/fota/fota_event_handler.c
+++ b/fota/fota_event_handler.c
@@ -20,6 +20,9 @@
#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
+// TODO: Replace this with a proper define
+#if !defined(FOTA_UNIT_TEST)
+
#define TRACE_GROUP "FOTA"
#include
@@ -195,4 +198,5 @@ void fota_event_handler_defer_with_result_ignore_busy(
}
}
+#endif // !defined(FOTA_UNIT_TEST)
#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/fota_event_handler.h b/fota/fota_event_handler.h
index 077b86cd8..4a4c296d9 100644
--- a/fota/fota_event_handler.h
+++ b/fota/fota_event_handler.h
@@ -29,7 +29,7 @@ extern "C" {
#include "fota_internal.h"
typedef void (*fota_deferred_data_callabck_t)(uint8_t *data, size_t size);
-typedef void (*fota_deferred_result_callabck_t)(int32_t status);
+typedef void (*fota_deferred_result_callabck_t)(int32_t param);
/*
* Initialize event handler
diff --git a/fota/fota_internal.h b/fota/fota_internal.h
index 9a2faee16..2ae201d61 100644
--- a/fota/fota_internal.h
+++ b/fota/fota_internal.h
@@ -100,7 +100,7 @@ void fota_on_defer(int32_t status);
void fota_on_authorize(int32_t status);
void fota_on_fragment(uint8_t *buf, size_t size);
void fota_on_fragment_failure(int32_t status);
-void fota_on_resume(int32_t status);
+void fota_on_resume(int32_t param);
#ifdef __cplusplus
}
#endif
diff --git a/fota/fota_internal_ifs.c b/fota/fota_internal_ifs.c
new file mode 100644
index 000000000..73a2e53a8
--- /dev/null
+++ b/fota/fota_internal_ifs.c
@@ -0,0 +1,30 @@
+// ----------------------------------------------------------------------------
+// Copyright 2021 Pelion Ltd.
+//
+// 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 "fota_internal_ifs.h"
+
+#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
+
+#include "fota/fota_event_handler.h"
+
+void fota_internal_resume()
+{
+ fota_event_handler_defer_with_result_ignore_busy(fota_on_resume, /*fota resume by internal flow */ 1);
+}
+
+#endif
diff --git a/fota/fota_internal_ifs.h b/fota/fota_internal_ifs.h
new file mode 100644
index 000000000..e74479aec
--- /dev/null
+++ b/fota/fota_internal_ifs.h
@@ -0,0 +1,44 @@
+// ----------------------------------------------------------------------------
+// Copyright 2021 Pelion Ltd.
+//
+// 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 __FOTA_INTERNAL_IFS_H_
+#define __FOTA_INTERNAL_IFS_H_
+
+#include "fota/fota_config.h"
+
+#if defined(MBED_CLOUD_CLIENT_FOTA_ENABLE)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Resume Pelion FOTA update - internal
+ *
+ * If the update process is interrupted, the interal flow can call this function to resume the process.
+ */
+void fota_internal_resume(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // (MBED_CLOUD_CLIENT_FOTA_ENABLE)
+
+#endif // __FOTA_INTERNAL_IFS_H_
diff --git a/fota/fota_nvm.c b/fota/fota_nvm.c
index c36185f0f..5d3e56fdd 100644
--- a/fota/fota_nvm.c
+++ b/fota/fota_nvm.c
@@ -20,6 +20,9 @@
#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
+// TODO: Replace this with a proper define
+#if !defined(FOTA_UNIT_TEST)
+
#define TRACE_GROUP "FOTA"
#include "fota/fota_status.h"
@@ -52,6 +55,7 @@ static fota_status_e map_store_result(int result)
return res;
}
+
#if (MBED_CLOUD_CLIENT_PROFILE == MBED_CLOUD_CLIENT_PROFILE_FULL)
int fota_nvm_get(cloud_client_param key, uint8_t *buffer, size_t buffer_size, size_t *bytes_read, ccs_item_type_e item_type)
{
@@ -104,10 +108,8 @@ int fota_nvm_remove(cloud_client_param key, ccs_item_type_e item_type)
return map_store_result(status);
}
-
#endif // (MBED_CLOUD_CLIENT_PROFILE == MBED_CLOUD_CLIENT_PROFILE_FULL)
-
#if !defined(FOTA_KEY_ENCRYPTION_EXTERNAL_STORAGE)
int fota_nvm_fw_encryption_key_get(uint8_t buffer[FOTA_ENCRYPT_KEY_SIZE])
{
@@ -372,4 +374,5 @@ int fota_nvm_comp_version_get(const char *comp_name, fota_component_version_t *v
return fota_nvm_get(key, (uint8_t *)version, sizeof(*version), &bytes_read, CCS_CONFIG_ITEM);
}
+#endif //!defined(FOTA_UNIT_TEST)
#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/fota_platform.h b/fota/fota_platform_hooks.h
similarity index 98%
rename from fota/fota_platform.h
rename to fota/fota_platform_hooks.h
index 88d3ec78a..f292c206b 100644
--- a/fota/fota_platform.h
+++ b/fota/fota_platform_hooks.h
@@ -30,7 +30,7 @@ extern "C" {
#endif
/**
- * @file fota_platform.h
+ * @file fota_platform_hooks.h
* \brief Platform hooks that the platform can implement if the target requires more complex FOTA initialization and teardown steps.
* By default, Pelion FOTA provides an empty implementation for these hooks.
* An application developer can override these hooks by injecting the ::FOTA_CUSTOM_PLATFORM macro to the build and implementing all the callback functions listed below.
diff --git a/fota/fota_platform_default.c b/fota/fota_platform_hooks_default.c
similarity index 97%
rename from fota/fota_platform_default.c
rename to fota/fota_platform_hooks_default.c
index bd16998c6..e4d1400a4 100644
--- a/fota/fota_platform_default.c
+++ b/fota/fota_platform_hooks_default.c
@@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------
-#include "fota_platform.h"
+#include "fota_platform_hooks.h"
#if defined(MBED_CLOUD_CLIENT_FOTA_ENABLE)
diff --git a/fota/fota_source_profile_full.cpp b/fota/fota_source_profile_full.cpp
index 6983508f1..0092b7ed0 100644
--- a/fota/fota_source_profile_full.cpp
+++ b/fota/fota_source_profile_full.cpp
@@ -19,7 +19,7 @@
#include "fota/fota_base.h"
#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
-#if (MBED_CLOUD_CLIENT_PROFILE == MBED_CLOUD_CLIENT_PROFILE_FULL)
+#if (MBED_CLOUD_CLIENT_PROFILE == MBED_CLOUD_CLIENT_PROFILE_FULL) && !defined(FOTA_UNIT_TEST)
#define TRACE_GROUP "FOTA"
@@ -303,11 +303,11 @@ int fota_source_init(
bin_to_hex_string(curr_fw_digest, FOTA_CRYPTO_HASH_SIZE, str_digest, FOTA_CRYPTO_HASH_SIZE * 2 + 1);
M2MResource *pkg_name_resource = lwm2m_object_instance->create_dynamic_resource(
- "5",
- "PkgName",
- M2MResourceInstance::STRING,
- false // observable
- );
+ "5",
+ "PkgName",
+ M2MResourceInstance::STRING,
+ false // observable
+ );
FOTA_ASSERT(pkg_name_resource);
pkg_name_resource->set_operation(M2MBase::GET_ALLOWED);
pkg_name_resource->set_value(str_digest, curr_fw_digest_size);
@@ -318,11 +318,11 @@ int fota_source_init(
// Create package version resource /10252/0/6
FOTA_TRACE_DEBUG("Announcing version is %" PRIu64, curr_fw_version);
M2MResource *pkg_version_resource = lwm2m_object_instance->create_dynamic_resource(
- "6",
- "PkgVersion",
- M2MResourceInstance::INTEGER,
- false // observable
- );
+ "6",
+ "PkgVersion",
+ M2MResourceInstance::INTEGER,
+ false // observable
+ );
FOTA_ASSERT(pkg_version_resource);
pkg_version_resource->set_operation(M2MBase::GET_ALLOWED);
pkg_version_resource->set_value(curr_fw_version);
@@ -378,7 +378,7 @@ int fota_source_init(
#if (FOTA_SOURCE_LEGACY_OBJECTS_REPORT == 0)
// Create
g_component_lwm2m_object = M2MInterfaceFactory::create_object("14");
- FOTA_ASSERT(g_component_lwm2m_object );
+ FOTA_ASSERT(g_component_lwm2m_object);
m2m_object_list->push_back(g_component_lwm2m_object);
#endif
diff --git a/fota/fota_status.h b/fota/fota_status.h
index bfa94d4e9..41428de1f 100644
--- a/fota/fota_status.h
+++ b/fota/fota_status.h
@@ -63,6 +63,7 @@ typedef enum {
FOTA_STATUS_RESOURCE_BUSY = -85, /**< Resource (typically storage) is busy */
FOTA_STATUS_MULTICAST_UPDATE_ABORTED = -86, /**< Received abort request from Multicast */
FOTA_STATUS_MULTICAST_UPDATE_ACTIVATED = -87, /**< Received abort request or new manifest from Multicast, when previous one was activated*/
+ FOTA_STATUS_INVALID_ARGUMENT = -88 /**< Invalid argument was received */
} fota_status_e;
diff --git a/fota/import_ref.txt b/fota/import_ref.txt
index 78206e02a..a1fa4e7c0 100644
--- a/fota/import_ref.txt
+++ b/fota/import_ref.txt
@@ -1 +1 @@
-Imported from origin/nanoclient at hash: 6f7eaea4f420967339ce6d47721f8e120a408cb5
+Imported from nanoclient at hash: 030df6546e99d8b1ccbf97361e48a7b4220156b7
diff --git a/fota/platform/linux/.mbedignore b/fota/platform/linux/.mbedignore
new file mode 100644
index 000000000..72e8ffc0d
--- /dev/null
+++ b/fota/platform/linux/.mbedignore
@@ -0,0 +1 @@
+*
diff --git a/fota/fota_block_device_linux.c b/fota/platform/linux/fota_block_device_linux.c
similarity index 98%
rename from fota/fota_block_device_linux.c
rename to fota/platform/linux/fota_block_device_linux.c
index 829413607..545faaa56 100644
--- a/fota/fota_block_device_linux.c
+++ b/fota/platform/linux/fota_block_device_linux.c
@@ -217,6 +217,11 @@ int fota_bd_get_erase_value(int *erase_value)
return FOTA_STATUS_SUCCESS;
}
+size_t fota_bd_physical_addr_to_logical_addr(size_t phys_addr)
+{
+ return phys_addr;
+}
+
#endif // (MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE != FOTA_EXTERNAL_BD)
#endif // defined(TARGET_LIKE_LINUX)
#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/fota_curr_fw_linux.c b/fota/platform/linux/fota_curr_fw_linux.c
similarity index 100%
rename from fota/fota_curr_fw_linux.c
rename to fota/platform/linux/fota_curr_fw_linux.c
diff --git a/fota/fota_curr_fw_linux.h b/fota/platform/linux/fota_curr_fw_linux.h
similarity index 100%
rename from fota/fota_curr_fw_linux.h
rename to fota/platform/linux/fota_curr_fw_linux.h
diff --git a/fota/fota_platform_linux.c b/fota/platform/linux/fota_platform_linux.c
similarity index 97%
rename from fota/fota_platform_linux.c
rename to fota/platform/linux/fota_platform_linux.c
index 7e22434fa..5085cbdaf 100644
--- a/fota/fota_platform_linux.c
+++ b/fota/platform/linux/fota_platform_linux.c
@@ -63,8 +63,8 @@ static void set_full_file_name(char **var, const char *base)
#if MBED_CLOUD_CLIENT_FOTA_SUPPORT_PAL
// In yocto, header file and temp header file reside in primary pal partition (mnt/config),and defined in fota_config.h as a simple file name.
// The candidate and raw candidate files reside in /mnt/cache directory and defined as a full path.
-
- // If fota file starts with '/' -> its already have a full path, we don't need to build full file name.
+
+ // If fota file starts with '/' - its already have a full path, we don't need to build full file name
if (base[0] != '/') {
char primary[PAL_MAX_FILE_AND_FOLDER_LENGTH];
pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, primary);
@@ -249,7 +249,7 @@ int fota_linux_init()
// Header completely invalid - regenerate it from scratch
memset(&header_info, 0, sizeof(header_info));
- if( fota_component_version_semver_to_int(INIT_MAIN_VERSION, &header_info.version)){
+ if (fota_component_version_semver_to_int(INIT_MAIN_VERSION, &header_info.version)) {
FOTA_TRACE_ERROR("Invalid initial version " INIT_MAIN_VERSION);
FOTA_ASSERT(!status);
}
diff --git a/fota/fota_platform_linux.h b/fota/platform/linux/fota_platform_linux.h
similarity index 100%
rename from fota/fota_platform_linux.h
rename to fota/platform/linux/fota_platform_linux.h
diff --git a/fota/fota_block_device.cpp b/fota/platform/mbed-os/fota_block_device_mbed_os.cpp
similarity index 97%
rename from fota/fota_block_device.cpp
rename to fota/platform/mbed-os/fota_block_device_mbed_os.cpp
index 27d901258..7f9420f5c 100644
--- a/fota/fota_block_device.cpp
+++ b/fota/platform/mbed-os/fota_block_device_mbed_os.cpp
@@ -28,6 +28,7 @@
// External BD should supply all these APIs
#if (MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE != FOTA_EXTERNAL_BD)
+#if defined(__MBED__)
static bool initialized = false;
@@ -183,12 +184,6 @@ int fota_bd_get_erase_value(int *erase_value)
return FOTA_STATUS_SUCCESS;
}
-#ifdef __cplusplus
-}
-#endif
-
-#endif // (MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE != FOTA_EXTERNAL_BD)
-
static bool is_internal_flash_bd()
{
#if (MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE == FOTA_INTERNAL_FLASH_MBED_OS_BD)
@@ -205,7 +200,7 @@ static bool is_internal_flash_bd()
#endif
}
-extern "C" size_t fota_bd_physical_addr_to_logical_addr(size_t phys_addr)
+size_t fota_bd_physical_addr_to_logical_addr(size_t phys_addr)
{
#ifdef __MBED__
if (is_internal_flash_bd()) {
@@ -215,4 +210,10 @@ extern "C" size_t fota_bd_physical_addr_to_logical_addr(size_t phys_addr)
return phys_addr;
}
+#ifdef __cplusplus
+}
+#endif
+
+#endif // defined(__MBED__)
+#endif // (MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE != FOTA_EXTERNAL_BD)
#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/fota_curr_fw.c b/fota/platform/mbed-os/fota_curr_fw_mbed_os.c
similarity index 86%
rename from fota/fota_curr_fw.c
rename to fota/platform/mbed-os/fota_curr_fw_mbed_os.c
index 92def312b..218d9b383 100644
--- a/fota/fota_curr_fw.c
+++ b/fota/platform/mbed-os/fota_curr_fw_mbed_os.c
@@ -20,17 +20,14 @@
#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
+#if defined(__MBED__)
+
#define TRACE_GROUP "FOTA"
#include "fota/fota_curr_fw.h"
#include "fota/fota_status.h"
#include
-// Non Linux target here means an embedded target.
-// Note that MBED (mbed-os) targets are a subset of embedded targets.
-// MBED targets don't have custom FW structure. Embedded ones that aren't MBED based - do.
-#if !FOTA_CUSTOM_CURR_FW_STRUCTURE && !defined(TARGET_LIKE_LINUX)
-#if defined(__MBED__)
// Bootloader and application have different defines
#if !defined(APPLICATION_ADDR)
#if defined(MBED_CONF_MBED_BOOTLOADER_APPLICATION_START_ADDRESS)
@@ -52,9 +49,7 @@
#endif
#endif // !defined(HEADER_ADDR)
-
-// The following two functions should be overridden in the non mbed-os cases.
-uint8_t *fota_curr_fw_get_app_start_addr(void)
+static uint8_t *fota_curr_fw_get_app_start_addr(void)
{
#ifdef APPLICATION_ADDR
return (uint8_t *) APPLICATION_ADDR;
@@ -65,7 +60,7 @@ uint8_t *fota_curr_fw_get_app_start_addr(void)
#endif
}
-uint8_t *fota_curr_fw_get_app_header_addr(void)
+static uint8_t *fota_curr_fw_get_app_header_addr(void)
{
#ifdef HEADER_ADDR
return (uint8_t *) HEADER_ADDR;
@@ -75,7 +70,6 @@ uint8_t *fota_curr_fw_get_app_header_addr(void)
return NULL;
#endif
}
-#endif // defined(__MBED__)
int fota_curr_fw_read_header(fota_header_info_t *header_info)
{
@@ -119,6 +113,6 @@ int fota_curr_fw_get_digest(uint8_t *buf)
return FOTA_STATUS_SUCCESS;
}
-#endif // !FOTA_CUSTOM_CURR_FW_STRUCTURE && !defined(TARGET_LIKE_LINUX)
+#endif // defined(__MBED__)
#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/platform/nxp/fota_block_device_nxp_lpc.cpp b/fota/platform/nxp/fota_block_device_nxp_lpc.cpp
new file mode 100644
index 000000000..505a02d58
--- /dev/null
+++ b/fota/platform/nxp/fota_block_device_nxp_lpc.cpp
@@ -0,0 +1,143 @@
+// ----------------------------------------------------------------------------
+// Copyright 2021 Pelion Ltd.
+//
+// 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 "fota/fota_base.h"
+
+#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
+
+#define TRACE_GROUP "FOTA"
+
+#include "fota/fota_config.h"
+#include "fota/fota_status.h"
+#include "fota/fota_block_device.h"
+
+#if (MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE == FOTA_EXTERNAL_BD)
+//Should be compiled only for nxp freertos and nxp bootloader
+#if defined(__NXP_FREERTOS__) || defined(FLASH_W25Q) || defined(FLASH_MT25Q) || defined(FLASH_MX25R)
+#include "ExternalBlockDevice.h"
+
+// This ifdef is here (always true) to prevent astyle from indenting enclosed functions
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*Fota block device implementation for external bd of NXP LPC */
+using namespace mbed;
+static bool initialized = false;
+static ExternalBlockDevice *bd = 0;
+
+int fota_bd_init(void)
+{
+ if (initialized) {
+ return 0;
+ }
+ if (!bd) {
+ bd = new ExternalBlockDevice();
+ }
+
+ if (!bd) {
+ return FOTA_STATUS_INTERNAL_ERROR;
+ }
+
+ int ret = bd->init();
+ if (!ret) {
+ initialized = true;
+ }
+ return ret;
+}
+
+int fota_bd_deinit(void)
+{
+
+ if (!initialized) {
+ return 0;
+ }
+
+ int ret = bd->deinit();
+
+ delete bd;
+ initialized = false;
+
+ return ret;
+}
+
+int fota_bd_size(size_t *size)
+{
+ FOTA_ASSERT(bd);
+
+ *size = (size_t)bd->size();
+
+ return 0;
+}
+
+int fota_bd_read(void *buffer, size_t addr, size_t size)
+{
+ FOTA_ASSERT(bd);
+ return bd->read(buffer,(bd_addr_t)addr, (bd_size_t)size);
+}
+
+int fota_bd_program(const void *buffer, size_t addr, size_t size)
+{
+ FOTA_ASSERT(bd);
+ return bd->program(buffer, addr, size);
+}
+
+int fota_bd_erase(size_t addr, size_t size)
+{
+ FOTA_ASSERT(bd);
+ return bd->erase((bd_addr_t)addr, (bd_size_t)size);
+}
+
+int fota_bd_get_read_size(size_t *read_size)
+{
+ FOTA_ASSERT(bd);
+ *read_size = (size_t)bd->get_read_size();
+ return 0;
+}
+
+int fota_bd_get_program_size(size_t *prog_size)
+{
+ FOTA_ASSERT(bd);
+ *prog_size = (size_t)bd->get_program_size();
+ return 0;
+}
+
+int fota_bd_get_erase_size(size_t addr, size_t *erase_size)
+{
+ FOTA_ASSERT(bd);
+ *erase_size = (size_t)bd->get_erase_size();
+ return 0;
+}
+
+int fota_bd_get_erase_value(int *erase_value)
+{
+ FOTA_DBG_ASSERT(initialized);
+ *erase_value = (int)bd->get_erase_value();
+ return 0;
+}
+size_t fota_bd_physical_addr_to_logical_addr(size_t phys_addr)
+{
+ return phys_addr;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif // __NXP_FREERTOS__
+#endif // MBED_CLOUD_CLIENT_FOTA_BLOCK_DEVICE_TYPE == FOTA_EXTERNAL_BD)
+#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/fota/platform/nxp/fota_curr_fw_nxp_lpc.c b/fota/platform/nxp/fota_curr_fw_nxp_lpc.c
new file mode 100644
index 000000000..59f7f6390
--- /dev/null
+++ b/fota/platform/nxp/fota_curr_fw_nxp_lpc.c
@@ -0,0 +1,122 @@
+// ----------------------------------------------------------------------------
+// Copyright 2021 Pelion Ltd.
+//
+// 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 "fota/fota_base.h"
+
+#ifdef MBED_CLOUD_CLIENT_FOTA_ENABLE
+
+#ifdef __NXP_FREERTOS__
+
+#define TRACE_GROUP "FOTA"
+
+#include "fota/fota_curr_fw.h"
+#include "fota/fota_status.h"
+#include
+
+// Bootloader and application have different defines
+#if !defined(APPLICATION_ADDR)
+#if defined(MBED_CONF_MBED_BOOTLOADER_APPLICATION_START_ADDRESS)
+#define APPLICATION_ADDR MBED_CONF_MBED_BOOTLOADER_APPLICATION_START_ADDRESS
+#elif defined(MBED_CONF_TARGET_APP_OFFSET)
+#define APPLICATION_ADDR MBED_CONF_TARGET_APP_OFFSET
+#else
+#error Application start address not defined
+#endif
+#endif // !defined(APPLICATION_ADDR)
+
+#if !defined(HEADER_ADDR)
+#if defined(MBED_CONF_MBED_BOOTLOADER_APPLICATION_HEADER_ADDRESS)
+#define HEADER_ADDR MBED_CONF_MBED_BOOTLOADER_APPLICATION_HEADER_ADDRESS
+#elif defined(MBED_CONF_TARGET_HEADER_OFFSET)
+#define HEADER_ADDR MBED_CONF_TARGET_HEADER_OFFSET
+#else
+#error Header start address not defined
+#endif
+#endif // !defined(HEADER_ADDR)
+
+
+/*Custom fw implementation */
+#if defined(FOTA_CUSTOM_CURR_FW_STRUCTURE) && (FOTA_CUSTOM_CURR_FW_STRUCTURE == 0)
+
+static uint8_t *fota_curr_fw_get_app_start_addr(void)
+{
+#ifdef APPLICATION_ADDR
+ return (uint8_t *) APPLICATION_ADDR;
+#else
+//#error No address was defined for application
+ FOTA_ASSERT(!"No app start address defined");
+ return NULL;
+#endif
+}
+
+static uint8_t *fota_curr_fw_get_app_header_addr(void)
+{
+#ifdef HEADER_ADDR
+ return (uint8_t *) HEADER_ADDR;
+#else
+//#error No address was defined for application header
+ FOTA_ASSERT(!"No app start address defined");
+ return NULL;
+#endif
+}
+
+int fota_curr_fw_read_header(fota_header_info_t *header_info)
+{
+ uint8_t *header_in_curr_fw = (uint8_t *)fota_curr_fw_get_app_header_addr();
+ return fota_deserialize_header(header_in_curr_fw, fota_get_header_size(), header_info);
+}
+
+int fota_curr_fw_read(uint8_t *buf, size_t offset, size_t size, size_t *num_read)
+{
+ fota_header_info_t header_info;
+ int ret = FOTA_STATUS_INTERNAL_ERROR;
+
+ ret = fota_curr_fw_read_header(&header_info);
+ if (ret) {
+ return ret;
+ }
+
+ if (offset >= header_info.fw_size) {
+ return FOTA_STATUS_INTERNAL_ERROR;
+ }
+
+ *num_read = header_info.fw_size - offset;
+ if (*num_read > size) {
+ *num_read = size;
+ }
+
+ memcpy(buf, fota_curr_fw_get_app_start_addr() + offset, *num_read);
+ return FOTA_STATUS_SUCCESS;
+
+}
+
+int fota_curr_fw_get_digest(uint8_t *buf)
+{
+ fota_header_info_t curr_fw_info;
+ int ret = fota_curr_fw_read_header(&curr_fw_info);
+ if (ret) {
+ FOTA_TRACE_ERROR("Failed to read current header");
+ return ret;
+ }
+ memcpy(buf, curr_fw_info.digest, FOTA_CRYPTO_HASH_SIZE);
+ return FOTA_STATUS_SUCCESS;
+}
+
+#endif //defined(FOTA_CUSTOM_CURR_FW_STRUCTURE) && (FOTA_CUSTOM_CURR_FW_STRUCTURE == 0)
+
+#endif // __NXP_FREERTOS__
+#endif // MBED_CLOUD_CLIENT_FOTA_ENABLE
diff --git a/mbed-client-pal/Configs/mbedTLS/pelion_mbedtls_config.h b/mbed-client-pal/Configs/mbedTLS/pelion_mbedtls_config.h
new file mode 100644
index 000000000..d8521a47c
--- /dev/null
+++ b/mbed-client-pal/Configs/mbedTLS/pelion_mbedtls_config.h
@@ -0,0 +1,1099 @@
+/* Copyright (c) 2021 Pelion IoT
+ *
+ * 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 PELION_MBEDTLS_CONFIG_H
+#define PELION_MBEDTLS_CONFIG_H
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#ifndef MBEDTLS_CIPHER_MODE_CBC
+#define MBEDTLS_CIPHER_MODE_CBC
+#endif
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#ifndef MBEDTLS_CIPHER_MODE_CTR
+#define MBEDTLS_CIPHER_MODE_CTR
+#endif
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+#ifndef MBEDTLS_CIPHER_PADDING_PKCS7
+#define MBEDTLS_CIPHER_PADDING_PKCS7
+#endif
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+#ifndef MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+#endif
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module. By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+#ifndef MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#endif
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#ifndef MBEDTLS_ECP_NIST_OPTIM
+#define MBEDTLS_ECP_NIST_OPTIM
+#endif
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#ifndef MBEDTLS_ECDSA_DETERMINISTIC
+#define MBEDTLS_ECDSA_DETERMINISTIC
+#endif
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+#ifndef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#endif
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#ifndef MBEDTLS_PKCS1_V15
+#define MBEDTLS_PKCS1_V15
+#endif
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#ifndef MBEDTLS_PKCS1_V21
+#define MBEDTLS_PKCS1_V21
+#endif
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+#ifndef MBEDTLS_SSL_ALL_ALERT_MESSAGES
+#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+#endif
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1 or
+ * MBEDTLS_SSL_PROTO_TLS1_1 or
+ * MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+#ifndef MBEDTLS_SSL_ENCRYPT_THEN_MAC
+#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+#endif
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for Extended Master Secret, aka Session Hash
+ * (draft-ietf-tls-session-hash-02).
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1 or
+ * MBEDTLS_SSL_PROTO_TLS1_1 or
+ * MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+#ifndef MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+#endif
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Enable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note Even if this option is disabled, both client and server are aware
+ * of the Renegotiation Indication Extension (RFC 5746) used to
+ * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ * (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ * configuration of this extension).
+ *
+ * \note This feature is required by Device Management Client for Client-side
+ * certificate expiration verification. Disabling it will also require
+ * setting PAL_USE_SECURE_TIME to 0.
+ *
+ */
+#ifndef MBEDTLS_SSL_RENEGOTIATION
+#define MBEDTLS_SSL_RENEGOTIATION
+#endif
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+#ifndef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+#endif
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ * (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+#ifndef MBEDTLS_SSL_PROTO_TLS1_2
+#define MBEDTLS_SSL_PROTO_TLS1_2
+#endif
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ * or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+#ifndef MBEDTLS_SSL_PROTO_DTLS
+#define MBEDTLS_SSL_PROTO_DTLS
+#endif
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+#ifndef MBEDTLS_SSL_ALPN
+#define MBEDTLS_SSL_ALPN
+#endif
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ * MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+#ifndef MBEDTLS_SSL_DTLS_ANTI_REPLAY
+#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+#endif
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+#ifndef MBEDTLS_SSL_DTLS_HELLO_VERIFY
+#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+#endif
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+#ifndef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+#endif
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+#ifndef MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+#endif
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintainance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+#ifndef MBEDTLS_SSL_SESSION_TICKETS
+#define MBEDTLS_SSL_SESSION_TICKETS
+#endif
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+#ifndef MBEDTLS_SSL_EXPORT_KEYS
+#define MBEDTLS_SSL_EXPORT_KEYS
+#endif
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+#ifndef MBEDTLS_SSL_SERVER_NAME_INDICATION
+#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+#endif
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+#ifndef MBEDTLS_X509_CHECK_KEY_USAGE
+#define MBEDTLS_X509_CHECK_KEY_USAGE
+#endif
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+#ifndef MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+#endif
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module: library/aes.c
+ * Caller: library/ssl_tls.c
+ * library/pem.c
+ * library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#ifndef MBEDTLS_AES_C
+#define MBEDTLS_AES_C
+#endif
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module: library/asn1.c
+ * Caller: library/x509.c
+ * library/dhm.c
+ * library/pkcs12.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ */
+#ifndef MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_PARSE_C
+#endif
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module: library/asn1write.c
+ * Caller: library/ecdsa.c
+ * library/pkwrite.c
+ * library/x509_create.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ */
+#ifndef MBEDTLS_ASN1_WRITE_C
+#define MBEDTLS_ASN1_WRITE_C
+#endif
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module: library/base64.c
+ * Caller: library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+// needed for Base64 encoding Opaque data for
+// registration payload, adds 500 bytes to flash.
+#ifndef MBEDTLS_BASE64_C
+#define MBEDTLS_BASE64_C
+#endif
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module: library/bignum.c
+ * Caller: library/dhm.c
+ * library/ecp.c
+ * library/ecdsa.c
+ * library/rsa.c
+ * library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#ifndef MBEDTLS_BIGNUM_C
+#define MBEDTLS_BIGNUM_C
+#endif
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module: library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#ifndef MBEDTLS_CCM_C
+#define MBEDTLS_CCM_C
+#endif
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module: library/cipher.c
+ * Caller: library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#ifndef MBEDTLS_CIPHER_C
+#define MBEDTLS_CIPHER_C
+#endif
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module: library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+#ifndef MBEDTLS_CMAC_C
+#define MBEDTLS_CMAC_C
+#endif
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-256-based random generator.
+ *
+ * Module: library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES-256 random number generator.
+ */
+#ifndef MBEDTLS_CTR_DRBG_C
+#define MBEDTLS_CTR_DRBG_C
+#endif
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module: library/ecdh.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#ifndef MBEDTLS_ECDH_C
+#define MBEDTLS_ECDH_C
+#endif
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module: library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ */
+#ifndef MBEDTLS_ECDSA_C
+#define MBEDTLS_ECDSA_C
+#endif
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module: library/ecp.c
+ * Caller: library/ecdh.c
+ * library/ecdsa.c
+ * library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#ifndef MBEDTLS_ECP_C
+#define MBEDTLS_ECP_C
+#endif
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module: library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#ifndef MBEDTLS_ENTROPY_C
+#define MBEDTLS_ENTROPY_C
+#endif
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module: library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#ifndef MBEDTLS_GCM_C
+#define MBEDTLS_GCM_C
+#endif
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module: library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#ifndef MBEDTLS_HMAC_DRBG_C
+#define MBEDTLS_HMAC_DRBG_C
+#endif
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module: library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#ifndef MBEDTLS_MD_C
+#define MBEDTLS_MD_C
+#endif
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module: library/oid.c
+ * Caller: library/asn1write.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ * library/pkwrite.c
+ * library/rsa.c
+ * library/x509.c
+ * library/x509_create.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#ifndef MBEDTLS_OID_C
+#define MBEDTLS_OID_C
+#endif
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module: library/pk.c
+ * Caller: library/ssl_tls.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#ifndef MBEDTLS_PK_C
+#define MBEDTLS_PK_C
+#endif
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module: library/pkparse.c
+ * Caller: library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#ifndef MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_PARSE_C
+#endif
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module: library/pkwrite.c
+ * Caller: library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#ifndef MBEDTLS_PK_WRITE_C
+#define MBEDTLS_PK_WRITE_C
+#endif
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module: library/platform.c
+ * Caller: Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#ifndef MBEDTLS_PLATFORM_C
+#define MBEDTLS_PLATFORM_C
+#endif
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module: library/sha256.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#ifndef MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_C
+#endif
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module: library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+#ifndef MBEDTLS_SSL_CACHE_C
+#define MBEDTLS_SSL_CACHE_C
+#endif
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module: library/ssl_cookie.c
+ * Caller:
+ */
+#ifndef MBEDTLS_SSL_COOKIE_C
+#define MBEDTLS_SSL_COOKIE_C
+#endif
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module: library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+#ifndef MBEDTLS_SSL_TICKET_C
+#define MBEDTLS_SSL_TICKET_C
+#endif
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module: library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+#ifndef MBEDTLS_SSL_CLI_C
+#define MBEDTLS_SSL_CLI_C
+#endif
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module: library/ssl_tls.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+#ifndef MBEDTLS_SSL_TLS_C
+#define MBEDTLS_SSL_TLS_C
+#endif
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module: library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#ifndef MBEDTLS_VERSION_C
+#define MBEDTLS_VERSION_C
+#endif
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module: library/x509.c
+ * Caller: library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ * MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+#ifndef MBEDTLS_X509_USE_C
+#define MBEDTLS_X509_USE_C
+#endif
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module: library/x509_crt.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+#ifndef MBEDTLS_X509_CRT_PARSE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+#endif
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module: library/x509_crl.c
+ * Caller: library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+#ifndef MBEDTLS_X509_CRL_PARSE_C
+#define MBEDTLS_X509_CRL_PARSE_C
+#endif
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module: library/x509_csr.c
+ * Caller: library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+#ifndef MBEDTLS_X509_CSR_PARSE_C
+#define MBEDTLS_X509_CSR_PARSE_C
+#endif
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module: library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+#ifndef MBEDTLS_X509_CREATE_C
+#define MBEDTLS_X509_CREATE_C
+#endif
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module: library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+#ifndef MBEDTLS_X509_CSR_WRITE_C
+#define MBEDTLS_X509_CSR_WRITE_C
+#endif
+
+/* SSL options */
+#ifndef MBEDTLS_SSL_MAX_CONTENT_LEN
+#define MBEDTLS_SSL_MAX_CONTENT_LEN 4096 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
+#endif
+
+/**
+ * Enable ARIA ciphersuites.
+ */
+#ifndef MBEDTLS_ARIA_C
+#define MBEDTLS_ARIA_C
+#endif
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+#ifndef MBEDTLS_SSL_CIPHERSUITES
+#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, \
+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, \
+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, \
+ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, \
+ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, \
+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+#endif
+
+// Need MBEDTLS_SSL_CONTEXT_SERIALIZATION and MBEDTLS_SSL_DTLS_CONNECTION_ID for CID feature
+#ifndef MBEDTLS_SSL_CONTEXT_SERIALIZATION
+#define MBEDTLS_SSL_CONTEXT_SERIALIZATION
+#endif
+
+#ifndef MBEDTLS_SSL_DTLS_CONNECTION_ID
+#define MBEDTLS_SSL_DTLS_CONNECTION_ID
+#endif
+
+#endif // PELION_MBEDTLS_CONFIG_H
diff --git a/mbed-client-pal/Configs/pal_config/Linux/Linux_default.h b/mbed-client-pal/Configs/pal_config/Linux/Linux_default.h
index 818f7df56..540d210d3 100644
--- a/mbed-client-pal/Configs/pal_config/Linux/Linux_default.h
+++ b/mbed-client-pal/Configs/pal_config/Linux/Linux_default.h
@@ -84,6 +84,15 @@
#endif
#endif
+#ifndef PAL_ASYNC_DNS_THREAD_STACK_SIZE
+ #define PAL_ASYNC_DNS_THREAD_STACK_SIZE (1024 * 24)
+#else
+ #if (PAL_ASYNC_DNS_THREAD_STACK_SIZE < PTHREAD_STACK_MIN)
+ #undef PAL_ASYNC_DNS_THREAD_STACK_SIZE
+ #define PAL_ASYNC_DNS_THREAD_STACK_SIZE PTHREAD_STACK_MIN
+ #endif
+#endif
+
#ifndef PAL_FORMAT_CMD_MAX_LENGTH
#define PAL_FORMAT_CMD_MAX_LENGTH 256
#endif
diff --git a/mbed-client-pal/Source/PAL-Impl/Modules/Networking/pal_network.c b/mbed-client-pal/Source/PAL-Impl/Modules/Networking/pal_network.c
index 3322bde32..d1b5b5f80 100644
--- a/mbed-client-pal/Source/PAL-Impl/Modules/Networking/pal_network.c
+++ b/mbed-client-pal/Source/PAL-Impl/Modules/Networking/pal_network.c
@@ -206,20 +206,20 @@ palStatus_t pal_setSockAddrNAT64Addr(palSocketAddress_t* address, palIpV4Addr_t
pal_socketAddressInternal6_t* innerAddr = (pal_socketAddressInternal6_t*)address;
innerAddr->pal_sin6_family = PAL_AF_INET6;
- innerAddr->pal_sin6_addr[0] = 0x00;
- innerAddr->pal_sin6_addr[1] = 0x64;
- innerAddr->pal_sin6_addr[2] = 0xFF;
- innerAddr->pal_sin6_addr[3] = 0x9B;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[0] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[1] = 0x64;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[2] = 0xFF;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[3] = 0x9B;
- innerAddr->pal_sin6_addr[4] = 0x00;
- innerAddr->pal_sin6_addr[5] = 0x00;
- innerAddr->pal_sin6_addr[6] = 0x00;
- innerAddr->pal_sin6_addr[7] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[4] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[5] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[6] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[7] = 0x00;
- innerAddr->pal_sin6_addr[8] = 0x00;
- innerAddr->pal_sin6_addr[9] = 0x00;
- innerAddr->pal_sin6_addr[10] = 0x00;
- innerAddr->pal_sin6_addr[11] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[8] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[9] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[10] = 0x00;
+ ((volatile uint8_t*) innerAddr->pal_sin6_addr)[11] = 0x00;
innerAddr->pal_sin6_addr[12] = ipV4Addr[0];
innerAddr->pal_sin6_addr[13] = ipV4Addr[1];
@@ -491,18 +491,23 @@ palStatus_t pal_getAddressInfoAsync(const char* hostname,
}
return status;
}
-#elif (PAL_DNS_API_VERSION == 2)
-#ifndef TARGET_LIKE_MBED
+
+#elif (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
+#if !defined(TARGET_LIKE_MBED) && (PAL_DNS_API_VERSION == 2)
#error "PAL_DNS_API_VERSION 2 is only supported with mbed-os"
#endif
palStatus_t pal_getAddressInfoAsync(const char* hostname,
- palSocketAddress_t* address,
- palGetAddressInfoAsyncCallback_t callback,
- void* callbackArgument,
- palDNSQuery_t* queryHandle)
+#if (PAL_DNS_API_VERSION == 2)
+ palSocketAddress_t* address,
+#endif
+ palGetAddressInfoAsyncCallback_t callback,
+ void* callbackArgument,
+ palDNSQuery_t* queryHandle)
{
- PAL_VALIDATE_ARGUMENTS ((NULL == hostname) || (NULL == address) || (NULL == callback))
-
+ PAL_VALIDATE_ARGUMENTS ((NULL == hostname) || (NULL == callback))
+#if (PAL_DNS_API_VERSION == 2)
+ PAL_VALIDATE_ARGUMENTS (NULL == address)
+#endif
palStatus_t status;
pal_asyncAddressInfo_t* info = (pal_asyncAddressInfo_t*)malloc(sizeof(pal_asyncAddressInfo_t));
@@ -511,7 +516,9 @@ palStatus_t pal_getAddressInfoAsync(const char* hostname,
}
else {
info->hostname = (char*)hostname;
+#if (PAL_DNS_API_VERSION == 2)
info->address = address;
+#endif
info->callback = callback;
info->callbackArgument = callbackArgument;
info->queryHandle = queryHandle;
@@ -528,6 +535,29 @@ palStatus_t pal_cancelAddressInfoAsync(palDNSQuery_t queryHandle)
return pal_plat_cancelAddressInfoAsync(queryHandle);
}
+#if (PAL_DNS_API_VERSION == 3)
+palStatus_t pal_getDNSAddress(palAddressInfo_t *addrInfo, uint16_t index, palSocketAddress_t *addr)
+{
+ PAL_VALIDATE_ARGUMENTS ((NULL == addrInfo) || (NULL == addr))
+ PAL_VALIDATE_ARGUMENTS (pal_getDNSCount(addrInfo) <= index)
+ return pal_plat_getDNSAddress(addrInfo, index, addr);
+}
+
+int pal_getDNSCount(palAddressInfo_t *addrInfo)
+{
+ return pal_plat_getDNSCount(addrInfo);
+}
+
+void pal_freeAddrInfo(palAddressInfo_t* addrInfo)
+{
+ pal_plat_freeAddrInfo(addrInfo);
+}
+
+palStatus_t pal_free_addressinfoAsync(palDNSQuery_t handle)
+{
+ return pal_plat_free_addressinfoAsync(handle);
+}
+#endif
#endif // PAL_DNS_API_VERSION
#endif // PAL_NET_DNS_SUPPORT
diff --git a/mbed-client-pal/Source/PAL-Impl/Modules/ROT/pal_rot.c b/mbed-client-pal/Source/PAL-Impl/Modules/ROT/pal_rot.c
index df7913c93..a292fa549 100644
--- a/mbed-client-pal/Source/PAL-Impl/Modules/ROT/pal_rot.c
+++ b/mbed-client-pal/Source/PAL-Impl/Modules/ROT/pal_rot.c
@@ -16,7 +16,7 @@
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "pal_plat_rot.h"
#ifndef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
#include "sotp.h"
diff --git a/mbed-client-pal/Source/PAL-Impl/Modules/TLS/pal_TLS.c b/mbed-client-pal/Source/PAL-Impl/Modules/TLS/pal_TLS.c
index c44907b50..384bce3c6 100644
--- a/mbed-client-pal/Source/PAL-Impl/Modules/TLS/pal_TLS.c
+++ b/mbed-client-pal/Source/PAL-Impl/Modules/TLS/pal_TLS.c
@@ -17,7 +17,7 @@
#include "pal.h"
#include "pal_plat_TLS.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
// do not require storage unless this modules is configured to use it
#if PAL_USE_SECURE_TIME
@@ -448,17 +448,19 @@ PAL_PRIVATE palStatus_t pal_updateTime(uint64_t serverTime, bool trustedTimeServ
}
#endif //PAL_USE_SECURE_TIME
-palStatus_t pal_handShake_ping(palTLSHandle_t palTLSHandle)
+#if (PAL_USE_SSL_SESSION_RESUME == 1)
+void pal_print_cid(palTLSHandle_t palTLSHandle)
{
- palTLSService_t* palTLSCtx = (palTLSService_t*)palTLSHandle;
-
- PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSCtx);
- PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSCtx->platTlsHandle);
-
- return pal_plat_handShake_ping(palTLSCtx->platTlsHandle);
+ uint8_t data_ptr[32];// MBEDTLS_SSL_CID_OUT_LEN_MAX = 32
+ size_t data_len = 0;
+ pal_plat_get_cid_value(palTLSHandle, data_ptr, &data_len);
+ if (data_len) {
+ PAL_LOG_DBG("CID: %s", PAL_LOG_ARRAY_FUNC(data_ptr, data_len));
+ }
}
+#endif
-palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf)
+palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf, bool skipResume)
{
palStatus_t status = PAL_SUCCESS;
palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
@@ -468,9 +470,10 @@ palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLS
PAL_VALIDATE_ARGUMENTS((NULLPTR == palTLSCtx->platTlsHandle || NULLPTR == palTLSConfCtx->platTlsConfHandle));
#if (PAL_USE_SSL_SESSION_RESUME == 1)
- if(palTLSConfCtx->isDtlsMode) {
- if(pal_plat_sslSessionAvailable()) {
- PAL_LOG_DBG("Using stored session");
+ if (!skipResume && palTLSConfCtx->isDtlsMode) {
+ if (pal_plat_sslSessionAvailable()) {
+ PAL_LOG_DBG("pal_handShake: using stored session");
+ pal_print_cid(palTLSCtx->platTlsHandle);
return status;
}
}
@@ -481,62 +484,56 @@ palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLS
status = pal_plat_handShake(palTLSCtx->platTlsHandle, &palTLSCtx->serverTime);
if (PAL_SUCCESS == status)
{
-#if PAL_USE_SECURE_TIME
int32_t verifyResult = 0;
status = pal_sslGetVerifyResultExtended(palTLSHandle, &verifyResult);
if (PAL_ERR_X509_CERT_VERIFY_FAILED == status)
{
- if ((PAL_ERR_X509_BADCERT_FUTURE & verifyResult) || ((true == palTLSConfCtx->trustedTimeServer) && (PAL_ERR_X509_BADCERT_EXPIRED & verifyResult)))
+#if PAL_USE_SECURE_TIME
+ // if cert verification fails _only_ on certificate time being wrong (and we use 'secure time' feature),
+ // try to renegotiate using server's time
+
+ // Cert being in future means client is actually in the past, so we're allowed to correct it always (sleepy device...)
+ // Cert being in the past (expired) means client is in future, so we only trust it when talking to Time RoT (trustedTimeServer)
+ if ((PAL_ERR_X509_BADCERT_FUTURE == verifyResult) || ((true == palTLSConfCtx->trustedTimeServer) && (PAL_ERR_X509_BADCERT_EXPIRED == verifyResult)))
{
- PAL_LOG_DBG("SSL EXPIRED OR FUTURE - retry");
+ PAL_LOG_DBG("SSL EXPIRED OR FUTURE - renegotiate");
palTLSCtx->retryHandShake = true;
status = PAL_SUCCESS;
}
- else if (PAL_SUCCESS != status)
+#else
+ // If PAL_USE_SECURE_TIME is not on, don't do time verification from certificate
+ if ((PAL_ERR_X509_BADCERT_FUTURE == verifyResult) || (PAL_ERR_X509_BADCERT_EXPIRED == verifyResult))
+ {
+ PAL_LOG_WARN("SSL EXPIRED OR FUTURE - passing due to PAL_USE_SECURE_TIME not set");
+ status = PAL_SUCCESS;
+ }
+#endif
+ if (PAL_SUCCESS != status)
{
- status = PAL_ERR_X509_CERT_VERIFY_FAILED;
palTLSCtx->serverTime = 0;
#if (PAL_USE_SSL_SESSION_RESUME == 1)
pal_removeSslSessionFromStorage(palTLSConfCtx->platTlsConfHandle);
#endif
}
}
-#else
- if (PAL_SUCCESS != status)
- {
- status = PAL_ERR_X509_CERT_VERIFY_FAILED;
- palTLSCtx->serverTime = 0;
- }
-
-#endif //PAL_USE_SECURE_TIME
}
}
#if PAL_USE_SECURE_TIME
if ((PAL_SUCCESS == status) && (palTLSCtx->retryHandShake))
{
PAL_LOG_DBG("SSL START RENEGOTIATE");
- if (!palTLSConfCtx->trustedTimeServer) //! if we are not proccessing handshake with the time trusted server we
- { //! will use PAL_TLS_VERIFY_REQUIRED authentication mode
- status = pal_plat_setAuthenticationMode(palTLSConfCtx->platTlsConfHandle, PAL_TLS_VERIFY_REQUIRED);
- if (PAL_SUCCESS != status)
- {
+ // We can now set verify required which does full certificate verification inside pal_plat_renegotiate call
+ // since time should be fine as we just got it from the server.
+ status = pal_plat_setAuthenticationMode(palTLSConfCtx->platTlsConfHandle, PAL_TLS_VERIFY_REQUIRED);
+ if (PAL_SUCCESS != status)
+ {
#if (PAL_USE_SSL_SESSION_RESUME == 1)
- pal_removeSslSessionFromStorage(palTLSConfCtx->platTlsConfHandle);
+ pal_removeSslSessionFromStorage(palTLSConfCtx->platTlsConfHandle);
#endif
- goto finish;
- }
+ goto finish;
}
+
status = pal_plat_renegotiate(palTLSCtx->platTlsHandle, palTLSCtx->serverTime);
- if (PAL_SUCCESS == status)
- {
- int32_t verifyResult = 0;
- status = pal_sslGetVerifyResultExtended(palTLSHandle, &verifyResult);
- if ((palTLSConfCtx->trustedTimeServer) &&
- ((PAL_ERR_X509_CERT_VERIFY_FAILED == status) && ((PAL_ERR_X509_BADCERT_EXPIRED & verifyResult) || (PAL_ERR_X509_BADCERT_FUTURE & verifyResult))))
- {
- status = PAL_SUCCESS;
- }
- }
}
if (PAL_SUCCESS == status)
@@ -549,14 +546,19 @@ palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLS
#if (PAL_USE_SSL_SESSION_RESUME == 1)
if (PAL_SUCCESS == status) {
pal_saveSslSessionToStorage(palTLSHandle, palTLSConf);
- PAL_LOG_DBG("Storing session !");
+ PAL_LOG_DBG("pal_handShake: handshake done, storing session!");
+ if (palTLSConfCtx->isDtlsMode) {
+ pal_print_cid(palTLSCtx->platTlsHandle);
+ }
}
+
#endif // PAL_USE_SSL_SESSION_RESUME
+#if PAL_USE_SECURE_TIME
finish:
+#endif //PAL_USE_SECURE_TIME
return status;
}
-#if PAL_USE_SECURE_TIME
palStatus_t pal_sslGetVerifyResultExtended(palTLSHandle_t palTLSHandle, int32_t* verifyResult)
{
palStatus_t status = PAL_SUCCESS;
@@ -571,29 +573,12 @@ palStatus_t pal_sslGetVerifyResultExtended(palTLSHandle_t palTLSHandle, int32_t*
if (0 != *verifyResult)
{
status = PAL_ERR_X509_CERT_VERIFY_FAILED;
- *verifyResult = *verifyResult ^ PAL_ERR_MODULE_BITMASK_BASE; //! in order to turn off the MSB bit.
}
return status;
}
-palStatus_t pal_sslGetVerifyResult(palTLSHandle_t palTLSHandle)
-{
- palStatus_t status = PAL_SUCCESS;
- palTLSService_t* palTLSCtx = NULL;
- int32_t verifyResult = 0;
-
- PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSHandle);
-
- palTLSCtx = (palTLSService_t*)palTLSHandle;
- PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSCtx->platTlsHandle);
-
- status = pal_plat_sslGetVerifyResultExtended(palTLSCtx->platTlsHandle, &verifyResult);
- return status;
-}
-#endif //PAL_USE_SECURE_TIME
-
palStatus_t pal_setHandShakeTimeOut(palTLSConfHandle_t palTLSConf, uint32_t minTimeout, uint32_t maxTimeout)
{
palStatus_t status = PAL_SUCCESS;
@@ -625,11 +610,12 @@ palStatus_t pal_sslWrite(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSC
palTLSService_t* palTLSCtx = (palTLSService_t*)palTLSHandle;
PAL_VALIDATE_ARGUMENTS((NULLPTR == palTLSHandle || NULL == buffer || NULL == bytesWritten));
-
status = pal_plat_sslWrite(palTLSCtx->platTlsHandle, buffer, len, bytesWritten);
#if (PAL_USE_SSL_SESSION_RESUME == 1)
- palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
- if(palTLSConfCtx->isDtlsMode) {
+ palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
+ if (palTLSConfCtx->isDtlsMode) {
+ PAL_LOG_DBG("pal_plat_sslWrite, using stored session!");
+ pal_print_cid(palTLSCtx->platTlsHandle);
pal_saveSslSessionToStorage(palTLSHandle, palTLSConf);
}
#endif // (PAL_USE_SSL_SESSION_RESUME == 1)
@@ -908,10 +894,11 @@ void pal_setDTLSSocketCallback(palTLSConfHandle_t palTLSConf, palSocketCallback_
pal_plat_SetDTLSSocketCallback(palTLSConfCtx->platTlsConfHandle, callback, argument);
}
-void pal_set_cid_value(palTLSHandle_t palTLSHandle, const uint8_t *data_ptr, const size_t data_len)
+void pal_set_cid_value(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf, const uint8_t *data_ptr, const size_t data_len)
{
#if (PAL_USE_SSL_SESSION_RESUME == 1)
palTLSService_t* palTLSCtx = (palTLSService_t*)palTLSHandle;
pal_plat_set_cid_value(palTLSCtx->platTlsHandle, data_ptr, data_len);
+ pal_loadSslSessionFromStorage(palTLSHandle, palTLSConf);
#endif
}
diff --git a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_TLS.h b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_TLS.h
index 5e7c11035..81a972950 100644
--- a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_TLS.h
+++ b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_TLS.h
@@ -204,10 +204,11 @@ palStatus_t pal_tlsSetSocket(palTLSConfHandle_t palTLSConf, palTLSSocket_t* sock
* with the peer.
* @param[in] palTLSHandle: The TLS context.
* @param[in] palTLSConf: The TLS configuration context.
+ * @param[in] skipResume: If true, will skip resume. Resume may be active only in UDP DTLS.
*
* \return PAL_SUCCESS on success, or a negative value indicating a specific error code in case of failure.
*/
-palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf);
+palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf, bool skipResume);
/*! \brief Set the retransmit timeout values for the DTLS handshake.
* DTLS only, no effect on TLS.
@@ -220,15 +221,6 @@ palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLS
*/
palStatus_t pal_setHandShakeTimeOut(palTLSConfHandle_t palTLSConf, uint32_t minTimeout, uint32_t maxTimeout);
-#if PAL_USE_SECURE_TIME
-/*! \brief Return the result of the certificate verification.
- *
- * @param[in] palTLSHandle: The TLS context.
- *
- * \return PAL_SUCCESS on success, or a negative value indicating a specific error code in case of failure.
- */
-palStatus_t pal_sslGetVerifyResult(palTLSHandle_t palTLSHandle);
-
/*! \brief Return the result of the certificate verification.
*
* @param[in] palTLSHandle: The TLS context.
@@ -239,7 +231,6 @@ palStatus_t pal_sslGetVerifyResult(palTLSHandle_t palTLSHandle);
* \return PAL_ERR_X509_CERT_VERIFY_FAILED in case of failure.
*/
palStatus_t pal_sslGetVerifyResultExtended(palTLSHandle_t palTLSHandle, int32_t* verifyResult);
-#endif //PAL_USE_SECURE_TIME
/*! \brief Read the application data bytes (the max number of bytes).
*
@@ -298,13 +289,6 @@ void pal_remove_cid();
*/
bool pal_is_cid_available();
-/*! \brief DTLS ping to Cloud to check connectivity status.
- * @param[in] palTLSHandle: The TLS context.
- *
- * \return PAL_SUCCESS on success, or a negative value indicating a specific error code in case of failure.
- */
-palStatus_t pal_handShake_ping(palTLSHandle_t palTLSHandle);
-
#if (PAL_USE_SSL_SESSION_RESUME == 1)
/*! \brief Enable SSL session storing. Disabled by default.
*
@@ -331,10 +315,11 @@ void pal_setDTLSSocketCallback(palTLSConfHandle_t palTLSConf, palSocketCallback_
/**
* \brief Internal test function. Set CID for current tls session.
- * @param palTLSHandle: The TLS context.
- * @param data_ptr: CID
- * @param data_len: length of the CID
+ * @param[in] palTLSHandle: The TLS context.
+ * @param[in] palTLSConf: The DTLS configuration context.
+ * @param[in] data_ptr: CID
+ * @param[in] data_len: length of the CID
*/
-void pal_set_cid_value(palTLSHandle_t palTLSHandle, const uint8_t *data_ptr, const size_t data_len);
+void pal_set_cid_value(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf, const uint8_t *data_ptr, const size_t data_len);
#endif // _PAL_DTLS_H_
diff --git a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_macros.h b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_macros.h
index 61a1dd932..34640253c 100644
--- a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_macros.h
+++ b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_macros.h
@@ -220,10 +220,11 @@ extern "C" {
assert(0);\
}
-#define PAL_LOG_ERR_FUNC tr_err
-#define PAL_LOG_WARN_FUNC tr_warn
-#define PAL_LOG_INFO_FUNC tr_info
-#define PAL_LOG_DBG_FUNC tr_debug
+#define PAL_LOG_ERR_FUNC tr_err
+#define PAL_LOG_WARN_FUNC tr_warn
+#define PAL_LOG_INFO_FUNC tr_info
+#define PAL_LOG_DBG_FUNC tr_debug
+#define PAL_LOG_ARRAY_FUNC tr_array
// Little trick with mbed-trace error level is equal to function name handling the same level of log output
#define PAL_LOG_LEVEL_ERR TRACE_LEVEL_ERROR
diff --git a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_network.h b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_network.h
index 4769482a8..5ddf0d8b0 100644
--- a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_network.h
+++ b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_network.h
@@ -20,7 +20,7 @@
#define _PAL_SOCKET_H
#ifndef _PAL_H
- #error "Please do not include this file directly, use pal.h instead"
+#error "Please do not include this file directly, use pal.h instead"
#endif
@@ -41,7 +41,7 @@ extern "C" {
*/
typedef uint32_t palSocketLength_t; /*!< \brief The length of data. */
-typedef void* palSocket_t; /*!< \brief PAL socket handle type. */
+typedef void *palSocket_t; /*!< \brief PAL socket handle type. */
#define PAL_NET_MAX_ADDR_SIZE 32 // check if we can make this more efficient
@@ -50,7 +50,13 @@ typedef struct palSocketAddress {
char addressData[PAL_NET_MAX_ADDR_SIZE]; /*!< \brief Address based on the protocol used. */
} palSocketAddress_t; /*!< \brief Address data structure with enough room to support IPV4 and IPV6. */
-typedef struct palNetInterfaceInfo{
+#if PAL_NET_DNS_SUPPORT
+#if (PAL_DNS_API_VERSION == 3)
+typedef void *palAddressInfo_t; /*!< \brief PAL address info handle type. */
+#endif // (PAL_DNS_API_VERSION == 3)
+#endif // PAL_NET_DNS_SUPPORT
+
+typedef struct palNetInterfaceInfo {
char interfaceName[16]; //15 + ‘\0’
palSocketAddress_t address;
uint32_t addressSize;
@@ -88,13 +94,14 @@ typedef enum {
#endif //PAL_NET_TCP_AND_TLS_SUPPORT
PAL_SO_SNDTIMEO = 0x1005, /*!< \brief Send timeout. */
PAL_SO_RCVTIMEO = 0x1006, /*!< \brief Receive timeout. */
- PAL_SO_IPV6_MULTICAST_HOPS = 0x1007 /*!< \brief Hop limit for subsequent multicast datagrams to be set to any value from 0 to 255. This ability is used to control the scope of the multicasts. */
+ PAL_SO_IPV6_MULTICAST_HOPS = 0x1007, /*!< \brief Hop limit for subsequent multicast datagrams to be set to any value from 0 to 255. This ability is used to control the scope of the multicasts. */
+ PAL_SO_IPV6_TRAFFIC_CLASS = 0x1008 /*!< \brief Use to set IPv6 traffic class priority. Default is 0. */
} palSocketOptionName_t;
/*! \brief Socket protocol level options supported by PAL. */
typedef enum {
PAL_SOL_SOCKET = 0,
- PAL_SOL_IPPROTO_IPV6 =1
+ PAL_SOL_IPPROTO_IPV6 = 1
} palSocketOptionLevelName_t;
#define PAL_NET_DEFAULT_INTERFACE 0xFFFFFFFF
@@ -105,7 +112,7 @@ typedef enum {
typedef uint8_t palIpV4Addr_t[PAL_IPV4_ADDRESS_SIZE];
typedef uint8_t palIpV6Addr_t[PAL_IPV6_ADDRESS_SIZE];
-typedef void(*connectionStatusCallback) (palNetworkStatus_t status, void *client_arg);
+typedef void(*connectionStatusCallback)(palNetworkStatus_t status, void *client_arg);
/*! \brief Register a network interface for use with PAL sockets.
*
@@ -119,7 +126,7 @@ typedef void(*connectionStatusCallback) (palNetworkStatus_t status, void *client
*
* \note If a context is not applicable on a target configuration, use \c NULL .
*/
-palStatus_t pal_registerNetworkInterface(void* networkInterfaceContext, uint32_t* interfaceIndex);
+palStatus_t pal_registerNetworkInterface(void *networkInterfaceContext, uint32_t *interfaceIndex);
/*! \brief Unregister a network interface.
* @param interfaceIndex Index of the network interface to be removed.
@@ -127,56 +134,56 @@ palStatus_t pal_registerNetworkInterface(void* networkInterfaceContext, uint32_t
*/
palStatus_t pal_unregisterNetworkInterface(uint32_t interfaceIndex);
- /*! \brief Set a port to an address data structure.
- * @param[in,out] address The address data structure to configure.
- * @param[in] port The port number to set.
- * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
- * \note To set the socket correctly, the `addressType` field of the address must be set correctly.
- * You can set it either directly, or using the `pal_setSockAddrIPV4Addr` or `pal_setSockAddrIPV6Addr` functions.
- */
-palStatus_t pal_setSockAddrPort(palSocketAddress_t* address, uint16_t port);
+/*! \brief Set a port to an address data structure.
+ * @param[in,out] address The address data structure to configure.
+ * @param[in] port The port number to set.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ * \note To set the socket correctly, the `addressType` field of the address must be set correctly.
+ * You can set it either directly, or using the `pal_setSockAddrIPV4Addr` or `pal_setSockAddrIPV6Addr` functions.
+ */
+palStatus_t pal_setSockAddrPort(palSocketAddress_t *address, uint16_t port);
/*! \brief Set an IPv4 address to an address data structure and set `addressType` as IPv4.
* @param[in,out] address The address data structure to configure.
* @param[in] ipV4Addr The address value to set.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_setSockAddrIPV4Addr(palSocketAddress_t* address, palIpV4Addr_t ipV4Addr);
+palStatus_t pal_setSockAddrIPV4Addr(palSocketAddress_t *address, palIpV4Addr_t ipV4Addr);
/*! \brief Get an IPv4 address from an address data structure.
* @param[in] address The address data structure to query.
* @param[out] ipV4Addr The IPv4 address to get.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getSockAddrIPV4Addr(const palSocketAddress_t* address, palIpV4Addr_t ipV4Addr);
+palStatus_t pal_getSockAddrIPV4Addr(const palSocketAddress_t *address, palIpV4Addr_t ipV4Addr);
/*! \brief Set an IPv6 address to an address data structure and set the `addressType` as IPv6.
* @param[in,out] address The address data structure to configure.
* @param[in] ipV6Addr The address value to set.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_setSockAddrIPV6Addr(palSocketAddress_t* address, palIpV6Addr_t ipV6Addr);
+palStatus_t pal_setSockAddrIPV6Addr(palSocketAddress_t *address, palIpV6Addr_t ipV6Addr);
/*! \brief Get an IPv6 address from an address data structure.
* @param[in] address The address data structure to query.
* @param[out] ipV6Addr The address to get.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getSockAddrIPV6Addr(const palSocketAddress_t* address, palIpV6Addr_t ipV6Addr);
+palStatus_t pal_getSockAddrIPV6Addr(const palSocketAddress_t *address, palIpV6Addr_t ipV6Addr);
/*! \brief Set a NAT64 address from an IPv4 address data structure and set `addressType` as IPv6.
* @param[in,out] address The address data structure to configure.
* @param[in] ipV4Addr The address value to set.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_setSockAddrNAT64Addr(palSocketAddress_t* address, palIpV4Addr_t ipV4Addr);
+palStatus_t pal_setSockAddrNAT64Addr(palSocketAddress_t *address, palIpV4Addr_t ipV4Addr);
/*! \brief Get a port from an address data structure.
* @param[in] address The address data structure to query.
* @param[out] port The port to get.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getSockAddrPort(const palSocketAddress_t* address, uint16_t* port);
+palStatus_t pal_getSockAddrPort(const palSocketAddress_t *address, uint16_t *port);
/*! \brief Set the value for a socket option on a network socket.
* @param[in] socket The socket to configure.
@@ -185,7 +192,7 @@ palStatus_t pal_getSockAddrPort(const palSocketAddress_t* address, uint16_t* por
* @param[in] optionLength The size of the buffer provided for `optionValue`.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_setSocketOptions(palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength);
+palStatus_t pal_setSocketOptions(palSocket_t socket, int optionName, const void *optionValue, palSocketLength_t optionLength);
/*! \brief Set the value for a socket option on a network socket.
* @param[in] socket The socket to configure.
@@ -195,14 +202,14 @@ palStatus_t pal_setSocketOptions(palSocket_t socket, int optionName, const void*
* @param[in] optionLength The size of the buffer provided for `optionValue`.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_setSocketOptionsWithLevel(palSocket_t socket, palSocketOptionLevelName_t optionLevel, int optionName, const void* optionValue, palSocketLength_t optionLength);
+palStatus_t pal_setSocketOptionsWithLevel(palSocket_t socket, palSocketOptionLevelName_t optionLevel, int optionName, const void *optionValue, palSocketLength_t optionLength);
/*! \brief Check if a socket is non-blocking.
* @param[in] socket The socket to check.
* @param[out] isNonBlocking `True` if the socket is non-blocking, otherwise `false`.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_isNonBlocking(palSocket_t socket, bool* isNonBlocking);
+palStatus_t pal_isNonBlocking(palSocket_t socket, bool *isNonBlocking);
/*! \brief Bind a socket to a local address.
* @param[in] socket The socket to bind.
@@ -210,7 +217,7 @@ palStatus_t pal_isNonBlocking(palSocket_t socket, bool* isNonBlocking);
* @param[in] addressLength The length of the address passed in `myAddress`.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength);
+palStatus_t pal_bind(palSocket_t socket, palSocketAddress_t *myAddress, palSocketLength_t addressLength);
/*! \brief Receive a payload from a specific socket.
* @param[in] socket The socket to receive from. The socket passed to this function should usually be of type `PAL_SOCK_DGRAM`, though your specific implementation may support other types as well.
@@ -221,7 +228,7 @@ palStatus_t pal_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocke
* @param[out] bytesReceived The actual amount of payload data received in the buffer.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_receiveFrom(palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived);
+palStatus_t pal_receiveFrom(palSocket_t socket, void *buffer, size_t length, palSocketAddress_t *from, palSocketLength_t *fromLength, size_t *bytesReceived);
/*! \brief Send a payload to an address using a specific socket.
* @param[in] socket The socket to use for sending the payload. The socket passed to this function should usually be of type `PAL_SOCK_DGRAM`, though your specific implementation may support other types as well.
@@ -232,27 +239,27 @@ palStatus_t pal_receiveFrom(palSocket_t socket, void* buffer, size_t length, pal
* @param[out] bytesSent The actual amount of payload data sent.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_sendTo(palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent);
+palStatus_t pal_sendTo(palSocket_t socket, const void *buffer, size_t length, const palSocketAddress_t *to, palSocketLength_t toLength, size_t *bytesSent);
/*! \brief Close a network socket.
* @param[in,out] socket The socket to be closed.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
* \note Receives `palSocket_t*`, \e not `palSocket_t`, so that it can zero the socket to avoid re-use.
*/
-palStatus_t pal_close(palSocket_t* socket);
+palStatus_t pal_close(palSocket_t *socket);
/*! \brief Get the number of current network interfaces.
* @param[out] numInterfaces The number of interfaces.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getNumberOfNetInterfaces(uint32_t* numInterfaces);
+palStatus_t pal_getNumberOfNetInterfaces(uint32_t *numInterfaces);
/*! \brief Get information regarding the socket at the interface index number given. This number is returned when registering the socket.
* @param[in] interfaceNum The number of the interface to get information for.
* @param[out] interfaceInfo The information for the given interface number.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t* interfaceInfo);
+palStatus_t pal_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t *interfaceInfo);
/*! \brief Set listener for connection status events.
* @param[in] interfaceNum Index of the network interface to be listen.
@@ -274,7 +281,7 @@ palStatus_t pal_setConnectionStatusCallback(uint32_t interfaceNum, connectionSta
/*! \brief The type of the callback function passed when creating asynchronous sockets.
* @param[in] argument The user provided argument passed to the callback function.
*/
-typedef void(*palAsyncSocketCallback_t)(void*);
+typedef void(*palAsyncSocketCallback_t)(void *);
#if PAL_NET_TCP_AND_TLS_SUPPORT // The functionality below is supported only if TCP is supported.
@@ -296,7 +303,7 @@ palStatus_t pal_listen(palSocket_t socket, int backlog);
* @param[in] callbackArgument The callback argument to be attached to the asynchronous accepted socket.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_accept(palSocket_t socket, palSocketAddress_t* address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket, palAsyncSocketCallback_t callback, void* callbackArgument);
+palStatus_t pal_accept(palSocket_t socket, palSocketAddress_t *address, palSocketLength_t *addressLen, palSocket_t *acceptedSocket, palAsyncSocketCallback_t callback, void *callbackArgument);
#endif // PAL_NET_SERVER_SOCKET_API
@@ -306,7 +313,7 @@ palStatus_t pal_accept(palSocket_t socket, palSocketAddress_t* address, palSocke
* @param[in] addressLen The length of the `address` field.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_connect(palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen);
+palStatus_t pal_connect(palSocket_t socket, const palSocketAddress_t *address, palSocketLength_t addressLen);
/*! \brief Receive data from a connected socket.
* @param[in] socket The connected socket on which to receive data. The socket passed to this function should usually be of type `PAL_SOCK_STREAM`, though your specific implementation may support other types as well.
@@ -315,7 +322,7 @@ palStatus_t pal_connect(palSocket_t socket, const palSocketAddress_t* address, p
* @param[out] recievedDataSize The length of the data actually received.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_recv(palSocket_t socket, void* buf, size_t len, size_t* recievedDataSize);
+palStatus_t pal_recv(palSocket_t socket, void *buf, size_t len, size_t *recievedDataSize);
/*! \brief Send a buffer via a connected socket.
* @param[in] socket The connected socket on which to send data. The socket passed to this function should usually be of type `PAL_SOCK_STREAM`, though your specific implementation may support other types as well.
@@ -324,7 +331,7 @@ palStatus_t pal_recv(palSocket_t socket, void* buf, size_t len, size_t* recieved
* @param[out] sentDataSize The length of the data sent.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_send(palSocket_t socket, const void* buf, size_t len, size_t* sentDataSize);
+palStatus_t pal_send(palSocket_t socket, const void *buf, size_t len, size_t *sentDataSize);
#endif //PAL_NET_TCP_AND_TLS_SUPPORT
@@ -338,7 +345,7 @@ palStatus_t pal_send(palSocket_t socket, const void* buf, size_t len, size_t* se
* @param[out] socket The socket is returned through this output parameter.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, palSocket_t* socket);
+palStatus_t pal_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, palSocket_t *socket);
/*! \brief Get an asynchronous network socket that passes the provided `callbackArgument` to a specified callback when it is triggered.
* @param[in] domain The domain for the created socket. See enum `palSocketDomain_t` for supported types.
@@ -350,7 +357,7 @@ palStatus_t pal_asynchronousSocket(palSocketDomain_t domain, palSocketType_t typ
* @param[out] socket The socket is returned through this output parameter.
* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_asynchronousSocketWithArgument(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback,void* callbackArgument, palSocket_t* socket);
+palStatus_t pal_asynchronousSocketWithArgument(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void *callbackArgument, palSocket_t *socket);
#if PAL_NET_DNS_SUPPORT
@@ -361,8 +368,9 @@ palStatus_t pal_asynchronousSocketWithArgument(palSocketDomain_t domain, palSock
* Supports both IP address as a string, and hostnames (using DNS lookup).
* @param[in] hostname The hostname (or IP address string) to be translated to a `palSocketAddress_t`.
* @param[out] address The address for the output of the translation.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getAddressInfo(const char* hostname, palSocketAddress_t* address, palSocketLength_t* addressLength);
+palStatus_t pal_getAddressInfo(const char *hostname, palSocketAddress_t *address, palSocketLength_t *addressLength);
#if (PAL_DNS_API_VERSION == 1)
@@ -372,8 +380,9 @@ palStatus_t pal_getAddressInfo(const char* hostname, palSocketAddress_t* address
* @param[in] addressLength The length of the address for the output of the translation in bytes.
* @param[in] status The status of the operation - PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
* @param[in] callbackArgument The user callback argument.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-typedef void(*palGetAddressInfoAsyncCallback_t)(const char* hostname, palSocketAddress_t* address, palSocketLength_t* addressLength, palStatus_t status, void* callbackArgument);
+typedef void(*palGetAddressInfoAsyncCallback_t)(const char *hostname, palSocketAddress_t *address, palSocketLength_t *addressLength, palStatus_t status, void *callbackArgument);
/*! \brief This function translates a hostname to `palSocketAddress_t` which can be used with PAL sockets.
*
@@ -384,11 +393,12 @@ typedef void(*palGetAddressInfoAsyncCallback_t)(const char* hostname, palSocketA
* @param[out] addressLength The length of the address for the output of the translation in bytes.
* @param[in] callback The user-provided callback to be invoked once the function has completed.
* @param[in] callbackArgument The user-provided callback argument which will be passed back to the callback function.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-palStatus_t pal_getAddressInfoAsync(const char* hostname, palSocketAddress_t* address, palSocketLength_t* addressLength, palGetAddressInfoAsyncCallback_t callback, void* callbackArgument);
+palStatus_t pal_getAddressInfoAsync(const char *hostname, palSocketAddress_t *address, palSocketLength_t *addressLength, palGetAddressInfoAsyncCallback_t callback, void *callbackArgument);
#endif
-
-#elif (PAL_DNS_API_VERSION == 2)
+#elif (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
+#if (PAL_DNS_API_VERSION == 2)
typedef int32_t palDNSQuery_t; /*!< \brief PAL DNS query handle. Can be used to cancel the asynchronous DNS query. */
/*! \brief Prototype of the callback function invoked when querying address info asynchronously using `pal_getAddressInfoAsync`.
@@ -396,8 +406,9 @@ typedef int32_t palDNSQuery_t; /*!< \brief PAL DNS query handle. Can be used to
* @param[out] address The address for the output of the translation.
* @param[out] status The status of the operation - PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
* @param[in] callbackArgument The user callback argument.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
-typedef void(*palGetAddressInfoAsyncCallback_t)(const char* hostname, palSocketAddress_t* address, palStatus_t status, void* callbackArgument);
+typedef void(*palGetAddressInfoAsyncCallback_t)(const char *hostname, palSocketAddress_t *address, palStatus_t status, void *callbackArgument);
/*! \brief Structure used by pal_getAddressInfoAsync.
* @param[in] hostname The user-provided hostname (or IP address string) to be translated.
@@ -405,37 +416,109 @@ typedef void(*palGetAddressInfoAsyncCallback_t)(const char* hostname, palSocketA
* @param[in] callback The user-provided callback.
* @param[in] callbackArgument The user callback argument of `pal_GetAddressInfoAsyncCallback_t`.
* @param[out] queryHandle Handler ID, which can be used for a cancellation request.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ */
+typedef struct pal_asyncAddressInfo {
+ char *hostname;
+ palSocketAddress_t *address;
+ palGetAddressInfoAsyncCallback_t callback;
+ void *callbackArgument;
+ palDNSQuery_t *queryHandle;
+} pal_asyncAddressInfo_t;
+
+/*! \brief This function translates a hostname to `palSocketAddress_t` which can be used with PAL sockets.
+ *
+ * Supports both IP address as a string, and hostname (using DNS lookup).
+ * \note The function is non-blocking.
+ * @param[in] hostname The user-provided hostname (or IP address string) to be translated.
+ * @param[out] address The address for the output of the translation.
+ * @param[in] callback The user-provided callback to be invoked once the function has completed.
+ * @param[in] callbackArgument The user callback argument of `pal_GetAddressInfoAsyncCallback_t`.
+ * @param[out] queryHandle DNS query handler. Caller must take care of allocation. If not used, then set as `NULL`.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ */
+palStatus_t pal_getAddressInfoAsync(const char *hostname,
+ palSocketAddress_t *address,
+ palGetAddressInfoAsyncCallback_t callback,
+ void *callbackArgument,
+ palDNSQuery_t *queryHandle);
+
+#elif (PAL_DNS_API_VERSION == 3)
+typedef uintptr_t palDNSQuery_t; /*!< \brief PAL DNS query handle. Can be used to cancel the asynchronous DNS query. */
+
+/*! \brief This function puts the palSocketAddress_t from the given index in palAddressInfo_t to the given addr
+ * @param[in] addrInfo The palAddressInfo_t which (if any) palSocketAddress_t is get.
+ * @param[in] index Index of the address in addrInfo to fetch.
+ * @param[out] addr palSocketAddress_t is put to this instance is any if found.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ */
+palStatus_t pal_getDNSAddress(palAddressInfo_t *addrInfo, uint16_t index, palSocketAddress_t *addr);
+
+/*! \brief Return the number of dns addresses in the given addrInfo
+ * @param[in] addrInfo The palAddressInfo_t to be used for countung dns addresses.
+ * \return Number of DNS addresses in the given addrInfo.
+ */
+int pal_getDNSCount(palAddressInfo_t *addrInfo);
+
+/*! \brief Free the given addrInfo.
+ * @param[in] addrInfo OS specific palAddressInfo_t which holds dns addresses.
+ */
+void pal_freeAddrInfo(palAddressInfo_t *addrInfo);
+
+/*! \brief This function free's the thread needed in pal_getAddressInfoAsync
+ * @param[out] handle PAL DNS query handle, used to cancel the asynchronous DNS query.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+*/
+palStatus_t pal_free_addressinfoAsync(palDNSQuery_t handle);
+
+/*! \brief Prototype of the callback function invoked when querying address info asynchronously using `pal_getAddressInfoAsync`.
+ * @param[in] hostname The user-provided hostname (or IP address string) to be translated.
+ * @param[out] addrInfo OS specific palAddressInfo_t which holds dns addresses.
+ * @param[out] status The status of the operation - PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ * @param[in] callbackArgument The user callback argument.
+ */
+typedef void(*palGetAddressInfoAsyncCallback_t)(const char *hostname, palAddressInfo_t *addrInfo, palStatus_t status, void *callbackArgument);
+
+/*! \brief Structure used by pal_getAddressInfoAsync.
+ * @param[in] hostname The user-provided hostname (or IP address string) to be translated.
+ * @param[out] addrInfo OS specific palAddressInfo_t which holds dns addresses.
+ * @param[in] callback The user-provided callback.
+ * @param[in] callbackArgument The user callback argument of `pal_GetAddressInfoAsyncCallback_t`.
+ * @param[out] queryHandle Handler ID, which can be used for a cancellation request.
*/
typedef struct pal_asyncAddressInfo
{
char* hostname;
- palSocketAddress_t* address;
+ palAddressInfo_t *addrInfo;
palGetAddressInfoAsyncCallback_t callback;
void* callbackArgument;
palDNSQuery_t *queryHandle;
} pal_asyncAddressInfo_t;
-/*! \brief This function translates a hostname to `palSocketAddress_t` which can be used with PAL sockets.
+/*! \brief This function translates a hostname to `palSocketAddress_t`(s) which can be used with PAL sockets.
*
* Supports both IP address as a string, and hostname (using DNS lookup).
* \note The function is non-blocking.
* @param[in] hostname The user-provided hostname (or IP address string) to be translated.
- * @param[out] address The address for the output of the translation.
* @param[in] callback The user-provided callback to be invoked once the function has completed.
+ * @param[in] callbackArgument The user callback argument of `pal_GetAddressInfoAsyncCallback_t`.
* @param[out] queryHandle DNS query handler. Caller must take care of allocation. If not used, then set as `NULL`.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
palStatus_t pal_getAddressInfoAsync(const char* hostname,
- palSocketAddress_t* address,
palGetAddressInfoAsyncCallback_t callback,
void* callbackArgument,
palDNSQuery_t* queryHandle);
+#endif
+
/*! \brief This function is a cancellation for `pal_getAddressInfoAsync`.
* @param[in] queryHandle Id of the ongoing DNS query.
+* \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
*/
palStatus_t pal_cancelAddressInfoAsync(palDNSQuery_t queryHandle);
#else
- #error "Please specify the platform PAL_DNS_API_VERSION 0, 1, or 2."
+ #error "Please specify the platform PAL_DNS_API_VERSION 0, 1, 2 or 3"
#endif // PAL_DNS_API_VERSION
#endif // PAL_NET_DNS_SUPPORT
diff --git a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_rtos.h b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_rtos.h
index 409a6abba..43683c115 100644
--- a/mbed-client-pal/Source/PAL-Impl/Services-API/pal_rtos.h
+++ b/mbed-client-pal/Source/PAL-Impl/Services-API/pal_rtos.h
@@ -141,7 +141,7 @@ uint64_t pal_osKernelSysTickFrequency(void);
*
* @param[in] function A function pointer to the thread callback function.
* @param[in] funcArgument An argument for the thread function.
-* @param[in] priority The priority of the thread.
+* @param[in] priority The priority of the thread. Not used in Linux.
* @param[in] stackSize The stack size of the thread, can NOT be 0.
* @param[in] store \b MUST be `NULL` - this functionality is not supported.
* @param[out] threadID: The created thread ID handle. In case of error, this value is `NULL`.
diff --git a/mbed-client-pal/Source/PAL-Impl/pal_init.c b/mbed-client-pal/Source/PAL-Impl/pal_init.c
index d74d3ca61..8acd995cc 100644
--- a/mbed-client-pal/Source/PAL-Impl/pal_init.c
+++ b/mbed-client-pal/Source/PAL-Impl/pal_init.c
@@ -18,7 +18,7 @@
#include "pal.h"
#include "pal_plat_network.h"
#include "pal_plat_TLS.h"
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#include "pal_plat_drbg.h"
#include "pal_macros.h"
#ifndef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
diff --git a/mbed-client-pal/Source/Port/Platform-API/pal_plat_TLS.h b/mbed-client-pal/Source/Port/Platform-API/pal_plat_TLS.h
index a7b39aa55..a5d3c194a 100644
--- a/mbed-client-pal/Source/Port/Platform-API/pal_plat_TLS.h
+++ b/mbed-client-pal/Source/Port/Platform-API/pal_plat_TLS.h
@@ -192,14 +192,6 @@ palStatus_t pal_plat_setHandShakeTimeOut(palTLSConfHandle_t palTLSConf, uint32_t
*/
palStatus_t pal_plat_sslSetup(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf);
-/*! \brief Perform the TLS handshake ping.
- *
- * @param[in] palTLSHandle: The TLS context.
- *
- * \return PAL_SUCCESS on success. A negative value indicating a specific error code in case of failure.
- */
-palStatus_t pal_plat_handShake_ping(palTLSHandle_t palTLSHandle);
-
/*! \brief Perform the TLS handshake.
*
* @param[in] palTLSHandle: The TLS context.
@@ -401,6 +393,14 @@ void pal_plat_set_cid(const uint8_t* context, const size_t length);
*/
void pal_plat_set_cid_value(palTLSHandle_t palTLSHandle, const uint8_t *data_ptr, const size_t data_len);
+/**
+ * \brief Internal test function. Get CID for the current tls session.
+ * \param[in] palTLSHandle: The TLS context.
+ * \param[out] data_ptr: CID
+ * \param[in,out] data_len: length of the CID
+ */
+void pal_plat_get_cid_value(palTLSHandle_t palTLSHandle, uint8_t *data_ptr, size_t *data_len);
+
#endif //PAL_USE_SSL_SESSION_RESUME
#endif //_PAL_PLAT_TLS_H_
diff --git a/mbed-client-pal/Source/Port/Platform-API/pal_plat_network.h b/mbed-client-pal/Source/Port/Platform-API/pal_plat_network.h
index a0d77f0df..8e8b37253 100644
--- a/mbed-client-pal/Source/Port/Platform-API/pal_plat_network.h
+++ b/mbed-client-pal/Source/Port/Platform-API/pal_plat_network.h
@@ -230,7 +230,31 @@ palStatus_t pal_plat_asynchronousSocket(palSocketDomain_t domain, palSocketType_
*/
palStatus_t pal_plat_getAddressInfo(const char* hostname, palSocketAddress_t* address, palSocketLength_t* addressLength);
-#elif (PAL_DNS_API_VERSION == 2)
+#elif (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
+#if (PAL_DNS_API_VERSION == 3)
+/*! \brief This function puts the palSocketAddress_t from the given index in palAddressInfo_t to the given addr
+ * @param[in] addrInfo The palAddressInfo_t which (if any) palSocketAddress_t is get.
+ * @param[in] index Index of the address in addrInfo to fetch.
+ * @param[out] addr palSocketAddress_t is put to this instance is any if found.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ */
+palStatus_t pal_plat_getDNSAddress(palAddressInfo_t *addrInfo, uint16_t index, palSocketAddress_t *addr);
+
+/*! \brief Return the number of dns addresses in the given addrInfo
+ * @param[in] addrInfo The palAddressInfo_t to be used for countung dns addresses.
+ * \return Number of DNS addresses in the given addrInfo.
+ */
+int pal_plat_getDNSCount(palAddressInfo_t *addrInfo);
+
+/*! \brief Free the given addrInfo.
+ * @param[in] addrInfo OS specific palAddressInfo_t which holds dns addresses.
+ */
+void pal_plat_freeAddrInfo(palAddressInfo_t* addrInfo);
+
+/*! \brief This function free's the thread used in pal_getAddressInfoAsync
+*/
+palStatus_t pal_plat_free_addressinfoAsync(palDNSQuery_t queryHandle);
+#endif
/*! \brief This function translates a hostname to a `palSocketAddress_t` that can be used with PAL sockets.
* @param[in] info address of `pal_asyncAddressInfo_t`.
@@ -242,7 +266,7 @@ palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo_t* info);
*/
palStatus_t pal_plat_cancelAddressInfoAsync(palDNSQuery_t queryHandle);
#else
- #error "Please specify the platform PAL_DNS_API_VERSION 0, 1, or 2."
+ #error "Please specify the platform PAL_DNS_API_VERSION 0, 1, 2 or 3."
#endif // PAL_DNS_API_VERSION
#endif // PAL_NET_DNS_SUPPORT
diff --git a/mbed-client-pal/Source/Port/Platform-API/pal_plat_rtos.h b/mbed-client-pal/Source/Port/Platform-API/pal_plat_rtos.h
index 5adc1afbc..67d720974 100644
--- a/mbed-client-pal/Source/Port/Platform-API/pal_plat_rtos.h
+++ b/mbed-client-pal/Source/Port/Platform-API/pal_plat_rtos.h
@@ -81,7 +81,7 @@ uint64_t pal_plat_osKernelSysTickFrequency(void);
*
* @param[in] function A function pointer to the thread callback function.
* @param[in] funcArgument An argument for the thread function.
- * @param[in] priority The priority of the thread.
+ * @param[in] priority The priority of the thread. Not used in Linux.
* @param[in] stackSize The stack size of the thread in bytes, can NOT be 0.
* @param[out] threadID: The created thread ID handle. In case of error, this value is NULL.
*
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/SOTP/pal_plat_drbg_sotp.c b/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/SOTP/pal_plat_drbg_sotp.c
index 8d5548699..40b850452 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/SOTP/pal_plat_drbg_sotp.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/SOTP/pal_plat_drbg_sotp.c
@@ -19,7 +19,7 @@
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "pal_plat_drbg.h"
#include "pal_plat_drbg_noise.h"
#include "sotp.h"
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/pal_plat_drbg_noise.c b/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/pal_plat_drbg_noise.c
index d8368d676..060a4fac2 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/pal_plat_drbg_noise.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/Generic/DRBG/pal_plat_drbg_noise.c
@@ -15,7 +15,7 @@
*******************************************************************************/
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "pal_plat_drbg.h"
/**
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/Generic/Entropy/PSA/pal_plat_entropy_psa.c b/mbed-client-pal/Source/Port/Reference-Impl/Generic/Entropy/PSA/pal_plat_entropy_psa.c
index e369e7d6f..ff88f3dc8 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/Generic/Entropy/PSA/pal_plat_entropy_psa.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/Generic/Entropy/PSA/pal_plat_entropy_psa.c
@@ -19,7 +19,7 @@
#if defined(MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT) || defined (MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT)
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "pal_plat_entropy.h"
// Include mbedtls config file explicitly for MBEDTLS_ENTROPY_NV_SEED flag
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/DRBG/pal_plat_drbg_w_entropy_sources.c b/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/DRBG/pal_plat_drbg_w_entropy_sources.c
index ba6c23b21..c841b13c3 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/DRBG/pal_plat_drbg_w_entropy_sources.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/DRBG/pal_plat_drbg_w_entropy_sources.c
@@ -30,7 +30,7 @@
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/config.h"
-#include "pal_plat_Crypto.h"
+#include "cs_pal_plat_crypto.h"
#if PAL_USE_HW_TRNG
#include "pal_plat_drbg_noise.h"
#endif
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/TLS/pal_plat_TLS.c b/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/TLS/pal_plat_TLS.c
index a0270e15f..ffcd5a7c6 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/TLS/pal_plat_TLS.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/Lib_Specific/mbedTLS/TLS/pal_plat_TLS.c
@@ -232,6 +232,8 @@ PAL_PRIVATE palStatus_t translateTLSHandShakeErrToPALError(palTLS_t* tlsCtx, int
status = PAL_ERR_X509_CERT_VERIFY_FAILED;
break;
#endif
+ // Treat unexpected messages during renegotiation as fatal.
+ case MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO:
case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
// In some cases the ssl->f_send() can already return connection termination.
case PAL_ERR_SOCKET_CONNECTION_RESET:
@@ -844,32 +846,6 @@ palStatus_t pal_plat_sslSetup(palTLSHandle_t palTLSHandle, palTLSConfHandle_t pa
return status;
}
-palStatus_t pal_plat_handShake_ping(palTLSHandle_t palTLSHandle)
-{
- palStatus_t status = PAL_SUCCESS;
- palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle;
- int32_t platStatus = SSL_LIB_SUCCESS;
-
- while( (MBEDTLS_SSL_SERVER_HELLO != localTLSCtx->tlsCtx.state) && (PAL_SUCCESS == status) )
- {
- platStatus = mbedtls_ssl_handshake_step( &localTLSCtx->tlsCtx );
-
- /* Extract the first 4 bytes of the ServerHello random */
- if( MBEDTLS_SSL_SERVER_HELLO == localTLSCtx->tlsCtx.state )
- {
- PAL_LOG_DBG("Server responded to CLIENT HELLO PING -success");
- }
-
- if (SSL_LIB_SUCCESS != platStatus)
- {
- status = translateTLSHandShakeErrToPALError(localTLSCtx, platStatus);
- }
- }
-
- return status;
-}
-
-
palStatus_t pal_plat_handShake(palTLSHandle_t palTLSHandle, uint64_t* serverTime)
{
palStatus_t status = PAL_SUCCESS;
@@ -1572,7 +1548,7 @@ void pal_plat_set_cid(const uint8_t* context, const size_t length)
memcpy(ssl_session_context, context, length);
ssl_session_context_length = length;
} else {
- PAL_LOG_ERR("pal_plat_set_cid - cid set failed, too long %lu (max was %d)", length, SSL_SESSION_STORE_SIZE);
+ PAL_LOG_ERR("pal_plat_set_cid - cid set failed, too long %" PRIu32 " (max was %d)", (uint32_t)length, SSL_SESSION_STORE_SIZE);
}
}
@@ -1586,4 +1562,21 @@ void pal_plat_set_cid_value(palTLSHandle_t palTLSHandle, const uint8_t *data_ptr
pal_plat_saveSslSessionBuffer(palTLSHandle);
#endif
}
+
+void pal_plat_get_cid_value(palTLSHandle_t palTLSHandle, uint8_t *data_ptr, size_t *data_len)
+{
+ palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle;
+ assert(data_ptr != NULL);
+ assert(data_len != NULL);
+ assert(MBEDTLS_SSL_CID_OUT_LEN_MAX >= *data_len);
+
+ *data_len = 0;
+ *data_ptr = 0;
+#ifdef MBEDTLS_SSL_DTLS_CONNECTION_ID
+ if (localTLSCtx->tlsCtx.transform_out) {
+ memcpy(data_ptr, localTLSCtx->tlsCtx.transform_out->out_cid, localTLSCtx->tlsCtx.transform_out->out_cid_len);
+ *data_len = localTLSCtx->tlsCtx.transform_out->out_cid_len;
+ }
+#endif
+}
#endif // PAL_USE_SSL_SESSION_RESUME
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Board_Specific/pal_plat_linux_common.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Board_Specific/pal_plat_linux_common.c
index 527c50af6..f9c9388af 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Board_Specific/pal_plat_linux_common.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Board_Specific/pal_plat_linux_common.c
@@ -74,6 +74,8 @@ palStatus_t pal_plat_osEntropyRead(const char *entropyFileName, uint8_t *randomB
status = PAL_ERR_FS_NO_FILE;
}
+ printf("Finished generating random from %s.\n", entropySourceFileName);
+
if (NULL != actualRandomSizeBytesOut) {
*actualRandomSizeBytesOut = actualRead;
}
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Networking/pal_plat_network.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Networking/pal_plat_network.c
index 7f6a516f3..58992e8f2 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Networking/pal_plat_network.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/Networking/pal_plat_network.c
@@ -1173,9 +1173,8 @@ palStatus_t pal_plat_getAddressInfo(const char *hostname, palSocketAddress_t *ad
struct addrinfo *pAddrInf = NULL;
struct addrinfo hints = {0};
int res;
- int supportedAddressType1 = 0;
- int supportedAddressType2 = 0;
- hints.ai_family = AF_UNSPEC;
+ int supportedAddressType1;
+ int supportedAddressType2;
#if PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_ANY
supportedAddressType1 = AF_INET;
@@ -1227,7 +1226,173 @@ palStatus_t pal_plat_getAddressInfo(const char *hostname, palSocketAddress_t *ad
return result;
}
+#if (PAL_DNS_API_VERSION == 3)
+
+PAL_PRIVATE palStatus_t getAddressInfo(const char *hostname, struct addrinfo **addrInfo)
+{
+ palStatus_t result = PAL_SUCCESS;
+ struct addrinfo hints = {0};
+ int err;
+ int supportedAddressType1;
+ int supportedAddressType2;
+
+#if PAL_NET_TCP_AND_TLS_SUPPORT == true
+ hints.ai_socktype = SOCK_STREAM;
+#else
+ hints.ai_socktype = SOCK_DGRAM;
#endif
+#if PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_ANY
+ supportedAddressType1 = AF_INET;
+ supportedAddressType2 = AF_INET6;
+ hints.ai_family = AF_UNSPEC;
+#elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV4_ONLY
+ supportedAddressType1 = AF_INET;
+ supportedAddressType2 = AF_INET;
+ hints.ai_family = AF_INET;
+#elif PAL_NET_DNS_IP_SUPPORT == PAL_NET_DNS_IPV6_ONLY
+ supportedAddressType1 = AF_INET6;
+ supportedAddressType2 = AF_INET6;
+ hints.ai_family = AF_INET6;
+#else
+#error PAL_NET_DNS_IP_SUPPORT is not defined to a valid value.
+#endif
+
+ err = getaddrinfo(hostname, NULL, &hints, addrInfo);
+ if (err < 0)
+ {
+ // getaddrinfo returns EAI-error. In case of EAI_SYSTEM, the error
+ // is 'Other system error, check errno for details'
+ // (http://man7.org/linux/man-pages/man3/getaddrinfo.3.html#RETURN_VALUE)
+ if (err == EAI_SYSTEM)
+ {
+ result = translateErrorToPALError(errno);
+ }
+ else
+ {
+ // errno values are positive, getaddrinfo errors are negative so they can be mapped
+ // in the same place.
+ result = translateErrorToPALError(err);
+ }
+ }
+ else
+ {
+ // remove addresses that don't match what hints tried to tell
+ struct addrinfo *prev = *addrInfo, *curr = *addrInfo;
+ while (curr) {
+ if ((curr->ai_family != supportedAddressType1 && curr->ai_family != supportedAddressType2) ||
+ curr->ai_socktype != hints.ai_socktype)
+ {
+ // remove from the list
+ if (prev == curr)
+ {
+ // remove first item
+ *addrInfo = curr->ai_next;
+ prev = curr->ai_next;
+ }
+ else
+ {
+ // remove from the middle or end
+ prev->ai_next = curr->ai_next;
+ prev = curr;
+ }
+ free(curr);
+ curr = prev->ai_next;
+ }
+ else
+ {
+ prev = curr;
+ curr = curr->ai_next;
+ }
+ }
+ }
+
+ return result;
+}
+
+// Thread function.
+PAL_PRIVATE void asyncDNSQueryFunc(void const *arg)
+{
+ pal_asyncAddressInfo_t *info = (pal_asyncAddressInfo_t *)(arg);
+ struct addrinfo *addr;
+ palStatus_t result = getAddressInfo(info->hostname, &addr);
+ if (result == PAL_SUCCESS)
+ {
+ info->addrInfo = (palAddressInfo_t *)addr;
+ }
+ else
+ {
+ info->addrInfo = NULL;
+ }
+
+ info->callback(info->hostname, info->addrInfo, result, info->callbackArgument); // invoke callback
+ free(info);
+}
+
+int pal_plat_getDNSCount(palAddressInfo_t *addrInfo)
+{
+ int count = 0;
+ struct addrinfo *curr = (struct addrinfo *)addrInfo;
+ while (curr)
+ {
+ count++;
+ curr = curr->ai_next;
+ }
+ return count;
+}
+
+palStatus_t pal_plat_getDNSAddress(palAddressInfo_t *addressInfo, uint16_t index, palSocketAddress_t *addr)
+{
+ struct addrinfo *info = (struct addrinfo *)addressInfo;
+ uint16_t count = 0;
+ palStatus_t result = PAL_ERR_INVALID_ARGUMENT;
+
+ while (info)
+ {
+ if (count == index)
+ {
+ mempcpy((void *)addr, info->ai_addr, info->ai_addrlen);
+ result = PAL_SUCCESS;
+ break;
+ }
+ count++;
+ info = info->ai_next;
+ }
+ return result;
+}
+
+void pal_plat_freeAddrInfo(palAddressInfo_t *addressInfo)
+{
+ freeaddrinfo((struct addrinfo *)addressInfo);
+}
+
+palStatus_t pal_plat_free_addressinfoAsync(palDNSQuery_t queryHandle)
+{
+ return pal_plat_cancelAddressInfoAsync(queryHandle);
+}
+
+palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo_t *info)
+{
+ return pal_osThreadCreateWithAlloc(asyncDNSQueryFunc, (void *)info, PAL_osPriorityReservedDNS, PAL_ASYNC_DNS_THREAD_STACK_SIZE, NULL, info->queryHandle);
+}
+
+palStatus_t pal_plat_cancelAddressInfoAsync(palDNSQuery_t queryHandle)
+{
+ // just try to delete thread
+ palStatus_t result = PAL_SUCCESS;
+ if (queryHandle != NULLPTR)
+ {
+ palStatus_t result = pal_osThreadTerminate(&queryHandle);
+ if (PAL_SUCCESS != result)
+ {
+ PAL_LOG_ERR("error terminating dns async thread: %d", result);
+ }
+ queryHandle = NULLPTR;
+ }
+ return result;
+}
+
+#endif // (PAL_DNS_API_VERSION == 3)
+#endif // PAL_NET_DNS_SUPPORT
palStatus_t pal_plat_setConnectionStatusCallback(uint32_t interfaceIndex, connectionStatusCallback callback, void *arg)
{
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/RTOS/pal_plat_rtos.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/RTOS/pal_plat_rtos.c
index 8c9431227..3998d024a 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/RTOS/pal_plat_rtos.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/Linux/RTOS/pal_plat_rtos.c
@@ -244,9 +244,9 @@ PAL_PRIVATE void* threadFunction(void* arg)
palStatus_t pal_plat_osThreadCreate(palThreadFuncPtr function, void* funcArgument, palThreadPriority_t priority, uint32_t stackSize, palThreadID_t* threadID)
{
+ (void)priority;
palStatus_t status = PAL_ERR_GENERIC_FAILURE;
pthread_t sysThreadID = (pthread_t)NULL;
- struct sched_param schedParam;
pthread_attr_t attr;
pthread_attr_t* ptrAttr = NULL;
palThreadData_t* threadData;
@@ -269,29 +269,8 @@ palStatus_t pal_plat_osThreadCreate(palThreadFuncPtr function, void* funcArgumen
goto finish;
}
- err = pthread_attr_setschedpolicy(ptrAttr, SCHED_RR);
- if (0 != err)
- {
- goto finish;
- }
-
-#if (PAL_SIMULATOR_TEST_ENABLE == 0) // disable ONLY for Linux PC simulator
- err = pthread_attr_setinheritsched(ptrAttr, PTHREAD_EXPLICIT_SCHED);
- if (0 != err)
- {
- goto finish;
- }
-#endif
-
err = pthread_attr_setdetachstate(ptrAttr, PTHREAD_CREATE_DETACHED);
if (0 != err)
- {
- goto finish;
- }
-
- schedParam.sched_priority = PAL_THREAD_PRIORITY_TRANSLATE(priority);
- err = pthread_attr_setschedparam(ptrAttr, &schedParam);
- if (0 != err)
{
goto finish;
}
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll.h b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll.h
index 6a7f13745..0315c8829 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll.h
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll.h
@@ -40,7 +40,7 @@ extern "C" {
typedef struct fd_work_poll_s {
#if (defined(PAL_SOCKET_USE_LONG_POLLING) && (PAL_SOCKET_USE_LONG_POLLING == 1)) || \
(defined(PAL_SOCKET_USE_LONG_POLLING_THREAD) && (PAL_SOCKET_USE_LONG_POLLING_THREAD == 1))
- struct k_delayed_work work;
+ struct k_work_delayable work;
int nfds;
k_ticks_t timeout;
k_ticks_t remaining;
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll_polling.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll_polling.c
index 775fa309a..c95ca0bd4 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll_polling.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/fd_work_poll_polling.c
@@ -90,7 +90,7 @@ void fd_work_poll_init(fd_work_poll_t *work, fd_work_handler_t handler)
}
#endif
- k_delayed_work_init(&work->work, fd_work_delayed_handler);
+ k_work_init_delayable(&work->work, fd_work_delayed_handler);
work->handler = handler;
}
@@ -112,7 +112,9 @@ int fd_work_poll_submit(fd_work_poll_t *work, struct zsock_pollfd *fds, int nfds
k_mutex_unlock(&fd_work_mutex);
/* wait at least one polling interval before actually polling. */
- k_delayed_work_submit_to_queue(&WORK_QUEUE_NAME, &work->work, Z_TIMEOUT_TICKS(work->timeout));
+ k_work_reschedule_for_queue(&WORK_QUEUE_NAME,
+ &work->work,
+ Z_TIMEOUT_TICKS(work->timeout));
}
return 0;
@@ -126,7 +128,7 @@ static void fd_work_delayed_handler(struct k_work* input)
* Get the encapsulating container which contains variables carried across
* work queue invocations.
*/
- struct k_delayed_work* delayed = CONTAINER_OF(input, struct k_delayed_work, work);
+ struct k_work_delayable* delayed = CONTAINER_OF(input, struct k_work_delayable, work);
fd_work_poll_t* work = CONTAINER_OF(delayed, fd_work_poll_t, work);
@@ -188,7 +190,9 @@ static void fd_work_delayed_handler(struct k_work* input)
} else {
/* reschedule work. */
- k_delayed_work_submit_to_queue(&WORK_QUEUE_NAME, &work->work, Z_TIMEOUT_TICKS(work_delay));
+ k_work_reschedule_for_queue(&WORK_QUEUE_NAME,
+ delayed,
+ Z_TIMEOUT_TICKS(work_delay));
}
}
}
@@ -202,7 +206,7 @@ int fd_work_poll_cancel(fd_work_poll_t *work)
if (work) {
/* remove work from queue. */
- status = k_delayed_work_cancel(&work->work);
+ status = k_work_cancel_delayable(&work->work);
/* Work is submitted from another thread. Ensure all values are set atomically. */
k_mutex_lock(&fd_work_mutex, K_FOREVER);
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/pal_plat_network.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/pal_plat_network.c
index a40168349..f8350b3e0 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/pal_plat_network.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/Networking/pal_plat_network.c
@@ -34,6 +34,10 @@
#if 1
#define TRACE_GROUP "PAL"
+//#include
+//#define DEBUG_DEBUG(...) { printf(__VA_ARGS__); printf("\r\n"); }
+//#define DEBUG_ERROR(...) { printf(__VA_ARGS__); printf("\r\n"); }
+
#define DEBUG_DEBUG PAL_LOG_DBG
#define DEBUG_ERROR PAL_LOG_ERR
#else
@@ -653,6 +657,11 @@ palStatus_t pal_plat_close(palSocket_t* handle)
return result;
}
+/******************************************************************************/
+/* DNS */
+/******************************************************************************/
+
+#if (PAL_DNS_API_VERSION == 0)
palStatus_t pal_plat_getAddressInfo(const char* hostname, palSocketAddress_t* address, palSocketLength_t* addressLength)
{
DEBUG_DEBUG("pal_plat_getAddressInfo");
@@ -704,8 +713,203 @@ palStatus_t pal_plat_getAddressInfo(const char* hostname, palSocketAddress_t* ad
return result;
}
+#elif (PAL_DNS_API_VERSION == 3)
+
+#if (PAL_SUPPORT_IP_V4 || PAL_SUPPORT_NAT64)
+#define PAL_DNS_DEFAULT_QUERY_TYPE DNS_QUERY_TYPE_A
+#else
+#define PAL_DNS_DEFAULT_QUERY_TYPE DNS_QUERY_TYPE_AAAA
+#endif
+
+static size_t pal_dns_counter = 0; // number of records in cache
+static uint16_t pal_dns_id = 0; // handle for cancelling request in progress
+static palSocketAddress_t pal_dns_cache[PAL_DNS_CACHE_MAX] = { 0 }; // cache
+
+/**
+ * @brief Callback function for Zephyr's DNS Resolve.
+ *
+ * @param[in] status Ongoing request's status.
+ * @param info DNS information.
+ * @param user_data User provided context.
+ */
+static void pal_plat_dns_resolve_cb(enum dns_resolve_status status,
+ struct dns_addrinfo *info,
+ void *user_data)
+{
+ DEBUG_DEBUG("pal_plat_dns_resolve_cb: %d", status);
+
+ /**
+ * Handle DNS record.
+ */
+ if ((status == DNS_EAI_INPROGRESS) &&
+ (pal_dns_counter < PAL_DNS_CACHE_MAX) && info) {
+ DEBUG_DEBUG("PAL DNS in progress");
+
+ palStatus_t result = PAL_ERR_SOCKET_DNS_ERROR;
+
+ /* get pointer to next slot in cache */
+ palSocketAddress_t* address = &pal_dns_cache[pal_dns_counter];
+
+ /* convert Zephyr address to PAL address */
+ if (info->ai_family == AF_INET) {
+
+#if !PAL_SUPPORT_IP_V4 && PAL_SUPPORT_NAT64
+ /* got IPv4 address on IPv6 network, convert to NAT64 address */
+ result = pal_setSockAddrNAT64Addr(address, net_sin(&info->ai_addr)->sin_addr.s4_addr);
+#else
+ result = pal_setSockAddrIPV4Addr(address, net_sin(&info->ai_addr)->sin_addr.s4_addr);
+#endif
+ } else if (info->ai_family == AF_INET6) {
+
+ result = pal_setSockAddrIPV6Addr(address, net_sin6(&info->ai_addr)->sin6_addr.s6_addr);
+
+ } else {
+ DEBUG_ERROR("Invalid IP address family %d", info->ai_family);
+ assert(0);
+ }
+
+ /* increment number of records in cache */
+ if (result == PAL_SUCCESS) {
+ pal_dns_counter++;
+ }
+
+ /**
+ * DNS lookup complete or failed.
+ */
+ } else {
+ DEBUG_DEBUG("PAL DNS done");
+
+ if (user_data) {
+
+ palStatus_t result = PAL_ERR_SOCKET_DNS_ERROR;
+
+ /* return success if at least one record has been received*/
+ if (pal_dns_counter) {
+ result = PAL_SUCCESS;
+ }
+
+ /* access user provided data */
+ pal_asyncAddressInfo_t* pal_info = (pal_asyncAddressInfo_t*) user_data;
+
+ /* invoke callback function with result */
+ pal_info->callback(pal_info->hostname,
+ (palAddressInfo_t*) pal_dns_cache,
+ result,
+ pal_info->callbackArgument);
+ }
+ }
+}
+
+/*! \brief This function translates a hostname to a `palSocketAddress_t` that can be used with PAL sockets.
+ * @param[in] info address of `pal_asyncAddressInfo_t`.
+ */
+palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo_t* info)
+{
+ DEBUG_DEBUG("pal_plat_getAddressInfoAsync");
+
+ palStatus_t result = PAL_ERR_SOCKET_DNS_ERROR;
+
+ if (info) {
+ DEBUG_DEBUG("hostname: %s", info->hostname);
+
+ /* reset counter */
+ pal_dns_counter = 0;
+
+ /* lookup address using Zephyr's DNS Resolve */
+ int retval = dns_get_addr_info(info->hostname, // const char *query,
+ PAL_DNS_DEFAULT_QUERY_TYPE, // enum dns_query_type type,
+ &pal_dns_id, // uint16_t *dns_id,
+ pal_plat_dns_resolve_cb, // dns_resolve_cb_tcb,
+ (void*) info, // void *user_data,
+ PAL_DNS_TIMEOUT_MS); // int32_t timeout
+
+ if (retval == 0) {
+
+ /* return handle for cancelling requests */
+ *info->queryHandle = pal_dns_id;
+
+ result = PAL_SUCCESS;
+ }
+ }
+
+ return result;
+}
+
+/*! \brief This function puts the palSocketAddress_t from the given index in palAddressInfo_t to the given addr
+ * @param[in] addrInfo The palAddressInfo_t which (if any) palSocketAddress_t is get.
+ * @param[in] index Index of the address in addrInfo to fetch.
+ * @param[out] addr palSocketAddress_t is put to this instance is any if found.
+ * \return PAL_SUCCESS (0) in case of success, or a specific negative error code in case of failure.
+ */
+palStatus_t pal_plat_getDNSAddress(palAddressInfo_t *addrInfo, uint16_t index, palSocketAddress_t *addr)
+{
+ DEBUG_DEBUG("pal_plat_getDNSAddress");
+
+ palStatus_t result = PAL_ERR_SOCKET_DNS_ERROR;
+
+ if (addr && (index < PAL_DNS_CACHE_MAX)) {
+
+ /* copy record from cache */
+ memcpy(addr, &pal_dns_cache[index], sizeof(palSocketAddress_t));
+
+ result = PAL_SUCCESS;
+ }
+
+ return result;
+}
+
+/*! \brief Return the number of dns addresses in the given addrInfo
+ * @param[in] addrInfo The palAddressInfo_t to be used for countung dns addresses.
+ * \return Number of DNS addresses in the given addrInfo.
+ */
+int pal_plat_getDNSCount(palAddressInfo_t *addrInfo)
+{
+ DEBUG_DEBUG("pal_plat_getDNSCount");
+
+ return pal_dns_counter;
+}
+
+/*! \brief This function is cancelation for `pal_plat_getAddressInfoAsync()`.
+ * @param[in] queryHandle ID of ongoing DNS query.
+ */
+palStatus_t pal_plat_cancelAddressInfoAsync(palDNSQuery_t queryHandle)
+{
+ DEBUG_DEBUG("pal_plat_cancelAddressInfoAsync");
+
+ /* cancel request */
+ int result = dns_cancel_addr_info(queryHandle);
+
+ return (result == 0) ? PAL_SUCCESS : PAL_ERR_SOCKET_DNS_ERROR;
+}
+
+/*! \brief This function free's the thread used in pal_getAddressInfoAsync
+*/
+palStatus_t pal_plat_free_addressinfoAsync(palDNSQuery_t queryHandle)
+{
+ DEBUG_DEBUG("pal_plat_free_addressinfoAsync");
+
+ /* reset counter */
+ pal_dns_counter = 0;
+
+ return PAL_SUCCESS;
+}
+
+/*! \brief Free the given addrInfo.
+ * @param[in] addrInfo OS specific palAddressInfo_t which holds dns addresses.
+ */
+void pal_plat_freeAddrInfo(palAddressInfo_t* addrInfo)
+{
+ DEBUG_DEBUG("pal_plat_freeAddrInfo");
+
+ /* unused */
+}
+#else
+#error PAL_DNS_API_VERSION must be either 0 or 3
+#endif
+
+/******************************************************************************/
+/* Feature dependant */
/******************************************************************************/
-/* Feature dependant */
// for blocking sockets
palStatus_t pal_plat_setSocketOptions(palSocket_t handle, int optionName, const void* optionValue, palSocketLength_t optionLength)
@@ -778,27 +982,36 @@ uint16_t pal_plat_getStaggerEstimate(uint16_t data_amount)
return PAL_DEFAULT_STAGGER_ESTIMATE;
}
-
/******************************************************************************/
-/* Unused */
+/* Network Interface */
+/******************************************************************************/
-palStatus_t pal_plat_getNumberOfNetInterfaces(uint32_t* numInterfaces)
+#if !(defined(PAL_USE_APPLICATION_NETWORK_CALLBACK) && \
+ (PAL_USE_APPLICATION_NETWORK_CALLBACK == 1))
+palStatus_t pal_plat_setConnectionStatusCallback(uint32_t interfaceIndex,
+ connectionStatusCallback callback,
+ void *client_arg)
{
- DEBUG_DEBUG("pal_plat_getNumberOfNetInterfaces");
+ DEBUG_DEBUG("pal_plat_setConnectionStatusCallback");
return PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED;
}
+#endif
-palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t* interfaceInfo)
+/******************************************************************************/
+/* Unused */
+/******************************************************************************/
+
+palStatus_t pal_plat_getNumberOfNetInterfaces(uint32_t* numInterfaces)
{
- DEBUG_DEBUG("pal_plat_getNetInterfaceInfo");
+ DEBUG_DEBUG("pal_plat_getNumberOfNetInterfaces");
return PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED;
}
-palStatus_t pal_plat_setConnectionStatusCallback(uint32_t interfaceIndex, connectionStatusCallback callback, void *client_arg)
+palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t* interfaceInfo)
{
- DEBUG_DEBUG("pal_plat_setConnectionStatusCallback");
+ DEBUG_DEBUG("pal_plat_getNetInterfaceInfo");
return PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED;
}
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/RTOS/pal_plat_rtos.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/RTOS/pal_plat_rtos.c
index 0377202c3..409d990e5 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/RTOS/pal_plat_rtos.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/ZephyrOS/RTOS/pal_plat_rtos.c
@@ -59,11 +59,9 @@ palStatus_t pal_plat_RTOSInitialize(void *opaqueContext)
palStatus_t pal_plat_RTOSDestroy(void)
{
- assert(0);
return PAL_ERR_NOT_IMPLEMENTED;
}
-
uint64_t pal_plat_osKernelSysTick(void)
{
return k_uptime_ticks();
@@ -183,7 +181,7 @@ palStatus_t pal_plat_osDelay(uint32_t milliseconds)
}
struct timer_data {
- struct k_delayed_work work;
+ struct k_work_delayable work;
palTimerFuncPtr callback;
void *arg;
struct k_mutex lock;
@@ -194,7 +192,7 @@ struct timer_data {
static void work_fn(struct k_work *work)
{
- struct k_delayed_work *dwork = CONTAINER_OF(work, struct k_delayed_work, work);
+ struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work);
struct timer_data *timer_data = CONTAINER_OF(dwork, struct timer_data, work);
uint64_t uptime = k_uptime_get();
@@ -228,15 +226,14 @@ static void work_fn(struct k_work *work)
delay = 0;
}
- int err = k_delayed_work_submit(&timer_data->work, K_MSEC(delay));
- __ASSERT_NO_MSG(!err);
+ k_work_reschedule(&timer_data->work, K_MSEC(delay));
/* If timer was started reference is already taken. */
k_sem_take(&timer_data->busy, K_NO_WAIT);
}
} else {
- if (!k_delayed_work_submit(&timer_data->work,
- K_MSEC(timer_data->timeout - uptime))) {
+ if (!k_work_reschedule(&timer_data->work,
+ K_MSEC(timer_data->timeout - uptime))) {
k_sem_take(&timer_data->busy, K_NO_WAIT);
}
}
@@ -270,7 +267,7 @@ palStatus_t pal_plat_osTimerCreate(palTimerFuncPtr function,
k_sem_init(&timer_data->busy, 2, 2);
k_mutex_init(&timer_data->lock);
- k_delayed_work_init(&timer_data->work, work_fn);
+ k_work_init_delayable(&timer_data->work, work_fn);
*timerID = (palTimerID_t)timer_data;
return PAL_SUCCESS;
@@ -298,12 +295,11 @@ palStatus_t pal_plat_osTimerStart(palTimerID_t timerID, uint32_t millisec)
timer_data->period = millisec;
}
- if (!k_delayed_work_cancel(&timer_data->work)) {
+ if (!k_work_cancel_delayable(&timer_data->work)) {
k_sem_give(&timer_data->busy);
- int err = k_delayed_work_submit(&timer_data->work, get_timeout(millisec));
- __ASSERT_NO_MSG(!err);
+ k_work_reschedule(&timer_data->work, get_timeout(millisec));
k_sem_take(&timer_data->busy, K_NO_WAIT);
- } else if (!k_delayed_work_submit(&timer_data->work, get_timeout(millisec))) {
+ } else if (!k_work_reschedule(&timer_data->work, get_timeout(millisec))) {
k_sem_take(&timer_data->busy, K_NO_WAIT);
} else {
/* Callback cannot be stopped or resubmitted.
@@ -331,7 +327,7 @@ palStatus_t pal_plat_osTimerStop(palTimerID_t timerID)
timer_data->period = UINT64_MAX;
}
- if (!k_delayed_work_cancel(&timer_data->work)) {
+ if (!k_work_cancel_delayable(&timer_data->work)) {
k_sem_give(&timer_data->busy);
} else {
/* Callback cannot be stopped.
@@ -585,18 +581,15 @@ palStatus_t pal_plat_osSetRtcTime(uint64_t rtcSetTime)
palStatus_t pal_plat_rtcDeInit(void)
{
- assert(0);
return PAL_ERR_NOT_IMPLEMENTED;
}
palStatus_t pal_plat_rtcInit(void)
{
- assert(0);
return PAL_ERR_NOT_IMPLEMENTED;
}
palStatus_t pal_plat_osRandomBuffer(uint8_t *randomBuf, size_t bufSizeBytes, size_t *actualRandomSizeBytes)
{
- assert(0);
return PAL_ERR_NOT_IMPLEMENTED;
}
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/mbedOS/Networking/pal_plat_network.cpp b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/mbedOS/Networking/pal_plat_network.cpp
index 3beaa0f8c..d9fb845f6 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/mbedOS/Networking/pal_plat_network.cpp
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/mbedOS/Networking/pal_plat_network.cpp
@@ -30,15 +30,15 @@
typedef void(*palSelectCallbackFunction_t)();
-typedef struct pal_plat_NetworkInterface{
- NetworkInterface* interface;
+typedef struct pal_plat_NetworkInterface {
+ NetworkInterface *interface;
void *clientArg;
connectionStatusCallback connectionStatusCb;
} pal_plat_NetworkInterface_t;
#if defined (__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)
-void palSelectCallbackNull(void* arg)
+void palSelectCallbackNull(void *arg)
{
}
@@ -67,356 +67,339 @@ void palConnectCallBack()
{
}
- class PALSocketWrapper
- {
- public:
- PALSocketWrapper() : initialized(false), activeSocket(NULL), isNonBlockingOnCreation(false), callbackFunction(NULL_FUNCTION), callbackArgument(NULL), selectCallbackFunction(NULL), connectState(PAL_PLAT_SOCKET_NOT_CONNECTED), socketTypeVal(PAL_SOCK_DGRAM), attachCallbackObject(NULL), rxBuffer(0), rxBufferSet(false)
- {
+class PALSocketWrapper {
+public:
+ PALSocketWrapper() : initialized(false), activeSocket(NULL), isNonBlockingOnCreation(false), callbackFunction(NULL_FUNCTION), callbackArgument(NULL), selectCallbackFunction(NULL), connectState(PAL_PLAT_SOCKET_NOT_CONNECTED), socketTypeVal(PAL_SOCK_DGRAM), attachCallbackObject(NULL), rxBuffer(0), rxBufferSet(false)
+ {
- }
- nsapi_error_t initialize(Socket* socket, palSocketType_t socketType,bool isNonBlocking, palAsyncSocketCallback_t callback, void* argument);
- palAsyncSocketCallback_t getCallback( ) const;
- void* getCallbackArgument() const ;
- bool isNonBlocking() const ;
- bool isConnected() const ;
- void attachCallback();
- Socket* getActiveSocket();
-
- palSocketType_t getSocketType() const;
- char getAndResetRxBuffer();
- bool isRxBufferSet() const;
- palStatus_t setRxBuffer(char data);
- void updateCallback(/*palAsyncSocketCallback_t callback, void* argument,*/ palSelectCallbackFunction_t selectCallback);
- virtual ~PALSocketWrapper()
- {
- if (NULL != activeSocket )
- {
- activeSocket->close();
- delete activeSocket;
- }
- }
+ }
+ nsapi_error_t initialize(Socket *socket, palSocketType_t socketType, bool isNonBlocking, palAsyncSocketCallback_t callback, void *argument);
+ palAsyncSocketCallback_t getCallback() const;
+ void *getCallbackArgument() const ;
+ bool isNonBlocking() const ;
+ bool isConnected() const ;
+ void attachCallback();
+ Socket *getActiveSocket();
+
+ palSocketType_t getSocketType() const;
+ char getAndResetRxBuffer();
+ bool isRxBufferSet() const;
+ palStatus_t setRxBuffer(char data);
+ void updateCallback(/*palAsyncSocketCallback_t callback, void* argument,*/ palSelectCallbackFunction_t selectCallback);
+ virtual ~PALSocketWrapper()
+ {
+ if (NULL != activeSocket) {
+ activeSocket->close();
+ delete activeSocket;
+ }
+ }
- // nsapi socket funcitons exposed:
- nsapi_error_t close();
- nsapi_error_t bind(const SocketAddress &address);
- void set_blocking(bool blocking);
- void set_timeout(int timeout);
- nsapi_error_t setsockopt(int level, int optname, const void *optval, unsigned optlen);
- nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen);
- void attach(mbed::Callback func);
- //void sigio(mbed::Callback func); // switch attach to sigio for verison 5.4
- // nsapi UDP socket funcitons exposed:
- nsapi_size_or_error_t recvfrom(SocketAddress *address, void *data, nsapi_size_t size);
- nsapi_size_or_error_t sendto(const SocketAddress &address, const void *data, nsapi_size_t size);
- //nsapi TCP socket funcitons exposed:
- nsapi_error_t connect(const SocketAddress &address);
- nsapi_size_or_error_t send(const void *data, nsapi_size_t size);
- nsapi_size_or_error_t recv(void *data, nsapi_size_t size);
+ // nsapi socket funcitons exposed:
+ nsapi_error_t close();
+ nsapi_error_t bind(const SocketAddress &address);
+ void set_blocking(bool blocking);
+ void set_timeout(int timeout);
+ nsapi_error_t setsockopt(int level, int optname, const void *optval, unsigned optlen);
+ nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen);
+ void attach(mbed::Callback func);
+ //void sigio(mbed::Callback func); // switch attach to sigio for verison 5.4
+ // nsapi UDP socket funcitons exposed:
+ nsapi_size_or_error_t recvfrom(SocketAddress *address, void *data, nsapi_size_t size);
+ nsapi_size_or_error_t sendto(const SocketAddress &address, const void *data, nsapi_size_t size);
+ //nsapi TCP socket funcitons exposed:
+ nsapi_error_t connect(const SocketAddress &address);
+ nsapi_size_or_error_t send(const void *data, nsapi_size_t size);
+ nsapi_size_or_error_t recv(void *data, nsapi_size_t size);
#if PAL_NET_SERVER_SOCKET_API
- //nsapi TCP server socket funcitons exposed:
- nsapi_error_t listen(int backlog = 1);
- Socket* accept(nsapi_error_t *error);
+ //nsapi TCP server socket funcitons exposed:
+ nsapi_error_t listen(int backlog = 1);
+ Socket *accept(nsapi_error_t *error);
#endif // PAL_NET_SERVER_SOCKET_API
- void freeSocket(bool freeSocket);
-
- private:
- bool initialized;
- Socket* activeSocket;
- bool isNonBlockingOnCreation;
- palAsyncSocketCallback_t callbackFunction;
- void* callbackArgument;
- palSelectCallbackFunction_t selectCallbackFunction;
- palConnectState connectState;
- palSocketType_t socketTypeVal;
- Callback attachCallbackObject;
- events::EventQueue* shared_event_queue;
- char rxBuffer;
- bool rxBufferSet;
- bool deleteSocket;
- };
-
- void PALSocketWrapper::updateCallback( palSelectCallbackFunction_t selectCallback )
- {
- bool shouldSetCallback = false;
- if ((NULL == selectCallbackFunction) && (NULL == callbackFunction)) //callback already set - no need to set again
- {
- shouldSetCallback = true;
- }
+ void freeSocket(bool freeSocket);
+
+private:
+ bool initialized;
+ Socket *activeSocket;
+ bool isNonBlockingOnCreation;
+ palAsyncSocketCallback_t callbackFunction;
+ void *callbackArgument;
+ palSelectCallbackFunction_t selectCallbackFunction;
+ palConnectState connectState;
+ palSocketType_t socketTypeVal;
+ Callback attachCallbackObject;
+ events::EventQueue *shared_event_queue;
+ char rxBuffer;
+ bool rxBufferSet;
+ bool deleteSocket;
+};
+
+void PALSocketWrapper::updateCallback(palSelectCallbackFunction_t selectCallback)
+{
+ bool shouldSetCallback = false;
+ if ((NULL == selectCallbackFunction) && (NULL == callbackFunction)) { //callback already set - no need to set again
+ shouldSetCallback = true;
+ }
- selectCallbackFunction = selectCallback;
+ selectCallbackFunction = selectCallback;
- if ((NULL != selectCallbackFunction) || (NULL != callbackFunction))
- {
- if (shouldSetCallback)
- {
- Callback mycall(this, &PALSocketWrapper::attachCallback);
- activeSocket->sigio(mycall);
- }
- }
- else
- {
- activeSocket->sigio(NULL);
- }
+ if ((NULL != selectCallbackFunction) || (NULL != callbackFunction)) {
+ if (shouldSetCallback) {
+ Callback mycall(this, &PALSocketWrapper::attachCallback);
+ activeSocket->sigio(mycall);
}
+ } else {
+ activeSocket->sigio(NULL);
+ }
+}
- Socket* PALSocketWrapper::getActiveSocket()
- {
- return activeSocket;
- }
+Socket *PALSocketWrapper::getActiveSocket()
+{
+ return activeSocket;
+}
- char PALSocketWrapper::getAndResetRxBuffer()
- {
- rxBufferSet = false;
- return rxBuffer;
- }
+char PALSocketWrapper::getAndResetRxBuffer()
+{
+ rxBufferSet = false;
+ return rxBuffer;
+}
- bool PALSocketWrapper::isRxBufferSet() const
- {
- return rxBufferSet;
- }
+bool PALSocketWrapper::isRxBufferSet() const
+{
+ return rxBufferSet;
+}
- palStatus_t PALSocketWrapper::setRxBuffer( char data)
- {
- PAL_VALIDATE_CONDITION_WITH_ERROR((true == rxBufferSet), PAL_ERR_SOCKET_GENERIC);
+palStatus_t PALSocketWrapper::setRxBuffer(char data)
+{
+ PAL_VALIDATE_CONDITION_WITH_ERROR((true == rxBufferSet), PAL_ERR_SOCKET_GENERIC);
- rxBuffer = data;
- rxBufferSet = true;
+ rxBuffer = data;
+ rxBufferSet = true;
- return PAL_SUCCESS;
- }
+ return PAL_SUCCESS;
+}
- palAsyncSocketCallback_t PALSocketWrapper::getCallback() const
- {
- return callbackFunction;
- }
+palAsyncSocketCallback_t PALSocketWrapper::getCallback() const
+{
+ return callbackFunction;
+}
- palSocketType_t PALSocketWrapper::getSocketType() const
- {
- return socketTypeVal;
- }
+palSocketType_t PALSocketWrapper::getSocketType() const
+{
+ return socketTypeVal;
+}
- void * PALSocketWrapper::getCallbackArgument() const
- {
- return callbackArgument;
- }
+void *PALSocketWrapper::getCallbackArgument() const
+{
+ return callbackArgument;
+}
- bool PALSocketWrapper::isNonBlocking() const
- {
- return isNonBlockingOnCreation;
- }
+bool PALSocketWrapper::isNonBlocking() const
+{
+ return isNonBlockingOnCreation;
+}
- bool PALSocketWrapper::isConnected() const
- {
- return ((PAL_PLAT_SOCKET_CONNECTED == connectState) && (PAL_SOCK_STREAM == socketTypeVal));
- }
+bool PALSocketWrapper::isConnected() const
+{
+ return ((PAL_PLAT_SOCKET_CONNECTED == connectState) && (PAL_SOCK_STREAM == socketTypeVal));
+}
- void PALSocketWrapper::attachCallback()
- {
- if (NULL != callbackFunction)
- {
- // Since the socket callback may be called from interrupt context, depending on the
- // network interface used, we need to debounce the client callback to happen from
- // a thread context to keep client side implementation platform agnostic.
- assert(shared_event_queue);
- shared_event_queue->call(callbackFunction, callbackArgument);
- }
- if (NULL != selectCallbackFunction)
- {
- // Note: this is not tested yet
- assert(shared_event_queue);
- shared_event_queue->call(selectCallbackFunction);
- }
- if (PAL_PLAT_SOCKET_CONNECTING == connectState)
- {
- connectState = PAL_PLAT_SOCKET_CONNECTED;// if we got a callback while connecting assume we are connected
- if (palConnectCallBack == selectCallbackFunction)
- {
- selectCallbackFunction = NULL;
- }
- }
+void PALSocketWrapper::attachCallback()
+{
+ if (NULL != callbackFunction) {
+ // Since the socket callback may be called from interrupt context, depending on the
+ // network interface used, we need to debounce the client callback to happen from
+ // a thread context to keep client side implementation platform agnostic.
+ assert(shared_event_queue);
+ shared_event_queue->call(callbackFunction, callbackArgument);
+ }
+ if (NULL != selectCallbackFunction) {
+ // Note: this is not tested yet
+ assert(shared_event_queue);
+ shared_event_queue->call(selectCallbackFunction);
+ }
+ if (PAL_PLAT_SOCKET_CONNECTING == connectState) {
+ connectState = PAL_PLAT_SOCKET_CONNECTED;// if we got a callback while connecting assume we are connected
+ if (palConnectCallBack == selectCallbackFunction) {
+ selectCallbackFunction = NULL;
}
+ }
+}
- nsapi_error_t PALSocketWrapper::initialize(Socket* socket, palSocketType_t socketType, bool isNonBlocking, palAsyncSocketCallback_t callback, void* argument)
- {
- // check that we got a valid socket and the socket type is supported
- PAL_VALIDATE_CONDITION_WITH_ERROR(((true == initialized) || (NULL == socket) ||
- ((socketType != PAL_SOCK_STREAM) && (socketType != PAL_SOCK_STREAM_SERVER) &&
- (socketType != PAL_SOCK_DGRAM))),NSAPI_ERROR_PARAMETER);
-
-
- // Pre fetch and store the shared queue used for bouncing the callbacks out of interrupt
- // context, as the user of it may be ran from interrupt and it can't go and start
- // creating worker threads from there.
- // Note: the code uses mbed_highprio_event_queue() instead of mbed_event_queue()
- // as the high priority queue and its thread is likely there already thanks to
- // arm_hal_timer.cpp. Technically the client side does not really care, if the events
- // were delayed a bit by other events or not.
+nsapi_error_t PALSocketWrapper::initialize(Socket *socket, palSocketType_t socketType, bool isNonBlocking, palAsyncSocketCallback_t callback, void *argument)
+{
+ // check that we got a valid socket and the socket type is supported
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((true == initialized) || (NULL == socket) ||
+ ((socketType != PAL_SOCK_STREAM) && (socketType != PAL_SOCK_STREAM_SERVER) &&
+ (socketType != PAL_SOCK_DGRAM))), NSAPI_ERROR_PARAMETER);
+
+
+ // Pre fetch and store the shared queue used for bouncing the callbacks out of interrupt
+ // context, as the user of it may be ran from interrupt and it can't go and start
+ // creating worker threads from there.
+ // Note: the code uses mbed_highprio_event_queue() instead of mbed_event_queue()
+ // as the high priority queue and its thread is likely there already thanks to
+ // arm_hal_timer.cpp. Technically the client side does not really care, if the events
+ // were delayed a bit by other events or not.
#if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT
- shared_event_queue = mbed_highprio_event_queue();
+ shared_event_queue = mbed_highprio_event_queue();
#else
- shared_event_queue = mbed_event_queue();
+ shared_event_queue = mbed_event_queue();
#endif
- PAL_VALIDATE_CONDITION_WITH_ERROR((shared_event_queue == NULL),NSAPI_ERROR_UNSUPPORTED);
+ PAL_VALIDATE_CONDITION_WITH_ERROR((shared_event_queue == NULL), NSAPI_ERROR_UNSUPPORTED);
+
+ Callback mycall(this, &PALSocketWrapper::attachCallback);
+ attachCallbackObject = mycall;
+ activeSocket = socket;
+ socketTypeVal = socketType;
+ isNonBlockingOnCreation = isNonBlocking;
+ deleteSocket = true;
+ activeSocket->set_blocking(!isNonBlocking);
+ if (NULL != callback) {
+ callbackFunction = callback;
+ callbackArgument = argument;
+ activeSocket->sigio(attachCallbackObject);
+ }
- Callback mycall(this, &PALSocketWrapper::attachCallback);
- attachCallbackObject = mycall;
- activeSocket = socket;
- socketTypeVal = socketType;
- isNonBlockingOnCreation = isNonBlocking;
- deleteSocket = true;
- activeSocket->set_blocking(!isNonBlocking);
- if (NULL != callback)
- {
- callbackFunction = callback;
- callbackArgument = argument;
- activeSocket->sigio(attachCallbackObject);
- }
+ initialized = true;
+ return NSAPI_ERROR_OK;
+}
- initialized = true;
- return NSAPI_ERROR_OK;
+nsapi_error_t PALSocketWrapper::close()
+{
+ nsapi_error_t status = NSAPI_ERROR_OK;
+ if (NULL != activeSocket) {
+ status = activeSocket->close();
+ // When allocated by accept() call, socket will destroy itself on close();
+ if (deleteSocket) {
+ delete activeSocket;
}
+ activeSocket = NULL;
+ }
+ return status;
+}
- nsapi_error_t PALSocketWrapper::close()
- {
- nsapi_error_t status= NSAPI_ERROR_OK;
- if (NULL != activeSocket)
- {
- status = activeSocket->close();
- // When allocated by accept() call, socket will destroy itself on close();
- if (deleteSocket)
- {
- delete activeSocket;
- }
- activeSocket = NULL;
- }
- return status;
- }
+nsapi_error_t PALSocketWrapper::bind(const SocketAddress &address)
+{
+ nsapi_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized), NSAPI_ERROR_PARAMETER);
+ status = activeSocket->bind(address);
+ return status;
+}
- nsapi_error_t PALSocketWrapper::bind(const SocketAddress &address)
- {
- nsapi_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized), NSAPI_ERROR_PARAMETER);
- status= activeSocket->bind(address);
- return status;
- }
+void PALSocketWrapper::set_blocking(bool blocking)
+{
+ activeSocket->set_blocking(blocking);
+}
- void PALSocketWrapper::set_blocking(bool blocking)
- {
- activeSocket->set_blocking(blocking);
- }
+void PALSocketWrapper::set_timeout(int timeout)
+{
+ activeSocket->set_timeout(timeout);
+}
- void PALSocketWrapper::set_timeout(int timeout)
- {
- activeSocket->set_timeout(timeout);
- }
+nsapi_error_t PALSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
+{
+ nsapi_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized), NSAPI_ERROR_PARAMETER);
+ status = activeSocket->setsockopt(level, optname, optval, optlen);
+ return status;
+}
- nsapi_error_t PALSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
- {
- nsapi_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized),NSAPI_ERROR_PARAMETER);
- status = activeSocket->setsockopt(level, optname, optval, optlen);
- return status;
- }
+nsapi_error_t PALSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
+{
+ nsapi_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized), NSAPI_ERROR_PARAMETER);
+ status = activeSocket->getsockopt(level, optname, optval, optlen);
+ return status;
+}
- nsapi_error_t PALSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
- {
- nsapi_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR((false == initialized),NSAPI_ERROR_PARAMETER);
- status = activeSocket->getsockopt(level, optname, optval, optlen);
- return status;
- }
+void PALSocketWrapper::attach(mbed::Callback func)
+{
+ activeSocket->sigio(func);
+}
+//void sigio(mbed::Callback func); // switch attach to sigio for verison 5.4
+// nsapi UDP socket funcitons exposed:
+nsapi_size_or_error_t PALSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size)
+{
+ nsapi_size_or_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_DGRAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
- void PALSocketWrapper::attach(mbed::Callback func)
- {
- activeSocket->sigio(func);
- }
- //void sigio(mbed::Callback func); // switch attach to sigio for verison 5.4
- // nsapi UDP socket funcitons exposed:
- nsapi_size_or_error_t PALSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size)
- {
- nsapi_size_or_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_DGRAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
-
- status = activeSocket->recvfrom(address, data, size);
- return status;
- }
+ status = activeSocket->recvfrom(address, data, size);
+ return status;
+}
- nsapi_size_or_error_t PALSocketWrapper::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
- {
- nsapi_size_or_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_DGRAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
- status = activeSocket->sendto(address, data, size);
- return status;
- }
+nsapi_size_or_error_t PALSocketWrapper::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
+{
+ nsapi_size_or_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_DGRAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
+ status = activeSocket->sendto(address, data, size);
+ return status;
+}
- //nsapi TCP socket funcitons exposed:
- nsapi_error_t PALSocketWrapper::connect(const SocketAddress &address)
- {
- nsapi_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // tcp sockets only
-
- connectState = PAL_PLAT_SOCKET_CONNECTING;
- updateCallback(palConnectCallBack); // make sure callback is enabled to see if we get callback to signal connections end
- status = activeSocket->connect(address);
- if (status >= 0 || status == NSAPI_ERROR_IS_CONNECTED)
- {
- connectState = PAL_PLAT_SOCKET_CONNECTED;
- updateCallback(NULL); // make sure callback is enabled to see if we get callback to signal connections end
- }
- else if ((NSAPI_ERROR_WOULD_BLOCK != status) && (NSAPI_ERROR_IN_PROGRESS != status) && (NSAPI_ERROR_ALREADY != status))
- {
- connectState = PAL_PLAT_SOCKET_NOT_CONNECTED;
- }
- return status;
- }
+//nsapi TCP socket funcitons exposed:
+nsapi_error_t PALSocketWrapper::connect(const SocketAddress &address)
+{
+ nsapi_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // tcp sockets only
+
+ connectState = PAL_PLAT_SOCKET_CONNECTING;
+ updateCallback(palConnectCallBack); // make sure callback is enabled to see if we get callback to signal connections end
+ status = activeSocket->connect(address);
+ if (status >= 0 || status == NSAPI_ERROR_IS_CONNECTED) {
+ connectState = PAL_PLAT_SOCKET_CONNECTED;
+ updateCallback(NULL); // make sure callback is enabled to see if we get callback to signal connections end
+ } else if ((NSAPI_ERROR_WOULD_BLOCK != status) && (NSAPI_ERROR_IN_PROGRESS != status) && (NSAPI_ERROR_ALREADY != status)) {
+ connectState = PAL_PLAT_SOCKET_NOT_CONNECTED;
+ }
+ return status;
+}
- nsapi_size_or_error_t PALSocketWrapper::send(const void *data, nsapi_size_t size)
- {
- nsapi_size_or_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // tcp sockets only
+nsapi_size_or_error_t PALSocketWrapper::send(const void *data, nsapi_size_t size)
+{
+ nsapi_size_or_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // tcp sockets only
- status = ((TCPSocket*)activeSocket)->send(data, size);
- return status;
- }
+ status = ((TCPSocket *)activeSocket)->send(data, size);
+ return status;
+}
- nsapi_size_or_error_t PALSocketWrapper::recv(void *data, nsapi_size_t size)
- {
- nsapi_size_or_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)),NSAPI_ERROR_PARAMETER); // tcp sockets only
- status = activeSocket->recv(data, size);
- return status;
- }
+nsapi_size_or_error_t PALSocketWrapper::recv(void *data, nsapi_size_t size)
+{
+ nsapi_size_or_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM != socketTypeVal)), NSAPI_ERROR_PARAMETER); // tcp sockets only
+ status = activeSocket->recv(data, size);
+ return status;
+}
#if PAL_NET_SERVER_SOCKET_API
- //nsapi TCP server socket funcitons exposed:
- nsapi_error_t PALSocketWrapper::listen(int backlog )
- {
- nsapi_error_t status = NSAPI_ERROR_OK;
- PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM_SERVER != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
- status = activeSocket->listen(backlog);
- return status;
- }
+//nsapi TCP server socket funcitons exposed:
+nsapi_error_t PALSocketWrapper::listen(int backlog)
+{
+ nsapi_error_t status = NSAPI_ERROR_OK;
+ PAL_VALIDATE_CONDITION_WITH_ERROR(((false == initialized) || (PAL_SOCK_STREAM_SERVER != socketTypeVal)), NSAPI_ERROR_PARAMETER); // udp sockets only
+ status = activeSocket->listen(backlog);
+ return status;
+}
- Socket* PALSocketWrapper::accept(nsapi_error_t *error)
- {
- *error = NSAPI_ERROR_OK;
+Socket *PALSocketWrapper::accept(nsapi_error_t *error)
+{
+ *error = NSAPI_ERROR_OK;
- if (!initialized || PAL_SOCK_STREAM_SERVER != socketTypeVal) {
- *error = NSAPI_ERROR_PARAMETER;
- return NULL;
- }
+ if (!initialized || PAL_SOCK_STREAM_SERVER != socketTypeVal) {
+ *error = NSAPI_ERROR_PARAMETER;
+ return NULL;
+ }
- return activeSocket->accept(error);
- }
+ return activeSocket->accept(error);
+}
#endif // PAL_NET_SERVER_SOCKET_API
- void PALSocketWrapper::freeSocket(bool freeSocket)
- {
- deleteSocket = freeSocket;
- }
+void PALSocketWrapper::freeSocket(bool freeSocket)
+{
+ deleteSocket = freeSocket;
+}
PAL_PRIVATE pal_plat_NetworkInterface_t s_pal_networkInterfacesSupported[PAL_MAX_SUPORTED_NET_INTERFACES] = { 0 };
@@ -425,83 +408,81 @@ PAL_PRIVATE uint32_t s_pal_numberOFInterfaces = 0;
PAL_PRIVATE uint32_t s_pal_network_initialized = 0;
-PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg, palSocket_t* socket);
+PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void *arg, palSocket_t *socket);
-PAL_PRIVATE palStatus_t set_sock_options(PALSocketWrapper *socketObj, int optionLevel, int optionName, const void* optionValue, palSocketLength_t optionLength);
+PAL_PRIVATE palStatus_t set_sock_options(PALSocketWrapper *socketObj, int optionLevel, int optionName, const void *optionValue, palSocketLength_t optionLength);
void pal_plat_connectionStatusCallback(void *interfaceIndex, nsapi_event_t status, intptr_t param);
PAL_PRIVATE palStatus_t translateErrorToPALError(int errnoValue)
{
palStatus_t status;
- switch (errnoValue)
- {
- case NSAPI_ERROR_WOULD_BLOCK:
- status = PAL_ERR_SOCKET_WOULD_BLOCK;
- break;
- case NSAPI_ERROR_UNSUPPORTED:
- status = PAL_ERR_NOT_SUPPORTED;
- break;
- case NSAPI_ERROR_PARAMETER:
- status = PAL_ERR_SOCKET_INVALID_VALUE;
- break;
- case NSAPI_ERROR_NO_CONNECTION:
- status = PAL_ERR_SOCKET_NOT_CONNECTED;
- break;
-
- case NSAPI_ERROR_NO_SOCKET:
- status = PAL_ERR_SOCKET_ALLOCATION_FAILED;
- break;
- case NSAPI_ERROR_NO_ADDRESS:
- status = PAL_ERR_SOCKET_INVALID_ADDRESS;
- break;
- case NSAPI_ERROR_NO_MEMORY:
- status = PAL_ERR_NO_MEMORY;
- break;
- case NSAPI_ERROR_DNS_FAILURE:
- status = PAL_ERR_SOCKET_DNS_ERROR;
- break;
- case NSAPI_ERROR_DHCP_FAILURE:
- status = PAL_ERR_SOCKET_HDCP_ERROR;
- break;
- case NSAPI_ERROR_AUTH_FAILURE:
- status = PAL_ERR_SOCKET_AUTH_ERROR;
- break;
- case NSAPI_ERROR_DEVICE_ERROR:
- status = PAL_ERR_SOCKET_INPUT_OUTPUT_ERROR;
- break;
- case NSAPI_ERROR_IN_PROGRESS:
- case NSAPI_ERROR_ALREADY:
- status = PAL_ERR_SOCKET_IN_PROGRES;
- break;
- case NSAPI_ERROR_IS_CONNECTED:
- status = PAL_SUCCESS;
- break;
- case NSAPI_ERROR_CONNECTION_LOST:
- status = PAL_ERR_SOCKET_CONNECTION_RESET;
- break;
- case NSAPI_ERROR_CONNECTION_TIMEOUT:
- case NSAPI_ERROR_TIMEOUT:
- status = PAL_ERR_TIMEOUT_EXPIRED;
- break;
- case NSAPI_ERROR_ADDRESS_IN_USE:
- status = PAL_ERR_SOCKET_ADDRESS_IN_USE;
- break;
-
- default:
- PAL_LOG_ERR("translateErrorToPALError() cannot translate %d", errnoValue);
- status = PAL_ERR_SOCKET_GENERIC;
- break;
+ switch (errnoValue) {
+ case NSAPI_ERROR_WOULD_BLOCK:
+ status = PAL_ERR_SOCKET_WOULD_BLOCK;
+ break;
+ case NSAPI_ERROR_UNSUPPORTED:
+ status = PAL_ERR_NOT_SUPPORTED;
+ break;
+ case NSAPI_ERROR_PARAMETER:
+ status = PAL_ERR_SOCKET_INVALID_VALUE;
+ break;
+ case NSAPI_ERROR_NO_CONNECTION:
+ status = PAL_ERR_SOCKET_NOT_CONNECTED;
+ break;
+
+ case NSAPI_ERROR_NO_SOCKET:
+ status = PAL_ERR_SOCKET_ALLOCATION_FAILED;
+ break;
+ case NSAPI_ERROR_NO_ADDRESS:
+ status = PAL_ERR_SOCKET_INVALID_ADDRESS;
+ break;
+ case NSAPI_ERROR_NO_MEMORY:
+ status = PAL_ERR_NO_MEMORY;
+ break;
+ case NSAPI_ERROR_DNS_FAILURE:
+ status = PAL_ERR_SOCKET_DNS_ERROR;
+ break;
+ case NSAPI_ERROR_DHCP_FAILURE:
+ status = PAL_ERR_SOCKET_HDCP_ERROR;
+ break;
+ case NSAPI_ERROR_AUTH_FAILURE:
+ status = PAL_ERR_SOCKET_AUTH_ERROR;
+ break;
+ case NSAPI_ERROR_DEVICE_ERROR:
+ status = PAL_ERR_SOCKET_INPUT_OUTPUT_ERROR;
+ break;
+ case NSAPI_ERROR_IN_PROGRESS:
+ case NSAPI_ERROR_ALREADY:
+ status = PAL_ERR_SOCKET_IN_PROGRES;
+ break;
+ case NSAPI_ERROR_IS_CONNECTED:
+ status = PAL_SUCCESS;
+ break;
+ case NSAPI_ERROR_CONNECTION_LOST:
+ status = PAL_ERR_SOCKET_CONNECTION_RESET;
+ break;
+ case NSAPI_ERROR_CONNECTION_TIMEOUT:
+ case NSAPI_ERROR_TIMEOUT:
+ status = PAL_ERR_TIMEOUT_EXPIRED;
+ break;
+ case NSAPI_ERROR_ADDRESS_IN_USE:
+ status = PAL_ERR_SOCKET_ADDRESS_IN_USE;
+ break;
+
+ default:
+ PAL_LOG_ERR("translateErrorToPALError() cannot translate %d", errnoValue);
+ status = PAL_ERR_SOCKET_GENERIC;
+ break;
}
return status;
}
-palStatus_t pal_plat_socketsInit(void* context)
+palStatus_t pal_plat_socketsInit(void *context)
{
(void)context; // replace with macro
int result = PAL_SUCCESS;
- if (s_pal_network_initialized == 1)
- {
+ if (s_pal_network_initialized == 1) {
return PAL_SUCCESS; // already initialized.
}
@@ -510,32 +491,26 @@ palStatus_t pal_plat_socketsInit(void* context)
return result;
}
-palStatus_t pal_plat_registerNetworkInterface(void* context, uint32_t* interfaceIndex)
+palStatus_t pal_plat_registerNetworkInterface(void *context, uint32_t *interfaceIndex)
{
palStatus_t result = PAL_SUCCESS;
uint32_t index = 0;
bool found = false;
- for (index = 0; index < s_pal_numberOFInterfaces; index++) // if specific context already registered return exisitng index instead of registering again.
- {
- if (s_pal_networkInterfacesSupported[index].interface == context)
- {
+ for (index = 0; index < s_pal_numberOFInterfaces; index++) { // if specific context already registered return exisitng index instead of registering again.
+ if (s_pal_networkInterfacesSupported[index].interface == context) {
found = true;
*interfaceIndex = index;
break;
}
}
- if (false == found)
- {
- if (s_pal_numberOFInterfaces < PAL_MAX_SUPORTED_NET_INTERFACES)
- {
- s_pal_networkInterfacesSupported[s_pal_numberOFInterfaces].interface = (NetworkInterface*)context;
+ if (false == found) {
+ if (s_pal_numberOFInterfaces < PAL_MAX_SUPORTED_NET_INTERFACES) {
+ s_pal_networkInterfacesSupported[s_pal_numberOFInterfaces].interface = (NetworkInterface *)context;
*interfaceIndex = s_pal_numberOFInterfaces;
++s_pal_numberOFInterfaces;
- }
- else
- {
+ } else {
result = PAL_ERR_SOCKET_MAX_NUMBER_OF_INTERFACES_REACHED;
}
}
@@ -549,7 +524,7 @@ palStatus_t pal_plat_setConnectionStatusCallback(uint32_t interfaceIndex, connec
if (interfaceIndex > PAL_MAX_SUPORTED_NET_INTERFACES - 1) {
result = PAL_ERR_INVALID_ARGUMENT;
} else {
- s_pal_networkInterfacesSupported[interfaceIndex].interface->add_event_listener(mbed::callback(&pal_plat_connectionStatusCallback, (void*)interfaceIndex));
+ s_pal_networkInterfacesSupported[interfaceIndex].interface->add_event_listener(mbed::callback(&pal_plat_connectionStatusCallback, (void *)interfaceIndex));
s_pal_networkInterfacesSupported[interfaceIndex].connectionStatusCb = callback;
s_pal_networkInterfacesSupported[interfaceIndex].clientArg = arg;
}
@@ -560,8 +535,8 @@ palStatus_t pal_plat_setConnectionStatusCallback(uint32_t interfaceIndex, connec
palStatus_t pal_plat_unregisterNetworkInterface(uint32_t interfaceIndex)
{
if (interfaceIndex < PAL_MAX_SUPORTED_NET_INTERFACES &&
- s_pal_networkInterfacesSupported[interfaceIndex].interface) {
- s_pal_networkInterfacesSupported[interfaceIndex].interface->remove_event_listener(mbed::callback(&pal_plat_connectionStatusCallback, (void*)interfaceIndex));
+ s_pal_networkInterfacesSupported[interfaceIndex].interface) {
+ s_pal_networkInterfacesSupported[interfaceIndex].interface->remove_event_listener(mbed::callback(&pal_plat_connectionStatusCallback, (void *)interfaceIndex));
s_pal_networkInterfacesSupported[interfaceIndex].interface = NULL;
s_pal_networkInterfacesSupported[interfaceIndex].clientArg = NULL;
s_pal_networkInterfacesSupported[interfaceIndex].connectionStatusCb = NULL;
@@ -572,7 +547,7 @@ palStatus_t pal_plat_unregisterNetworkInterface(uint32_t interfaceIndex)
}
}
-palStatus_t pal_plat_socketsTerminate(void* context)
+palStatus_t pal_plat_socketsTerminate(void *context)
{
(void)context; // replace with macro
return PAL_SUCCESS;
@@ -581,67 +556,64 @@ palStatus_t pal_plat_socketsTerminate(void* context)
PAL_PRIVATE int translateNSAPItoPALSocketOption(int option)
{
int optionVal = PAL_SOCKET_OPTION_ERROR;
- switch (option)
- {
- case PAL_SO_REUSEADDR:
- optionVal = NSAPI_REUSEADDR;
- break;
+ switch (option) {
+ case PAL_SO_REUSEADDR:
+ optionVal = NSAPI_REUSEADDR;
+ break;
#if PAL_NET_TCP_AND_TLS_SUPPORT // socket options below supported only if TCP is supported.
- case PAL_SO_KEEPALIVE:
- optionVal = NSAPI_KEEPALIVE;
- break;
- case PAL_SO_KEEPIDLE:
- optionVal = NSAPI_KEEPIDLE;
- break;
- case PAL_SO_KEEPINTVL:
- optionVal = NSAPI_KEEPINTVL;
- break;
+ case PAL_SO_KEEPALIVE:
+ optionVal = NSAPI_KEEPALIVE;
+ break;
+ case PAL_SO_KEEPIDLE:
+ optionVal = NSAPI_KEEPIDLE;
+ break;
+ case PAL_SO_KEEPINTVL:
+ optionVal = NSAPI_KEEPINTVL;
+ break;
#endif //PAL_NET_TCP_AND_TLS_SUPPORT
- case PAL_SO_IPV6_MULTICAST_HOPS:
- optionVal = SOCKET_IPV6_MULTICAST_HOPS;
- break;
- case PAL_SO_SNDTIMEO:
- case PAL_SO_RCVTIMEO:
- default:
- optionVal = PAL_SOCKET_OPTION_ERROR;
+ case PAL_SO_IPV6_MULTICAST_HOPS:
+ optionVal = SOCKET_IPV6_MULTICAST_HOPS;
+ break;
+ case PAL_SO_IPV6_TRAFFIC_CLASS:
+ optionVal = SOCKET_IPV6_TCLASS;
+ break;
+ case PAL_SO_SNDTIMEO:
+ case PAL_SO_RCVTIMEO:
+ default:
+ optionVal = PAL_SOCKET_OPTION_ERROR;
}
return optionVal;
}
-PAL_PRIVATE palStatus_t palSockAddrToSocketAddress(const palSocketAddress_t* palAddr, int length, SocketAddress& output)
+PAL_PRIVATE palStatus_t palSockAddrToSocketAddress(const palSocketAddress_t *palAddr, int length, SocketAddress &output)
{
palStatus_t result = PAL_SUCCESS;
uint16_t port = 0;
nsapi_version_t version = NSAPI_IPv4;
result = pal_getSockAddrPort(palAddr, &port);
- if (result != PAL_SUCCESS)
- {
+ if (result != PAL_SUCCESS) {
return result;
}
output.set_port(port);
#if PAL_SUPPORT_IP_V4
- if (PAL_AF_INET == palAddr->addressType)
- {
+ if (PAL_AF_INET == palAddr->addressType) {
palIpV4Addr_t ipV4Addr;
version = NSAPI_IPv4;
result = pal_getSockAddrIPV4Addr(palAddr, ipV4Addr);
- if (result == PAL_SUCCESS)
- {
+ if (result == PAL_SUCCESS) {
output.set_ip_bytes(&ipV4Addr, version);
}
}
#endif
#if PAL_SUPPORT_IP_V6
- if (PAL_AF_INET6 == palAddr->addressType)
- {
+ if (PAL_AF_INET6 == palAddr->addressType) {
palIpV6Addr_t ipV6Addr;
version = NSAPI_IPv6;
result = pal_getSockAddrIPV6Addr(palAddr, ipV6Addr);
- if (result == PAL_SUCCESS)
- {
+ if (result == PAL_SUCCESS) {
output.set_ip_bytes(&ipV6Addr, version);
}
}
@@ -651,9 +623,9 @@ PAL_PRIVATE palStatus_t palSockAddrToSocketAddress(const palSocketAddress_t* pal
}
#if (PAL_DNS_API_VERSION != 2)
-PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSocketAddress_t* out, palSocketLength_t* length)
+PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress &input, palSocketAddress_t *out, palSocketLength_t *length)
#else
-PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSocketAddress_t* out)
+PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress &input, palSocketAddress_t *out)
#endif
{
palStatus_t result = PAL_SUCCESS;
@@ -661,14 +633,12 @@ PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSock
bool found = false;
#if PAL_SUPPORT_IP_V4
- if (input.get_ip_version() == NSAPI_IPv4)
- {
+ if (input.get_ip_version() == NSAPI_IPv4) {
palIpV4Addr_t addr;
found = true;
- const void* tmp = input.get_ip_bytes();
- for (index = 0; index < PAL_IPV4_ADDRESS_SIZE; index++)
- {
- addr[index] = ((const uint8_t*)tmp)[index];
+ const void *tmp = input.get_ip_bytes();
+ for (index = 0; index < PAL_IPV4_ADDRESS_SIZE; index++) {
+ addr[index] = ((const uint8_t *)tmp)[index];
}
result = pal_setSockAddrIPV4Addr(out, addr);
#if (PAL_DNS_API_VERSION != 2)
@@ -678,14 +648,12 @@ PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSock
}
#endif
#if PAL_SUPPORT_IP_V6
- if (input.get_ip_version() == NSAPI_IPv6)
- {
+ if (input.get_ip_version() == NSAPI_IPv6) {
palIpV6Addr_t addr;
found = true;
- const void* tmp = input.get_ip_bytes();
- for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++)
- {
- addr[index] = ((const uint8_t*)tmp)[index];
+ const void *tmp = input.get_ip_bytes();
+ for (index = 0; index < PAL_IPV6_ADDRESS_SIZE; index++) {
+ addr[index] = ((const uint8_t *)tmp)[index];
}
result = pal_setSockAddrIPV6Addr(out, addr);
#if (PAL_DNS_API_VERSION != 2)
@@ -693,26 +661,24 @@ PAL_PRIVATE palStatus_t socketAddressToPalSockAddr(SocketAddress& input, palSock
#endif
}
#endif
- if (false == found )
- {
+ if (false == found) {
result = PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY;
}
- if (result == PAL_SUCCESS)
- {
+ if (result == PAL_SUCCESS) {
result = pal_setSockAddrPort(out, input.get_port());
}
return result;
}
-palStatus_t pal_plat_setSocketOptions(palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength)
+palStatus_t pal_plat_setSocketOptions(palSocket_t socket, int optionName, const void *optionValue, palSocketLength_t optionLength)
{
return pal_plat_setSocketOptionsWithLevel(socket, PAL_SOL_SOCKET, optionName, optionValue, optionLength);
}
-palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOptionLevelName_t optionLevel, int optionName, const void* optionValue, palSocketLength_t optionLength)
+palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOptionLevelName_t optionLevel, int optionName, const void *optionValue, palSocketLength_t optionLength)
{
int result = PAL_SUCCESS;
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
PAL_VALIDATE_ARGUMENTS(NULL == socket);
int level;
@@ -724,40 +690,37 @@ palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOpti
level = PAL_SOCKET_OPTION_ERROR;
}
- if (PAL_SOCKET_OPTION_ERROR != level)
- {
+ if (PAL_SOCKET_OPTION_ERROR != level) {
result = set_sock_options(socketObj, level, optionName, optionValue, optionLength);
}
return result;
}
-palStatus_t pal_plat_isNonBlocking(palSocket_t socket, bool* isNonBlocking)
+palStatus_t pal_plat_isNonBlocking(palSocket_t socket, bool *isNonBlocking)
{
- PALSocketWrapper* socketObj = NULL;
+ PALSocketWrapper *socketObj = NULL;
PAL_VALIDATE_ARGUMENTS(NULL == socket);
- socketObj = (PALSocketWrapper*)socket;
+ socketObj = (PALSocketWrapper *)socket;
*isNonBlocking = socketObj->isNonBlocking();
return PAL_SUCCESS;
}
-palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength)
+palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t *myAddress, palSocketLength_t addressLength)
{
int result = PAL_SUCCESS;
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
SocketAddress internalAddr;
- PAL_VALIDATE_ARGUMENTS ((NULL == socket));
+ PAL_VALIDATE_ARGUMENTS((NULL == socket));
result = palSockAddrToSocketAddress(myAddress, addressLength, internalAddr);
- if (result == 0)
- {
+ if (result == 0) {
result = socketObj->bind(internalAddr);
- if (result < 0)
- {
+ if (result < 0) {
result = translateErrorToPALError(result);
}
}
@@ -765,57 +728,46 @@ palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t* myAddress, pal
return result;
}
-palStatus_t pal_plat_receiveFrom(palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived)
+palStatus_t pal_plat_receiveFrom(palSocket_t socket, void *buffer, size_t length, palSocketAddress_t *from, palSocketLength_t *fromLength, size_t *bytesReceived)
{
int result = PAL_SUCCESS;
int status = 0;
*bytesReceived = 0;
SocketAddress sockAddr;
- PALSocketWrapper* socketObj;
- uint8_t* internalBufferPtr = (uint8_t*)buffer;
+ PALSocketWrapper *socketObj;
+ uint8_t *internalBufferPtr = (uint8_t *)buffer;
uint32_t bufferUsed = 0;
PAL_VALIDATE_ARGUMENTS((NULL == socket));
- socketObj = (PALSocketWrapper*)socket;
+ socketObj = (PALSocketWrapper *)socket;
- if (true == socketObj->isRxBufferSet())
- {
+ if (true == socketObj->isRxBufferSet()) {
internalBufferPtr[0] = socketObj->getAndResetRxBuffer();
internalBufferPtr++;
length--;
bufferUsed += 1;
}
- if (length > 0)
- {
+ if (length > 0) {
status = socketObj->recvfrom(&sockAddr, internalBufferPtr, length);
- if (status < 0)
- {
+ if (status < 0) {
result = translateErrorToPALError(status);
- }
- else if (status == 0)
- {
+ } else if (status == 0) {
result = PAL_ERR_SOCKET_CONNECTION_CLOSED;
- }
- else // only return address / bytesReceived in case of success
- {
+ } else { // only return address / bytesReceived in case of success
#if (PAL_DNS_API_VERSION != 2)
- if ((NULL != from) && (NULL != fromLength))
- {
+ if ((NULL != from) && (NULL != fromLength)) {
result = socketAddressToPalSockAddr(sockAddr, from, fromLength);
}
#else
- if (NULL != from)
- {
+ if (NULL != from) {
result = socketAddressToPalSockAddr(sockAddr, from);
}
#endif
*bytesReceived = status + bufferUsed;
}
- }
- else
- {
+ } else {
*bytesReceived = bufferUsed;
}
@@ -823,7 +775,7 @@ palStatus_t pal_plat_receiveFrom(palSocket_t socket, void* buffer, size_t length
}
-palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent)
+palStatus_t pal_plat_sendTo(palSocket_t socket, const void *buffer, size_t length, const palSocketAddress_t *to, palSocketLength_t toLength, size_t *bytesSent)
{
int result = PAL_SUCCESS;
int status = 0;
@@ -831,19 +783,15 @@ palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t lengt
PAL_VALIDATE_ARGUMENTS((NULL == socket));
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
*bytesSent = 0;
result = palSockAddrToSocketAddress(to, toLength, sockAddr);
- if (result == 0)
- {
+ if (result == 0) {
status = socketObj->sendto(sockAddr, buffer, length);
- if (status < 0)
- {
+ if (status < 0) {
result = translateErrorToPALError(status);
- }
- else
- {
+ } else {
*bytesSent = status;
}
}
@@ -851,18 +799,16 @@ palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t lengt
return result;
}
-palStatus_t pal_plat_close(palSocket_t* socket)
+palStatus_t pal_plat_close(palSocket_t *socket)
{
int result = PAL_SUCCESS;
- if (NULL == *socket)
- {
+ if (NULL == *socket) {
PAL_LOG_DBG("socket close called on socket which was already closed");
return result; // socket already closed (or not opened) - no need to close.
}
- PALSocketWrapper* socketObj = (PALSocketWrapper*)*socket;
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)*socket;
result = socketObj->close();
- if (result < 0)
- {
+ if (result < 0) {
result = translateErrorToPALError(result);
}
delete socketObj;
@@ -870,20 +816,20 @@ palStatus_t pal_plat_close(palSocket_t* socket)
return result;
}
-palStatus_t pal_plat_getNumberOfNetInterfaces( uint32_t* numInterfaces)
+palStatus_t pal_plat_getNumberOfNetInterfaces(uint32_t *numInterfaces)
{
*numInterfaces = s_pal_numberOFInterfaces;
return PAL_SUCCESS;
}
-palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t * interfaceInfo)
+palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t *interfaceInfo)
{
palStatus_t result = PAL_SUCCESS;
SocketAddress addr;
PAL_VALIDATE_ARGUMENTS((interfaceNum >= s_pal_numberOFInterfaces));
#if defined (MBED_MAJOR_VERSION) && (MBED_MAJOR_VERSION==5)
- const char* address = NULL;
+ const char *address = NULL;
address = s_pal_networkInterfacesSupported[interfaceNum].interface->get_ip_address(); // ip address returned is a null terminated string
if (NULL != address) {
@@ -962,34 +908,31 @@ palStatus_t pal_plat_listen(palSocket_t socket, int backlog)
int result = PAL_SUCCESS;
PAL_VALIDATE_ARGUMENTS(NULL == socket);
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
result = socketObj->listen(backlog);
- if (result < 0)
- {
+ if (result < 0) {
return translateErrorToPALError(result);
}
return PAL_SUCCESS;
}
-palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t * address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket, palAsyncSocketCallback_t callback, void* callbackArgument)
+palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t *address, palSocketLength_t *addressLen, palSocket_t *acceptedSocket, palAsyncSocketCallback_t callback, void *callbackArgument)
{
int result = PAL_SUCCESS;
bool isNonBlocking = callback ? true : false;
- PAL_VALIDATE_ARGUMENTS ((NULL == socket));
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
+ PAL_VALIDATE_ARGUMENTS((NULL == socket));
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
// Create wrapper
PALSocketWrapper *out = new PALSocketWrapper;
// Try to accept incoming socket
Socket *s = socketObj->accept(&result);
- if (result < 0)
- {
+ if (result < 0) {
result = translateErrorToPALError(result);
delete out;
- } else
- {
+ } else {
// Incoming socket accepted - initialize the wrapper
out->initialize(s, PAL_SOCK_STREAM, isNonBlocking, callback, callbackArgument);
out->freeSocket(false);
@@ -1001,19 +944,17 @@ palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t * address, pa
#endif // PAL_NET_SERVER_SOCKET_API
-palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen)
+palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t *address, palSocketLength_t addressLen)
{
int result = PAL_SUCCESS;
SocketAddress internalAddr;
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
- PAL_VALIDATE_ARGUMENTS ((NULL == socket));
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
+ PAL_VALIDATE_ARGUMENTS((NULL == socket));
result = palSockAddrToSocketAddress(address, addressLen, internalAddr);
- if (result == PAL_SUCCESS)
- {
+ if (result == PAL_SUCCESS) {
result = socketObj->connect(internalAddr);
- if (result < 0)
- {
+ if (result < 0) {
result = translateErrorToPALError(result);
}
}
@@ -1021,33 +962,29 @@ palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t* addre
return result;
}
-palStatus_t pal_plat_recv(palSocket_t socket, void *buf, size_t len, size_t* recievedDataSize)
+palStatus_t pal_plat_recv(palSocket_t socket, void *buf, size_t len, size_t *recievedDataSize)
{
int result = PAL_SUCCESS;
int status = 0;
- uint8_t* internalBufferPtr = (uint8_t*)buf;
+ uint8_t *internalBufferPtr = (uint8_t *)buf;
uint32_t bufferUsed = 0;
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
- PAL_VALIDATE_ARGUMENTS ((NULL == socket));
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
+ PAL_VALIDATE_ARGUMENTS((NULL == socket));
- if (true == socketObj->isRxBufferSet())
- {
+ if (true == socketObj->isRxBufferSet()) {
internalBufferPtr[0] = socketObj->getAndResetRxBuffer();
internalBufferPtr++;
len--;
bufferUsed += 1;
}
- if (len > 0)
- {
+ if (len > 0) {
status = socketObj->recv(internalBufferPtr, len);
- if (status < 0)
- {
+ if (status < 0) {
result = translateErrorToPALError(status);
- }
- else if (status == 0) {
+ } else if (status == 0) {
return PAL_ERR_SOCKET_CONNECTION_CLOSED;
}
}
@@ -1056,23 +993,20 @@ palStatus_t pal_plat_recv(palSocket_t socket, void *buf, size_t len, size_t* rec
return result;
}
-palStatus_t pal_plat_send(palSocket_t socket, const void *buf, size_t len, size_t* sentDataSize)
+palStatus_t pal_plat_send(palSocket_t socket, const void *buf, size_t len, size_t *sentDataSize)
{
palStatus_t result = PAL_SUCCESS;
int status = 0;
- PALSocketWrapper* socketObj = (PALSocketWrapper*)socket;
- PAL_VALIDATE_ARGUMENTS ((NULL == socket));
+ PALSocketWrapper *socketObj = (PALSocketWrapper *)socket;
+ PAL_VALIDATE_ARGUMENTS((NULL == socket));
status = socketObj->send(buf, len);
- if (status < 0)
- {
- PAL_LOG_DBG("pal_plat_send status %d",status);
+ if (status < 0) {
+ PAL_LOG_DBG("pal_plat_send status %d", status);
result = translateErrorToPALError(status);
- }
- else
- {
+ } else {
*sentDataSize = status;
}
@@ -1081,14 +1015,14 @@ palStatus_t pal_plat_send(palSocket_t socket, const void *buf, size_t len, size_
#endif //PAL_NET_TCP_AND_TLS_SUPPORT
-palStatus_t pal_plat_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg, palSocket_t* socket)
+palStatus_t pal_plat_asynchronousSocket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void *arg, palSocket_t *socket)
{
return create_socket(domain, type, nonBlockingSocket, interfaceNum, callback, arg, socket);
}
#if PAL_NET_DNS_SUPPORT
#if (PAL_DNS_API_VERSION == 0) || (PAL_DNS_API_VERSION == 1)
-palStatus_t pal_plat_getAddressInfo(const char *hostname, palSocketAddress_t *address, palSocketLength_t* length)
+palStatus_t pal_plat_getAddressInfo(const char *hostname, palSocketAddress_t *address, palSocketLength_t *length)
{
palStatus_t result = PAL_SUCCESS;
SocketAddress translatedAddress; // by default use the fist supported net interface - TODO: do we need to select a different interface?
@@ -1108,8 +1042,7 @@ palStatus_t pal_plat_getAddressInfo(const char *hostname, palSocketAddress_t *ad
if (result == 0) {
result = socketAddressToPalSockAddr(translatedAddress, address, length);
- }
- else { // error happened
+ } else { // error happened
result = translateErrorToPALError(result);
}
return result;
@@ -1119,12 +1052,11 @@ palStatus_t pal_plat_getAddressInfo(const char *hostname, palSocketAddress_t *ad
void pal_plat_getAddressInfoAsync_callback(void *data, nsapi_error_t result, SocketAddress *address)
{
palStatus_t status = PAL_SUCCESS;
- pal_asyncAddressInfo_t* info = (pal_asyncAddressInfo_t*)(data);
+ pal_asyncAddressInfo_t *info = (pal_asyncAddressInfo_t *)(data);
if (result >= NSAPI_ERROR_OK) {
status = socketAddressToPalSockAddr(*address, info->address);
- }
- else { // error happened
+ } else { // error happened
status = translateErrorToPALError(result);
}
@@ -1132,7 +1064,7 @@ void pal_plat_getAddressInfoAsync_callback(void *data, nsapi_error_t result, Soc
free(info);
}
-palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo* info)
+palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo *info)
{
PAL_LOG_DBG("pal_plat_getAddressInfoAsync");
palStatus_t result;
@@ -1149,18 +1081,17 @@ palStatus_t pal_plat_getAddressInfoAsync(pal_asyncAddressInfo* info)
if (s_pal_networkInterfacesSupported[0].interface == NULL) {
result = PAL_ERR_INVALID_ARGUMENT;
} else {
- result = s_pal_networkInterfacesSupported[0].interface->gethostbyname_async(info->hostname, mbed::Callback(pal_plat_getAddressInfoAsync_callback,(void*)info), version);
+ result = s_pal_networkInterfacesSupported[0].interface->gethostbyname_async(info->hostname, mbed::Callback(pal_plat_getAddressInfoAsync_callback, (void *)info), version);
}
PAL_LOG_DBG("pal_plat_getAddressInfoAsync result %" PRId32 ".", result);
if (result < 0) {
result = translateErrorToPALError(result);
- }
- else {
+ } else {
/* Skip over setting queryHandle when:
* 1. info->queryHandle not allocated
* 2. if result is zero then callback pal_plat_getAddressInfoAsync_callback will be called immediately and address info has been deallocated. */
- if ( (info->queryHandle != NULL) && result) {
+ if ((info->queryHandle != NULL) && result) {
*(info->queryHandle) = result;
}
result = PAL_SUCCESS;
@@ -1181,73 +1112,57 @@ palStatus_t pal_plat_cancelAddressInfoAsync(palDNSQuery_t queryHandle)
return status;
}
#else
- #error "Please specify the platform PAL_DNS_API_VERSION 0, 1 or 2."
+#error "Please specify the platform PAL_DNS_API_VERSION 0, 1 or 2."
#endif // PAL_DNS_API_VERSION
#endif
-PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void* arg, palSocket_t* socket)
+PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palAsyncSocketCallback_t callback, void *arg, palSocket_t *socket)
{
int result = PAL_SUCCESS;
- PALSocketWrapper * socketObj = NULL;
- InternetSocket* internalSocket = NULL;
+ PALSocketWrapper *socketObj = NULL;
+ InternetSocket *internalSocket = NULL;
PAL_VALIDATE_ARGUMENTS((NULL == socket));
- if (PAL_NET_DEFAULT_INTERFACE == interfaceNum)
- {
+ if (PAL_NET_DEFAULT_INTERFACE == interfaceNum) {
interfaceNum = 0;
}
- if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_DGRAM == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain))) //check that we got correct parameters for UDP socket
- {
+ if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_DGRAM == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain))) { //check that we got correct parameters for UDP socket
internalSocket = new UDPSocket;
}
#if PAL_NET_TCP_AND_TLS_SUPPORT // functionality below supported only in case TCP is supported.
- else if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_STREAM == type || PAL_SOCK_STREAM_SERVER == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain))) //check that we got correct parameters for TCP socket
- {
+ else if ((s_pal_numberOFInterfaces > interfaceNum) && (PAL_SOCK_STREAM == type || PAL_SOCK_STREAM_SERVER == type) && ((PAL_AF_INET == domain) || (PAL_AF_INET6 == domain) || (PAL_AF_UNSPEC == domain))) { //check that we got correct parameters for TCP socket
internalSocket = new TCPSocket;
}
#endif
- else
- {
+ else {
result = PAL_ERR_INVALID_ARGUMENT;
}
- if (internalSocket && result == PAL_SUCCESS)
- {
+ if (internalSocket && result == PAL_SUCCESS) {
result = internalSocket->open(s_pal_networkInterfacesSupported[interfaceNum].interface);
- if (result < 0)
- {
+ if (result < 0) {
result = translateErrorToPALError(result);
}
- }
- else
- {
+ } else {
result = PAL_ERR_NO_MEMORY;
}
- if (PAL_SUCCESS == result)
- {
+ if (PAL_SUCCESS == result) {
socketObj = new PALSocketWrapper();
- if (NULL != socketObj)
- {
- if (0 == socketObj->initialize(internalSocket, type, nonBlockingSocket, callback, arg))
- {
+ if (NULL != socketObj) {
+ if (0 == socketObj->initialize(internalSocket, type, nonBlockingSocket, callback, arg)) {
*socket = (palSocket_t)socketObj;
- }
- else
- {
+ } else {
result = PAL_ERR_INVALID_ARGUMENT;
}
- }
- else
- {
+ } else {
result = PAL_ERR_NO_MEMORY;
}
}
- if (PAL_SUCCESS != result) //cleanup
- {
+ if (PAL_SUCCESS != result) { //cleanup
delete internalSocket;
delete socketObj;
@@ -1259,23 +1174,19 @@ PAL_PRIVATE palStatus_t create_socket(palSocketDomain_t domain, palSocketType_t
void pal_plat_connectionStatusCallback(void *interfaceIndex, nsapi_event_t status, intptr_t param)
{
uint32_t index = (uint32_t)interfaceIndex;
- if (status == NSAPI_EVENT_CONNECTION_STATUS_CHANGE)
- {
- switch(param)
- {
+ if (status == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
+ switch (param) {
case NSAPI_STATUS_GLOBAL_UP:
- if (s_pal_networkInterfacesSupported[index].connectionStatusCb)
- {
- s_pal_networkInterfacesSupported[index].connectionStatusCb(PAL_NETWORK_STATUS_CONNECTED,
- s_pal_networkInterfacesSupported[index].clientArg);
+ if (s_pal_networkInterfacesSupported[index].connectionStatusCb) {
+ s_pal_networkInterfacesSupported[index].connectionStatusCb(PAL_NETWORK_STATUS_CONNECTED,
+ s_pal_networkInterfacesSupported[index].clientArg);
}
break;
case NSAPI_STATUS_DISCONNECTED:
- if (s_pal_networkInterfacesSupported[index].connectionStatusCb)
- {
+ if (s_pal_networkInterfacesSupported[index].connectionStatusCb) {
s_pal_networkInterfacesSupported[index].connectionStatusCb(PAL_NETWORK_STATUS_DISCONNECTED,
- s_pal_networkInterfacesSupported[index].clientArg);
+ s_pal_networkInterfacesSupported[index].clientArg);
}
break;
@@ -1297,7 +1208,7 @@ uint8_t pal_plat_getRttEstimate()
SocketAddress sa;
nsapi_error_t err;
- NetworkInterface* net;
+ NetworkInterface *net;
UDPSocket socket;
net = s_pal_networkInterfacesSupported[0].interface;
@@ -1326,7 +1237,7 @@ uint8_t pal_plat_getRttEstimate()
}
// Returned value is in milliseconds, convert to seconds and limit to uint8_t max
- rtt_temp = rtt_temp/1000;
+ rtt_temp = rtt_temp / 1000;
if (rtt_temp > UINT8_MAX) {
rtt_temp = UINT8_MAX;
}
@@ -1357,7 +1268,7 @@ uint16_t pal_plat_getStaggerEstimate(uint16_t data_amount)
PAL_LOG_DBG("pal_plat_getStaggerEstimate asking stack");
SocketAddress sa;
nsapi_error_t err;
- NetworkInterface* net;
+ NetworkInterface *net;
UDPSocket socket;
net = s_pal_networkInterfacesSupported[0].interface;
@@ -1393,50 +1304,40 @@ uint16_t pal_plat_getStaggerEstimate(uint16_t data_amount)
return stagger_rand;
}
-PAL_PRIVATE palStatus_t set_sock_options(PALSocketWrapper *socketObj, int optionLevel, int optionName, const void* optionValue, palSocketLength_t optionLength)
+PAL_PRIVATE palStatus_t set_sock_options(PALSocketWrapper *socketObj, int optionLevel, int optionName, const void *optionValue, palSocketLength_t optionLength)
{
int result = PAL_SUCCESS;
int socketOption = PAL_SOCKET_OPTION_ERROR;
socketOption = translateNSAPItoPALSocketOption(optionName);
- if (PAL_SOCKET_OPTION_ERROR != socketOption)
- {
- if (PAL_SO_REUSEADDR == optionName)
- {
+ if (PAL_SOCKET_OPTION_ERROR != socketOption) {
+ if (PAL_SO_REUSEADDR == optionName) {
result = socketObj->setsockopt(optionLevel, socketOption, optionValue, optionLength);
}
#if PAL_NET_TCP_AND_TLS_SUPPORT
else if (PAL_SO_KEEPIDLE == optionName ||
- PAL_SO_KEEPINTVL == optionName )
- {
- // Timeouts are in milliseconds
- uint32_t timeout = (*(int *)optionValue) * 1000;
- result = socketObj->setsockopt(optionLevel, socketOption, (void*)&timeout, sizeof(timeout));
+ PAL_SO_KEEPINTVL == optionName) {
+ // Timeouts are in milliseconds
+ uint32_t timeout = (*(int *)optionValue) * 1000;
+ result = socketObj->setsockopt(optionLevel, socketOption, (void *)&timeout, sizeof(timeout));
}
#endif
- else
- {
+ else {
result = socketObj->setsockopt(optionLevel, socketOption, optionValue, optionLength);
}
- if (result < 0)
- {
+ if (result < 0) {
result = translateErrorToPALError(result);
}
- }
- else
- {
- if ((PAL_SO_SNDTIMEO == optionName) || (PAL_SO_RCVTIMEO == optionName)) // timeouts in MBED API are not managed though socket options, bun instead via a different funciton call
- {
- int timeout = *((int*)optionValue);
+ } else {
+ if ((PAL_SO_SNDTIMEO == optionName) || (PAL_SO_RCVTIMEO == optionName)) { // timeouts in MBED API are not managed though socket options, bun instead via a different funciton call
+ int timeout = *((int *)optionValue);
// SO_xxxTIMEO should only affect blocking sockets - it only limits the block,
// whereas NSAPI's set_timeout is coupled with the blocking setting
if (!socketObj->isNonBlocking()) {
socketObj->set_timeout(timeout);
}
- }
- else
- {
+ } else {
result = PAL_ERR_SOCKET_OPTION_NOT_SUPPORTED;
}
}
diff --git a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/nanosimulator/Networking/pal_plat_network.c b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/nanosimulator/Networking/pal_plat_network.c
index f8246c607..0b8808b75 100644
--- a/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/nanosimulator/Networking/pal_plat_network.c
+++ b/mbed-client-pal/Source/Port/Reference-Impl/OS_Specific/nanosimulator/Networking/pal_plat_network.c
@@ -44,7 +44,7 @@ static struct {
} sock_control[NUMBER_OF_SOCKETS];
-static int8_t get_socket_handle(const palSocket_t* socket, int8_t* index)
+static int8_t get_socket_handle(const palSocket_t *socket, int8_t *index)
{
for (int i = 0; i < NUMBER_OF_SOCKETS; i++) {
if (sock_control[i].socket_id == (intptr_t)socket) {
@@ -60,10 +60,10 @@ static int8_t get_socket_handle(const palSocket_t* socket, int8_t* index)
void socket_callback(void *raw_param)
{
- const socket_callback_t *cb_event = (const socket_callback_t*)raw_param;
+ const socket_callback_t *cb_event = (const socket_callback_t *)raw_param;
if (cb_event != NULL && cb_event->event_type == SOCKET_DATA) {
int8_t index;
- int8_t socket_handle = get_socket_handle((const palSocket_t*)cb_event->socket_id, &index);
+ int8_t socket_handle = get_socket_handle((const palSocket_t *)cb_event->socket_id, &index);
if (socket_handle == -1) {
PAL_LOG_ERR("socket_callback - socket id not found!");
} else {
@@ -112,7 +112,7 @@ static int8_t address_pal2nanostack(const palSocketAddress_t *pal_addr, ns_addre
{
uint16_t port;
- if (pal_getSockAddrPort (pal_addr, &port) != PAL_SUCCESS) {
+ if (pal_getSockAddrPort(pal_addr, &port) != PAL_SUCCESS) {
return 0;
}
@@ -122,7 +122,7 @@ static int8_t address_pal2nanostack(const palSocketAddress_t *pal_addr, ns_addre
ns_addr->type = ADDRESS_IPV6;
ns_addr->identifier = port;
memcpy(ns_addr->address, &addr, sizeof(addr));
- return (sizeof (addr));
+ return (sizeof(addr));
} else {
return 0;
}
@@ -131,7 +131,7 @@ static int8_t address_pal2nanostack(const palSocketAddress_t *pal_addr, ns_addre
return 0;
}
-palStatus_t pal_plat_socketsInit(void* context)
+palStatus_t pal_plat_socketsInit(void *context)
{
(void)context;
@@ -140,7 +140,7 @@ palStatus_t pal_plat_socketsInit(void* context)
return PAL_SUCCESS;
}
-palStatus_t pal_plat_registerNetworkInterface(void* context, uint32_t* interfaceIndex)
+palStatus_t pal_plat_registerNetworkInterface(void *context, uint32_t *interfaceIndex)
{
(void)context;
(void)interfaceIndex;
@@ -153,13 +153,13 @@ palStatus_t pal_plat_unregisterNetworkInterface(uint32_t interfaceIndex)
return PAL_SUCCESS;
}
-palStatus_t pal_plat_socketsTerminate(void* context)
+palStatus_t pal_plat_socketsTerminate(void *context)
{
(void)context;
return PAL_SUCCESS;
}
-palStatus_t pal_plat_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palSocket_t* socket)
+palStatus_t pal_plat_socket(palSocketDomain_t domain, palSocketType_t type, bool nonBlockingSocket, uint32_t interfaceNum, palSocket_t *socket)
{
(void)interfaceNum;
(void)type;
@@ -172,12 +172,12 @@ palStatus_t pal_plat_socket(palSocketDomain_t domain, palSocketType_t type, bool
return PAL_ERR_NOT_SUPPORTED;
}
-palStatus_t pal_plat_setSocketOptions(palSocket_t socket, int optionName, const void* optionValue, palSocketLength_t optionLength)
+palStatus_t pal_plat_setSocketOptions(palSocket_t socket, int optionName, const void *optionValue, palSocketLength_t optionLength)
{
return pal_plat_setSocketOptionsWithLevel(socket, PAL_SOL_IPPROTO_IPV6, optionName, optionValue, optionLength);
}
-palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOptionLevelName_t optionLevel, int optionName, const void* optionValue, palSocketLength_t optionLength)
+palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOptionLevelName_t optionLevel, int optionName, const void *optionValue, palSocketLength_t optionLength)
{
int8_t index;
int8_t socket_handle = get_socket_handle(socket, &index);
@@ -200,6 +200,8 @@ palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOpti
int optionVal;
if (optionName == PAL_SO_IPV6_MULTICAST_HOPS) {
optionVal = SOCKET_IPV6_MULTICAST_HOPS;
+ } else if (optionName == PAL_SO_IPV6_TRAFFIC_CLASS) {
+ optionVal = SOCKET_IPV6_TCLASS;
} else {
return PAL_ERR_SOCKET_GENERIC;
}
@@ -214,14 +216,14 @@ palStatus_t pal_plat_setSocketOptionsWithLevel(palSocket_t socket, palSocketOpti
return PAL_SUCCESS;
}
-palStatus_t pal_plat_isNonBlocking(palSocket_t socket, bool* isNonBlocking)
+palStatus_t pal_plat_isNonBlocking(palSocket_t socket, bool *isNonBlocking)
{
*isNonBlocking = true;
return PAL_SUCCESS;
}
-palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t* myAddress, palSocketLength_t addressLength)
+palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t *myAddress, palSocketLength_t addressLength)
{
if (myAddress == NULL) {
return PAL_ERR_INVALID_ARGUMENT;
@@ -250,7 +252,7 @@ palStatus_t pal_plat_bind(palSocket_t socket, palSocketAddress_t* myAddress, pal
return PAL_SUCCESS;
}
-palStatus_t pal_plat_receiveFrom(palSocket_t socket, void* buffer, size_t length, palSocketAddress_t* from, palSocketLength_t* fromLength, size_t* bytesReceived)
+palStatus_t pal_plat_receiveFrom(palSocket_t socket, void *buffer, size_t length, palSocketAddress_t *from, palSocketLength_t *fromLength, size_t *bytesReceived)
{
if ((bytesReceived == NULL) || (from == NULL) || (fromLength == NULL)) {
return PAL_ERR_INVALID_ARGUMENT;
@@ -281,7 +283,7 @@ palStatus_t pal_plat_receiveFrom(palSocket_t socket, void* buffer, size_t length
}
}
-palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t length, const palSocketAddress_t* to, palSocketLength_t toLength, size_t* bytesSent)
+palStatus_t pal_plat_sendTo(palSocket_t socket, const void *buffer, size_t length, const palSocketAddress_t *to, palSocketLength_t toLength, size_t *bytesSent)
{
if ((bytesSent == NULL) || (to == NULL)) {
return PAL_ERR_INVALID_ARGUMENT;
@@ -300,7 +302,7 @@ palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t lengt
return PAL_ERR_SOCKET_INVALID_ADDRESS;
}
- int16_t ret = socket_sendto(socket_handle, &ns_addr, (void*)buffer, length);
+ int16_t ret = socket_sendto(socket_handle, &ns_addr, (void *)buffer, length);
if (ret < 0) {
PAL_LOG_ERR("pal_plat_sendTo - socket_sendto failed: %d", ret);
@@ -311,7 +313,7 @@ palStatus_t pal_plat_sendTo(palSocket_t socket, const void* buffer, size_t lengt
return PAL_SUCCESS;
}
-palStatus_t pal_plat_close(palSocket_t* socket)
+palStatus_t pal_plat_close(palSocket_t *socket)
{
int8_t index;
int8_t socket_index = get_socket_handle(*socket, &index);
@@ -340,7 +342,7 @@ palStatus_t pal_plat_close(palSocket_t* socket)
return PAL_SUCCESS;
}
-palStatus_t pal_plat_getNumberOfNetInterfaces(uint32_t* numInterfaces)
+palStatus_t pal_plat_getNumberOfNetInterfaces(uint32_t *numInterfaces)
{
if (numInterfaces == NULL) {
return (PAL_ERR_INVALID_ARGUMENT);
@@ -351,7 +353,7 @@ palStatus_t pal_plat_getNumberOfNetInterfaces(uint32_t* numInterfaces)
return PAL_SUCCESS;
}
-palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t * interfaceInfo)
+palStatus_t pal_plat_getNetInterfaceInfo(uint32_t interfaceNum, palNetInterfaceInfo_t *interfaceInfo)
{
(void)interfaceNum;
(void)interfaceInfo;
@@ -379,7 +381,7 @@ palStatus_t pal_plat_listen(palSocket_t socket, int backlog)
return PAL_SUCCESS;
}
-palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t* address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket, palAsyncSocketCallback_t callback, void* callbackArgument)
+palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t *address, palSocketLength_t *addressLen, palSocket_t *acceptedSocket, palAsyncSocketCallback_t callback, void *callbackArgument)
{
if (acceptedSocket == NULL) {
return PAL_ERR_INVALID_ARGUMENT;
@@ -407,7 +409,7 @@ palStatus_t pal_plat_accept(palSocket_t socket, palSocketAddress_t* address, pal
return PAL_SUCCESS;
}
-palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t* address, palSocketLength_t addressLen)
+palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t *address, palSocketLength_t addressLen)
{
if (address == NULL) {
return PAL_ERR_INVALID_ARGUMENT;
@@ -443,7 +445,7 @@ palStatus_t pal_plat_connect(palSocket_t socket, const palSocketAddress_t* addre
}
}
-palStatus_t pal_plat_recv(palSocket_t socket, void *buffer, size_t len, size_t* receivedDataSize)
+palStatus_t pal_plat_recv(palSocket_t socket, void *buffer, size_t len, size_t *receivedDataSize)
{
if (receivedDataSize == NULL) {
return (PAL_ERR_INVALID_ARGUMENT);
@@ -486,7 +488,7 @@ palStatus_t pal_plat_send(palSocket_t socket, const void *buf, size_t len, size_
return PAL_ERR_ITEM_NOT_EXIST;
}
- int16_t ret = socket_send(socket_handle, (void*)buf, len);
+ int16_t ret = socket_send(socket_handle, (void *)buf, len);
PAL_LOG_DBG("pal_plat_send - socket_send return %d", ret);
@@ -511,8 +513,8 @@ palStatus_t pal_plat_asynchronousSocket(palSocketDomain_t domain,
bool nonBlockingSocket,
uint32_t interfaceNum,
palAsyncSocketCallback_t callback,
- void* callbackArgument,
- palSocket_t* socket)
+ void *callbackArgument,
+ palSocket_t *socket)
{
uint8_t protocol;
int8_t socket_id;
@@ -583,64 +585,63 @@ palStatus_t pal_plat_setConnectionStatusCallback(uint32_t interfaceIndex, connec
PAL_PRIVATE palStatus_t translateErrorToPALError(int errnoValue)
{
palStatus_t status;
- switch (errnoValue)
- {
- case EAI_MEMORY:
- status = PAL_ERR_NO_MEMORY;
- break;
- case EWOULDBLOCK:
- status = PAL_ERR_SOCKET_WOULD_BLOCK;
- break;
- case ENOTSOCK:
- status = PAL_ERR_SOCKET_INVALID_VALUE;
- break;
- case EPERM:
- case EACCES:
- status = PAL_ERR_SOCKET_OPERATION_NOT_PERMITTED;
- break;
- case ETIMEDOUT:
- status = PAL_ERR_TIMEOUT_EXPIRED;
- break;
- case EISCONN:
- status = PAL_ERR_SOCKET_ALREADY_CONNECTED;
- break;
- case EAI_FAMILY:
- status = PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY;
- break;
- case EINPROGRESS:
- status = PAL_ERR_SOCKET_IN_PROGRES;
- break;
- case EALREADY:
- status = PAL_ERR_SOCKET_ALREADY_CONNECTED;
- break;
- case EINVAL:
- status = PAL_ERR_SOCKET_INVALID_VALUE;
- break;
- case EADDRINUSE:
- status = PAL_ERR_SOCKET_ADDRESS_IN_USE;
- break;
- case ECONNABORTED:
- status = PAL_ERR_SOCKET_CONNECTION_ABORTED;
- break;
- case ECONNRESET:
- case ECONNREFUSED:
- status = PAL_ERR_SOCKET_CONNECTION_RESET;
- break;
- case ENOBUFS:
- case ENOMEM:
- status = PAL_ERR_SOCKET_NO_BUFFERS;
- break;
- case EINTR:
- status = PAL_ERR_SOCKET_INTERRUPTED;
- break;
- case EAI_AGAIN:
- case EAI_NONAME:
- status = PAL_ERR_SOCKET_DNS_ERROR;
- break;
- default:
- PAL_LOG_ERR("translateErrorToPALError() cannot translate %d", errnoValue);
- status = PAL_ERR_SOCKET_GENERIC;
- break;
+ switch (errnoValue) {
+ case EAI_MEMORY:
+ status = PAL_ERR_NO_MEMORY;
+ break;
+ case EWOULDBLOCK:
+ status = PAL_ERR_SOCKET_WOULD_BLOCK;
+ break;
+ case ENOTSOCK:
+ status = PAL_ERR_SOCKET_INVALID_VALUE;
+ break;
+ case EPERM:
+ case EACCES:
+ status = PAL_ERR_SOCKET_OPERATION_NOT_PERMITTED;
+ break;
+ case ETIMEDOUT:
+ status = PAL_ERR_TIMEOUT_EXPIRED;
+ break;
+ case EISCONN:
+ status = PAL_ERR_SOCKET_ALREADY_CONNECTED;
+ break;
+ case EAI_FAMILY:
+ status = PAL_ERR_SOCKET_INVALID_ADDRESS_FAMILY;
+ break;
+ case EINPROGRESS:
+ status = PAL_ERR_SOCKET_IN_PROGRES;
+ break;
+ case EALREADY:
+ status = PAL_ERR_SOCKET_ALREADY_CONNECTED;
+ break;
+ case EINVAL:
+ status = PAL_ERR_SOCKET_INVALID_VALUE;
+ break;
+ case EADDRINUSE:
+ status = PAL_ERR_SOCKET_ADDRESS_IN_USE;
+ break;
+ case ECONNABORTED:
+ status = PAL_ERR_SOCKET_CONNECTION_ABORTED;
+ break;
+ case ECONNRESET:
+ case ECONNREFUSED:
+ status = PAL_ERR_SOCKET_CONNECTION_RESET;
+ break;
+ case ENOBUFS:
+ case ENOMEM:
+ status = PAL_ERR_SOCKET_NO_BUFFERS;
+ break;
+ case EINTR:
+ status = PAL_ERR_SOCKET_INTERRUPTED;
+ break;
+ case EAI_AGAIN:
+ case EAI_NONAME:
+ status = PAL_ERR_SOCKET_DNS_ERROR;
+ break;
+ default:
+ PAL_LOG_ERR("translateErrorToPALError() cannot translate %d", errnoValue);
+ status = PAL_ERR_SOCKET_GENERIC;
+ break;
}
return status;
}
@@ -648,7 +649,7 @@ PAL_PRIVATE palStatus_t translateErrorToPALError(int errnoValue)
#if PAL_NET_DNS_SUPPORT
-palStatus_t pal_plat_getAddressInfo(const char *url, palSocketAddress_t *address, palSocketLength_t* length)
+palStatus_t pal_plat_getAddressInfo(const char *url, palSocketAddress_t *address, palSocketLength_t *length)
{
if ((url == NULL) || (address == NULL) || (length == NULL)) {
return PAL_ERR_INVALID_ARGUMENT;
@@ -661,10 +662,10 @@ palStatus_t pal_plat_getAddressInfo(const char *url, palSocketAddress_t *address
struct addrinfo *addr_result;
struct addrinfo hints;
- memset (&hints, 0, sizeof (hints));
+ memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
int res = getaddrinfo(url, NULL, &hints, &addr_result);
- if(res < 0) {
+ if (res < 0) {
// getaddrinfo returns EAI-error. In case of EAI_SYSTEM, the error
// is 'Other system error, check errno for details'
// (http://man7.org/linux/man-pages/man3/getaddrinfo.3.html#RETURN_VALUE)
@@ -677,7 +678,7 @@ palStatus_t pal_plat_getAddressInfo(const char *url, palSocketAddress_t *address
}
} else {
if (addr_result != NULL) {
- int error = getnameinfo((struct sockaddr*)addr_result->ai_addr, addr_result->ai_addrlen, ip_addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ int error = getnameinfo((struct sockaddr *)addr_result->ai_addr, addr_result->ai_addrlen, ip_addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (error == 0) {
ns_address_t ns_address;
int8_t ns_addr_len = strlen(ip_addr);
diff --git a/mbed-client-pal/Test/PAL_Modules/Networking/pal_socket_test.c b/mbed-client-pal/Test/PAL_Modules/Networking/pal_socket_test.c
index 6540201af..439714534 100644
--- a/mbed-client-pal/Test/PAL_Modules/Networking/pal_socket_test.c
+++ b/mbed-client-pal/Test/PAL_Modules/Networking/pal_socket_test.c
@@ -15,7 +15,7 @@
*******************************************************************************/
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "unity.h"
#include "unity_fixture.h"
#include "test_runners.h"
@@ -68,7 +68,9 @@ PAL_PRIVATE palSocket_t g_testSockets[PAL_NET_TEST_SOCKETS] = {0,0,0,0};
#define PAL_NET_TEST_BUFFERED_UDP_MESSAGE_SIZE (1024 * 256)
PAL_PRIVATE uint8_t *g_testRecvBuffer = NULLPTR;
PAL_PRIVATE uint8_t *g_testSendBuffer = NULLPTR;
+#ifdef TARGET_LIKE_MBED
PAL_PRIVATE bool g_interfaceConnected = false;
+#endif
#define PAL_NET_TEST_ECHO_TEST_SERVER_ADDRESS "echo.mbedcloudtesting.com"
// the tests expect to have guaranteed forward progress, even if they fail. So the semaphore
@@ -156,21 +158,30 @@ PAL_PRIVATE void socketCallback1( void * arg)
static palSemaphoreID_t s_semaphoreID = NULLPTR;
static palSemaphoreID_t s_semaphoreID3 = NULLPTR;
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
static palSemaphoreID_t s_asyncDnsSemaphore = NULLPTR;
// flag marking if the pal_getAddressInfoAsync callback has been invoked
PAL_PRIVATE bool g_getAddressInfoAsyncCallbackInvoked = false;
-
+#if (PAL_DNS_API_VERSION == 3)
+static palAddressInfo_t *global_addrInfo = NULLPTR;
+static palDNSQuery_t dns_query_t = 0;
+// callback invoked from the call to pal_getAddressInfoAsync
+PAL_PRIVATE void getAddressInfoAsyncCallback(const char* url, palAddressInfo_t *addrInfo, palStatus_t status, void* callbackArgument)
+{
+ global_addrInfo = addrInfo;
+#else
// callback invoked from the call to pal_getAddressInfoAsync
PAL_PRIVATE void getAddressInfoAsyncCallback(const char* url, palSocketAddress_t* address, palStatus_t status, void* callbackArgument)
{
+#endif
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
g_getAddressInfoAsyncCallbackInvoked = true;
pal_osSemaphoreRelease(s_asyncDnsSemaphore);
}
+
#endif
PAL_PRIVATE palStatus_t doDnsQuery(const char* hostname, palSocketAddress_t *address, palSocketLength_t *addrlen)
@@ -186,6 +197,20 @@ PAL_PRIVATE palStatus_t doDnsQuery(const char* hostname, palSocketAddress_t *add
NULL);
result = pal_osSemaphoreWait(s_asyncDnsSemaphore, 5000, NULL);
+#elif (PAL_DNS_API_VERSION == 3)
+ result = pal_osSemaphoreCreate(0, &s_asyncDnsSemaphore);
+ TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result);
+ result = pal_getAddressInfoAsync(hostname,
+ &getAddressInfoAsyncCallback,
+ NULL,
+ &dns_query_t);
+ result = pal_osSemaphoreWait(s_asyncDnsSemaphore, 5000, NULL);
+ result = pal_free_addressinfoAsync(dns_query_t);
+ result = pal_getDNSAddress(global_addrInfo, 0, address);
+ *addrlen = sizeof(palSocketAddress_t);
+ pal_freeAddrInfo(global_addrInfo);
+ global_addrInfo = NULLPTR;
+ dns_query_t = 0;
#else
result = pal_getAddressInfo(hostname, address, addrlen);
#endif
@@ -777,7 +802,7 @@ TEST(pal_socket, ServerSocketScenario)
/*#S3*/
uint32_t rand_number = 0;
uint16_t incoming_port;
-
+
#if !PAL_USE_HW_TRNG
palStatus_t status = PAL_SUCCESS;
// If no hardware trng - entropy must be injected for random to work
@@ -1334,7 +1359,7 @@ PAL_PRIVATE void socketTCPBuffered(size_t bufSize)
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
/*#1*/
- result = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback3, &g_testSockets[0]);
+ result = pal_asynchronousSocket(address.addressType, PAL_SOCK_STREAM, true, 0, socketCallback3, &g_testSockets[0]);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
/*#3*/
@@ -1739,7 +1764,7 @@ PAL_PRIVATE void echo_test(bool tcp)
result = pal_osSemaphoreCreate(1, &s_semaphoreID3);
TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result);
- result = pal_asynchronousSocket(PAL_AF_INET, sockType, true, 0, socketCallback3, &g_testSockets[0]);
+ result = pal_asynchronousSocket(address.addressType, sockType, true, 0, socketCallback3, &g_testSockets[0]);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
/*#3*/
@@ -1750,7 +1775,7 @@ PAL_PRIVATE void echo_test(bool tcp)
if (sockType == PAL_SOCK_STREAM)
{
do {
- result = pal_connect(g_testSockets[0], &address, 16);
+ result = pal_connect(g_testSockets[0], &address, addrlen);
pal_osSemaphoreWait(s_semaphoreID3, 10000, &temp);
} while (result == PAL_ERR_SOCKET_IN_PROGRES || result == PAL_ERR_SOCKET_WOULD_BLOCK);
@@ -1768,7 +1793,7 @@ PAL_PRIVATE void echo_test(bool tcp)
}
else
{
- result = pal_sendTo(g_testSockets[0], message, strlen(message), &address, 16, &sent);
+ result = pal_sendTo(g_testSockets[0], message, strlen(message), &address, addrlen, &sent);
}
pal_osSemaphoreWait(s_semaphoreID3, 1000, &temp);
} while (PAL_ERR_SOCKET_WOULD_BLOCK == result);
diff --git a/mbed-client-pal/Test/PAL_Modules/SOTP/pal_SOTP_test.c b/mbed-client-pal/Test/PAL_Modules/SOTP/pal_SOTP_test.c
index c8fe2feef..d003554ee 100644
--- a/mbed-client-pal/Test/PAL_Modules/SOTP/pal_SOTP_test.c
+++ b/mbed-client-pal/Test/PAL_Modules/SOTP/pal_SOTP_test.c
@@ -15,7 +15,7 @@
*******************************************************************************/
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "unity.h"
#include "unity_fixture.h"
#include "test_runners.h"
diff --git a/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test.c b/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test.c
index 0b467e7cb..3b7bd23c0 100644
--- a/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test.c
+++ b/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test.c
@@ -18,7 +18,7 @@
#include "unity.h"
#include "unity_fixture.h"
#include "pal.h"
-#include "pal_Crypto.h"
+#include "cs_pal_crypto.h"
#include "pal_tls_utils.h"
#include "storage_kcm.h"
#include "test_runners.h"
@@ -62,17 +62,19 @@ PAL_PRIVATE palSocket_t g_socket = 0;
extern void * g_palTestTLSInterfaceCTX; // this is set by the palTestMain funciton
PAL_PRIVATE uint32_t g_interfaceCTXIndex = 0;
-#if ((PAL_USE_SECURE_TIME == 1) && (PAL_USE_INTERNAL_FLASH == 1))
+#if (PAL_USE_INTERNAL_FLASH == 1)
PAL_PRIVATE uint8_t g_trustedServerID[PAL_CERT_ID_SIZE] __attribute__((aligned(4))) = { 0 };
PAL_PRIVATE size_t g_actualServerIDSize = 0;
#endif
+#if ((PAL_USE_SECURE_TIME == 1) && (PAL_ENABLE_X509 == 1))
PAL_PRIVATE palMutexID_t g_mutex1 = NULLPTR;
#if (PAL_ENABLE_X509 == 1)
PAL_PRIVATE palMutexID_t g_mutex2 = NULLPTR;
#endif
PAL_PRIVATE palMutexID_t g_mutexHandShake1 = NULLPTR;
PAL_PRIVATE bool g_retryHandshake = false;
+#endif
#define PAL_TLS_INT32_CHECK_NOT_EQUAL_GOTO_FINISH(a, b) \
if (a != b) \
@@ -81,18 +83,48 @@ PAL_PRIVATE bool g_retryHandshake = false;
goto finish;\
}
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
static palSemaphoreID_t s_asyncDnsSemaphore = NULLPTR;
// callback invoked from the call to pal_getAddressInfoAsync
+#if (PAL_DNS_API_VERSION == 2)
+
PAL_PRIVATE void getAddressInfoAsyncCallback(const char* url, palSocketAddress_t* address, palStatus_t status, void* callbackArgument)
{
+#else // (PAL_DNS_API_VERSION == 3)
+static palAddressInfo_t *global_addrInfo = NULLPTR;
+static palDNSQuery_t dns_query_t = 0;
+PAL_PRIVATE void getAddressInfoAsyncCallback(const char* url, palAddressInfo_t *addrInfo, palStatus_t status, void* callbackArgument)
+{
+ global_addrInfo = addrInfo;
+#endif
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
pal_osSemaphoreRelease(s_asyncDnsSemaphore);
}
#endif
+#if !(PAL_USE_SECURE_TIME)
+// If testing without PAL secure time, some tests require faking the time to mbedtls to get desired effect
+// from certificate verification
+#include "mbedtls/ssl.h"
+#include "mbedtls/platform.h"
+static mbedtls_time_t time_to_return;
+static mbedtls_time_t definately_in_future = 1935316090; // Wednesday, April 30, 2031 11:48:10 AM
+static int return_fake_time = 0;
+mbedtls_time_t pal_mbedtlsTimeCB(mbedtls_time_t* timer)
+{
+ if(return_fake_time) {
+ return time_to_return++;
+ }
+ else {
+ // this is what mbedtls calls by default if mbedtls_platform_set_time was not called
+ return MBEDTLS_PLATFORM_STD_TIME(timer);
+ }
+}
+#endif
+
+
PAL_PRIVATE palStatus_t doDnsQuery(const char* hostname, palSocketAddress_t *address, palSocketLength_t *addrlen)
{
palStatus_t result = PAL_SUCCESS;
@@ -106,6 +138,20 @@ PAL_PRIVATE palStatus_t doDnsQuery(const char* hostname, palSocketAddress_t *add
NULL);
result = pal_osSemaphoreWait(s_asyncDnsSemaphore, 5000, NULL);
+#elif (PAL_DNS_API_VERSION == 3)
+ result = pal_osSemaphoreCreate(0, &s_asyncDnsSemaphore);
+ TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, result);
+ result = pal_getAddressInfoAsync(hostname,
+ &getAddressInfoAsyncCallback,
+ NULL,
+ &dns_query_t);
+ result = pal_osSemaphoreWait(s_asyncDnsSemaphore, 5000, NULL);
+ result = pal_free_addressinfoAsync(dns_query_t);
+ result = pal_getDNSAddress(global_addrInfo, 0, address);
+ *addrlen = sizeof(palSocketAddress_t);
+ pal_freeAddrInfo(global_addrInfo);
+ global_addrInfo = NULLPTR;
+ dns_query_t = 0;
#else
result = pal_getAddressInfo(hostname, address, addrlen);
#endif
@@ -123,6 +169,7 @@ PAL_PRIVATE void socketCallback1( void * arg)
}
static void setCredentials(palTLSConfHandle_t handle);
+static void setCredentialsWrongCA(palTLSConfHandle_t handle);
static void do_handshake(palTLSTransportMode_t mode, bool enable_session_storing);
//! This structre is for tests only and MUST be the same structure as in the pal_TLS.c file
@@ -193,10 +240,16 @@ TEST_SETUP(pal_tls)
status = pal_osSetTime(currentTime);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+#if !(PAL_USE_SECURE_TIME)
+ mbedtls_platform_set_time(pal_mbedtlsTimeCB);
+#endif
}
TEST_TEAR_DOWN(pal_tls)
{
+#if !(PAL_USE_SECURE_TIME)
+ return_fake_time = 0;
+#endif
if (0 != g_socket)
{
pal_close(&g_socket);
@@ -449,8 +502,8 @@ TEST(pal_tls, tlsCACertandPSK)
*
* | # | Step | Expected |
* |---|--------------------------------|-------------|
-* | 1 | Create a TCP socket. | PAL_SUCCESS |
-* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 1 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Create a TCP socket. | PAL_SUCCESS |
* | 3 | Set the server port. | PAL_SUCCESS |
* | 4 | Connect the TCP socket to the server. | PAL_SUCCESS |
* | 5 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
@@ -490,10 +543,6 @@ TEST(pal_tls, tlsHandshakeTCP)
struct server_address server;
/*#1*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#2*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
@@ -504,6 +553,10 @@ TEST(pal_tls, tlsHandshakeTCP)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#2*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
tlsSocket.addressLength = addressLength;
tlsSocket.socket = g_socket;
@@ -559,7 +612,7 @@ TEST(pal_tls, tlsHandshakeTCP)
curTimeInSec = pal_osGetTime();
TEST_ASSERT_TRUE(curTimeInSec >= minSecSinceEpoch);
timePassedInSec = curTimeInSec - minSecSinceEpoch;
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while ((PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status) &&
@@ -617,8 +670,8 @@ TEST(pal_tls, tlsHandshakeTCP)
*
* | # | Step | Expected |
* |---|--------------------------------|-------------|
-* | 1 | Create a UDP socket. | PAL_SUCCESS |
-* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 1 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Create a UDP socket. | PAL_SUCCESS |
* | 3 | Set the server port. | PAL_SUCCESS |
* | 4 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
* | 5 | Initialize the TLS context using `pal_initTLS`. | PAL_SUCCESS |
@@ -654,16 +707,12 @@ TEST(pal_tls, tlsHandshakeUDP)
palTLSSocket_t tlsSocket = {g_socket, &socketAddr, 0, transportationMode};
int32_t verifyResult = 0;
struct server_address server;
-
- /*#1*/
int32_t temp;
- status = pal_osSemaphoreCreate(1, &s_semaphoreID);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_DGRAM, true, 0, socketCallback1, &g_socket);
+ status = pal_osSemaphoreCreate(1, &s_semaphoreID);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
- /*#2*/
+ /*#1*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
@@ -673,6 +722,10 @@ TEST(pal_tls, tlsHandshakeUDP)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#2*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_DGRAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
tlsSocket.addressLength = addressLength;
tlsSocket.socket = g_socket;
@@ -711,7 +764,7 @@ TEST(pal_tls, tlsHandshakeUDP)
/*#9*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -763,8 +816,8 @@ TEST(pal_tls, tlsHandshakeUDP)
*
* | # | Step | Expected |
* |---|--------------------------------|-------------|
-* | 1 | Create a UDP socket. | PAL_SUCCESS |
-* | 2 | Perform a DNS lookup on server adderss. | PAL_SUCCESS |
+* | 1 | Perform a DNS lookup on server adderss. | PAL_SUCCESS |
+* | 2 | Create a UDP socket. | PAL_SUCCESS |
* | 3 | Set the server port. | PAL_SUCCESS |
* | 4 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
* | 5 | Initialize the TLS context using `pal_initTLS`. | PAL_SUCCESS |
@@ -792,19 +845,14 @@ TEST(pal_tls, tlsHandshakeUDPTimeOut)
#endif
palTLSSocket_t tlsSocket = { g_socket, &socketAddr, 0, transportationMode };
struct server_address server;
-
+ int32_t temp;
uint64_t curTimeInSec;
const uint64_t minSecSinceEpoch = PAL_MIN_SEC_FROM_EPOCH + 1; //At least 47 years passed from 1.1.1970 in seconds
- /*#1*/
- int32_t temp;
status = pal_osSemaphoreCreate(1, &s_semaphoreID);
TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, status);
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_DGRAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#2*/
+ /*#1*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
if (PAL_SUCCESS != status)
@@ -813,6 +861,10 @@ TEST(pal_tls, tlsHandshakeUDPTimeOut)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#2*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_DGRAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
tlsSocket.addressLength = addressLength;
tlsSocket.socket = g_socket;
@@ -854,7 +906,7 @@ TEST(pal_tls, tlsHandshakeUDPTimeOut)
/*#9*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -885,8 +937,8 @@ TEST(pal_tls, tlsHandshakeUDPTimeOut)
*
* | # | Step | Expected |
* |---|--------------------------------|-------------|
-* | 1 | Create a TCP socket. | PAL_SUCCESS |
-* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 1 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Create a TCP socket. | PAL_SUCCESS |
* | 3 | Set the server port. | PAL_SUCCESS |
* | 4 | Connect the TCP socket to the server. | PAL_SUCCESS |
* | 5 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
@@ -927,16 +979,12 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M)
uint64_t initialTime = 0;
int32_t verifyResult = 0;
struct server_address server;
-
int32_t temp;
+
status = pal_osSemaphoreCreate(1, &s_semaphoreID);
TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, status);
/*#1*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#2*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
if (PAL_SUCCESS != status)
@@ -945,6 +993,10 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#2*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
tlsSocket.addressLength = addressLength;
tlsSocket.socket = g_socket;
@@ -987,7 +1039,7 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M)
/*#10*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -1064,8 +1116,8 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M)
* |---|--------------------------------|-------------|
* | 1 | Get saved time from storage, move backward half day and set time to RAM | PAL_SUCCESS |
* | 2 | Update `STORAGE_RBP_SAVED_TIME_NAME` directly in storage to the new time from #1 | PAL_SUCCESS |
-* | 3 | Create a TCP socket. | PAL_SUCCESS |
-* | 4 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 3 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 4 | Create a TCP socket. | PAL_SUCCESS |
* | 5 | Set the server port. | PAL_SUCCESS |
* | 6 | Connect the TCP socket to the server. | PAL_SUCCESS |
* | 7 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
@@ -1125,10 +1177,6 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M_NoTimeUpdate)
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
/*#3*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#4*/
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
if (PAL_SUCCESS != status)
{
@@ -1136,6 +1184,10 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M_NoTimeUpdate)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#4*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
/*#5*/
status = pal_setSockAddrPort(&socketAddr, server.port);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
@@ -1182,7 +1234,7 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M_NoTimeUpdate)
/*#11*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -1253,13 +1305,14 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M_NoTimeUpdate)
/**
-* @brief Test TLS handshake (TCP) with future time to make handshake to fail due to bad cert time from server.
+* @brief Test TLS handshake (TCP) with future time to make handshake to fail when PAL_USE_SECURE_TIME is set
+* and pass if unset, due to bad cert time from server.
*
*
* | # | Step | Expected |
* |---|--------------------------------|-------------|
-* | 1 | Create a TCP socket. | PAL_SUCCESS |
-* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 1 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Create a TCP socket. | PAL_SUCCESS |
* | 3 | Set the server port. | PAL_SUCCESS |
* | 4 | Connect the TCP socket to the server. | PAL_SUCCESS |
* | 5 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
@@ -1267,7 +1320,7 @@ TEST(pal_tls, tlsHandshakeTCP_FutureLWM2M_NoTimeUpdate)
* | 7 | Set the certificate and keys. | PAL_SUCCESS |
* | 8 | Set the socket chain to the configuration using `pal_tlsSetSocket`. | PAL_SUCCESS |
* | 9 | Setsystem time to be far in the future `pal_osSetTime`. | PAL_SUCCESS |
-* | 10 | Perform a TLS handshake with the server using `pal_handShake`. | PAL_ERR_X509_CERT_VERIFY_FAILED |
+* | 10 | Perform a TLS handshake with the server using `pal_handShake`. | PAL_ERR_X509_CERT_VERIFY_FAILED OR PAL_SUCCESS |
* | 11 | Verify the handshake result using `pal_sslGetVerifyResult`. | PAL_ERR_X509_BADCERT_EXPIRED |
* | 12 | Set tme back to the original time before the test. | PAL_SUCCESS |
* | 13 | Uninitialize the TLS context using `pal_freeTLS`. | PAL_SUCCESS |
@@ -1279,7 +1332,7 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
#ifndef MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT
-#if ((PAL_USE_SECURE_TIME == 1) && (PAL_USE_INTERNAL_FLASH == 1))
+#if (PAL_USE_INTERNAL_FLASH)
palStatus_t status = PAL_SUCCESS;
palTLSConfHandle_t palTLSConf = NULLPTR;
palTLSHandle_t palTLSHandle = NULLPTR;
@@ -1287,9 +1340,11 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
palSocketAddress_t socketAddr = {0};
palSocketLength_t addressLength = 0;
palTLSSocket_t tlsSocket = { g_socket, &socketAddr, 0, transportationMode };
+#if PAL_USE_SECURE_TIME
uint64_t futureTime = 2145542642; //Wed, 27 Dec 2037 16:04:02 GMT
uint64_t currentTime = 0;
size_t actualSavedTimeSize = 0;
+#endif
int32_t verifyResult = 0;
struct server_address server;
@@ -1301,10 +1356,6 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
do_handshake(PAL_TLS_MODE, false);
/*#1*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#2*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
@@ -1314,6 +1365,10 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#2*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
tlsSocket.addressLength = addressLength;
tlsSocket.socket = g_socket;
@@ -1359,6 +1414,7 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
}
/*#9*/
+#if PAL_USE_SECURE_TIME
status = storage_rbp_read(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t*)¤tTime, sizeof(currentTime), &actualSavedTimeSize);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
status = pal_osSetTime(futureTime);
@@ -1368,15 +1424,21 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
pal_tlsConfigurationFree(&palTLSConf);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
}
+#else
+ // Set time to future
+ return_fake_time = 1;
+ time_to_return = definately_in_future;
+#endif
/*#10*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
+#if PAL_USE_SECURE_TIME
if (PAL_ERR_X509_CERT_VERIFY_FAILED != status)
{
pal_osSetTime(currentTime);
@@ -1384,20 +1446,32 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
pal_tlsConfigurationFree(&palTLSConf);
TEST_ASSERT_EQUAL_HEX(PAL_ERR_X509_CERT_VERIFY_FAILED, status);
}
+#else
+ if (PAL_SUCCESS != status)
+ {
+ pal_freeTLS(&palTLSHandle);
+ pal_tlsConfigurationFree(&palTLSConf);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+#endif
/*#11*/
status = pal_sslGetVerifyResultExtended(palTLSHandle, &verifyResult);
if ((PAL_ERR_X509_CERT_VERIFY_FAILED != status) || (0 == (PAL_ERR_X509_BADCERT_EXPIRED & verifyResult)))
{
+#if PAL_USE_SECURE_TIME
pal_osSetTime(currentTime);
+#endif
pal_freeTLS(&palTLSHandle);
pal_tlsConfigurationFree(&palTLSConf);
TEST_ASSERT_TRUE(PAL_ERR_X509_BADCERT_EXPIRED & verifyResult);
}
+#if PAL_USE_SECURE_TIME
/*#12*/
status = pal_osSetTime(currentTime);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+#endif
/*#13*/
status = pal_freeTLS(&palTLSHandle);
@@ -1414,19 +1488,19 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
status = pal_close(&g_socket);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+#if PAL_USE_SECURE_TIME
/*#15*/
status = storage_rbp_read(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t*)¤tTime, sizeof(currentTime), &actualSavedTimeSize);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
TEST_ASSERT_TRUE(futureTime > currentTime);
+#endif
#else
- TEST_IGNORE_MESSAGE("Ignored, PAL_USE_SECURE_TIME or PAL_USE_INTERNAL_FLASH not set");
+ TEST_IGNORE_MESSAGE("Ignored, PAL_USE_INTERNAL_FLASH not set");
#endif
#else //MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
TEST_IGNORE_MESSAGE("Ignored, MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT is defined");
#endif
-
-
}
/**
@@ -1435,8 +1509,8 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredLWM2MCert)
*
* | # | Step | Expected |
* |---|--------------------------------|-------------|
-* | 1 | Create a TCP socket. | PAL_SUCCESS |
-* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 1 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Create a TCP socket. | PAL_SUCCESS |
* | 3 | Set the server port. | PAL_SUCCESS |
* | 4 | Parse the CA cert. | PAL_SUCCESS |
* | 5 | Get the CA cert ID. | PAL_SUCCESS |
@@ -1484,10 +1558,6 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredServerCert_Trusted)
TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, status);
/*#1*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#2*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
if (PAL_SUCCESS != status)
@@ -1496,6 +1566,10 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredServerCert_Trusted)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#1*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
/*#3*/
status = pal_setSockAddrPort(&socketAddr, server.port);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
@@ -1587,7 +1661,7 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredServerCert_Trusted)
/*#13*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -1698,8 +1772,8 @@ TEST(pal_tls, tlsHandshakeTCP_ExpiredServerCert_Trusted)
* | # | Step | Expected |
* |---|--------------------------------|-------------|
* | 1 | Get saved time from storage, move backward half day and set time to RAM | PAL_SUCCESS |
-* | 2 | Create a TCP socket. | PAL_SUCCESS |
-* | 3 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 3 | Create a TCP socket. | PAL_SUCCESS |
* | 4 | Set the server port. | PAL_SUCCESS |
* | 5 | Parse the CA cert. | PAL_SUCCESS |
* | 6 | Get the CA cert ID. | PAL_SUCCESS |
@@ -1757,10 +1831,6 @@ TEST(pal_tls, tlsHandshakeTCP_FutureTrustedServer_NoTimeUpdate)
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
/*#2*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#3*/
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
if (PAL_SUCCESS != status)
@@ -1769,6 +1839,10 @@ TEST(pal_tls, tlsHandshakeTCP_FutureTrustedServer_NoTimeUpdate)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#3*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
/*#4*/
status = pal_setSockAddrPort(&socketAddr, server.port);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
@@ -1854,7 +1928,7 @@ TEST(pal_tls, tlsHandshakeTCP_FutureTrustedServer_NoTimeUpdate)
/*#13*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -1959,8 +2033,8 @@ TEST(pal_tls, tlsHandshakeTCP_FutureTrustedServer_NoTimeUpdate)
* | # | Step | Expected |
* |---|--------------------------------|-------------|
* | 1 | Get saved time from storage, move forward half day and set time to RAM | PAL_SUCCESS |
-* | 2 | Create a TCP socket. | PAL_SUCCESS |
-* | 3 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 3 | Create a TCP socket. | PAL_SUCCESS |
* | 4 | Set the server port. | PAL_SUCCESS |
* | 5 | Parse the CA cert. | PAL_SUCCESS |
* | 6 | Get the CA cert ID. | PAL_SUCCESS |
@@ -2020,10 +2094,6 @@ TEST(pal_tls, tlsHandshakeTCP_NearPastTrustedServer_NoTimeUpdate)
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
/*#2*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
- /*#3*/
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
if (PAL_SUCCESS != status)
{
@@ -2031,6 +2101,10 @@ TEST(pal_tls, tlsHandshakeTCP_NearPastTrustedServer_NoTimeUpdate)
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ /*#3*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
/*#4*/
status = pal_setSockAddrPort(&socketAddr, server.port);
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
@@ -2116,7 +2190,7 @@ TEST(pal_tls, tlsHandshakeTCP_NearPastTrustedServer_NoTimeUpdate)
/*#13*/
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
@@ -2229,16 +2303,6 @@ static void do_handshake(palTLSTransportMode_t mode, bool enable_session_storing
palTLSSocket_t tlsSocket = { g_socket, &socketAddr, 0, transportationMode };
struct server_address server;
- if (mode == PAL_TLS_MODE)
- {
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
- }
- else
- {
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_DGRAM, true, 0, socketCallback1, &g_socket);
- }
- TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
-
parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
@@ -2249,6 +2313,16 @@ static void do_handshake(palTLSTransportMode_t mode, bool enable_session_storing
}
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ if (mode == PAL_TLS_MODE)
+ {
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ }
+ else
+ {
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_DGRAM, true, 0, socketCallback1, &g_socket);
+ }
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
tlsSocket.addressLength = addressLength;
tlsSocket.socket = g_socket;
@@ -2298,7 +2372,7 @@ static void do_handshake(palTLSTransportMode_t mode, bool enable_session_storing
do
{
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
}
while ((PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status));
@@ -2346,12 +2420,12 @@ static palStatus_t ThreadHandshakeTCP()
mutexWait = true;
/*#1*/
- status = pal_asynchronousSocket(PAL_AF_INET, PAL_SOCK_STREAM, true, 0, socketCallback1, &socketTCP);
+ parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
+ status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
PAL_TLS_INT32_CHECK_NOT_EQUAL_GOTO_FINISH(PAL_SUCCESS, status);
/*#2*/
- parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
- status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &socketTCP);
PAL_TLS_INT32_CHECK_NOT_EQUAL_GOTO_FINISH(PAL_SUCCESS, status);
tlsSocket.addressLength = addressLength;
@@ -2409,7 +2483,7 @@ static palStatus_t ThreadHandshakeTCP()
pal_osDelay(600);
}
}
- status = pal_handShake(palTLSHandle, palTLSConf);
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
pal_osDelay(1000);
}
while ( (PAL_ERR_TLS_WANT_READ == status) || (PAL_ERR_TLS_WANT_WRITE == status));
@@ -2708,6 +2782,228 @@ TEST(pal_tls, tlsHandshake_SessionResume)
}
+/**
+* @brief Test TLS handshake (TCP) to make sure client handles multiple error messages from certificate verification.
+*
+*
+* | # | Step | Expected |
+* |---|--------------------------------|-------------|
+* | 1 | Perform a DNS lookup on the server address. | PAL_SUCCESS |
+* | 2 | Create a TCP socket. | PAL_SUCCESS |
+* | 3 | Set the server port. | PAL_SUCCESS |
+* | 4 | Parse the CA cert. | PAL_SUCCESS |
+* | 5 | Get the CA cert ID. | PAL_SUCCESS |
+* | 6 | Set the CA cert ID into the storage. | PAL_SUCCESS |
+* | 7 | Connect the TCP socket to the server. | PAL_SUCCESS |
+* | 8 | Initialize the TLS configuration using `pal_initTLSConfiguration`. | PAL_SUCCESS |
+* | 9 | Initialize the TLS context using `pal_initTLS`. | PAL_SUCCESS |
+* | 10 | Set the certificate and keys. set CA cert so that it will not be valid. | PAL_SUCCESS |
+* | 11 | Set the socket to the configuration using `pal_tlsSetSocket`. | PAL_SUCCESS |
+* | 12 | Set system time to be far in the future `pal_osSetTime`. | PAL_SUCCESS |
+* | 13 | Perform a TLS handshake with the server using `pal_handShake`. | PAL_ERR_X509_CERT_VERIFY_FAILED |
+* | 14 | Uninitialize the TLS context using `pal_freeTLS`. | PAL_SUCCESS |
+* | 15 | Uninitialize the TLS configuration using `pal_tlsConfigurationFree`. | PAL_SUCCESS |
+* | 16 | Free X509 handle. | PAL_SUCCESS |
+*/
+// this is copy-paste of palTLSService_t from pal_TLS.c. It's not meant to be used outside PAL but
+// since this test needs to mimic malicious server returning a certificate which is wrong in two
+// ways and also returning non-valid 'secure time' in the ServerHello message we need to modify
+// it during the test.
+typedef struct tls_ctx
+{
+ bool retryHandShake;
+ uint64_t serverTime;
+ uintptr_t platTlsHandle;
+}tls_ctx_t;
+
+TEST(pal_tls, tlsHandshakeTCP_ExpiredServerCert_UnTrusted)
+{
+
+#ifndef MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT
+
+#if (PAL_USE_INTERNAL_FLASH)
+ palStatus_t status = PAL_SUCCESS;
+ palTLSConfHandle_t palTLSConf = NULLPTR;
+ palTLSHandle_t palTLSHandle = NULLPTR;
+ palTLSTransportMode_t transportationMode = PAL_TLS_MODE;
+ palSocketAddress_t socketAddr = { 0 };
+ palSocketLength_t addressLength = 0;
+ palTLSSocket_t tlsSocket = { g_socket, &socketAddr, 0, transportationMode };
+ uint64_t futureTime = 2145542642; //Wed, 27 Dec 2037 16:04:02 GMT
+ uint64_t updatedTime = 0;
+ size_t actualSavedTimeSize = 0;
+ palX509Handle_t trustedServerCA = NULLPTR;
+ struct server_address server;
+
+ int32_t temp;
+ status = pal_osSemaphoreCreate(1, &s_semaphoreID);
+ TEST_ASSERT_EQUAL_HEX( PAL_SUCCESS, status);
+
+ /*#1*/
+ parseServerAddress(&server, PAL_TLS_TEST_SERVER_ADDRESS);
+ status = doDnsQuery(server.hostname, &socketAddr, &addressLength);
+ if (PAL_SUCCESS != status)
+ {
+ PAL_LOG_ERR("DNS query error for %s", PAL_TLS_TEST_SERVER_ADDRESS);
+ }
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ /*#2*/
+ status = pal_asynchronousSocket(socketAddr.addressType, PAL_SOCK_STREAM, true, 0, socketCallback1, &g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ /*#3*/
+ status = pal_setSockAddrPort(&socketAddr, server.port);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ tlsSocket.addressLength = addressLength;
+ tlsSocket.socket = g_socket;
+
+ /*#4*/
+ status = pal_x509Initiate(&trustedServerCA);
+ TEST_ASSERT_NOT_EQUAL(trustedServerCA, NULLPTR);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ status = pal_x509CertParse(trustedServerCA, (const unsigned char *)PAL_TLS_TEST_DEVICE_CERTIFICATE, MAX_CERTIFICATE_SIZE);
+ if (PAL_SUCCESS != status)
+ {
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#5*/
+ status = pal_x509CertGetAttribute(trustedServerCA, PAL_X509_CERT_ID_ATTR, g_trustedServerID, sizeof(g_trustedServerID), &g_actualServerIDSize);
+ if (PAL_SUCCESS != status)
+ {
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#6*/
+ status = storage_rbp_write(STORAGE_RBP_TRUSTED_TIME_SRV_ID_NAME, (uint8_t*)g_trustedServerID, g_actualServerIDSize, false);
+ if (PAL_SUCCESS != status)
+ {
+ status = pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#7*/
+ do {
+ status = pal_connect(g_socket, &socketAddr, addressLength);
+ pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
+ } while (status == PAL_ERR_SOCKET_IN_PROGRES || status == PAL_ERR_SOCKET_WOULD_BLOCK);
+
+ if (status == PAL_ERR_SOCKET_ALREADY_CONNECTED) {
+ status = PAL_SUCCESS;
+ }
+
+ if (PAL_SUCCESS != status)
+ {
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#8*/
+ status = pal_initTLSConfiguration(&palTLSConf, transportationMode);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ /*#9*/
+ status = pal_initTLS(palTLSConf, &palTLSHandle, false);
+ if (PAL_SUCCESS != status)
+ {
+ pal_freeTLS(&palTLSHandle);
+ pal_tlsConfigurationFree(&palTLSConf);
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#10*/
+ setCredentialsWrongCA(palTLSConf);
+
+ /*#11*/
+ status = pal_tlsSetSocket(palTLSConf, &tlsSocket);
+ if (PAL_SUCCESS != status)
+ {
+ pal_freeTLS(&palTLSHandle);
+ pal_tlsConfigurationFree(&palTLSConf);
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#12*/
+ status = pal_osSetStrongTime(futureTime);
+ if (PAL_SUCCESS != status)
+ {
+ pal_freeTLS(&palTLSHandle);
+ pal_tlsConfigurationFree(&palTLSConf);
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#13*/
+ do
+ {
+ status = pal_handShake(palTLSHandle, palTLSConf, false);
+ tls_ctx_t* tls_ctx = (tls_ctx_t*)palTLSHandle;
+ if (tls_ctx->retryHandShake) {
+ // server should really fail before logic goes to renegotiation...
+ // ..but this hack ensures we get server's cert to appear from future
+ // if it happens to still continue there
+ tls_ctx->serverTime = 50;
+ }
+ pal_osSemaphoreWait(s_semaphoreID, 1000, &temp);
+ }
+ while (PAL_ERR_TLS_WANT_READ == status || PAL_ERR_TLS_WANT_WRITE == status);
+
+ if (PAL_ERR_X509_CERT_VERIFY_FAILED != status)
+ {
+ pal_freeTLS(&palTLSHandle);
+ pal_tlsConfigurationFree(&palTLSConf);
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_ERR_X509_CERT_VERIFY_FAILED, status);
+ }
+
+ /*#14*/
+ status = pal_freeTLS(&palTLSHandle);
+ if (PAL_SUCCESS != status)
+ {
+ pal_x509Free(&trustedServerCA);
+ pal_tlsConfigurationFree(&palTLSConf);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#15*/
+ status = pal_tlsConfigurationFree(&palTLSConf);
+ if (PAL_SUCCESS != status)
+ {
+ pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ }
+
+ /*#16*/
+ status = pal_x509Free(&trustedServerCA);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ status = pal_close(&g_socket);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ status = storage_rbp_read(STORAGE_RBP_SAVED_TIME_NAME, (uint8_t*)&updatedTime, sizeof(updatedTime), &actualSavedTimeSize);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ TEST_ASSERT_TRUE(updatedTime <= futureTime);
+
+ status = storage_rbp_read(STORAGE_RBP_LAST_TIME_BACK_NAME, (uint8_t*)&updatedTime, sizeof(updatedTime), &actualSavedTimeSize);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ TEST_ASSERT_TRUE(updatedTime <= futureTime);
+#else
+ TEST_IGNORE_MESSAGE("Ignored, PAL_USE_INTERNAL_FLASH not set");
+#endif
+
+#else //MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
+ TEST_IGNORE_MESSAGE("Ignored, MBED_CONF_MBED_CLOUD_CLIENT_PSA_SUPPORT is defined");
+#endif
+
+}
+
static void setCredentials(palTLSConfHandle_t handle)
{
palX509_t pubKey = {(const void*)PAL_TLS_TEST_DEVICE_CERTIFICATE, MAX_CERTIFICATE_SIZE};
@@ -2726,6 +3022,24 @@ static void setCredentials(palTLSConfHandle_t handle)
TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
}
+static void setCredentialsWrongCA(palTLSConfHandle_t handle)
+{
+ palX509_t pubKey = {(const void*)PAL_TLS_TEST_DEVICE_CERTIFICATE, MAX_CERTIFICATE_SIZE};
+ palX509_t caCert = { (const void*)PAL_TLS_TEST_DEVICE_CERTIFICATE, MAX_CERTIFICATE_SIZE };
+
+ palStatus_t status;
+ palPrivateKey_t prvKey;
+ status = pal_initPrivateKey((const void*)PAL_TLS_TEST_DEVICE_PRIVATE_KEY, MAX_CERTIFICATE_SIZE, &prvKey);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+
+ status = pal_setOwnCertChain(handle, &pubKey);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ status = pal_setOwnPrivateKey(handle, &prvKey);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+ status = pal_setCAChain(handle, &caCert, NULL);
+ TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
+}
+
#if (PAL_USE_SSL_SESSION_RESUME == 1)
static bool isSslSessionAvailable()
{
diff --git a/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test_runner.c b/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test_runner.c
index ad6d49c7b..84e8498cb 100644
--- a/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test_runner.c
+++ b/mbed-client-pal/Test/PAL_Modules/TLS/pal_tls_test_runner.c
@@ -37,5 +37,6 @@ TEST_GROUP_RUNNER(pal_tls)
RUN_TEST_CASE(pal_tls, TCPHandshakeWhileCertVerify_threads);
RUN_TEST_CASE(pal_tls, tlsHandshakeUDP);
RUN_TEST_CASE(pal_tls, tlsHandshake_SessionResume);
+ RUN_TEST_CASE(pal_tls, tlsHandshakeTCP_ExpiredServerCert_UnTrusted);
#endif
}
diff --git a/mbed-client/mbed-client-c/nsdl-c/sn_nsdl_lib.h b/mbed-client/mbed-client-c/nsdl-c/sn_nsdl_lib.h
index df615358d..9f8af8116 100755
--- a/mbed-client/mbed-client-c/nsdl-c/sn_nsdl_lib.h
+++ b/mbed-client/mbed-client-c/nsdl-c/sn_nsdl_lib.h
@@ -343,7 +343,7 @@ extern int32_t sn_nsdl_send_observation_notification(struct nsdl_s *handle, uint
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)
+ * \fn extern int8_t sn_nsdl_process_coap(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *src_ptr)
*
* \brief To push CoAP packet to mbed Device C Client library
*
@@ -361,9 +361,9 @@ extern char *sn_nsdl_get_version(void);
* the destination address of the response packet.
*
* \return 0 Success
- * \return -1 Failure
+ * \return < 0 Failure
*/
-extern int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src);
+extern int8_t sn_nsdl_process_coap(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *src_ptr);
/**
* \fn extern int8_t sn_nsdl_exec(struct nsdl_s *handle, uint32_t time);
@@ -494,7 +494,7 @@ extern int32_t sn_nsdl_send_request(struct nsdl_s *handle,
*
* \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).
+ * \return < 0 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, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type);
diff --git a/mbed-client/mbed-client-c/source/sn_grs.c b/mbed-client/mbed-client-c/source/sn_grs.c
index 24d3d4e32..105f48666 100755
--- a/mbed-client/mbed-client-c/source/sn_grs.c
+++ b/mbed-client/mbed-client-c/source/sn_grs.c
@@ -271,19 +271,21 @@ extern int8_t sn_grs_process_coap(struct nsdl_s *nsdl_handle, sn_coap_hdr_s *coa
return sn_grs_core_request(nsdl_handle, src_addr_ptr, coap_packet_ptr);
}
- /* Get resource */
- char* path = nsdl_handle->grs->sn_grs_alloc(coap_packet_ptr->uri_path_len + 1);
- if (!path) {
- return SN_NSDL_FAILURE;
- }
+ if (coap_packet_ptr->uri_path_len > 0) {
+ /* Get resource */
+ char* path = nsdl_handle->grs->sn_grs_alloc(coap_packet_ptr->uri_path_len + 1);
+ if (!path) {
+ return SN_NSDL_FAILURE;
+ }
- memcpy(path,
- coap_packet_ptr->uri_path_ptr,
- coap_packet_ptr->uri_path_len);
- path[coap_packet_ptr->uri_path_len] = '\0';
+ memcpy(path,
+ coap_packet_ptr->uri_path_ptr,
+ coap_packet_ptr->uri_path_len);
+ path[coap_packet_ptr->uri_path_len] = '\0';
- resource_temp_ptr = sn_grs_search_resource(handle, path, SN_GRS_SEARCH_METHOD);
- nsdl_handle->grs->sn_grs_free(path);
+ resource_temp_ptr = sn_grs_search_resource(handle, path, SN_GRS_SEARCH_METHOD);
+ nsdl_handle->grs->sn_grs_free(path);
+ }
/* * * * * * * * * * * */
/* If resource exists */
diff --git a/mbed-client/mbed-client-c/source/sn_nsdl.c b/mbed-client/mbed-client-c/source/sn_nsdl.c
index b35b35b9d..57c0210b6 100755
--- a/mbed-client/mbed-client-c/source/sn_nsdl.c
+++ b/mbed-client/mbed-client-c/source/sn_nsdl.c
@@ -262,6 +262,9 @@ int32_t sn_nsdl_register_endpoint(struct nsdl_s *handle,
register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;
+ /* Register message content format must be Core Link Format as stated in OMA LwM2M */
+ register_message_ptr->content_format = COAP_CT_LINK_FORMAT;
+
/* Allocate memory for the extended options list */
if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) {
sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
@@ -283,11 +286,12 @@ int32_t sn_nsdl_register_endpoint(struct nsdl_s *handle,
if (endpoint_info_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) {
/* Built body for message */
- if (sn_nsdl_build_registration_body(handle, register_message_ptr, 0) == SN_NSDL_FAILURE) {
+ int ret = sn_nsdl_build_registration_body(handle, register_message_ptr, 0);
+ if (ret != SN_NSDL_SUCCESS) {
register_message_ptr->uri_path_ptr = NULL;
register_message_ptr->options_list_ptr->uri_host_ptr = NULL;
sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
- return SN_NSDL_FAILURE;
+ return ret;
}
}
@@ -458,6 +462,9 @@ int32_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint
register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;
+ /* Register update message content format must be same as register messages content format which is Core Link Format */
+ register_message_ptr->content_format = COAP_CT_LINK_FORMAT;
+
if (handle->ep_information_ptr->location_ptr) {
register_message_ptr->uri_path_len = handle->ep_information_ptr->location_len; /* = Only location set by Device Server*/
@@ -507,9 +514,10 @@ int32_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint
/* Build payload */
if (handle->ep_information_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) {
- if (sn_nsdl_build_registration_body(handle, register_message_ptr, 1) == SN_NSDL_FAILURE) {
+ int8_t ret = sn_nsdl_build_registration_body(handle, register_message_ptr, 1);
+ if (ret != SN_NSDL_SUCCESS) {
sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
- return SN_NSDL_MEMORY_ALLOCATION_FAILED;
+ return ret;
}
}
@@ -651,12 +659,13 @@ int32_t sn_nsdl_oma_bootstrap(struct nsdl_s *handle,
return SN_NSDL_FAILURE;
}
- if (set_NSP_address(handle,
- bootstrap_address_ptr->addr_ptr,
- bootstrap_address_ptr->addr_len,
- bootstrap_address_ptr->port,
- bootstrap_address_ptr->type) == SN_NSDL_FAILURE) {
- return SN_NSDL_FAILURE;
+ int8_t ret = set_NSP_address(handle,
+ bootstrap_address_ptr->addr_ptr,
+ bootstrap_address_ptr->addr_len,
+ bootstrap_address_ptr->port,
+ bootstrap_address_ptr->type);
+ if (ret != SN_NSDL_SUCCESS) {
+ return ret;
}
handle->is_bs_server = true;
@@ -737,24 +746,15 @@ char *sn_nsdl_get_version(void)
#endif
}
-int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet_ptr, uint16_t packet_len, sn_nsdl_addr_s *src_ptr)
+int8_t sn_nsdl_process_coap(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *src_ptr)
{
- sn_coap_hdr_s *coap_packet_ptr = NULL;
sn_coap_hdr_s *coap_response_ptr = NULL;
sn_nsdl_dynamic_resource_parameters_s *resource = NULL;
- /* Check parameters */
- if (handle == NULL) {
- return SN_NSDL_FAILURE;
- }
- /* Parse CoAP packet */
- coap_packet_ptr = sn_coap_protocol_parse(handle->grs->coap, src_ptr, packet_len, packet_ptr, (void *)handle);
-
- /* Check if parsing was successfull */
- if (coap_packet_ptr == (sn_coap_hdr_s *)NULL) {
+ /* Check parameters */
+ if (handle == NULL || coap_packet_ptr == NULL) {
return SN_NSDL_FAILURE;
}
- sn_nsdl_print_coap_data(coap_packet_ptr, false);
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_DUPLICATED_MSG) {
@@ -989,7 +989,7 @@ static char *sn_nsdl_build_resource_attribute_str(char *dst, const sn_nsdl_attri
* \param *handle Pointer to nsdl-library handle
* \param *message_ptr Pointer to CoAP message header
*
- * \return SN_NSDL_SUCCESS = 0, Failed = -1
+ * \return SN_NSDL_SUCCESS = 0, Failed < 0
*/
int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration)
{
@@ -1687,8 +1687,9 @@ static int8_t sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *co
handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_IS_REGISTERED;
sn_grs_mark_resources_as_registered(handle);
is_reg_msg = true;
- if (sn_nsdl_resolve_ep_information(handle, coap_packet_ptr) != SN_NSDL_SUCCESS) {
- return SN_NSDL_FAILURE;
+ int8_t ret = sn_nsdl_resolve_ep_information(handle, coap_packet_ptr);
+ if (ret != SN_NSDL_SUCCESS) {
+ return ret;
}
}
@@ -1762,7 +1763,7 @@ static int8_t sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *co
* \param *handle Pointer to nsdl-library handle
* \param *coap_packet_ptr Pointer to received CoAP message
*
- * \return SN_NSDL_SUCCESS = 0, Failed = -1
+ * \return SN_NSDL_SUCCESS = 0, Failed < 0
*/
static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr)
{
diff --git a/mbed-client/mbed-client-classic/mbed-client-classic/m2mconnectionhandlerpimpl.h b/mbed-client/mbed-client-classic/mbed-client-classic/m2mconnectionhandlerpimpl.h
index aa0a2361d..d8c92f9f2 100644
--- a/mbed-client/mbed-client-classic/mbed-client-classic/m2mconnectionhandlerpimpl.h
+++ b/mbed-client/mbed-client-classic/mbed-client-classic/m2mconnectionhandlerpimpl.h
@@ -24,16 +24,16 @@
#include "mbed-client/m2minterface.h"
#include "mbed-client/m2mconnectionobserver.h"
#include "mbed-client/m2mconnectionsecurity.h"
+#include "mbed-client/m2mconnectionhandler.h"
#include "nsdl-c/sn_nsdl.h"
#include "pal.h"
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
#include "mbed-client/m2mtimerobserver.h"
#endif
class M2MConnectionSecurity;
-class M2MConnectionHandler;
class M2MSecurity;
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
class M2MTimer;
#endif
@@ -43,7 +43,7 @@ class M2MTimer;
*/
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
class M2MConnectionHandlerPimpl : public M2MTimerObserver {
#else
class M2MConnectionHandlerPimpl {
@@ -51,13 +51,14 @@ class M2MConnectionHandlerPimpl {
public:
enum SocketEvent {
- ESocketIdle = 0x00,
- ESocketCallback = 0x02,
- ESocketConnect = 0x04,
- ESocketSend = 0x08,
- ESocketDnsResolved = 0x10,
- ESocketDnsError = 0x20,
- ESocketClose = 0x40
+ ESocketIdle = 0x00,
+ ESocketCallback = 0x02,
+ ESocketConnect = 0x04,
+ ESocketSend = 0x08,
+ ESocketDnsResolved = 0x10,
+ ESocketDnsError = 0x20,
+ ESocketAlreadyConnected = 0x40,
+ ESocketClose = 0x80
};
// NOTE! Check that these values does not overlap with the SocketEvent values
@@ -69,15 +70,15 @@ class M2MConnectionHandlerPimpl {
/**
* @brief Constructor
*/
- M2MConnectionHandlerPimpl(M2MConnectionHandler* base, M2MConnectionObserver &observer,
- M2MConnectionSecurity* sec,
+ M2MConnectionHandlerPimpl(M2MConnectionHandler *base, M2MConnectionObserver &observer,
+ M2MConnectionSecurity *sec,
M2MInterface::BindingMode mode,
M2MInterface::NetworkStack /*stack*/);
/**
* @brief Destructor
*/
- ~M2MConnectionHandlerPimpl();
+ virtual ~M2MConnectionHandlerPimpl();
void start_timer(void);
@@ -97,11 +98,11 @@ class M2MConnectionHandlerPimpl {
* @param is_server_ping Defines whether the call is for Server ping or not.
* @return true if address is valid else false.
*/
- bool resolve_server_address(const String& server_address,
+ bool resolve_server_address(const String &server_address,
const uint16_t server_port,
M2MConnectionObserver::ServerType server_type,
- const M2MSecurity* security,
- bool is_server_ping =false);
+ const M2MSecurity *security,
+ bool is_server_ping = false);
/**
* @brief Sends data, to the connected sent to server.
@@ -187,6 +188,12 @@ class M2MConnectionHandlerPimpl {
*/
void unregister_network_handler();
+ /**
+ * \brief Set socket priority.
+ * \return true if socket option was set correctly.
+ */
+ bool set_socket_priority(M2MConnectionHandler::SocketPriority priority);
+
/**
* \brief Stores CID persistently for DTLS connections.
*/
@@ -210,11 +217,18 @@ class M2MConnectionHandlerPimpl {
*/
void set_cid_value(const uint8_t *data_ptr, const size_t data_len);
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
/**
* \brief stop _dns_fallback_timer
*/
void stop_dns_fallback_timer();
+#if (PAL_DNS_API_VERSION == 3)
+ /**
+ * \brief Set palAddressInfo_t. Used from callback address_resolver_cb.
+ * \param addrInfo pointer to palAddressInfo_t object
+ */
+ void set_address_info(palAddressInfo_t *addrInfo);
+#endif
#endif
private:
@@ -267,7 +281,7 @@ class M2MConnectionHandlerPimpl {
*/
void initialize_event(arm_event_storage_t *event);
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
/**
* \brief Indicates that the timer has expired.
* \param type The type of the timer that has expired.
@@ -295,13 +309,16 @@ class M2MConnectionHandlerPimpl {
/**
* @brief Get first item from the queue list.
*/
- send_data_queue_s* get_item_from_list();
+ send_data_queue_s *get_item_from_list();
/**
* @brief Add queue data back to list.
*/
- void add_item_to_list(send_data_queue_s* data);
-
+ void add_item_to_list(send_data_queue_s *data);
+#if (PAL_DNS_API_VERSION == 3)
+private:
+ void free_address_info();
+#endif
private:
enum SocketState {
@@ -358,7 +375,12 @@ class M2MConnectionHandlerPimpl {
uint32_t _net_iface;
#if (PAL_DNS_API_VERSION == 0) || (PAL_DNS_API_VERSION == 1)
palSocketLength_t _socket_address_len;
-#else
+#elif (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
+#if (PAL_DNS_API_VERSION == 3)
+ uint16_t _current_address_info;
+ uint16_t _address_info_count;
+ palAddressInfo_t *_address_info;
+#endif
palDNSQuery_t _handler_async_DNS;
M2MTimer *_dns_fallback_timer;
#endif
@@ -375,10 +397,10 @@ class M2MConnectionHandlerPimpl {
bool _is_server_ping;
arm_event_storage_t _event;
arm_event_storage_t _socket_callback_event;
-friend class Test_M2MConnectionHandlerPimpl;
-friend class Test_M2MConnectionHandlerPimpl_mbed;
-friend class Test_M2MConnectionHandlerPimpl_classic;
-friend class M2MConnection_TestObserver;
+ friend class Test_M2MConnectionHandlerPimpl;
+ friend class Test_M2MConnectionHandlerPimpl_mbed;
+ friend class Test_M2MConnectionHandlerPimpl_classic;
+ friend class M2MConnection_TestObserver;
};
#endif //M2M_CONNECTION_HANDLER_PIMPL_H__
diff --git a/mbed-client/mbed-client-classic/source/m2mconnectionhandler.cpp b/mbed-client/mbed-client-classic/source/m2mconnectionhandler.cpp
index 44dbcfa05..fa1664046 100644
--- a/mbed-client/mbed-client-classic/source/m2mconnectionhandler.cpp
+++ b/mbed-client/mbed-client-classic/source/m2mconnectionhandler.cpp
@@ -19,10 +19,10 @@
#include "mbed-client/m2mconstants.h"
M2MConnectionHandler::M2MConnectionHandler(M2MConnectionObserver &observer,
- M2MConnectionSecurity* sec,
+ M2MConnectionSecurity *sec,
M2MInterface::BindingMode mode,
M2MInterface::NetworkStack stack)
-:_observer(observer)
+ : _observer(observer)
{
_private_impl = new M2MConnectionHandlerPimpl(this, observer, sec, mode, stack);
}
@@ -38,11 +38,11 @@ bool M2MConnectionHandler::bind_connection(const uint16_t listen_port)
return _private_impl->bind_connection(listen_port);
}
-bool M2MConnectionHandler::resolve_server_address(const String& server_address,
- const uint16_t server_port,
- M2MConnectionObserver::ServerType server_type,
- const M2MSecurity* security,
- bool is_server_ping)
+bool M2MConnectionHandler::resolve_server_address(const String &server_address,
+ const uint16_t server_port,
+ M2MConnectionObserver::ServerType server_type,
+ const M2MSecurity *security,
+ bool is_server_ping)
{
return _private_impl->resolve_server_address(server_address, server_port,
server_type, security, is_server_ping);
@@ -114,3 +114,8 @@ void M2MConnectionHandler::set_cid_value(const uint8_t *data_ptr, const size_t d
{
_private_impl->set_cid_value(data_ptr, data_len);
}
+
+bool M2MConnectionHandler::set_socket_priority(M2MConnectionHandler::SocketPriority priority)
+{
+ return _private_impl->set_socket_priority(priority);
+}
diff --git a/mbed-client/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp b/mbed-client/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp
index 2037e5315..7b5eb4258 100644
--- a/mbed-client/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp
+++ b/mbed-client/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp
@@ -23,7 +23,7 @@
#include "mbed-client/m2mconstants.h"
#include "mbed-client/m2msecurity.h"
#include "mbed-client/m2mconnectionhandler.h"
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
#include "mbed-client/m2mtimer.h"
#endif
#include "pal.h"
@@ -38,7 +38,7 @@
#error "For async PAL DNS only API v2 or greater is supported on Mbed."
#endif
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
#define DNS_FALLBACK_TIMEOUT 600000
#endif
@@ -127,6 +127,10 @@ void M2MConnectionHandlerPimpl::event_handler(arm_event_s *event)
socket_connect_handler();
break;
+ case M2MConnectionHandlerPimpl::ESocketAlreadyConnected:
+ socket_connect_handler();
+ break;
+
case M2MConnectionHandlerPimpl::ESocketClose:
close_socket();
break;
@@ -168,7 +172,12 @@ M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler *base,
_net_iface(0),
#if (PAL_DNS_API_VERSION == 0) || (PAL_DNS_API_VERSION == 1)
_socket_address_len(0),
-#elif (PAL_DNS_API_VERSION == 2)
+#elif (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
+#if (PAL_DNS_API_VERSION == 3)
+ _current_address_info(0),
+ _address_info_count(0),
+ _address_info(0),
+#endif
_handler_async_DNS(0),
#endif
_socket_state(ESocketStateDisconnected),
@@ -181,7 +190,7 @@ M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler *base,
return;
}
#endif
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
_dns_fallback_timer = new M2MTimer(*this);
#endif
if (PAL_SUCCESS != pal_init()) {
@@ -189,6 +198,7 @@ M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler *base,
}
memset(&_address, 0, sizeof _address);
+ _address._stack = stack;
memset((void *)&_socket_address, 0, sizeof _socket_address);
memset(&_ipV4Addr, 0, sizeof(palIpV4Addr_t));
memset(&_ipV6Addr, 0, sizeof(palIpV6Addr_t));
@@ -207,13 +217,16 @@ M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler *base,
M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl()
{
tr_debug("~M2MConnectionHandlerPimpl()");
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
if (_handler_async_DNS > 0) {
pal_cancelAddressInfoAsync(_handler_async_DNS);
}
delete _dns_fallback_timer;
#endif
+#if (PAL_DNS_API_VERSION == 3)
+ free_address_info();
+#endif
close_socket();
delete _security_impl;
_security_impl = NULL;
@@ -251,12 +264,19 @@ void M2MConnectionHandlerPimpl::send_event(SocketEvent event_type)
}
// This callback is used from PAL pal_getAddressInfoAsync,
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
#if (PAL_DNS_API_VERSION == 2)
extern "C" void address_resolver_cb(const char *url, palSocketAddress_t *address, palStatus_t status, void *callbackArgument)
+#elif (PAL_DNS_API_VERSION == 3)
+extern "C" void address_resolver_cb(const char *url, palAddressInfo_t *addrInfo, palStatus_t status, void *callbackArgument)
+#endif
{
tr_debug("M2MConnectionHandlerPimpl::address_resolver callback");
M2MConnectionHandlerPimpl *instance = (M2MConnectionHandlerPimpl *)callbackArgument;
instance->stop_dns_fallback_timer();
+#if (PAL_DNS_API_VERSION == 3)
+ instance->set_address_info(addrInfo);
+#endif
if (PAL_SUCCESS != status) {
tr_error("M2MConnectionHandlerPimpl::address_resolver callback failed with %" PRIx32, status);
instance->send_event(M2MConnectionHandlerPimpl::ESocketDnsError);
@@ -266,27 +286,60 @@ extern "C" void address_resolver_cb(const char *url, palSocketAddress_t *address
}
#endif
+#if (PAL_DNS_API_VERSION == 3)
+void M2MConnectionHandlerPimpl::set_address_info(palAddressInfo_t *addrInfo)
+{
+ _address_info = addrInfo;
+ _address_info_count = pal_getDNSCount(_address_info);
+ tr_debug("Found %d dns addresses", _address_info_count);
+}
+
+void M2MConnectionHandlerPimpl::free_address_info()
+{
+ _current_address_info = 0;
+ _address_info_count = 0;
+ pal_freeAddrInfo(_address_info);
+ _address_info = NULL;
+}
+#endif
+
bool M2MConnectionHandlerPimpl::address_resolver(void)
{
palStatus_t status;
bool ret = false;
+#if (PAL_DNS_API_VERSION == 3)
+ if (_current_address_info < _address_info_count) {
+ send_event(ESocketDnsResolved);
+ return true;
+ }
+ // start new dns query, reset current address info
+ free_address_info();
+#endif
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
tr_debug("M2MConnectionHandlerPimpl::address_resolver:asynchronous DNS");
_handler_async_DNS = 0;
tr_debug("M2MConnectionHandlerPimpl::address_resolver start _dns_fallback_timer");
_dns_fallback_timer->stop_timer();
_dns_fallback_timer->start_timer(DNS_FALLBACK_TIMEOUT, M2MTimerObserver::DnsQueryFallback, true);
+#if (PAL_DNS_API_VERSION == 2)
status = pal_getAddressInfoAsync(_server_address.c_str(), (palSocketAddress_t *)&_socket_address, &address_resolver_cb, this, &_handler_async_DNS);
+#elif (PAL_DNS_API_VERSION == 3)
+ status = pal_getAddressInfoAsync(_server_address.c_str(), &address_resolver_cb, this, &_handler_async_DNS);
+#endif
if (PAL_SUCCESS != status) {
_dns_fallback_timer->stop_timer();
tr_error("M2MConnectionHandlerPimpl::address_resolver, pal_getAddressInfoAsync fail. %" PRIx32, status);
+#if (PAL_DNS_API_VERSION == 3)
+ free_address_info();
+#endif
_observer.socket_error(M2MConnectionHandler::DNS_RESOLVING_ERROR);
} else {
ret = true;
}
#else // #if (PAL_DNS_API_VERSION == 0)
tr_debug("M2MConnectionHandlerPimpl::address_resolver:synchronous DNS");
+
status = pal_getAddressInfo(_server_address.c_str(), (palSocketAddress_t *)&_socket_address, &_socket_address_len);
if (PAL_SUCCESS != status) {
tr_error("M2MConnectionHandlerPimpl::getAddressInfo failed with %" PRIx32, status);
@@ -302,7 +355,10 @@ bool M2MConnectionHandlerPimpl::address_resolver(void)
void M2MConnectionHandlerPimpl::handle_dns_result(bool success)
{
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
+#if (PAL_DNS_API_VERSION == 3)
+ pal_free_addressinfoAsync(_handler_async_DNS);
+#endif
_handler_async_DNS = 0;
#endif
if (_socket_state != ESocketStateDNSResolving) {
@@ -315,6 +371,9 @@ void M2MConnectionHandlerPimpl::handle_dns_result(bool success)
socket_connect_handler();
} else {
+#if (PAL_DNS_API_VERSION == 3)
+ free_address_info();
+#endif
_observer.socket_error(M2MConnectionHandler::DNS_RESOLVING_ERROR);
}
}
@@ -325,13 +384,33 @@ bool M2MConnectionHandlerPimpl::resolve_server_address(const String &server_addr
const M2MSecurity *security,
bool is_server_ping)
{
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
if (_handler_async_DNS > 0) {
if (pal_cancelAddressInfoAsync(_handler_async_DNS) != PAL_SUCCESS) {
return false;
}
}
#endif
+
+ // if we already have a secure connection set up for the server address (and LWM2MServer, not bootstrap)
+ // we should skip over the DNS query. In case of CID there might be situation that we have a valid CID for ip address x, now if we query
+ // dns again we might get ip address to y and COAP sending with the CID will fail. We will skip unnecessary dns query also if CID is not in use.
+ if ((_socket_state == ESocketStateSecureConnection) &&
+ (server_type == M2MConnectionObserver::LWM2MServer) && (_server_address == server_address)) {
+ _is_server_ping = is_server_ping;
+ if (is_server_ping) {
+ // skip over dns query to handshake. This will reset tls and do a clean tls handshake
+ tr_debug("M2MConnectionHandlerPimpl::resolve_server_address (server ping), skip dns to handshake");
+ _socket_state = ESocketStateDNSResolving;
+ send_event(ESocketDnsResolved);
+ } else {
+ // skip over dns query straight to COAP sending
+ tr_debug("M2MConnectionHandlerPimpl::resolve_server_address (), skip dns to COAP sending");
+ send_event(M2MConnectionHandlerPimpl::ESocketAlreadyConnected);
+ }
+ return true;
+ }
+
_socket_state = ESocketStateDNSResolving;
_security = security;
@@ -349,12 +428,18 @@ bool M2MConnectionHandlerPimpl::resolve_server_address(const String &server_addr
_secure_connection = false;
}
+#if (PAL_DNS_API_VERSION == 3)
+ if (!(server_address == _server_address)) {
+ // new address, must do dns query
+ free_address_info();
+ tr_debug("M2MConnectionHandlerPimpl::resolve_server_address, new address, must do dns query.");
+ }
+#endif
_server_port = server_port;
_server_type = server_type;
_server_address = server_address;
_is_server_ping = is_server_ping;
-
return address_resolver();
}
@@ -374,7 +459,6 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
case ESocketStateDisconnected:
case ESocketStateHandshaking:
case ESocketStateUnsecureConnection:
- case ESocketStateSecureConnection:
// Ignore these events
break;
@@ -382,13 +466,27 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
// Initialize the socket to stable state
close_socket();
-
+#if (PAL_DNS_API_VERSION == 3)
+ if (_address_info) {
+ status = pal_getDNSAddress(_address_info, _current_address_info, (palSocketAddress_t *)&_socket_address);
+ _current_address_info++;
+ if (PAL_SUCCESS != status) {
+ tr_error("M2MConnectionHandlerPimpl::socket_connect_handler - pal_getDNSAddress %" PRIx32, status);
+ _observer.socket_error(M2MConnectionHandler::DNS_RESOLVING_ERROR);
+ return;
+ }
+ tr_debug("M2MConnectionHandlerPimpl::socket_connect_handler - trying dns address %d of possible %d", _current_address_info, _address_info_count);
+ } else {
+ // current DNS should be ok, resources are free'd
+ tr_debug("M2MConnectionHandlerPimpl::socket_connect_handler - continue with current DNS");
+ }
+#endif
status = pal_setSockAddrPort((palSocketAddress_t *)&_socket_address, _server_port);
if (PAL_SUCCESS != status) {
tr_error("M2MConnectionHandlerPimpl::socket_connect_handler - setSockAddrPort err: %" PRIx32, status);
} else {
- tr_debug("address family: %d", (int)_socket_address.addressType);
+ tr_debug("M2MConnectionHandlerPimpl::socket_connect_handler - address family: %d", (int)_socket_address.addressType);
}
if (_socket_address.addressType == PAL_AF_INET) {
@@ -401,7 +499,7 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
tr_info("M2MConnectionHandlerPimpl::socket_connect_handler - IPv4 Address %d.%d.%d.%d",
_ipV4Addr[0], _ipV4Addr[1], _ipV4Addr[2], _ipV4Addr[3]);
-
+ _address._stack = M2MInterface::LwIP_IPv4;
_address._address = (void *)_ipV4Addr;
_address._length = PAL_IPV4_ADDRESS_SIZE;
_address._port = _server_port;
@@ -414,7 +512,7 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
}
tr_info("M2MConnectionHandlerPimpl::socket_connect_handler - IPv6 Address: %s", mbed_trace_ipv6(_ipV6Addr));
-
+ _address._stack = M2MInterface::LwIP_IPv6;
_address._address = (void *)_ipV6Addr;
_address._length = PAL_IPV6_ADDRESS_SIZE;
_address._port = _server_port;
@@ -435,7 +533,7 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
// Now that we just retry connect when it is not yet succeeded anyway this state might be removed completely.
_socket_state = ESocketStateConnectBeingCalled;
- // fall through is intentional
+ // fall through
case ESocketStateConnectBeingCalled:
case ESocketStateConnecting:
if (is_tcp_connection()) {
@@ -470,13 +568,14 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
tr_info("M2MConnectionHandlerPimpl::socket_connect_handler - Using UDP");
_socket_state = ESocketStateConnected;
}
-
- // fall through is a normal flow in case the UDP was used or pal_connect() happened to return immediately with PAL_SUCCESS
+ // fall through
+ // is a normal flow in case the UDP was used or pal_connect() happened to return immediately with PAL_SUCCESS
case ESocketStateConnected:
if (_security && security_instance_id >= 0) {
if (_secure_connection) {
if (_security_impl != NULL) {
_security_impl->reset();
+ tr_debug("M2MConnectionHandlerPimpl::socket_connect_handler - security reseted!");
int ret_code = _security_impl->init(_security, security_instance_id, _is_server_ping);
if (ret_code == M2MConnectionHandler::ERROR_NONE) {
ret_code = _security_impl->set_dtls_socket_callback(&socket_event_handler, this);
@@ -507,11 +606,12 @@ void M2MConnectionHandlerPimpl::socket_connect_handler()
}
if (_socket_state != ESocketStateHandshaking) {
_socket_state = ESocketStateUnsecureConnection;
- _observer.address_ready(_address,
- _server_type,
- _address._port);
+ _observer.address_ready(_address, _server_type, _address._port);
}
break;
+ case ESocketStateSecureConnection:
+ _observer.address_ready(_address, _server_type, _address._port);
+ break;
}
}
@@ -708,22 +808,30 @@ void M2MConnectionHandlerPimpl::receive_handshake_handler()
int return_value;
tr_debug("M2MConnectionHandlerPimpl::receive_handshake_handler()");
- // assert(_socket_state == ESocketStateHandshaking);
+ assert(_socket_state == ESocketStateHandshaking);
return_value = _security_impl->connect(_base, _is_server_ping);
-
+#if (PAL_DNS_API_VERSION == 3)
+ if (return_value == M2MConnectionHandler::ERROR_NONE) {
+ // current address worked so let's continue using that
+ _current_address_info--;
+ // free current dns resources
+ pal_freeAddrInfo(_address_info);
+ _address_info = NULL;
+ }
+#endif
if (_is_server_ping && return_value == M2MConnectionHandler::ERROR_NONE) {
// The callback for server-ping may trigger more than once.
// Only handle it if CID exists, ignore otherwise.
if (_security_impl->is_cid_available()) {
tr_debug("M2MConnectionHandlerPimpl::receive_handshake_handler() - Server ping success");
+ _socket_state = ESocketStateSecureConnection;
_observer.data_available(NULL, 0, _address);
}
return;
}
if (return_value == M2MConnectionHandler::ERROR_NONE) {
-
_socket_state = ESocketStateSecureConnection;
_observer.address_ready(_address,
_server_type,
@@ -1016,7 +1124,7 @@ void M2MConnectionHandlerPimpl::initialize_event(arm_event_storage_t *event)
event->link.next = NULL;
event->link.prev = NULL;
}
-#if (PAL_DNS_API_VERSION == 2)
+#if (PAL_DNS_API_VERSION == 2) || (PAL_DNS_API_VERSION == 3)
void M2MConnectionHandlerPimpl::stop_dns_fallback_timer()
{
_dns_fallback_timer->stop_timer();
@@ -1037,3 +1145,26 @@ void M2MConnectionHandlerPimpl::timer_expired(M2MTimerObserver::Type type)
}
}
#endif
+
+bool M2MConnectionHandlerPimpl::set_socket_priority(M2MConnectionHandler::SocketPriority priority)
+{
+ if (!_socket) {
+ tr_error("M2MConnectionHandlerPimpl::set_socket_priority - socket not created");
+ return false;
+ }
+
+ palStatus_t status;
+ int16_t traffic_class = priority;
+ status = pal_setSocketOptionsWithLevel(_socket,
+ PAL_SOL_IPPROTO_IPV6,
+ PAL_SO_IPV6_TRAFFIC_CLASS,
+ &traffic_class,
+ sizeof(traffic_class));
+
+ if (PAL_ERR_NOT_SUPPORTED != status && PAL_SUCCESS != status) {
+ tr_error("M2MConnectionHandlerPimpl::set_socket_priority - err: %" PRIx32, status);
+ return false;
+ }
+
+ return true;
+}
diff --git a/mbed-client/mbed-client-mbed-tls/source/m2mconnectionsecuritypimpl.cpp b/mbed-client/mbed-client-mbed-tls/source/m2mconnectionsecuritypimpl.cpp
index 5ddf9f7a7..d81dff616 100644
--- a/mbed-client/mbed-client-mbed-tls/source/m2mconnectionsecuritypimpl.cpp
+++ b/mbed-client/mbed-client-mbed-tls/source/m2mconnectionsecuritypimpl.cpp
@@ -123,12 +123,11 @@ int M2MConnectionSecurityPimpl::init(const M2MSecurity *security, uint16_t secur
palX509_t owncert;
palPrivateKey_t privateKey;
palX509_t caChain;
- size_t len;
+ size_t len = MAX_CERTIFICATE_SIZE;
uint8_t certificate[MAX_CERTIFICATE_SIZE];
uint8_t *certificate_ptr = (uint8_t *)&certificate;
- size_t resource_buffer_size;
+ size_t resource_buffer_size = MAX_CERTIFICATE_SIZE;
- caChain.size = MAX_CERTIFICATE_SIZE;
int ret_code = security->resource_value_buffer(M2MSecurity::ServerPublicKey, certificate_ptr, security_instance_id, &resource_buffer_size);
caChain.buffer = certificate_ptr;
caChain.size = static_cast(resource_buffer_size);
@@ -174,8 +173,8 @@ int M2MConnectionSecurityPimpl::init(const M2MSecurity *security, uint16_t secur
size_t index = 0;
while (index < cert_chain_size) {
- size_t resource_buffer_size = 0;
- owncert.size = MAX_CERTIFICATE_SIZE;
+ size_t resource_buffer_size = MAX_CERTIFICATE_SIZE;
+
ret_code = security->resource_value_buffer(M2MSecurity::ReadDeviceCertificateChain, certificate_ptr, security_instance_id, &resource_buffer_size);
owncert.buffer = certificate_ptr;
@@ -199,10 +198,10 @@ int M2MConnectionSecurityPimpl::init(const M2MSecurity *security, uint16_t secur
uint8_t identity[MAX_CERTIFICATE_SIZE];
uint8_t *identity_ptr = (uint8_t *)&identity;
- size_t identity_len = 0;
+ size_t identity_len = MAX_CERTIFICATE_SIZE;
uint8_t psk[MAX_CERTIFICATE_SIZE];
uint8_t *psk_ptr = (uint8_t *)&psk;
- size_t psk_len = 0;
+ size_t psk_len = MAX_CERTIFICATE_SIZE;
int ret_code = security->resource_value_buffer(M2MSecurity::PublicKey, identity_ptr, security_instance_id, &identity_len);
if (ret_code < 0) {
@@ -253,12 +252,12 @@ int M2MConnectionSecurityPimpl::init(const M2MSecurity *security, uint16_t secur
int M2MConnectionSecurityPimpl::connect(M2MConnectionHandler* /*connHandler*/, bool is_server_ping)
{
palStatus_t ret = PAL_SUCCESS;
- if(is_server_ping) {
+ if (is_server_ping) {
tr_info("M2MConnectionSecurityPimpl::connect is SERVER PING");
- ret = pal_handShake_ping(_ssl);
+ ret = pal_handShake(_ssl, _conf, true);
} else {
tr_debug("M2MConnectionSecurityPimpl::connect is normal HANDSHAKE");
- ret = pal_handShake(_ssl, _conf);
+ ret = pal_handShake(_ssl, _conf, false);
}
tr_debug("M2MConnectionSecurityPimpl::connect return code %" PRIx32, ret);
@@ -392,5 +391,5 @@ bool M2MConnectionSecurityPimpl::is_cid_available()
void M2MConnectionSecurityPimpl::set_cid_value(const uint8_t *data_ptr, const size_t data_len)
{
- pal_set_cid_value(_ssl, data_ptr, data_len);
+ pal_set_cid_value(_ssl, _conf, data_ptr, data_len);
}
diff --git a/mbed-client/mbed-client/m2mbase.h b/mbed-client/mbed-client/m2mbase.h
index 01ab00405..4c28da66b 100644
--- a/mbed-client/mbed-client/m2mbase.h
+++ b/mbed-client/mbed-client/m2mbase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 ARM Limited. All rights reserved.
+ * Copyright (c) 2015-2021 Pelion. 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.
@@ -87,9 +87,9 @@ class M2MBase : public M2MReportObserver {
* \brief Enum defining a resource type.
*/
typedef enum {
- Static,
- Dynamic,
- Directory
+ Static, ///< Static resource, value cannot change.
+ Dynamic, ///< Dynamic resource.
+ Directory ///< Unsupported. \deprecated. Obsolete resource type.
} Mode;
/**
@@ -110,22 +110,22 @@ class M2MBase : public M2MReportObserver {
* supported by a given resource.
*/
typedef enum {
- NOT_ALLOWED = 0x00,
- GET_ALLOWED = 0x01,
- PUT_ALLOWED = 0x02,
- GET_PUT_ALLOWED = 0x03,
- POST_ALLOWED = 0x04,
- GET_POST_ALLOWED = 0x05,
- PUT_POST_ALLOWED = 0x06,
- GET_PUT_POST_ALLOWED = 0x07,
- DELETE_ALLOWED = 0x08,
- GET_DELETE_ALLOWED = 0x09,
- PUT_DELETE_ALLOWED = 0x0A,
- GET_PUT_DELETE_ALLOWED = 0x0B,
- POST_DELETE_ALLOWED = 0x0C,
- GET_POST_DELETE_ALLOWED = 0x0D,
- PUT_POST_DELETE_ALLOWED = 0x0E,
- GET_PUT_POST_DELETE_ALLOWED = 0x0F
+ NOT_ALLOWED = 0x00, ///< No operations allowed.
+ GET_ALLOWED = 0x01, ///< Only GET operation allowed.
+ PUT_ALLOWED = 0x02, ///< Only PUT operation allowed.
+ GET_PUT_ALLOWED = 0x03, ///< GET and PUT operations allowed.
+ POST_ALLOWED = 0x04, ///< Only POST operation allowed.
+ GET_POST_ALLOWED = 0x05, ///< \deprecated Unsupported operation mode.
+ PUT_POST_ALLOWED = 0x06, ///< \deprecated Unsupported operation mode.
+ GET_PUT_POST_ALLOWED = 0x07, ///< \deprecated Unsupported operation mode.
+ DELETE_ALLOWED = 0x08, ///< Only DELETE operation allowed.
+ GET_DELETE_ALLOWED = 0x09, ///< GET and DELETE operations allowed.
+ PUT_DELETE_ALLOWED = 0x0A, ///< PUT and DELETE operations allowed.
+ GET_PUT_DELETE_ALLOWED = 0x0B, ///< GET, PUT and DELETE operations allowed.
+ POST_DELETE_ALLOWED = 0x0C, ///< \deprecated Unsupported operation mode.
+ GET_POST_DELETE_ALLOWED = 0x0D, ///< \deprecated Unsupported operation mode.
+ PUT_POST_DELETE_ALLOWED = 0x0E, ///< \deprecated Unsupported operation mode.
+ GET_PUT_POST_DELETE_ALLOWED = 0x0F ///< \deprecated Unsupported operation mode.
} Operation;
/**
@@ -194,6 +194,7 @@ class M2MBase : public M2MReportObserver {
#endif // ENABLE_ASYNC_REST_RESPONSE
/*! \brief LwM2M parameters.
+ * \deprecated This is internal datastructure and subject to be changed or removed. Do not use on application.
*/
typedef struct lwm2m_parameters {
//add multiple_instances
@@ -262,26 +263,31 @@ class M2MBase : public M2MReportObserver {
/**
* \brief Sets the operation type for an object.
* \param operation The operation to be set.
+ *
+ * \deprecated Switching of operation mode on run time is deprecated. Set correct operation mode when creating the resource.
*/
void set_operation(M2MBase::Operation operation);
#if !defined(MEMORY_OPTIMIZED_API) || defined(RESOURCE_ATTRIBUTES_LIST)
+#if !defined(DISABLE_INTERFACE_DESCRIPTION) || defined(RESOURCE_ATTRIBUTES_LIST)
/**
* \brief Sets the interface description of the object.
* \param description The description to be set.
+ * \deprecated Human readable interface descriptions are deprecated.
*/
-#if !defined(DISABLE_INTERFACE_DESCRIPTION) || defined(RESOURCE_ATTRIBUTES_LIST)
void set_interface_description(const String &description);
/**
* \brief Sets the interface description of the object.
* \param description The description to be set.
+ * \deprecated Human readable interface descriptions are deprecated.
*/
void set_interface_description(const char *description);
/**
* \brief Returns the interface description of the object.
* \return The interface description of the object.
+ * \deprecated Human readable interface descriptions are deprecated.
*/
const char *interface_description() const;
#endif
@@ -289,18 +295,21 @@ class M2MBase : public M2MReportObserver {
/**
* \brief Sets the resource type of the object.
* \param resource_type The resource type to be set.
+ * \deprecated Textual content types are deprecated. Please define correct content type when resource is created.
*/
virtual void set_resource_type(const String &resource_type);
/**
* \brief Sets the resource type of the object.
* \param resource_type The resource type to be set.
+ * \deprecated Textual content types are deprecated. Please define correct content type when resource is created.
*/
virtual void set_resource_type(const char *resource_type);
/**
* \brief Returns the resource type of the object.
* \return The resource type of the object.
+ * \deprecated Textual content types are deprecated. Please define correct content type when resource is created.
*/
const char *resource_type() const;
#endif
@@ -310,12 +319,14 @@ class M2MBase : public M2MReportObserver {
* \brief Sets the CoAP content type of the object.
* \param content_type The content type to be set based on
* CoAP specifications.
+ * \deprecated Modifying underlying CoAP library parameters is deprecated. Please define correct content type when resource is created.
*/
void set_coap_content_type(const uint16_t content_type);
/**
* \brief Sets the observable mode for the object.
* \param observable A value for the observation.
+ * \deprecated By default, all resources are now observable so this API is subject to be removed.
*/
void set_observable(bool observable);
@@ -346,12 +357,14 @@ class M2MBase : public M2MReportObserver {
/**
* \brief Adds the observation level for the object.
* \param observation_level The level of observation.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual void add_observation_level(M2MBase::Observation observation_level);
/**
* \brief Removes the observation level for the object.
* \param observation_level The level of observation.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual void remove_observation_level(M2MBase::Observation observation_level);
@@ -360,24 +373,28 @@ class M2MBase : public M2MReportObserver {
* \param observed The value for observation. When true, starts observing. When false, the ongoing observation is cancelled.
* \param handler A handler object for sending
* observation callbacks.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
void set_under_observation(bool observed,
M2MObservationHandler *handler);
/**
* \brief Returns the Observation Handler object.
* \return M2MObservationHandler object.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual M2MObservationHandler *observation_handler() const = 0;
/**
* \brief Sets the observation handler
* \param handler Observation handler
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual void set_observation_handler(M2MObservationHandler *handler) = 0;
/**
* \brief Sets the instance ID of the object.
* \param instance_id The instance ID of the object.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
void set_instance_id(const uint16_t instance_id);
@@ -426,12 +443,14 @@ class M2MBase : public M2MReportObserver {
/**
* \brief Returns the CoAP content type of the object.
* \return The CoAP content type of the object.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
uint16_t coap_content_type() const;
/**
* \brief Returns the observation status of the object.
* \return True if observable, else false.
+ * \deprecated All resources are observable by default.
*/
bool is_observable() const;
@@ -444,6 +463,7 @@ class M2MBase : public M2MReportObserver {
/**
* \brief Returns the observation level of the object.
* \return The observation level of the object.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
M2MBase::Observation observation_level() const;
@@ -471,6 +491,7 @@ class M2MBase : public M2MReportObserver {
* attribute.
* \param query The query that needs to be parsed.
* \return True if required attributes are present, else false.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual bool handle_observation_attribute(const char *query);
#endif
@@ -482,6 +503,7 @@ class M2MBase : public M2MReportObserver {
* \param observation_handler A handler object for sending
* observation callbacks.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual sn_coap_hdr_s *handle_get_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -494,6 +516,7 @@ class M2MBase : public M2MReportObserver {
* observation callbacks.
* \param execute_value_updated True executes the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual sn_coap_hdr_s *handle_put_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -508,6 +531,7 @@ class M2MBase : public M2MReportObserver {
* observation callbacks.
* \param execute_value_updated True executes the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
virtual sn_coap_hdr_s *handle_post_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -523,18 +547,21 @@ class M2MBase : public M2MReportObserver {
/**
* \brief Sets whether this resource is published to server or not.
* \param register_uri True sets the resource as part of registration message.
+ * \deprecated All resources are published. This API is subject to be removed.
*/
void set_register_uri(bool register_uri);
/**
* \brief Returns whether this resource is published to server or not.
* \return True if the resource is a part of the registration message, else false.
+ * \deprecated All resources are published. This API is subject to be removed.
*/
bool register_uri();
/**
* @brief Returns whether this resource is under observation or not.
* @return True if the resource is under observation, else false,
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
bool is_under_observation() const;
@@ -543,6 +570,7 @@ class M2MBase : public M2MReportObserver {
* object receives a PUT or POST command.
* @param callback The function pointer that is called.
* @return True, if callback could be set, false otherwise.
+ * \deprecated Function pointer classes are deprecated. Please use the M2MBase::set_value_updated_function(value_updated_callback2) instead.
*/
bool set_value_updated_function(value_updated_callback callback);
@@ -557,12 +585,14 @@ class M2MBase : public M2MReportObserver {
/**
* @brief Returns whether a callback function is set or not.
* @return True if the callback function is set, else false.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
bool is_value_updated_function_set() const;
/**
* @brief Calls the function that is set in the "set_value_updated_function".
* @param name The name of the object.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
void execute_value_updated(const String &name);
@@ -575,12 +605,14 @@ class M2MBase : public M2MReportObserver {
/**
* @brief Returns the resource information.
* @return Resource information.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
sn_nsdl_dynamic_resource_parameters_s *get_nsdl_resource() const;
/**
* @brief Returns the resource structure.
* @return Resource structure.
+ * \deprecated Internal API. Subject to be removed, please don't use on application code.
*/
M2MBase::lwm2m_parameters_s *get_lwm2m_parameters() const;
@@ -798,8 +830,9 @@ class M2MBase : public M2MReportObserver {
* \brief Cancels the ongoing observation.
*
* \param status Delivery status to be sent to application
+ * \param notify Whether application is notified or not
*/
- void cancel_observation(M2MBase::MessageDeliveryStatus status = M2MBase::MESSAGE_STATUS_UNSUBSCRIBED);
+ void cancel_observation(M2MBase::MessageDeliveryStatus status = M2MBase::MESSAGE_STATUS_UNSUBSCRIBED, bool notify = true);
/**
* \brief Start the observation.
diff --git a/mbed-client/mbed-client/m2mconfig.h b/mbed-client/mbed-client/m2mconfig.h
index 9b0fb14ab..b7860c853 100644
--- a/mbed-client/mbed-client/m2mconfig.h
+++ b/mbed-client/mbed-client/m2mconfig.h
@@ -110,11 +110,11 @@ typedef uint32_t (*random_number_cb)(void) ;
* a complement.
*/
typedef struct mbedtls_entropy {
- int (*entropy_source_ptr)(void *, unsigned char *,size_t , size_t *);
+ int (*entropy_source_ptr)(void *, unsigned char *, size_t, size_t *);
void *p_source;
size_t threshold;
int strong;
-}entropy_cb;
+} entropy_cb;
// Include user provided configuration
@@ -174,10 +174,23 @@ typedef struct mbedtls_entropy {
#define MEMORY_OPTIMIZED_API MBED_CONF_MBED_CLIENT_MEMORY_OPTIMIZED_API
#endif
+#ifdef MBED_CONF_MBED_CLIENT_MAX_CERTIFICATE_SIZE
+#define MAX_CERTIFICATE_SIZE MBED_CONF_MBED_CLIENT_MAX_CERTIFICATE_SIZE
+#else
+#define MAX_CERTIFICATE_SIZE 1024
+#endif
+
#ifndef MBED_CONF_MBED_CLIENT_ENABLE_OBSERVATION_PARAMETERS
#define MBED_CONF_MBED_CLIENT_ENABLE_OBSERVATION_PARAMETERS 1
#endif
+#ifdef MBED_CONF_MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
+#define MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE MBED_CONF_MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
+#endif
+#ifndef MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
+#define MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE 1
+#endif
+
// Define defaults if not defined yet.
#ifndef MBED_CLIENT_RECONNECTION_COUNT
diff --git a/mbed-client/mbed-client/m2mconnectionhandler.h b/mbed-client/mbed-client/m2mconnectionhandler.h
index 8e7072bab..3b44a3ca9 100644
--- a/mbed-client/mbed-client/m2mconnectionhandler.h
+++ b/mbed-client/mbed-client/m2mconnectionhandler.h
@@ -52,13 +52,24 @@ class M2MConnectionHandler {
SOCKET_TIMEOUT = -13,
} ConnectionError;
+ /**
+ * @enum SocketPriority
+ * This enum defines priority for the socket.
+ * Used for setting traffic class socket option.
+ */
+ typedef enum {
+ DEFAULT_PRIORITY = 0,
+ HIGH_PRIORITY = 10,
+ ALERT_PRIORITY = 46
+ } SocketPriority;
+
public:
/**
* \brief Constructor
*/
M2MConnectionHandler(M2MConnectionObserver &observer,
- M2MConnectionSecurity* sec,
+ M2MConnectionSecurity *sec,
M2MInterface::BindingMode mode,
M2MInterface::NetworkStack stack);
@@ -85,10 +96,10 @@ class M2MConnectionHandler {
* \param is_server_ping Defines whether the call is for Server ping or not.
* \return True if the address is valid, else false.
*/
- bool resolve_server_address(const String& server_address,
+ bool resolve_server_address(const String &server_address,
const uint16_t server_port,
M2MConnectionObserver::ServerType server_type,
- const M2MSecurity* security,
+ const M2MSecurity *security,
bool is_server_ping = false);
/**
@@ -99,8 +110,8 @@ class M2MConnectionHandler {
* \return True if data is sent successfully, else false.
*/
bool send_data(uint8_t *data_ptr,
- uint16_t data_len,
- sn_nsdl_addr_s *address_ptr);
+ uint16_t data_len,
+ sn_nsdl_addr_s *address_ptr);
/**
* \brief Listens to the incoming data from a remote server.
@@ -151,6 +162,12 @@ class M2MConnectionHandler {
*/
void unregister_network_handler();
+ /**
+ * \brief Set socket priority.
+ * \return true if socket option was set correctly.
+ */
+ bool set_socket_priority(M2MConnectionHandler::SocketPriority priority);
+
/**
* \brief Stores CID persistently for DTLS connections.
*/
@@ -163,7 +180,7 @@ class M2MConnectionHandler {
/**
* \brief Status of CID availability in client.
- * return true if CID is available else false.
+ * \return true if CID is available else false.
*/
bool is_cid_available();
@@ -179,10 +196,10 @@ class M2MConnectionHandler {
M2MConnectionObserver &_observer;
M2MConnectionHandlerPimpl *_private_impl;
-friend class Test_M2MConnectionHandler;
-friend class Test_M2MConnectionHandler_mbed;
-friend class Test_M2MConnectionHandler_linux;
-friend class M2MConnection_TestObserver;
+ friend class Test_M2MConnectionHandler;
+ friend class Test_M2MConnectionHandler_mbed;
+ friend class Test_M2MConnectionHandler_linux;
+ friend class M2MConnection_TestObserver;
};
#endif //M2M_CONNECTION_HANDLER_H__
diff --git a/mbed-client/mbed-client/m2mconstants.h b/mbed-client/mbed-client/m2mconstants.h
index 2c3e27a3c..67198f95b 100644
--- a/mbed-client/mbed-client/m2mconstants.h
+++ b/mbed-client/mbed-client/m2mconstants.h
@@ -30,8 +30,8 @@ const uint8_t MINIMUM_REGISTRATION_TIME = 60; //in seconds
const uint8_t ONE_SECOND_TIMER = 1;
const uint8_t MAX_ALLOWED_STRING_LENGTH = 64;
const uint8_t MAX_ALLOWED_ERROR_STRING_LENGTH = 64;
-const uint16_t MAX_CERTIFICATE_SIZE = 1024;
const uint16_t CONFIG_BOOLEAN_ITEM_SIZE = 4;
+const uint16_t MAX_FIRMWARE_PACKAGE_URI_PATH_LEN = 255;
const uint32_t HANDSHAKE_TIMEOUT_MSECS = (30 * 60 * 1000);
// XXX:
@@ -150,7 +150,7 @@ const uint32_t HANDSHAKE_TIMEOUT_MSECS = (30 * 60 * 1000);
#define FIRMWARE_UPDATE_RESULT "5"
#define FIRMWARE_PACKAGE_NAME "6"
#define FIRMWARE_PACKAGE_VERSION "7"
-#define FIRMAWARE_PACKAGE_URI_PATH FIRMWARE_PATH_PREFIX FIRMWARE_PACKAGE_URI
+#define FIRMWARE_PACKAGE_URI_PATH FIRMWARE_PATH_PREFIX FIRMWARE_PACKAGE_URI
// Error Strings
diff --git a/mbed-client/mbed-client/m2minterface.h b/mbed-client/mbed-client/m2minterface.h
index 234a3c2b4..c0460d4d4 100644
--- a/mbed-client/mbed-client/m2minterface.h
+++ b/mbed-client/mbed-client/m2minterface.h
@@ -34,8 +34,8 @@ class M2MBase;
class M2MInterfaceObserver;
class M2MServer;
-typedef Vector M2MObjectList;
-typedef Vector M2MBaseList;
+typedef Vector M2MObjectList;
+typedef Vector M2MBaseList;
typedef FP callback_handler;
typedef enum request_error_e {
@@ -112,7 +112,7 @@ class M2MInterface {
ESTEnrollmentFailed,
FailedToStoreCredentials,
FailedToReadCredentials
- }Error;
+ } Error;
/**
* \brief An enum defining different kinds of binding
@@ -123,13 +123,13 @@ class M2MInterface {
UDP = 0x01,
UDP_QUEUE = 0x03,
SMS = 0x04,
- SMS_QUEUE =0x06,
+ SMS_QUEUE = 0x06,
UDP_SMS_QUEUE = 0x07,
TCP = 0x09, //not real value, spec does not have one!
- //this has nsdl binding mode bit UDP set
+ //this has nsdl binding mode bit UDP set
TCP_QUEUE = 0x0b //not real value, spec does not have one!
- //this has nsdl binding mode bits, UDP and UDP_QUEUE set
- }BindingMode;
+ //this has nsdl binding mode bits, UDP and UDP_QUEUE set
+ } BindingMode;
/**
* \brief An enum defining different kinds of network
@@ -143,11 +143,11 @@ class M2MInterface {
Nanostack_IPv6,
ATWINC_IPv4,
Unknown
- }NetworkStack;
+ } NetworkStack;
public:
- virtual ~M2MInterface(){}
+ virtual ~M2MInterface() {}
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
/**
@@ -250,7 +250,7 @@ class M2MInterface {
* needs to be unregistered. If there is only one LWM2M server registered,
* this parameter can be NULL.
*/
- virtual void unregister_object(M2MSecurity* security_object = NULL) = 0;
+ virtual void unregister_object(M2MSecurity *security_object = NULL) = 0;
/**
* \brief Sets the function that is called for indicating that the client
@@ -380,13 +380,25 @@ class M2MInterface {
*/
virtual void pause() = 0;
- virtual nsdl_s* get_nsdl_handle() const = 0;
+ /**
+ * \brief Sets client into an alert mode.
+ *
+ * \note In alert mode client halts all data
+ * sendings/active operations and waits for priority data to be sent.
+ */
+ virtual void alert() = 0;
+
+ /**
+ * @brief Get ndsl handle.
+ * @return nsdl handle
+ */
+ virtual nsdl_s *get_nsdl_handle() const = 0;
/**
* @brief Returns M2MServer handle.
* @return M2MServer handle
*/
- virtual M2MServer* get_m2mserver() const = 0;
+ virtual M2MServer *get_m2mserver() const = 0;
virtual uint16_t stagger_wait_time(bool boostrap) const = 0;
diff --git a/mbed-client/mbed-client/m2minterfaceobserver.h b/mbed-client/mbed-client/m2minterfaceobserver.h
index 1d5a2f164..b76f62200 100644
--- a/mbed-client/mbed-client/m2minterfaceobserver.h
+++ b/mbed-client/mbed-client/m2minterfaceobserver.h
@@ -67,7 +67,7 @@ class M2MInterfaceObserver {
* \param server_object An object containing information about the LWM2M server.
* The client maintains the object.
*/
- virtual void registration_updated(M2MSecurity *security_object, const M2MServer & server_object) = 0;
+ virtual void registration_updated(M2MSecurity *security_object, const M2MServer &server_object) = 0;
/**
* \brief A callback indicating that there was an error during the operation.
@@ -94,6 +94,15 @@ class M2MInterfaceObserver {
*/
virtual void network_status_changed(bool connected) = 0;
+ /**
+ * \brief A callback indicating that client is paused.
+ */
+ virtual void paused() = 0;
+
+ /**
+ * \brief A callback indicating that client is in alert mode.
+ */
+ virtual void alert_mode() = 0;
};
#endif // M2M_INTERFACE_OBSERVER_H
diff --git a/mbed-client/mbed-client/m2mobject.h b/mbed-client/mbed-client/m2mobject.h
index dfc6ba479..c98fe399a 100644
--- a/mbed-client/mbed-client/m2mobject.h
+++ b/mbed-client/mbed-client/m2mobject.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 ARM Limited. All rights reserved.
+ * Copyright (c) 2015-2021 Pelion. 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.
@@ -85,6 +85,8 @@ protected :
* \brief Creates a new object instance for a given mbed Client Interface object. With this,
* the client can respond to server's GET methods with the provided value.
* \return M2MObjectInstance. An object instance for managing other client operations.
+ *
+ * \deprecated Internal lwm2m_parameter_s structure is deprecated. Please use M2MObject::create_object_instance(uint16_t) instead.
*/
M2MObjectInstance* create_object_instance(const lwm2m_parameters_s* s);
@@ -117,24 +119,28 @@ protected :
/**
* \brief Returns the Observation Handler object.
* \return M2MObservationHandler object.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual M2MObservationHandler* observation_handler() const;
/**
* \brief Sets the observation handler
* \param handler Observation handler
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void set_observation_handler(M2MObservationHandler *handler);
/**
* \brief Adds the observation level for the object.
* \param observation_level The level of observation.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void add_observation_level(M2MBase::Observation observation_level);
/**
* \brief Removes the observation level from the object.
* \param observation_level The level of observation.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void remove_observation_level(M2MBase::Observation observation_level);
@@ -145,6 +151,7 @@ protected :
* \param observation_handler The handler object for sending
* observation callbacks.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_get_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -158,6 +165,7 @@ protected :
* observation callbacks.
* \param execute_value_updated True will execute the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_put_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -172,6 +180,7 @@ protected :
* observation callbacks.
* \param execute_value_updated True will execute the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -179,6 +188,9 @@ protected :
bool &execute_value_updated,
sn_nsdl_addr_s *address = NULL);
+ /**
+ * \deprecated Internal API, subject to be modified or removed.
+ */
void notification_update(uint16_t obj_instance_id);
#ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION
diff --git a/mbed-client/mbed-client/m2mobjectinstance.h b/mbed-client/mbed-client/m2mobjectinstance.h
index 0e5bb1086..5bd201120 100644
--- a/mbed-client/mbed-client/m2mobjectinstance.h
+++ b/mbed-client/mbed-client/m2mobjectinstance.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 ARM Limited. All rights reserved.
+ * Copyright (c) 2015-2021 Pelion. 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.
@@ -75,6 +75,7 @@ friend class M2MObject;
/**
* \brief TODO!
* \return M2MResource The resource for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResource* create_static_resource(const lwm2m_parameters_s* static_res,
M2MResourceInstance::ResourceType type);
@@ -91,6 +92,7 @@ friend class M2MObject;
* \param external_blockwise_store If true CoAP blocks are passed to application through callbacks
* otherwise handled in mbed-client-c.
* \return M2MResource The resource for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResource* create_static_resource(const String &resource_name,
const String &resource_type,
@@ -112,6 +114,7 @@ friend class M2MObject;
* \param external_blockwise_store If true CoAP blocks are passed to application through callbacks
* otherwise handled in mbed-client-c.
* \return M2MResource The resource for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResource* create_dynamic_resource(const String &resource_name,
const String &resource_type,
@@ -132,6 +135,7 @@ friend class M2MObject;
* \param external_blockwise_store If true CoAP blocks are passed to application through callbacks
* otherwise handled in mbed-client-c.
* \return M2MResource The resource for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResource* create_dynamic_resource(const uint16_t resource_name,
const char *resource_type,
@@ -143,6 +147,7 @@ friend class M2MObject;
/**
* \brief TODO!
* \return M2MResource The resource for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResource* create_dynamic_resource(const lwm2m_parameters_s* static_res,
M2MResourceInstance::ResourceType type,
@@ -159,6 +164,7 @@ friend class M2MObject;
* \param external_blockwise_store If true CoAP blocks are passed to application through callbacks
* otherwise handled in mbed-client-c.
* \return M2MResourceInstance The resource instance for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResourceInstance* create_static_resource_instance(const String &resource_name,
const String &resource_type,
@@ -179,6 +185,7 @@ friend class M2MObject;
* \param external_blockwise_store If true CoAP blocks are passed to application through callbacks
* otherwise handled in mbed-client-c.
* \return M2MResourceInstance The resource instance for managing other client operations.
+ * \deprecated Please use M2MInterfaceFactory::create_resource() instead.
*/
M2MResourceInstance* create_dynamic_resource_instance(const String &resource_name,
const String &resource_type,
@@ -193,6 +200,7 @@ friend class M2MObject;
* Note: this will be removed in next version, please use the
* remove_resource(const char*) version instead.
* \return True if removed, else false.
+ * \deprecated String based APIs are deprecated. Please use the id or path instead.
*/
bool remove_resource(const String &name);
@@ -219,6 +227,9 @@ friend class M2MObject;
*/
M2MResource* resource(const uint16_t resource_id) const;
+ /**
+ * \deprecated String based APIs are deprecated. Please use resource_id or path instead.
+ */
M2MResource* resource(const String &name) const;
M2MResource* resource(const char *resource) const;
@@ -241,6 +252,7 @@ friend class M2MObject;
* resource_count(const char*) version instead.
* \param resource The name of the resource.
* \return Total number of the resources.
+ * \deprecated String based APIs are deprecated. Please use resource_id or path instead.
*/
uint16_t resource_count(const String& resource) const;
@@ -254,24 +266,28 @@ friend class M2MObject;
/**
* \brief Adds the observation level for the object.
* \param observation_level The level of observation.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void add_observation_level(M2MBase::Observation observation_level);
/**
* \brief Removes the observation level from the object.
* \param observation_level The level of observation.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void remove_observation_level(M2MBase::Observation observation_level);
/**
* \brief Returns the Observation Handler object.
* \return M2MObservationHandler object.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual M2MObservationHandler* observation_handler() const;
/**
* \brief Sets the observation handler
* \param handler Observation handler
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void set_observation_handler(M2MObservationHandler *handler);
@@ -282,6 +298,7 @@ friend class M2MObject;
* \param observation_handler The handler object for sending
* observation callbacks.
* return sn_coap_hdr_s The message that needs to be sent to the server.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_get_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -294,6 +311,7 @@ friend class M2MObject;
* observation callbacks.
* \param execute_value_updated True will execute the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_put_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -308,6 +326,7 @@ friend class M2MObject;
* observation callbacks.
* \param execute_value_updated True will execute the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to server.
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -317,7 +336,9 @@ friend class M2MObject;
inline M2MObject& get_parent_object() const;
- // callback used from M2MResource/M2MResourceInstance
+ /** callback used from M2MResource/M2MResourceInstance
+ * \deprecated Internal API, subject to be modified or removed.
+ */
void notification_update(M2MBase::Observation observation_level);
protected:
@@ -353,6 +374,7 @@ friend class M2MObject;
friend class Test_M2MResourceInstance;
friend class Test_M2MReportHandler;
friend class TestFactory;
+ friend class Test_M2MInterfaceImpl;
};
inline M2MObject& M2MObjectInstance::get_parent_object() const
diff --git a/mbed-client/mbed-client/m2mresource.h b/mbed-client/mbed-client/m2mresource.h
index 9a9b505fa..50eefa51d 100644
--- a/mbed-client/mbed-client/m2mresource.h
+++ b/mbed-client/mbed-client/m2mresource.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 ARM Limited. All rights reserved.
+ * Copyright (c) 2015-2021 Pelion. 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.
@@ -144,6 +144,13 @@ class M2MResource : public M2MResourceBase
#else
void set_delayed_response(bool delayed_response);
#endif
+ /**
+ * \brief Check if resource is set to send delayed responses for POST request.
+ * Use set_delayed_response() for enabling or disabling delayed response.
+ * \return True, if delayed response is enabled.
+ */
+ bool delayed_response() const;
+
/**
* \brief A trigger to send the delayed response for the POST request.
* The delayed_response flag must be set before receiving the POST request
@@ -152,22 +159,19 @@ class M2MResource : public M2MResourceBase
* Please use M2MBase::send_async_response_with_code method, if you are using
* ENABLE_ASYNC_REST_RESPONSE flag, because this method will be deprecated.
* \param code Response code to be sent.
- * \return True if a response is sent, else false.
+ * \return True if delayed response is enabled.
*/
bool send_delayed_post_response(sn_coap_msg_code_e code = COAP_MSG_CODE_RESPONSE_CHANGED);
- /**
+ /** \internal
* \brief Provides the value of the token of the delayed post response.
* \param[out] token A pointer to the token value.
* \param[out] token_length The length of the token pointer.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
void get_delayed_token(uint8_t *&token, uint8_t &token_length);
- /**
- * \brief Returns the value set for delayed response for POST requests.
- * \return The value for delayed response.
- */
- bool delayed_response() const;
#endif //DISABLE_DELAYED_RESPONSE
/**
@@ -199,12 +203,16 @@ class M2MResource : public M2MResourceBase
/**
* \brief Returns the Observation Handler object.
* \return M2MObservationHandler object.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual M2MObservationHandler* observation_handler() const;
/**
* \brief Sets the observation handler
* \param handler Observation handler
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void set_observation_handler(M2MObservationHandler *handler);
@@ -213,6 +221,8 @@ class M2MResource : public M2MResourceBase
* \brief Parses the received query for a notification
* attribute.
* \return True if required attributes are present, else false.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual bool handle_observation_attribute(const char *query);
#endif
@@ -220,12 +230,16 @@ class M2MResource : public M2MResourceBase
/**
* \brief Adds the observation level for the object.
* \param observation_level The level of observation.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void add_observation_level(M2MBase::Observation observation_level);
/**
* \brief Removes the observation level from an object.
* \param observation_level The level of observation.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual void remove_observation_level(M2MBase::Observation observation_level);
@@ -236,6 +250,8 @@ class M2MResource : public M2MResourceBase
* \param observation_handler A handler object for sending
* observation callbacks.
* \return sn_coap_hdr_s The message that needs to be sent to the server.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_get_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -248,6 +264,8 @@ class M2MResource : public M2MResourceBase
* observation callbacks.
* \param execute_value_updated True executes the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to the server.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_put_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -261,6 +279,8 @@ class M2MResource : public M2MResourceBase
* observation callbacks.
* \param execute_value_updated True executes the "value_updated" callback.
* \return sn_coap_hdr_s The message that needs to be sent to the server.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl,
sn_coap_hdr_s *received_coap_header,
@@ -268,6 +288,9 @@ class M2MResource : public M2MResourceBase
bool &execute_value_updated,
sn_nsdl_addr_s *address = NULL);
+ /**
+ * \deprecated Internal API, subject to be modified or removed.
+ */
M2MObjectInstance& get_parent_object_instance() const;
/**
@@ -326,6 +349,7 @@ friend class Test_M2MTLVDeserializer;
friend class Test_M2MBase;
friend class Test_M2MResourceInstance;
friend class TestFactory;
+friend class Test_M2MInterfaceImpl;
};
/**
@@ -344,7 +368,9 @@ class M2MResource::M2MExecuteParameter {
#ifdef MEMORY_OPTIMIZED_API
M2MExecuteParameter(const char *object_name, const char *resource_name, uint16_t object_instance_id);
#else
- // This is a deprecated constructor, to be removed on next release.
+ /**
+ * \deprecated This is a deprecated constructor. Subject to be removed.
+ */
M2MExecuteParameter(const String &object_name, const String &resource_name, uint16_t object_instance_id);
#endif
public:
diff --git a/mbed-client/mbed-client/m2mresourcebase.h b/mbed-client/mbed-client/m2mresourcebase.h
index 5908e0161..62bc14dbd 100644
--- a/mbed-client/mbed-client/m2mresourcebase.h
+++ b/mbed-client/mbed-client/m2mresourcebase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 ARM Limited. All rights reserved.
+ * Copyright (c) 2015-2021 Pelion. 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.
@@ -66,7 +66,7 @@ class M2MResourceBase : public M2MBase {
OBJLINK
} ResourceType;
- /*
+ /**
* \brief Value set callback function.
* \param resource Pointer to resource whose value should be updated
* \param value Pointer to value buffer containing new value, ownership is transferred to callback function
@@ -74,7 +74,7 @@ class M2MResourceBase : public M2MBase {
*/
typedef void(*value_set_callback)(const M2MResourceBase *resource, uint8_t *value, const uint32_t value_length);
- /*
+ /**
* \brief Read resource value callback function.
* \param resource Pointer to resource whose value should will be read
* \param buffer[OUT] Buffer containing the resource value
@@ -87,7 +87,7 @@ class M2MResourceBase : public M2MBase {
size_t *buffer_size,
void *client_args);
- /*
+ /**
* \brief Type definition for a read resource value callback function.
* \param[in] resource Pointer to resource whose value should will be read.
* \param[out] buffer Pointer to value buffer.
@@ -104,9 +104,7 @@ class M2MResourceBase : public M2MBase {
const size_t offset,
void *client_args);
-
-
- /*
+ /**
* \brief Read resource value size callback function.
* \param resource Pointer to resource whose size will be read
* \param buffer_size[OUT] Buffer size
@@ -117,7 +115,7 @@ class M2MResourceBase : public M2MBase {
size_t *buffer_size,
void *client_args);
- /*
+ /**
* \brief Set resource value callback function.
* \param resource Pointer to resource whose value will be updated
* \param buffer Buffer containing the new value
@@ -207,6 +205,8 @@ class M2MResourceBase : public M2MBase {
* resource receives a POST command.
* \param callback The function pointer that needs to be executed.
* \return True, if callback could be set, false otherwise.
+ *
+ * \deprecated Function pointer classes are deprecated. Please use M2MResourceBase::set_execute_function(execute_callback_2 callback) instead.
*/
bool set_execute_function(execute_callback callback);
@@ -393,6 +393,8 @@ class M2MResourceBase : public M2MBase {
/**
* \brief Function to report the value changes to the object instance and object parent of the
* resource if they have been subscribed
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
void report_to_parents();
@@ -433,6 +435,9 @@ class M2MResourceBase : public M2MBase {
*/
virtual const char *object_name() const = 0;
+ /**
+ * \deprecated Internal API, subject to be modified or removed.
+ */
virtual M2MResource &get_parent_resource() const = 0;
#ifndef DISABLE_BLOCK_MESSAGE
@@ -462,7 +467,7 @@ class M2MResourceBase : public M2MBase {
#endif
/**
- * @brief Set the status whether resource value will be part of registration message. *
+ * @brief Set the status whether resource value will be part of registration message.
* This only allowed for following resource types:
* STRING,
* INTEGER,
@@ -471,6 +476,8 @@ class M2MResourceBase : public M2MBase {
* OPAQUE
*
* @param publish_value If true then resource value will be part of registration message.
+ *
+ * \deprecated Internal API, subject to be modified or removed.
*/
void publish_value_in_registration_msg(bool publish_value);
diff --git a/mbed-client/mbed-client/m2mserver.h b/mbed-client/mbed-client/m2mserver.h
index 8942678e7..5b47b9902 100644
--- a/mbed-client/mbed-client/m2mserver.h
+++ b/mbed-client/mbed-client/m2mserver.h
@@ -33,6 +33,7 @@ class M2MServer : public M2MObject
friend class M2MInterfaceFactory;
friend class M2MNsdlInterface;
+friend class M2MInterfaceImpl;
public:
diff --git a/mbed-client/mbed_lib.json b/mbed-client/mbed_lib.json
index 77ace385a..36b4ff10f 100644
--- a/mbed-client/mbed_lib.json
+++ b/mbed-client/mbed_lib.json
@@ -20,6 +20,12 @@
"disable-delayed-response": null,
"disable-block-message": null,
"memory-optimized-api": null,
- "enable-observation-parameters" : 1
+ "max-certificate-size": {
+ "help": "Maximum size for buffer passing around certificate chain.",
+ "default": 1024,
+ "value": 1024
+ },
+ "enable-observation-parameters" : 1,
+ "bootstrap-piggybacked-response" : null
}
}
diff --git a/mbed-client/source/include/m2minterfaceimpl.h b/mbed-client/source/include/m2minterfaceimpl.h
index 83ff4019a..9b153e2f2 100644
--- a/mbed-client/source/include/m2minterfaceimpl.h
+++ b/mbed-client/source/include/m2minterfaceimpl.h
@@ -41,18 +41,17 @@ class M2MUpdateRegisterData;
*/
class M2MInterfaceImpl : public M2MInterface,
- public M2MNsdlObserver,
- public M2MConnectionObserver,
- public M2MTimerObserver
-{
+ public M2MNsdlObserver,
+ public M2MConnectionObserver,
+ public M2MTimerObserver {
private:
// Prevents the use of assignment operator by accident.
- M2MInterfaceImpl& operator=( const M2MInterfaceImpl& /*other*/ );
+ M2MInterfaceImpl &operator=(const M2MInterfaceImpl & /*other*/);
// Prevents the use of copy constructor by accident
- M2MInterfaceImpl( const M2MInterfaceImpl& /*other*/ );
+ M2MInterfaceImpl(const M2MInterfaceImpl & /*other*/);
-friend class M2MInterfaceFactory;
+ friend class M2MInterfaceFactory;
private:
@@ -70,7 +69,7 @@ friend class M2MInterfaceFactory;
* @param context_address Context address, default is empty.
* @param version Version of the LwM2M Enabler that the LwM2M Client supports.
*/
- M2MInterfaceImpl(M2MInterfaceObserver& observer,
+ M2MInterfaceImpl(M2MInterfaceObserver &observer,
const String &endpoint_name,
const String &endpoint_type,
const int32_t life_time,
@@ -179,7 +178,7 @@ friend class M2MInterfaceFactory;
* needs to be unregistered. If there is only one LWM2M server registered
* this parameter can be NULL.
*/
- virtual void unregister_object(M2MSecurity* security = NULL);
+ virtual void unregister_object(M2MSecurity *security = NULL);
/**
* @brief Sets the function which will be called indicating client
@@ -315,13 +314,25 @@ friend class M2MInterfaceFactory;
*/
virtual void pause();
- virtual nsdl_s* get_nsdl_handle() const;
+ /**
+ * \brief Sets client into an alert mode.
+ *
+ * \note In alert mode client halts all data
+ * sendings/active operations and waits for priority data to be sent.
+ */
+ virtual void alert();
+
+ /**
+ * @brief Get ndsl handle.
+ * @return nsdl handle
+ */
+ virtual nsdl_s *get_nsdl_handle() const;
/**
* @brief Returns M2MServer handle.
* @return M2MServer handle
*/
- virtual M2MServer* get_m2mserver() const;
+ virtual M2MServer *get_m2mserver() const;
/**
* \brief Internal test function. Set CID for current tls session.
@@ -365,7 +376,7 @@ friend class M2MInterfaceFactory;
protected: // From M2MConnectionObserver
- virtual void data_available(uint8_t* data,
+ virtual void data_available(uint8_t *data,
uint16_t data_size,
const M2MConnectionObserver::SocketAddress &address);
@@ -389,94 +400,94 @@ friend class M2MInterfaceFactory;
/**
* When the state is Idle.
*/
- void state_idle(EventData* data);
+ void state_idle(EventData *data);
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
/**
* When the client starts bootstrap.
*/
- void state_bootstrap( EventData *data);
+ void state_bootstrap(EventData *data);
/**
* When the bootstrap server address is resolved.
*/
- void state_bootstrap_address_resolved( EventData *data);
+ void state_bootstrap_address_resolved(EventData *data);
/**
* When the bootstrap resource is created.
*/
- void state_bootstrap_resource_created( EventData *data);
+ void state_bootstrap_resource_created(EventData *data);
/**
* When the server has sent response and bootstrapping is done.
*/
- void state_bootstrapped( EventData *data);
+ void state_bootstrapped(EventData *data);
#endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
/**
* When the client starts register.
*/
- void state_register( EventData *data);
+ void state_register(EventData *data);
/**
* When the server address for register is resolved.
*/
- void state_register_address_resolved( EventData *data);
+ void state_register_address_resolved(EventData *data);
/**
* When the client is registered.
*/
- void state_registered( EventData *data);
+ void state_registered(EventData *data);
/**
* When the client is updating registration.
*/
- void state_update_registration( EventData *data);
+ void state_update_registration(EventData *data);
/**
* When the client starts unregister.
*/
- void state_unregister( EventData *data);
+ void state_unregister(EventData *data);
/**
* When the client has been unregistered.
*/
- void state_unregistered( EventData *data);
+ void state_unregistered(EventData *data);
/**
* When the coap data is been sent through socket.
*/
- void state_sending_coap_data( EventData *data);
+ void state_sending_coap_data(EventData *data);
/**
* When the coap data is sent successfully.
*/
- void state_coap_data_sent( EventData *data);
+ void state_coap_data_sent(EventData *data);
/**
* When the socket is receiving coap data.
*/
- void state_receiving_coap_data( EventData *data);
+ void state_receiving_coap_data(EventData *data);
/**
* When the socket has received coap data.
*/
- void state_coap_data_received( EventData *data);
+ void state_coap_data_received(EventData *data);
/**
* When the coap message is being processed.
*/
- void state_processing_coap_data( EventData *data);
+ void state_processing_coap_data(EventData *data);
/**
* When the coap message has been processed.
*/
- void state_coap_data_processed( EventData *data);
+ void state_coap_data_processed(EventData *data);
/**
* When the client is waiting to receive or send data.
*/
- void state_waiting( EventData *data);
+ void state_waiting(EventData *data);
/**
* Start registration update.
@@ -517,7 +528,7 @@ friend class M2MInterfaceFactory;
* @param current_state Current state to be set.
* @param data Data to be passed to the state function.
*/
- void state_function( uint8_t current_state, EventData* data );
+ void state_function(uint8_t current_state, EventData *data);
/**
* @brief State Engine maintaining state machine logic.
@@ -529,14 +540,14 @@ friend class M2MInterfaceFactory;
* @param New The state to which the state machine should go.
* @param data The data to be passed to the state machine.
*/
- void external_event(uint8_t, EventData* = NULL);
+ void external_event(uint8_t, EventData * = NULL);
/**
* Internal event generated by state machine.
* @param New State which the state machine should go to.
* @param data The data to be passed to the state machine.
*/
- void internal_event(uint8_t, EventData* = NULL);
+ void internal_event(uint8_t, EventData * = NULL);
/**
* Queue mode enabled or not.
@@ -544,8 +555,7 @@ friend class M2MInterfaceFactory;
*/
bool queue_mode() const;
- enum
- {
+ enum {
EVENT_IGNORED = 0xFE,
CANNOT_HAPPEN
};
@@ -557,7 +567,7 @@ friend class M2MInterfaceFactory;
* @param ip_address The extracted IP.
* @param port The extracted port.
*/
- static void process_address(const String& server_address, String& ip_address, uint16_t& port);
+ static void process_address(const String &server_address, String &ip_address, uint16_t &port);
/**
* Helper method for storing the error description to _error_description if the feature
@@ -569,11 +579,26 @@ friend class M2MInterfaceFactory;
/**
* Helper method for creating random initial reconnection time interval.
*/
- void create_random_initial_reconnection_time();
+ void create_random_initial_reconnection_time();
- void update_network_latency_configurations_with_rtt();
+ void update_network_latency_configurations_with_rtt();
+
+ /**
+ * @brief Callback function which is called when POST comes to resource 1/0/4. Triggers de-registration.
+ * @param argument, Pointer to M2MResource::M2MExecuteParameter.
+ */
+ void disable_callback(void *argument);
+
+ /**
+ * @brief Callback function which is called when acknowledgement for the response to POST to resource 1/0/4
+ * is received from server.
+ */
+ static void post_response_status_handler(const M2MBase &base,
+ const M2MBase::MessageDeliveryStatus status,
+ const M2MBase::MessageType type,
+ void *me);
- enum ReconnectionState{
+ enum ReconnectionState {
None,
WithUpdate,
Unregistration,
@@ -582,40 +607,41 @@ friend class M2MInterfaceFactory;
private:
- EventData *_event_data;
- uint16_t _server_port;
- uint16_t _listen_port;
- int32_t _life_time;
- String _server_ip_address;
- M2MSecurity *_register_server; //TODO: to be the list not owned
- M2MTimer _queue_sleep_timer;
- M2MTimer _retry_timer;
- callback_handler _callback_handler;
- const uint8_t _max_states;
- bool _event_ignored;
- bool _event_generated;
- bool _reconnecting;
- bool _retry_timer_expired;
- bool _bootstrapped;
- bool _bootstrap_finished;
- bool _queue_mode_timer_ongoing;
- uint8_t _current_state;
- BindingMode _binding_mode;
- ReconnectionState _reconnection_state;
- M2MInterfaceObserver &_observer;
- M2MConnectionSecurity *_security_connection; // Doesn't own
- M2MConnectionHandler _connection_handler;
- M2MNsdlInterface _nsdl_interface;
- M2MSecurity *_security;
+ EventData *_event_data;
+ M2MConnectionObserver::SocketAddress _server_address;
+ uint16_t _server_port;
+ uint16_t _listen_port;
+ int32_t _life_time;
+ String _server_ip_address;
+ M2MSecurity *_register_server; //TODO: to be the list not owned
+ M2MTimer _queue_sleep_timer;
+ M2MTimer _retry_timer;
+ callback_handler _callback_handler;
+ const uint8_t _max_states;
+ bool _event_ignored;
+ bool _event_generated;
+ bool _reconnecting;
+ bool _retry_timer_expired;
+ bool _bootstrapped;
+ bool _bootstrap_finished;
+ bool _queue_mode_timer_ongoing;
+ uint8_t _current_state;
+ BindingMode _binding_mode;
+ ReconnectionState _reconnection_state;
+ M2MInterfaceObserver &_observer;
+ M2MConnectionSecurity *_security_connection; // Doesn't own
+ M2MConnectionHandler _connection_handler;
+ M2MNsdlInterface _nsdl_interface;
+ M2MSecurity *_security;
#ifndef DISABLE_ERROR_DESCRIPTION
// The DISABLE_ERROR_DESCRIPTION macro will reduce the flash usage by ~1800 bytes.
- char _error_description[MAX_ALLOWED_ERROR_STRING_LENGTH];
+ char _error_description[MAX_ALLOWED_ERROR_STRING_LENGTH];
#endif
// Reconnection related variables (in seconds)
- uint16_t _initial_reconnection_time;
- uint32_t _reconnection_time;
+ uint16_t _initial_reconnection_time;
+ uint32_t _reconnection_time;
friend class Test_M2MInterfaceImpl;
diff --git a/mbed-client/source/include/m2mnsdlinterface.h b/mbed-client/source/include/m2mnsdlinterface.h
index 0b98c0cb1..3cf133c02 100644
--- a/mbed-client/source/include/m2mnsdlinterface.h
+++ b/mbed-client/source/include/m2mnsdlinterface.h
@@ -89,6 +89,15 @@ class M2MNsdlInterface : public M2MTimerObserver,
typedef NS_LIST_HEAD(coap_response_s, link) response_list_t;
+ /**
+ * Enum defining an Notification queue options
+ */
+ typedef enum {
+ SEND_NOTIFICATION, // Send next notification
+ CLEAR_NOTIFICATION_TOKEN, // Clear notification token
+ REMOVE_NOTIFICATION // Remove notification from queue
+ } NotificationQueueOption;
+
/**
* @brief Constructor
* @param observer, Observer to pass the event callbacks from nsdl library.
@@ -289,6 +298,18 @@ class M2MNsdlInterface : public M2MTimerObserver,
*/
void stop_timers();
+ /**
+ * @brief Store alert mode state.
+ * @param alert Alert mode set or not.
+ */
+ void set_alert_mode(bool alert);
+
+ /**
+ * @brief Get the client alert mode status.
+ * @return True if client in alert mode otherwise False.
+ */
+ bool alert_mode() const;
+
/**
* @brief Returns nsdl handle.
* @return ndsl handle
@@ -325,7 +346,7 @@ class M2MNsdlInterface : public M2MTimerObserver,
*/
bool remove_object_from_list(M2MBase *base);
- /*
+ /**
* @brief Get NSDL timer.
* @return NSDL execution timer.
*/
@@ -348,6 +369,11 @@ class M2MNsdlInterface : public M2MTimerObserver,
*/
void start_nsdl_execution_timer();
+ /**
+ * @brief Stops the NSDL execution timer.
+ */
+ void stop_nsdl_execution_timer();
+
/**
* @brief Returns security object.
* @return M2MSecurity object, contains lwm2m server information.
@@ -383,7 +409,7 @@ class M2MNsdlInterface : public M2MTimerObserver,
/**
* @brief Send next notification message.
*/
- void send_next_notification(bool clear_token);
+ void send_next_notification(NotificationQueueOption option);
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
/**
@@ -463,6 +489,13 @@ class M2MNsdlInterface : public M2MTimerObserver,
*/
void set_cid_value(const uint8_t *data_ptr, const size_t data_len);
+ /**
+ * Helper method called from lifetime_write_callback.
+ * \param buffer Data holding lifetime value.
+ * \param buffer_size Size of the buffer.
+ */
+ bool update_server_lifetime(const uint8_t *buffer, const size_t buffer_size);
+
protected: // from M2MTimerObserver
virtual void timer_expired(M2MTimerObserver::Type type);
@@ -664,7 +697,7 @@ class M2MNsdlInterface : public M2MTimerObserver,
bool lifetime_value_changed() const;
- void execute_notification_delivery_status_cb(M2MBase *object, int32_t msgid);
+ void handle_observation_response(M2MBase *object, int32_t msgid);
bool is_response_to_request(const sn_coap_hdr_s *coap_header,
struct request_context_s &get_data);
@@ -685,7 +718,8 @@ class M2MNsdlInterface : public M2MTimerObserver,
* @param clear_token, Flag to indicate whether observation token should be cleared.
* @return True if notification sent, false otherwise or if send already in progress
*/
- bool send_next_notification_for_object(M2MObject &object, bool clear_token);
+ bool send_next_notification_for_object(M2MObject &object, NotificationQueueOption option);
+ bool handle_notification_queue(M2MObject &object, NotificationQueueOption option);
static char *parse_uri_query_parameters(char *uri);
@@ -706,7 +740,7 @@ class M2MNsdlInterface : public M2MTimerObserver,
void handle_request_response(const sn_coap_hdr_s *coap_header, struct request_context_s *request_context);
- void handle_message_delivered(M2MBase *base, const M2MBase::MessageType type);
+ void handle_message_status_callback(M2MBase *base, const M2MBase::MessageType type, const M2MBase::MessageDeliveryStatus status);
void handle_empty_ack(const sn_coap_hdr_s *coap_header, bool is_bootstrap_msg);
@@ -779,6 +813,9 @@ class M2MNsdlInterface : public M2MTimerObserver,
M2MTimer _download_retry_timer;
uint32_t _download_retry_time;
uint8_t _network_rtt_estimate;
+ bool _alert_mode;
+ NotificationQueueOption _last_notif_queue_event;
+ sn_coap_msg_code_e _current_request_code;
friend class Test_M2MNsdlInterface;
diff --git a/mbed-client/source/include/m2mreporthandler.h b/mbed-client/source/include/m2mreporthandler.h
index 769d79194..f832bc5da 100644
--- a/mbed-client/source/include/m2mreporthandler.h
+++ b/mbed-client/source/include/m2mreporthandler.h
@@ -277,6 +277,11 @@ class M2MReportHandler
*/
void start_timers();
+ /**
+ * @brief Stop pmin & pmax timers.
+ */
+ void stop_timers();
+
protected : // from M2MTimerObserver
virtual void timer_expired(M2MTimerObserver::Type type =
@@ -310,10 +315,7 @@ protected : // from M2MTimerObserver
*/
bool check_attribute_validity() const;
- /**
- * @brief Stop pmin & pmax timers.
- */
- void stop_timers();
+
/**
* @brief Check if current value match threshold values.
diff --git a/mbed-client/source/include/m2mtlvdeserializer.h b/mbed-client/source/include/m2mtlvdeserializer.h
index c926f0eaa..20a547a5c 100644
--- a/mbed-client/source/include/m2mtlvdeserializer.h
+++ b/mbed-client/source/include/m2mtlvdeserializer.h
@@ -34,7 +34,8 @@ public :
NotFound,
NotAllowed,
NotValid,
- OutOfMemory
+ OutOfMemory,
+ NotAccepted
} Error;
typedef enum {
@@ -97,6 +98,15 @@ public :
M2MObjectInstance &object_instance,
M2MTLVDeserializer::Operation operation);
+ /**
+ * Deserialises the given binary that must encode a resource. Binary array
+ * can be checked before invoking this method.
+ */
+ static M2MTLVDeserializer::Error deserialize_resource(const uint8_t *tlv,
+ uint32_t tlv_size,
+ M2MResource &resource,
+ M2MTLVDeserializer::Operation operation);
+
/**
* Deserialises the given binary that must encode resource instances. Binary array
* can be checked before invoking this method.
@@ -128,6 +138,12 @@ public :
M2MTLVDeserializer::Operation operation,
bool update_value);
+ static M2MTLVDeserializer::Error deserialize_resource(const uint8_t *tlv,
+ uint32_t tlv_size,
+ M2MResource &resource,
+ M2MTLVDeserializer::Operation operation,
+ bool update_value);
+
static M2MTLVDeserializer::Error deserialize_resource_instances(const uint8_t *tlv,
uint32_t tlv_size,
uint32_t offset,
diff --git a/mbed-client/source/m2mbase.cpp b/mbed-client/source/m2mbase.cpp
index 6383a2a54..545e14209 100644
--- a/mbed-client/source/m2mbase.cpp
+++ b/mbed-client/source/m2mbase.cpp
@@ -142,6 +142,7 @@ M2MBase::~M2MBase()
delete callback;
M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseValueUpdatedCallback2);
+ M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseMessageDeliveryStatusCallback);
#ifdef ENABLE_ASYNC_REST_RESPONSE
M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MBaseAsyncCoapRequestCallback);
#endif
@@ -1019,7 +1020,7 @@ bool M2MBase::is_blockwise_needed(const nsdl_s *nsdl, uint32_t payload_len)
return false;
}
}
-void M2MBase::cancel_observation(M2MBase::MessageDeliveryStatus status)
+void M2MBase::cancel_observation(M2MBase::MessageDeliveryStatus status, bool notify)
{
tr_info("M2MBase::cancel_observation()");
@@ -1047,7 +1048,9 @@ void M2MBase::cancel_observation(M2MBase::MessageDeliveryStatus status)
_report_handler->set_under_observation(false);
}
- send_message_delivery_status(*this, status, M2MBase::NOTIFICATION);
+ if (notify) {
+ send_message_delivery_status(*this, status, M2MBase::NOTIFICATION);
+ }
}
void M2MBase::handle_observation(nsdl_s *nsdl,
diff --git a/mbed-client/source/m2mcallbackstorage.cpp b/mbed-client/source/m2mcallbackstorage.cpp
index 337f299ca..36ea7ebca 100644
--- a/mbed-client/source/m2mcallbackstorage.cpp
+++ b/mbed-client/source/m2mcallbackstorage.cpp
@@ -18,6 +18,7 @@
#include
+
// Dummy constructor, which does not init any value to something meaningful but needed for array construction.
// It is better to leave values unintialized, so the Valgrind will point out if the Vector is used without
// setting real values in there.
@@ -48,9 +49,13 @@ void M2MCallbackStorage::delete_instance()
M2MCallbackStorage::~M2MCallbackStorage()
{
- // TODO: go through the list and delete all the FP objects if there are any.
- // On the other hand, if the system is done properly, each m2mobject should actually
+ // Go through the list and delete all the FP objects if there are any.
+ // If the system is done properly, each m2mobject should actually
// remove its callbacks from its destructor so there is nothing here to do
+ // find any association to given object and delete them from the vector
+ for (int index = _callbacks.size()-1; index >=0; index --) {
+ _callbacks.erase(index);
+ }
}
bool M2MCallbackStorage::add_callback(const M2MBase &object,
@@ -72,13 +77,12 @@ bool M2MCallbackStorage::do_add_callback(const M2MBase &object, void *callback,
bool add_success = false;
// verify that the same callback is not re-added.
- if (does_callback_exist(object, callback, type) == false) {
+ if (!does_callback_exist(object, callback, type)) {
const M2MCallbackAssociation association(&object, callback, type, client_args);
_callbacks.push_back(association);
add_success = true;
}
-
return add_success;
}
@@ -109,11 +113,9 @@ void M2MCallbackStorage::do_remove_callbacks(const M2MBase &object)
void* M2MCallbackStorage::remove_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type)
{
void* callback = NULL;
-
// do not use the get_instance() here as it might create the instance
M2MCallbackStorage* instance = M2MCallbackStorage::_static_instance;
if (instance) {
-
callback = instance->do_remove_callback(object, type);
}
return callback;
@@ -127,7 +129,6 @@ void* M2MCallbackStorage::do_remove_callback(const M2MBase &object, M2MCallbackA
if ((_callbacks[index]._object == &object) && (_callbacks[index]._type == type)) {
callback = _callbacks[index]._callback;
_callbacks.erase(index);
- break;
}
}
return callback;
diff --git a/mbed-client/source/m2mdevice.cpp b/mbed-client/source/m2mdevice.cpp
index d5c2588d1..2f5edeb3f 100644
--- a/mbed-client/source/m2mdevice.cpp
+++ b/mbed-client/source/m2mdevice.cpp
@@ -24,11 +24,11 @@
#define BUFFER_SIZE 21
#define TRACE_GROUP "mClt"
-M2MDevice* M2MDevice::_instance = NULL;
+M2MDevice *M2MDevice::_instance = NULL;
-M2MDevice* M2MDevice::get_instance()
+M2MDevice *M2MDevice::get_instance()
{
- if(_instance == NULL) {
+ if (_instance == NULL) {
// ownership of this path is transferred to M2MBase.
// Since this object is a singleton, we could use the C-structs to avoid heap
// allocation on a lot of M2MDevice -objects data.
@@ -47,32 +47,31 @@ void M2MDevice::delete_instance()
}
M2MDevice::M2MDevice(char *path)
-: M2MObject(M2M_DEVICE_ID, path)
+ : M2MObject(M2M_DEVICE_ID, path)
{
M2MBase::set_register_uri(false);
M2MBase::set_operation(M2MBase::GET_ALLOWED);
_device_instance = M2MObject::create_object_instance();
- if(_device_instance) {
+ if (_device_instance) {
_device_instance->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
_device_instance->set_register_uri(false);
_device_instance->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
_device_instance->set_observable(true); // this object instance has observable resources so also obj inst should be observable
- M2MResource* res = _device_instance->create_dynamic_resource(DEVICE_REBOOT,
+ M2MResource *res = _device_instance->create_dynamic_resource(DEVICE_REBOOT,
OMA_RESOURCE_TYPE,
M2MResourceInstance::OPAQUE,
false);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::POST_ALLOWED);
res->set_register_uri(true);
}
- M2MResourceInstance* instance = _device_instance->create_dynamic_resource_instance(DEVICE_ERROR_CODE,
- OMA_RESOURCE_TYPE,
- M2MResourceInstance::INTEGER,
- true,0);
- if(instance) {
- M2MResource *dev_res = _device_instance->resource(DEVICE_ERROR_CODE);
+ M2MResourceInstance *instance = _device_instance->create_dynamic_resource_instance(DEVICE_ERROR_CODE,
+ OMA_RESOURCE_TYPE,
+ M2MResourceInstance::INTEGER,
+ true, 0);
+ if (instance) {
instance->set_operation(M2MBase::GET_ALLOWED);
instance->set_value(0);
instance->set_register_uri(true);
@@ -82,9 +81,9 @@ M2MDevice::M2MDevice(char *path)
OMA_RESOURCE_TYPE,
M2MResourceInstance::STRING,
true);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::GET_ALLOWED);
- res->set_value((const uint8_t*)BINDING_MODE_UDP,sizeof(BINDING_MODE_UDP)-1);
+ res->set_value((const uint8_t *)BINDING_MODE_UDP, sizeof(BINDING_MODE_UDP) - 1);
res->set_register_uri(true);
}
}
@@ -94,16 +93,16 @@ M2MDevice::~M2MDevice()
{
}
-M2MResource* M2MDevice::create_resource(DeviceResource resource, const String &value)
+M2MResource *M2MDevice::create_resource(DeviceResource resource, const String &value)
{
- M2MResource* res = NULL;
- const char* device_id_ptr = "";
+ M2MResource *res = NULL;
+ const char *device_id_ptr = "";
M2MBase::Operation operation = M2MBase::GET_ALLOWED;
- if(!is_resource_present(resource) && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
- switch(resource) {
+ if (!is_resource_present(resource) && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
+ switch (resource) {
case Manufacturer:
- device_id_ptr = DEVICE_MANUFACTURER;
- break;
+ device_id_ptr = DEVICE_MANUFACTURER;
+ break;
case DeviceType:
device_id_ptr = DEVICE_DEVICE_TYPE;
break;
@@ -136,19 +135,19 @@ M2MResource* M2MDevice::create_resource(DeviceResource resource, const String &v
}
const String device_id(device_id_ptr);
- if(!device_id.empty()) {
- if(_device_instance) {
+ if (!device_id.empty()) {
+ if (_device_instance) {
res = _device_instance->create_dynamic_resource(device_id,
OMA_RESOURCE_TYPE,
M2MResourceInstance::STRING,
true);
- if(res ) {
+ if (res) {
res->set_operation(operation);
if (value.empty()) {
res->clear_value();
} else {
- res->set_value((const uint8_t*)value.c_str(),
+ res->set_value((const uint8_t *)value.c_str(),
(uint32_t)value.length());
}
res->set_register_uri(true);
@@ -158,48 +157,48 @@ M2MResource* M2MDevice::create_resource(DeviceResource resource, const String &v
return res;
}
-M2MResource* M2MDevice::create_resource(DeviceResource resource, int64_t value)
+M2MResource *M2MDevice::create_resource(DeviceResource resource, int64_t value)
{
- M2MResource* res = NULL;
- const char* device_id_ptr = "";
+ M2MResource *res = NULL;
+ const char *device_id_ptr = "";
M2MBase::Operation operation = M2MBase::GET_ALLOWED;
- if(!is_resource_present(resource)) {
- switch(resource) {
- case BatteryLevel:
- if(check_value_range(resource, value)) {
- device_id_ptr = DEVICE_BATTERY_LEVEL;
- }
- break;
- case BatteryStatus:
- if(check_value_range(resource, value)) {
- device_id_ptr = DEVICE_BATTERY_STATUS;
- }
- break;
- case MemoryFree:
- device_id_ptr = DEVICE_MEMORY_FREE;
- break;
- case MemoryTotal:
- device_id_ptr = DEVICE_MEMORY_TOTAL;
- break;
- case CurrentTime:
- device_id_ptr = DEVICE_CURRENT_TIME;
- operation = M2MBase::GET_PUT_ALLOWED;
- break;
- default:
- break;
+ if (!is_resource_present(resource)) {
+ switch (resource) {
+ case BatteryLevel:
+ if (check_value_range(resource, value)) {
+ device_id_ptr = DEVICE_BATTERY_LEVEL;
+ }
+ break;
+ case BatteryStatus:
+ if (check_value_range(resource, value)) {
+ device_id_ptr = DEVICE_BATTERY_STATUS;
+ }
+ break;
+ case MemoryFree:
+ device_id_ptr = DEVICE_MEMORY_FREE;
+ break;
+ case MemoryTotal:
+ device_id_ptr = DEVICE_MEMORY_TOTAL;
+ break;
+ case CurrentTime:
+ device_id_ptr = DEVICE_CURRENT_TIME;
+ operation = M2MBase::GET_PUT_ALLOWED;
+ break;
+ default:
+ break;
}
}
const String device_id(device_id_ptr);
- if(!device_id.empty()) {
- if(_device_instance) {
+ if (!device_id.empty()) {
+ if (_device_instance) {
res = _device_instance->create_dynamic_resource(device_id,
OMA_RESOURCE_TYPE,
M2MResourceInstance::INTEGER,
true);
- if(res) {
+ if (res) {
res->set_operation(operation);
@@ -212,39 +211,39 @@ M2MResource* M2MDevice::create_resource(DeviceResource resource, int64_t value)
return res;
}
-M2MResourceInstance* M2MDevice::create_resource_instance(DeviceResource resource, int64_t value,
- uint16_t instance_id)
+M2MResourceInstance *M2MDevice::create_resource_instance(DeviceResource resource, int64_t value,
+ uint16_t instance_id)
{
- M2MResourceInstance* res_instance = NULL;
- const char* device_id_ptr = "";
+ M2MResourceInstance *res_instance = NULL;
+ const char *device_id_ptr = "";
// For these resources multiple instance can exist
- if(AvailablePowerSources == resource) {
- if(check_value_range(resource, value)) {
+ if (AvailablePowerSources == resource) {
+ if (check_value_range(resource, value)) {
device_id_ptr = DEVICE_AVAILABLE_POWER_SOURCES;
}
- } else if(PowerSourceVoltage == resource) {
+ } else if (PowerSourceVoltage == resource) {
device_id_ptr = DEVICE_POWER_SOURCE_VOLTAGE;
- } else if(PowerSourceCurrent == resource) {
+ } else if (PowerSourceCurrent == resource) {
device_id_ptr = DEVICE_POWER_SOURCE_CURRENT;
- } else if(ErrorCode == resource) {
- if(check_value_range(resource, value)) {
+ } else if (ErrorCode == resource) {
+ if (check_value_range(resource, value)) {
device_id_ptr = DEVICE_ERROR_CODE;
}
}
const String device_id(device_id_ptr);
- if(!device_id.empty()) {
- if(_device_instance) {
- res_instance = _device_instance->create_dynamic_resource_instance(device_id,OMA_RESOURCE_TYPE,
- M2MResourceInstance::INTEGER,
- true, instance_id);
+ if (!device_id.empty()) {
+ if (_device_instance) {
+ res_instance = _device_instance->create_dynamic_resource_instance(device_id, OMA_RESOURCE_TYPE,
+ M2MResourceInstance::INTEGER,
+ true, instance_id);
M2MResource *res = _device_instance->resource(device_id);
- if(res) {
+ if (res) {
res->set_register_uri(true);
}
- if(res_instance) {
+ if (res_instance) {
res_instance->set_value(value);
// Only read operation is allowed for above resources
res_instance->set_operation(M2MBase::GET_ALLOWED);
@@ -254,24 +253,24 @@ M2MResourceInstance* M2MDevice::create_resource_instance(DeviceResource resource
}
return res_instance;
}
-M2MResource* M2MDevice::create_resource(DeviceResource resource)
+M2MResource *M2MDevice::create_resource(DeviceResource resource)
{
- M2MResource* res = NULL;
- if(!is_resource_present(resource)) {
- const char* device_Id_ptr = "";
- if(FactoryReset == resource) {
+ M2MResource *res = NULL;
+ if (!is_resource_present(resource)) {
+ const char *device_Id_ptr = "";
+ if (FactoryReset == resource) {
device_Id_ptr = DEVICE_FACTORY_RESET;
- } else if(ResetErrorCode == resource) {
+ } else if (ResetErrorCode == resource) {
device_Id_ptr = DEVICE_RESET_ERROR_CODE;
}
const String device_Id(device_Id_ptr);
- if(_device_instance && !device_Id.empty()) {
+ if (_device_instance && !device_Id.empty()) {
res = _device_instance->create_dynamic_resource(device_Id,
OMA_RESOURCE_TYPE,
M2MResourceInstance::OPAQUE,
false);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::POST_ALLOWED);
res->set_register_uri(true);
@@ -290,10 +289,10 @@ M2MResource* M2MDevice::create_resource(DeviceResource resource)
bool M2MDevice::delete_resource(DeviceResource resource)
{
bool success = false;
- if(M2MDevice::Reboot != resource &&
- M2MDevice::ErrorCode != resource &&
- M2MDevice::SupportedBindingMode != resource) {
- if(_device_instance) {
+ if (M2MDevice::Reboot != resource &&
+ M2MDevice::ErrorCode != resource &&
+ M2MDevice::SupportedBindingMode != resource) {
+ if (_device_instance) {
success = _device_instance->remove_resource(resource_name(resource));
}
}
@@ -304,11 +303,11 @@ bool M2MDevice::delete_resource_instance(DeviceResource resource,
uint16_t instance_id)
{
bool success = false;
- if(M2MDevice::Reboot != resource &&
- M2MDevice::ErrorCode != resource &&
- M2MDevice::SupportedBindingMode != resource) {
- if(_device_instance) {
- success = _device_instance->remove_resource_instance(resource_name(resource),instance_id);
+ if (M2MDevice::Reboot != resource &&
+ M2MDevice::ErrorCode != resource &&
+ M2MDevice::SupportedBindingMode != resource) {
+ if (_device_instance) {
+ success = _device_instance->remove_resource_instance(resource_name(resource), instance_id);
}
}
return success;
@@ -319,45 +318,45 @@ bool M2MDevice::set_resource_value(DeviceResource resource,
uint16_t instance_id)
{
bool success = false;
- M2MResourceBase* res = get_resource_instance(resource, instance_id);
- if(res && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
- if(M2MDevice::Manufacturer == resource ||
- M2MDevice::ModelNumber == resource ||
- M2MDevice::DeviceType == resource ||
- M2MDevice::SerialNumber == resource ||
- M2MDevice::HardwareVersion == resource ||
- M2MDevice::FirmwareVersion == resource ||
- M2MDevice::SoftwareVersion == resource ||
- M2MDevice::UTCOffset == resource ||
- M2MDevice::Timezone == resource ||
- M2MDevice::SupportedBindingMode == resource) {
- if (value.empty()) {
- res->clear_value();
- success = true;
- } else {
- success = res->set_value((const uint8_t*)value.c_str(),(uint32_t)value.length());
- }
+ M2MResourceBase *res = get_resource_instance(resource, instance_id);
+ if (res && value.size() <= MAX_ALLOWED_STRING_LENGTH) {
+ if (M2MDevice::Manufacturer == resource ||
+ M2MDevice::ModelNumber == resource ||
+ M2MDevice::DeviceType == resource ||
+ M2MDevice::SerialNumber == resource ||
+ M2MDevice::HardwareVersion == resource ||
+ M2MDevice::FirmwareVersion == resource ||
+ M2MDevice::SoftwareVersion == resource ||
+ M2MDevice::UTCOffset == resource ||
+ M2MDevice::Timezone == resource ||
+ M2MDevice::SupportedBindingMode == resource) {
+ if (value.empty()) {
+ res->clear_value();
+ success = true;
+ } else {
+ success = res->set_value((const uint8_t *)value.c_str(), (uint32_t)value.length());
+ }
}
}
return success;
}
bool M2MDevice::set_resource_value(DeviceResource resource,
- int64_t value,
- uint16_t instance_id)
+ int64_t value,
+ uint16_t instance_id)
{
bool success = false;
- M2MResourceBase* res = get_resource_instance(resource, instance_id);
- if(res) {
- if(M2MDevice::BatteryLevel == resource ||
- M2MDevice::BatteryStatus == resource ||
- M2MDevice::MemoryFree == resource ||
- M2MDevice::MemoryTotal == resource ||
- M2MDevice::ErrorCode == resource ||
- M2MDevice::CurrentTime == resource ||
- M2MDevice::AvailablePowerSources == resource ||
- M2MDevice::PowerSourceVoltage == resource ||
- M2MDevice::PowerSourceCurrent == resource) {
+ M2MResourceBase *res = get_resource_instance(resource, instance_id);
+ if (res) {
+ if (M2MDevice::BatteryLevel == resource ||
+ M2MDevice::BatteryStatus == resource ||
+ M2MDevice::MemoryFree == resource ||
+ M2MDevice::MemoryTotal == resource ||
+ M2MDevice::ErrorCode == resource ||
+ M2MDevice::CurrentTime == resource ||
+ M2MDevice::AvailablePowerSources == resource ||
+ M2MDevice::PowerSourceVoltage == resource ||
+ M2MDevice::PowerSourceCurrent == resource) {
// If it is any of the above resource
// set the value of the resource.
if (check_value_range(resource, value)) {
@@ -373,18 +372,18 @@ String M2MDevice::resource_value_string(DeviceResource resource,
uint16_t instance_id) const
{
String value = "";
- const M2MResourceBase* res = get_resource_instance(resource, instance_id);
- if(res) {
- if(M2MDevice::Manufacturer == resource ||
- M2MDevice::ModelNumber == resource ||
- M2MDevice::DeviceType == resource ||
- M2MDevice::SerialNumber == resource ||
- M2MDevice::HardwareVersion == resource ||
- M2MDevice::FirmwareVersion == resource ||
- M2MDevice::SoftwareVersion == resource ||
- M2MDevice::UTCOffset == resource ||
- M2MDevice::Timezone == resource ||
- M2MDevice::SupportedBindingMode == resource) {
+ const M2MResourceBase *res = get_resource_instance(resource, instance_id);
+ if (res) {
+ if (M2MDevice::Manufacturer == resource ||
+ M2MDevice::ModelNumber == resource ||
+ M2MDevice::DeviceType == resource ||
+ M2MDevice::SerialNumber == resource ||
+ M2MDevice::HardwareVersion == resource ||
+ M2MDevice::FirmwareVersion == resource ||
+ M2MDevice::SoftwareVersion == resource ||
+ M2MDevice::UTCOffset == resource ||
+ M2MDevice::Timezone == resource ||
+ M2MDevice::SupportedBindingMode == resource) {
value = res->get_value_string();
@@ -397,17 +396,17 @@ int64_t M2MDevice::resource_value_int(DeviceResource resource,
uint16_t instance_id) const
{
int64_t value = -1;
- M2MResourceBase* res = get_resource_instance(resource, instance_id);
- if(res) {
- if(M2MDevice::BatteryLevel == resource ||
- M2MDevice::BatteryStatus == resource ||
- M2MDevice::MemoryFree == resource ||
- M2MDevice::MemoryTotal == resource ||
- M2MDevice::ErrorCode == resource ||
- M2MDevice::CurrentTime == resource ||
- M2MDevice::AvailablePowerSources == resource ||
- M2MDevice::PowerSourceVoltage == resource ||
- M2MDevice::PowerSourceCurrent == resource) {
+ M2MResourceBase *res = get_resource_instance(resource, instance_id);
+ if (res) {
+ if (M2MDevice::BatteryLevel == resource ||
+ M2MDevice::BatteryStatus == resource ||
+ M2MDevice::MemoryFree == resource ||
+ M2MDevice::MemoryTotal == resource ||
+ M2MDevice::ErrorCode == resource ||
+ M2MDevice::CurrentTime == resource ||
+ M2MDevice::AvailablePowerSources == resource ||
+ M2MDevice::PowerSourceVoltage == resource ||
+ M2MDevice::PowerSourceCurrent == resource) {
// note: the value may be 32bit int on 32b archs.
value = res->get_value_int();
@@ -419,8 +418,8 @@ int64_t M2MDevice::resource_value_int(DeviceResource resource,
bool M2MDevice::is_resource_present(DeviceResource resource) const
{
bool success = false;
- const M2MResourceBase* res = get_resource_instance(resource,0);
- if(res) {
+ const M2MResourceBase *res = get_resource_instance(resource, 0);
+ if (res) {
success = true;
}
return success;
@@ -429,7 +428,7 @@ bool M2MDevice::is_resource_present(DeviceResource resource) const
uint16_t M2MDevice::per_resource_count(DeviceResource res) const
{
uint16_t count = 0;
- if(_device_instance) {
+ if (_device_instance) {
count = _device_instance->resource_count(resource_name(res));
}
return count;
@@ -438,22 +437,22 @@ uint16_t M2MDevice::per_resource_count(DeviceResource res) const
uint16_t M2MDevice::total_resource_count() const
{
uint16_t count = 0;
- if(_device_instance) {
+ if (_device_instance) {
count = _device_instance->resources().size();
}
return count;
}
-M2MResourceBase* M2MDevice::get_resource_instance(DeviceResource dev_res,
- uint16_t instance_id) const
+M2MResourceBase *M2MDevice::get_resource_instance(DeviceResource dev_res,
+ uint16_t instance_id) const
{
- M2MResource* res = NULL;
- M2MResourceBase* inst = NULL;
- if(_device_instance) {
+ M2MResource *res = NULL;
+ M2MResourceBase *inst = NULL;
+ if (_device_instance) {
res = _device_instance->resource(resource_name(dev_res));
- if(res) {
- if(res->supports_multiple_instances()) {
- inst = res->resource_instance(instance_id);
+ if (res) {
+ if (res->supports_multiple_instances()) {
+ inst = res->resource_instance(instance_id);
} else {
inst = res;
}
@@ -462,10 +461,10 @@ M2MResourceBase* M2MDevice::get_resource_instance(DeviceResource dev_res,
return inst;
}
-const char* M2MDevice::resource_name(DeviceResource resource)
+const char *M2MDevice::resource_name(DeviceResource resource)
{
- const char* res_name = "";
- switch(resource) {
+ const char *res_name = "";
+ switch (resource) {
case Manufacturer:
res_name = DEVICE_MANUFACTURER;
break;
@@ -541,7 +540,7 @@ bool M2MDevice::check_value_range(DeviceResource resource, int64_t value)
bool success = false;
switch (resource) {
case AvailablePowerSources:
- if(value >= 0 && value <= 7) {
+ if (value >= 0 && value <= 7) {
success = true;
}
break;
@@ -560,9 +559,9 @@ bool M2MDevice::check_value_range(DeviceResource resource, int64_t value)
success = true;
}
break;
- default:
- success = true;
- break;
+ default:
+ success = true;
+ break;
}
return success;
}
diff --git a/mbed-client/source/m2minterfacefactory.cpp b/mbed-client/source/m2minterfacefactory.cpp
index 05fdcd41f..fc00fd7e1 100644
--- a/mbed-client/source/m2minterfacefactory.cpp
+++ b/mbed-client/source/m2minterfacefactory.cpp
@@ -34,7 +34,7 @@
#define TRACE_GROUP "mClt"
-M2MInterface* M2MInterfaceFactory::create_interface(M2MInterfaceObserver &observer,
+M2MInterface *M2MInterfaceFactory::create_interface(M2MInterfaceObserver &observer,
const String &endpoint_name,
const String &endpoint_type,
const int32_t life_time,
@@ -46,77 +46,77 @@ M2MInterface* M2MInterfaceFactory::create_interface(M2MInterfaceObserver &observ
const String &version)
{
tr_debug("M2MInterfaceFactory::create_interface - IN");
- tr_info("M2MInterfaceFactory::create_interface - parameters endpoint name : %s",endpoint_name.c_str());
- tr_info("M2MInterfaceFactory::create_interface - parameters endpoint type : %s",endpoint_type.c_str());
- tr_info("M2MInterfaceFactory::create_interface - parameters life time(in secs): %" PRId32,life_time);
- tr_info("M2MInterfaceFactory::create_interface - parameters Listen Port : %d",listen_port);
- tr_info("M2MInterfaceFactory::create_interface - parameters Binding Mode : %d",(int)mode);
- tr_info("M2MInterfaceFactory::create_interface - parameters NetworkStack : %d",(int)stack);
- tr_info("M2MInterfaceFactory::create_interface - parameters version : %s",version.c_str());
+ tr_info("M2MInterfaceFactory::create_interface - parameters endpoint name : %s", endpoint_name.c_str());
+ tr_info("M2MInterfaceFactory::create_interface - parameters endpoint type : %s", endpoint_type.c_str());
+ tr_info("M2MInterfaceFactory::create_interface - parameters life time(in secs): %" PRId32, life_time);
+ tr_info("M2MInterfaceFactory::create_interface - parameters Listen Port : %d", listen_port);
+ tr_info("M2MInterfaceFactory::create_interface - parameters Binding Mode : %d", (int)mode);
+ tr_info("M2MInterfaceFactory::create_interface - parameters NetworkStack : %d", (int)stack);
+ tr_info("M2MInterfaceFactory::create_interface - parameters version : %s", version.c_str());
M2MInterfaceImpl *interface = NULL;
bool endpoint_type_valid = true;
- if(!endpoint_type.empty()) {
- if(endpoint_type.size() > MAX_ALLOWED_STRING_LENGTH){
+ if (!endpoint_type.empty()) {
+ if (endpoint_type.size() > MAX_ALLOWED_STRING_LENGTH) {
endpoint_type_valid = false;
}
}
bool domain_valid = true;
- if(!domain.empty()) {
- if(domain.size() > MAX_ALLOWED_STRING_LENGTH){
+ if (!domain.empty()) {
+ if (domain.size() > MAX_ALLOWED_STRING_LENGTH) {
domain_valid = false;
}
}
bool version_valid = true;
- if(!version.empty()) {
- if(version.size() > MAX_ALLOWED_STRING_LENGTH){
+ if (!version.empty()) {
+ if (version.size() > MAX_ALLOWED_STRING_LENGTH) {
version_valid = false;
}
}
- if(((life_time == -1) || (life_time >= MINIMUM_REGISTRATION_TIME)) &&
- !endpoint_name.empty() && (endpoint_name.size() <= MAX_ALLOWED_STRING_LENGTH) &&
- endpoint_type_valid && domain_valid && version_valid) {
+ if (((life_time == -1) || (life_time >= MINIMUM_REGISTRATION_TIME)) &&
+ !endpoint_name.empty() && (endpoint_name.size() <= MAX_ALLOWED_STRING_LENGTH) &&
+ endpoint_type_valid && domain_valid && version_valid) {
tr_debug("M2MInterfaceFactory::create_interface - Creating M2MInterfaceImpl");
interface = new M2MInterfaceImpl(observer, endpoint_name,
- endpoint_type, life_time,
- listen_port, domain, mode,
- stack, context_address,
- version);
+ endpoint_type, life_time,
+ listen_port, domain, mode,
+ stack, context_address,
+ version);
}
tr_debug("M2MInterfaceFactory::create_interface - OUT");
return interface;
}
-M2MSecurity* M2MInterfaceFactory::create_security(M2MSecurity::ServerType server_type)
+M2MSecurity *M2MInterfaceFactory::create_security(M2MSecurity::ServerType server_type)
{
tr_debug("M2MInterfaceFactory::create_security");
M2MSecurity *security = M2MSecurity::get_instance();
return security;
}
-M2MServer* M2MInterfaceFactory::create_server()
+M2MServer *M2MInterfaceFactory::create_server()
{
tr_debug("M2MInterfaceFactory::create_server");
M2MServer *server = new M2MServer();
return server;
}
-M2MDevice* M2MInterfaceFactory::create_device()
+M2MDevice *M2MInterfaceFactory::create_device()
{
tr_debug("M2MInterfaceFactory::create_device");
- M2MDevice* device = M2MDevice::get_instance();
+ M2MDevice *device = M2MDevice::get_instance();
return device;
}
-M2MObject* M2MInterfaceFactory::create_object(const String &name)
+M2MObject *M2MInterfaceFactory::create_object(const String &name)
{
tr_debug("M2MInterfaceFactory::create_object : Name : %s", name.c_str());
- if(name.size() > MAX_ALLOWED_STRING_LENGTH || name.empty()){
+ if (name.size() > MAX_ALLOWED_STRING_LENGTH || name.empty()) {
return NULL;
}
@@ -128,13 +128,13 @@ M2MObject* M2MInterfaceFactory::create_object(const String &name)
return object;
}
-M2MObject* M2MInterfaceFactory::find_or_create_object(M2MObjectList &object_list,
+M2MObject *M2MInterfaceFactory::find_or_create_object(M2MObjectList &object_list,
const uint16_t object_id,
bool &object_created)
{
// Check list for existing object
object_created = false;
- for (int i=0; iname_id() == object_id) {
tr_debug("Found existing /%" PRIu16, object_id);
return object_list[i];
@@ -157,7 +157,7 @@ M2MObject* M2MInterfaceFactory::find_or_create_object(M2MObjectList &object_list
return object;
}
-M2MObjectInstance* M2MInterfaceFactory::find_or_create_object_instance(M2MObject &object,
+M2MObjectInstance *M2MInterfaceFactory::find_or_create_object_instance(M2MObject &object,
const uint16_t object_instance_id,
bool &object_instance_created)
{
@@ -173,7 +173,7 @@ M2MObjectInstance* M2MInterfaceFactory::find_or_create_object_instance(M2MObject
if (object_instance == NULL) {
object_instance = object.create_object_instance(object_instance_id);
if (object_instance == NULL) {
- tr_err("Couldn't create /%d/%" PRIu16 " (out of memory?)", object.name_id(), object_instance_id);
+ tr_err("Couldn't create /%" PRId32 "s/%" PRIu16 " (out of memory?)", object.name_id(), object_instance_id);
return NULL;
}
}
@@ -184,7 +184,7 @@ M2MObjectInstance* M2MInterfaceFactory::find_or_create_object_instance(M2MObject
return object_instance;
}
-M2MResource* M2MInterfaceFactory::find_or_create_resource(M2MObjectInstance &object_instance,
+M2MResource *M2MInterfaceFactory::find_or_create_resource(M2MObjectInstance &object_instance,
const uint16_t resource_id,
const M2MResourceInstance::ResourceType resource_type,
bool multiple_instance,
@@ -194,7 +194,7 @@ M2MResource* M2MInterfaceFactory::find_or_create_resource(M2MObjectInstance &obj
M2MResource *resource = object_instance.resource(resource_id);
if (resource != NULL) {
tr_debug("Found existing /%d/%d/%" PRIu16,
- object_instance.get_parent_object().name_id(), object_instance.instance_id(), resource_id);
+ object_instance.get_parent_object().name_id(), object_instance.instance_id(), resource_id);
return resource;
}
@@ -202,18 +202,18 @@ M2MResource* M2MInterfaceFactory::find_or_create_resource(M2MObjectInstance &obj
resource = object_instance.create_dynamic_resource(resource_id, "", resource_type,
true, multiple_instance, external_blockwise_store);
if (resource == NULL) {
- tr_err("Couldn't create /%d/%d/%" PRIu16 " (out of memory?)",
- object_instance.get_parent_object().name_id(), object_instance.instance_id(), resource_id);
+ tr_err("Couldn't create /%" PRId32 "/%" PRIu16 "/%" PRIu16 " (out of memory?)",
+ object_instance.get_parent_object().name_id(), object_instance.instance_id(), resource_id);
return NULL;
}
// All good
tr_debug("Created new /%d/%d/%" PRIu16,
- object_instance.get_parent_object().name_id(), object_instance.instance_id(), resource_id);
+ object_instance.get_parent_object().name_id(), object_instance.instance_id(), resource_id);
return resource;
}
-M2MResource* M2MInterfaceFactory::create_resource(M2MObjectList &object_list,
+M2MResource *M2MInterfaceFactory::create_resource(M2MObjectList &object_list,
const uint16_t object_id,
const uint16_t object_instance_id,
const uint16_t resource_id,
@@ -223,7 +223,7 @@ M2MResource* M2MInterfaceFactory::create_resource(M2MObjectList &object_list,
bool external_blockwise_store)
{
tr_debug("M2MInterfaceFactory::create_resource() - creating /%" PRIu16 "/%" PRIu16 "/%" PRIu16,
- object_id, object_instance_id, resource_id);
+ object_id, object_instance_id, resource_id);
M2MObject *object;
M2MObjectInstance *object_instance;
@@ -240,7 +240,7 @@ M2MResource* M2MInterfaceFactory::create_resource(M2MObjectList &object_list,
// Check and create object instance if necessary
bool object_instance_created;
object_instance = M2MInterfaceFactory::find_or_create_object_instance(
- *object, object_instance_id, object_instance_created);
+ *object, object_instance_id, object_instance_created);
if (object_instance == NULL) {
tr_err("M2MInterfaceFactory::create_resource() - failed to get object instance");
goto cleanup_object;
@@ -248,8 +248,8 @@ M2MResource* M2MInterfaceFactory::create_resource(M2MObjectList &object_list,
// Check and create resource if necessary
resource = M2MInterfaceFactory::find_or_create_resource(
- *object_instance, resource_id, resource_type,
- multiple_instance, external_blockwise_store);
+ *object_instance, resource_id, resource_type,
+ multiple_instance, external_blockwise_store);
if (resource == NULL) {
tr_err("M2MInterfaceFactory::create_resource() - failed to get resource");
goto cleanup_object_instance;
@@ -277,15 +277,15 @@ M2MResource* M2MInterfaceFactory::create_resource(M2MObjectList &object_list,
}
#ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION
-M2MEndpoint* M2MInterfaceFactory::create_endpoint(const String &name)
+M2MEndpoint *M2MInterfaceFactory::create_endpoint(const String &name)
{
tr_debug("M2MInterfaceFactory::create_endpoint : Name : %s", name.c_str());
- if(name.size() > MAX_ALLOWED_STRING_LENGTH || name.empty()){
+ if (name.size() > MAX_ALLOWED_STRING_LENGTH || name.empty()) {
return NULL;
}
M2MEndpoint *object = NULL;
- char *path = (char*)malloc(2 + name.size() + 1);
+ char *path = (char *)malloc(2 + name.size() + 1);
if (path) {
// Prepend path with directory prefix "d/" so that all endpoints will be under common path
path[0] = 'd';
diff --git a/mbed-client/source/m2minterfaceimpl.cpp b/mbed-client/source/m2minterfaceimpl.cpp
index 06cc379e6..c99eba1ac 100644
--- a/mbed-client/source/m2minterfaceimpl.cpp
+++ b/mbed-client/source/m2minterfaceimpl.cpp
@@ -56,6 +56,7 @@ M2MInterfaceImpl::M2MInterfaceImpl(M2MInterfaceObserver &observer,
const String &con_addr,
const String &version)
: _event_data(NULL),
+ _server_address{stack, NULL, 0, 0},
_server_port(0),
_listen_port(listen_port),
_life_time(l_time),
@@ -99,9 +100,36 @@ M2MInterfaceImpl::M2MInterfaceImpl(M2MInterfaceObserver &observer,
//Here we must use TCP still
_connection_handler.bind_connection(_listen_port);
+ M2MResource *disable_res = get_m2mserver()->get_resource(M2MServer::Disable);
+ if (disable_res) {
+ disable_res->set_execute_function(execute_callback(this, &M2MInterfaceImpl::disable_callback));
+ disable_res->set_delayed_response(true);
+ disable_res->set_message_delivery_status_cb(M2MInterfaceImpl::post_response_status_handler, this);
+ }
+
tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -OUT");
}
+void M2MInterfaceImpl::post_response_status_handler(const M2MBase &base,
+ const M2MBase::MessageDeliveryStatus status,
+ const M2MBase::MessageType type,
+ void *me)
+{
+ if (status == M2MBase::MESSAGE_STATUS_DELIVERED && type == M2MBase::DELAYED_POST_RESPONSE) {
+ ((M2MInterfaceImpl *)me)->unregister_object();
+ }
+}
+
+
+void M2MInterfaceImpl::disable_callback(void *)
+{
+ // Don't perform unregister yet, as server will not get response. Instead, send response and wait
+ // for acknowledgement before unregistering.
+ M2MResource *disable_res = get_m2mserver()->get_resource(M2MServer::Disable);
+ if (disable_res) {
+ disable_res->send_delayed_post_response();
+ }
+}
M2MInterfaceImpl::~M2MInterfaceImpl()
{
@@ -273,7 +301,7 @@ void M2MInterfaceImpl::update_registration(M2MSecurity *security_object,
void M2MInterfaceImpl::unregister_object(M2MSecurity * /*security*/)
{
tr_debug("M2MInterfaceImpl::unregister_object - IN - current state %d", _current_state);
- if (_nsdl_interface.is_unregister_ongoing()) {
+ if (_nsdl_interface.is_unregister_ongoing() || _nsdl_interface.alert_mode()) {
set_error_description(ERROR_REASON_27);
_observer.error(M2MInterface::NotAllowed);
return;
@@ -387,6 +415,10 @@ void M2MInterfaceImpl::registration_error(uint8_t error_code, bool retry, bool f
// else
// Network issue, do not delete CID but continue reconnection logic (99%)
tr_error("M2MInterfaceImpl::registration_error sending CLIENT HELLO PING");
+
+ // Make sure that FW download do resume after register update
+ _nsdl_interface.set_request_context_to_be_resend(NULL, 0);
+
_reconnection_state = M2MInterfaceImpl::ClientPing;
_connection_handler.resolve_server_address(_server_ip_address, _server_port,
M2MConnectionObserver::LWM2MServer,
@@ -542,31 +574,12 @@ void M2MInterfaceImpl::data_available(uint8_t *data,
{
tr_debug("M2MInterfaceImpl::data_available");
if (_reconnection_state == M2MInterfaceImpl::ClientPing) {
- tr_info("M2MInterfaceImpl::data_available() : Ping success, remove CID");
- // Lwm2m server has responded so it implies that CID has expired and
- // thats why message sending had failed so delete CID and re-do connection with full handshake
- if (_nsdl_interface.is_registered()) {
- _reconnection_state = M2MInterfaceImpl::WithUpdate;
- } else {
- _reconnection_state = M2MInterfaceImpl::None;
- }
-
- _connection_handler.remove_cid();
- // Update network stagger values as now device has to do full handshake for registration.
- _nsdl_interface.update_network_rtt_estimate();
-
- uint16_t rand_time = 10 + _nsdl_interface.get_network_stagger_estimate(false);
- // The new timeout is randomized to + 10% and -10% range from original random value
- randLIB_seed_random();
- rand_time = randLIB_randomise_base(rand_time, 0x7333, 0x8CCD);
-
- // Take in use the new timer. For single-device networks, reconnecting fast is the primary goal.
- // For multidevice networks sharing same pipe should provide stagger_estimates. In such case we need to
- // enforce that to prevent too large reconnection spike in the network.
+ tr_info("M2MInterfaceImpl::data_available() : Ping success");
+ _server_address = address;
+ // There can't be delay between handshake finished and sending the first COAP message as server
+ // needs the first message after handshake to set handshake successful. So let's launch timer after 1ms.
_retry_timer.stop_timer();
- _retry_timer.start_timer(rand_time * 1000,
- M2MTimerObserver::RetryTimer);
-
+ _retry_timer.start_timer(1, M2MTimerObserver::RetryTimer);
return;
}
ReceivedData event;
@@ -591,6 +604,13 @@ void M2MInterfaceImpl::socket_error(int error_code, bool retry)
tr_error("M2MInterfaceImpl::socket_error: (%d), retry (%d), reconnecting (%d), reconnection_state (%d)",
error_code, retry, _reconnecting, (int)_reconnection_state);
+ // Reconnection can't be done when in alert mode
+ if (_nsdl_interface.alert_mode()) {
+ tr_info("M2MInterfaceImpl::socket_error - in alert mode --> go to pause state");
+ pause();
+ return;
+ }
+
// Ignore errors while client is sleeping
if (queue_mode()) {
if (_callback_handler && _queue_mode_timer_ongoing) {
@@ -598,8 +618,8 @@ void M2MInterfaceImpl::socket_error(int error_code, bool retry)
return;
}
}
- _queue_sleep_timer.stop_timer();
+ _queue_sleep_timer.stop_timer();
_retry_timer.stop_timer();
const char *error_code_des;
@@ -647,6 +667,8 @@ void M2MInterfaceImpl::socket_error(int error_code, bool retry)
// Do a reconnect
if (retry) {
+ _nsdl_interface.set_registration_status(false);
+
if ((error == M2MInterface::SecureConnectionFailed || error == M2MInterface::InvalidParameters) &&
_bootstrapped) {
// Connector client will start the bootstrap flow again
@@ -655,7 +677,6 @@ void M2MInterfaceImpl::socket_error(int error_code, bool retry)
return;
}
- _nsdl_interface.set_request_context_to_be_resend(NULL, 0);
_reconnecting = true;
_connection_handler.stop_listening();
_retry_timer_expired = false;
@@ -772,14 +793,26 @@ void M2MInterfaceImpl::timer_expired(M2MTimerObserver::Type type)
} else if (M2MTimerObserver::RetryTimer == type) {
tr_debug("M2MInterfaceImpl::timer_expired() - retry");
_retry_timer_expired = true;
- if (_bootstrapped) {
- internal_event(STATE_REGISTER);
- }
+
+ if (_reconnection_state == M2MInterfaceImpl::ClientPing) {
+ // Lwm2m server has responded TLS handshake, set the reconnection state to correct state
+ if (_nsdl_interface.is_registered()) {
+ _reconnection_state = M2MInterfaceImpl::WithUpdate;
+ } else {
+ _reconnection_state = M2MInterfaceImpl::None;
+ }
+ // as we have now done handshake already we MUST NOT do any dns queries -> continue to address ready
+ address_ready(_server_address, M2MConnectionObserver::LWM2MServer, _server_address._port);
+ } else {
+ if (_bootstrapped) {
+ internal_event(STATE_REGISTER);
+ }
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
- else {
- internal_event(STATE_BOOTSTRAP);
- }
+ else {
+ internal_event(STATE_BOOTSTRAP);
+ }
#endif
+ }
} else if (M2MTimerObserver::BootstrapFlowTimer == type) {
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
@@ -811,6 +844,10 @@ void M2MInterfaceImpl::state_idle(EventData * /*data*/)
void M2MInterfaceImpl::state_bootstrap(EventData *data)
{
tr_debug("M2MInterfaceImpl::state_bootstrap");
+
+ // Disable CoAP retransmissions when connection is not ready.
+ _nsdl_interface.stop_nsdl_execution_timer();
+
// Start with bootstrapping preparation
_bootstrapped = false;
_bootstrap_finished = false;
@@ -939,9 +976,13 @@ void M2MInterfaceImpl::state_bootstrapped(EventData */*data*/)
void M2MInterfaceImpl::state_register(EventData *data)
{
tr_debug("M2MInterfaceImpl::state_register");
- _nsdl_interface.set_registration_status(false);
+
+ // Disable CoAP retransmissions when connection is not ready.
+ _nsdl_interface.stop_nsdl_execution_timer();
+
M2MRegisterData *event = static_cast(data);
if (!_security) {
+ _nsdl_interface.set_registration_status(false);
M2MInterface::Error error = M2MInterface::InvalidParameters;
// Start with registration preparation
if (event) {
@@ -1064,6 +1105,14 @@ void M2MInterfaceImpl::state_register_address_resolved(EventData *data)
_retry_timer.stop_timer();
+ // Reset back to normal mode
+ if (_nsdl_interface.alert_mode()) {
+ _nsdl_interface.set_alert_mode(false);
+ if (!_connection_handler.set_socket_priority(M2MConnectionHandler::DEFAULT_PRIORITY)) {
+ tr_warn("M2MInterfaceImpl::state_register_address_resolved - failed to set socket priority");
+ }
+ }
+
switch (_reconnection_state) {
case M2MInterfaceImpl::None:
if (!_nsdl_interface.send_register_message()) {
@@ -1079,6 +1128,8 @@ void M2MInterfaceImpl::state_register_address_resolved(EventData *data)
// Start registration update in case it is reconnection logic because of network issue.
internal_event(STATE_UPDATE_REGISTRATION);
break;
+ default:
+ break;
}
}
}
@@ -1139,9 +1190,11 @@ void M2MInterfaceImpl::pause()
{
tr_debug("M2MInterfaceImpl::pause()");
internal_event(STATE_IDLE);
+
if (_binding_mode == M2MInterface::UDP || _binding_mode == M2MInterface::UDP_QUEUE) {
_connection_handler.store_cid();
}
+
_connection_handler.unregister_network_handler();
_connection_handler.stop_listening();
_retry_timer.stop_timer();
@@ -1151,7 +1204,34 @@ void M2MInterfaceImpl::pause()
sn_nsdl_clear_coap_resending_queue(_nsdl_interface.get_nsdl_handle());
+ _observer.paused();
+}
+
+void M2MInterfaceImpl::alert()
+{
+ if (!_nsdl_interface.is_registered() || _reconnecting) {
+ tr_info("M2MInterfaceImpl::alert() - in reconnection or not registered --> go to pause");
+ pause();
+ return;
+ }
+
+ if (!_connection_handler.set_socket_priority(M2MConnectionHandler::ALERT_PRIORITY)) {
+ tr_warn("M2MInterfaceImpl::alert - failed to set socket into high priority mode");
+ }
+
+ sn_nsdl_clear_coap_resending_queue(_nsdl_interface.get_nsdl_handle());
+ _connection_handler.claim_mutex();
+ _nsdl_interface.set_request_context_to_be_resend(NULL, 0);
+ _connection_handler.release_mutex();
+ _queue_sleep_timer.stop_timer();
+
+ _nsdl_interface.set_alert_mode(true);
+ _nsdl_interface.clear_sent_blockwise_messages();
+ _nsdl_interface.clear_received_blockwise_messages();
+
+ internal_event(STATE_WAITING);
+ _observer.alert_mode();
}
void M2MInterfaceImpl::state_unregister(EventData */*data*/)
@@ -1500,7 +1580,7 @@ void M2MInterfaceImpl::network_interface_status_change(NetworkInterfaceStatus st
_retry_timer.start_timer(rand_time * 1000,
M2MTimerObserver::RetryTimer);
// The old value is an estimate as it has been randomized before use (+/- 10%).
- tr_info("M2MInterfaceImpl::network_interface_status_change - old value %d - new reconnection time %d", _reconnection_time / RECONNECT_INCREMENT_FACTOR, rand_time);
+ tr_info("M2MInterfaceImpl::network_interface_status_change - old value %" PRIu32 " - new reconnection time %" PRIu32, _reconnection_time / RECONNECT_INCREMENT_FACTOR, rand_time);
_reconnection_time = rand_time;
}
}
diff --git a/mbed-client/source/m2mnotificationhandler.cpp b/mbed-client/source/m2mnotificationhandler.cpp
index a97c32e2d..a6609a955 100644
--- a/mbed-client/source/m2mnotificationhandler.cpp
+++ b/mbed-client/source/m2mnotificationhandler.cpp
@@ -29,9 +29,9 @@ int8_t M2MNotificationHandler::_tasklet_id = -1;
extern "C" void notification_tasklet_func(arm_event_s *event)
{
- M2MNsdlInterface *iface = (M2MNsdlInterface*)event->data_ptr;
+ M2MNsdlInterface *iface = (M2MNsdlInterface *)event->data_ptr;
if (event->event_type == MBED_CLIENT_NOTIFICATION_HANDLER_EVENT) {
- iface->send_next_notification(false);
+ iface->send_next_notification(M2MNsdlInterface::SEND_NOTIFICATION);
event->event_data = 0;
}
}
@@ -52,7 +52,11 @@ M2MNotificationHandler::~M2MNotificationHandler()
void M2MNotificationHandler::send_notification(M2MNsdlInterface *interface)
{
- tr_debug("M2MNotificationHandler::send_notification");
+ if (interface->alert_mode()) {
+ tr_debug("M2MNotificationHandler::send_notification - in alert mode skip sending");
+ return;
+ }
+
if (!_event.data.event_data) {
_event.data.event_data = 1;
_event.data.event_type = MBED_CLIENT_NOTIFICATION_HANDLER_EVENT;
diff --git a/mbed-client/source/m2mnsdlinterface.cpp b/mbed-client/source/m2mnsdlinterface.cpp
index bb852dd9c..4a3291c7b 100644
--- a/mbed-client/source/m2mnsdlinterface.cpp
+++ b/mbed-client/source/m2mnsdlinterface.cpp
@@ -64,11 +64,12 @@
#define MBED_CLIENT_NSDLINTERFACE_TASKLET_INIT_EVENT 0 // Tasklet init occurs always when generating a tasklet
#define MBED_CLIENT_NSDLINTERFACE_EVENT 30
+#define MBED_CLIENT_NSDLINTERFACE_MESSAGE_STATUS_CB_EVENT 31
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
-#define MBED_CLIENT_NSDLINTERFACE_BS_EVENT 31
-#define MBED_CLIENT_NSDLINTERFACE_BS_PUT_EVENT 32
-#define MBED_CLIENT_NSDLINTERFACE_BS_FINISH_EVENT 33
+#define MBED_CLIENT_NSDLINTERFACE_BS_EVENT 32
+#define MBED_CLIENT_NSDLINTERFACE_BS_PUT_EVENT 33
+#define MBED_CLIENT_NSDLINTERFACE_BS_FINISH_EVENT 34
#endif
#ifdef MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
@@ -85,12 +86,16 @@
#define TRACE_GROUP "mClt"
#define MAX_QUERY_COUNT 10
-const char *MCC_VERSION = "mccv=4.8.0";
+#define REGISTRATION_UPDATE_DELAY 10 // wait 10ms before sending registration update for PUT to resource 1/0/1
+
+const char *MCC_VERSION = "mccv=4.9.0";
int8_t M2MNsdlInterface::_tasklet_id = -1;
extern "C" void nsdlinterface_tasklet_func(arm_event_s *event)
{
+ event->event_id = 0;
+
// skip the init event as there will be a timer event after
if (event->event_type == MBED_CLIENT_NSDLINTERFACE_EVENT) {
eventOS_scheduler_mutex_wait();
@@ -130,9 +135,11 @@ extern "C" void nsdlinterface_tasklet_func(arm_event_s *event)
coap_data->received_coap_header,
coap_data->received_coap_header->msg_code);
if (coap_response) {
+#if (MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE == 0)
coap_response->msg_type = coap_data->received_coap_header->msg_type;
// Let CoAP to choose next message id
coap_response->msg_id = 0;
+#endif // MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
if (sn_nsdl_send_coap_message(coap_data->nsdl_handle, &coap_data->address, coap_response) == 0) {
interface->store_bs_finished_response_id(coap_response->msg_id);
@@ -172,10 +179,46 @@ extern "C" void nsdlinterface_tasklet_func(arm_event_s *event)
nsdl_s *nsdl_handle = (nsdl_s *)event->data_ptr;
M2MNsdlInterface *interface = (M2MNsdlInterface *)sn_nsdl_get_context(nsdl_handle);
interface->handle_bootstrap_finish_ack(event->event_data);
+ } else if (event->event_type == MBED_CLIENT_NSDLINTERFACE_MESSAGE_STATUS_CB_EVENT) {
+ M2MObject *object = (M2MObject *)event->data_ptr;
+ uint8_t status = event->event_data >> 8;
+ uint8_t type = event->event_data;
+ object->send_message_delivery_status(*object,
+ (M2MBase::MessageDeliveryStatus)status,
+ (M2MBase::MessageType)type);
}
#endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
+}
+
+bool lifetime_write_callback(const M2MResourceBase &resource, const uint8_t *buffer, const size_t buffer_size, void *client_args)
+{
+ M2MNsdlInterface *m2m_interface = (M2MNsdlInterface *)client_args;
+
+ return m2m_interface->update_server_lifetime(buffer, buffer_size);
+}
+
+bool M2MNsdlInterface::update_server_lifetime(const uint8_t *buffer, const size_t buffer_size)
+{
+ bool retval = false;
+
+ M2MResource *lifetime_res = _server->get_resource(M2MServer::Lifetime);
+ if (lifetime_res) {
+ uint8_t *value_copy = alloc_string_copy(buffer, buffer_size);
+ if (value_copy) {
+ lifetime_res->update_value(value_copy, buffer_size);
+ retval = true;
+ }
- event->event_data = 0;
+ if (_current_request_code == COAP_MSG_CODE_REQUEST_PUT) {
+ _current_request_code = COAP_MSG_CODE_EMPTY;
+ if (retval) {
+ // OMA Registration Update, put to 1/0/1 must trigger update.
+ update_trigger_callback(NULL);
+ }
+ }
+ }
+
+ return retval;
}
M2MNsdlInterface::M2MNsdlInterface(M2MNsdlObserver &observer, M2MConnectionHandler &connection_handler)
@@ -202,7 +245,10 @@ M2MNsdlInterface::M2MNsdlInterface(M2MNsdlObserver &observer, M2MConnectionHandl
_waiting_for_bs_finish_ack(false),
_download_retry_timer(*this),
_download_retry_time(0),
- _network_rtt_estimate(10) // Use reasonable initialization value for the RTT estimate. Must be larger than 0.
+ _network_rtt_estimate(10), // Use reasonable initialization value for the RTT estimate. Must be larger than 0.
+ _alert_mode(false),
+ _last_notif_queue_event(M2MNsdlInterface::SEND_NOTIFICATION),
+ _current_request_code(COAP_MSG_CODE_EMPTY)
{
tr_debug("M2MNsdlInterface::M2MNsdlInterface()");
@@ -289,6 +335,11 @@ bool M2MNsdlInterface::initialize()
&M2MNsdlInterface::update_trigger_callback));
}
+ M2MResource *lifetime_res = _server->get_resource(M2MServer::Lifetime);
+ if (lifetime_res) {
+ lifetime_res->set_resource_write_callback(lifetime_write_callback, (void *)this);
+ }
+
add_object_to_list(_server);
create_nsdl_object_structure(_server);
ns_list_init(&_request_context_list);
@@ -501,7 +552,7 @@ bool M2MNsdlInterface::send_register_message()
bool success = false;
// Clear the observation tokens
- send_next_notification(true);
+ send_next_notification(M2MNsdlInterface::CLEAR_NOTIFICATION_TOKEN);
if (_server_address) {
success = parse_and_send_uri_query_parameters();
@@ -531,8 +582,8 @@ void M2MNsdlInterface::send_request(DownloadType type,
int32_t message_id = 0;
request_context_s *data_request = NULL;
- if (msg_code == COAP_MSG_CODE_REQUEST_GET && !_registered) {
- tr_error("M2MNsdlInterface::send_request - client not registered!");
+ if (msg_code == COAP_MSG_CODE_REQUEST_GET && (!_registered || _alert_mode)) {
+ tr_error("M2MNsdlInterface::send_request - client registered: %d, alert mode: %d!", _registered, _alert_mode);
error_cb(ERROR_NOT_REGISTERED, context);
return;
}
@@ -767,14 +818,18 @@ uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s *nsdl_hand
if (COAP_MSG_CODE_REQUEST_PUT == coap_header->msg_code) {
if (is_bootstrap_msg) {
#ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
+
+#if (MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE == 0)
send_empty_ack(coap_header, address);
+#endif // MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
+
nsdl_coap_data_s *nsdl_coap_data = create_coap_event_data(coap_header,
address,
nsdl_handle,
coap_header->msg_code);
if (nsdl_coap_data) {
- if (!_event.data.event_data) {
- _event.data.event_data = true;
+ if (!_event.data.event_id) {
+ _event.data.event_id = true;
_event.data.event_type = MBED_CLIENT_NSDLINTERFACE_BS_PUT_EVENT;
_event.data.data_ptr = (void *)nsdl_coap_data;
eventOS_event_send_user_allocated(&_event);
@@ -831,7 +886,7 @@ uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s *nsdl_hand
base->handle_observation(nsdl_handle, *coap_header, *coap_header, this, code);
base->start_observation(*coap_header, this);
} else {
- handle_message_delivered(base, resp->type);
+ handle_message_status_callback(base, resp->type, M2MBase::MESSAGE_STATUS_DELIVERED);
}
remove_item_from_response_list(NULL, coap_header->msg_id);
@@ -849,7 +904,7 @@ uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s *nsdl_hand
// Do not report notification sending timeout to application.
// Notifications has own queue which will take care of re-sending.
if (base && resp->type != M2MBase::NOTIFICATION) {
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_SEND_FAILED, resp->type);
+ handle_message_status_callback(base, resp->type, M2MBase::MESSAGE_STATUS_SEND_FAILED);
}
remove_item_from_response_list(resp->uri_path, coap_header->msg_id);
}
@@ -1000,13 +1055,13 @@ uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s *nsdl_handle,
}
send_empty_ack(received_coap_header, address);
- if (!_event.data.event_data) {
+ if (!_event.data.event_id) {
nsdl_coap_data_s *nsdl_coap_data = create_coap_event_data(received_coap_header,
address,
nsdl_handle,
received_coap_header->msg_code);
if (nsdl_coap_data) {
- _event.data.event_data = true;
+ _event.data.event_id = true;
_event.data.event_type = MBED_CLIENT_NSDLINTERFACE_EVENT;
_event.data.data_ptr = (void *)nsdl_coap_data;
eventOS_event_send_user_allocated(&_event);
@@ -1034,6 +1089,7 @@ uint8_t M2MNsdlInterface::resource_callback_handle_event(sn_coap_hdr_s *received
M2MBase *base = find_resource(resource_name);
bool subscribed = false;
if (base) {
+ _current_request_code = received_coap_header->msg_code;
if (COAP_MSG_CODE_REQUEST_GET == received_coap_header->msg_code) {
coap_response = base->handle_get_request(_nsdl_handle, received_coap_header, this);
@@ -1166,10 +1222,10 @@ uint8_t M2MNsdlInterface::resource_callback_handle_event(sn_coap_hdr_s *received
// Notify application that message has been sent so it can release the memory
if (!result) {
if (!coap_response->options_list_ptr || !(coap_response->options_list_ptr->block2 & 0x08) || coap_response->options_list_ptr->block2 == -1) {
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_DELIVERED, M2MBase::DELAYED_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_RESPONSE, M2MBase::MESSAGE_STATUS_DELIVERED);
}
} else {
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_SEND_FAILED, M2MBase::DELAYED_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_RESPONSE, M2MBase::MESSAGE_STATUS_SEND_FAILED);
}
} else {
free(coap_response->payload_ptr);
@@ -1260,9 +1316,28 @@ bool M2MNsdlInterface::process_received_data(uint8_t *data,
sn_nsdl_addr_s *address)
{
tr_debug("M2MNsdlInterface::process_received_data(data size %d)", data_size);
+
+ sn_coap_hdr_s *coap_packet_ptr = NULL;
+ /* Parse CoAP packet */
+ coap_packet_ptr = sn_coap_protocol_parse(_nsdl_handle->grs->coap, address, data_size, data, (void *)_nsdl_handle);
+
+ /* Check if parsing was successfull */
+ if (coap_packet_ptr == (sn_coap_hdr_s *)NULL) {
+ tr_error("M2MNsdlInterface::process_received_data - coap parsing fails");
+ return false;
+ }
+
+ sn_nsdl_print_coap_data(coap_packet_ptr, false);
+
+ // Do not process any incoming CON message while in alert mode
+ if (_alert_mode && coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
+ tr_info("M2MNsdlInterface::process_received_data - skip message in alert mode");
+ sn_coap_parser_release_allocated_coap_msg_mem(_nsdl_handle->grs->coap, coap_packet_ptr);
+ return true;
+ }
+
return (0 == sn_nsdl_process_coap(_nsdl_handle,
- data,
- data_size,
+ coap_packet_ptr,
address)) ? true : false;
}
@@ -1278,6 +1353,27 @@ void M2MNsdlInterface::stop_timers()
_download_retry_timer.stop_timer();
}
+void M2MNsdlInterface::set_alert_mode(bool alert)
+{
+ tr_debug("M2MNsdlInterface::set_alert_mode() - %d", alert);
+ _alert_mode = alert;
+
+ if (_alert_mode) {
+ // Remove pending notifications from the queue
+ send_next_notification(M2MNsdlInterface::REMOVE_NOTIFICATION);
+ _registration_timer.stop_timer();
+ _bootstrap_id = 0;
+ _nsdl_handle->update_register_token = 0;
+ _nsdl_handle->unregister_token = 0;
+ _download_retry_timer.stop_timer();
+ }
+}
+
+bool M2MNsdlInterface::alert_mode() const
+{
+ return _alert_mode;
+}
+
void M2MNsdlInterface::timer_expired(M2MTimerObserver::Type type)
{
if (M2MTimerObserver::NsdlExecution == type) {
@@ -1367,10 +1463,10 @@ void M2MNsdlInterface::send_delayed_response(M2MBase *base, sn_coap_msg_code_e c
if (sn_nsdl_send_coap_message(_nsdl_handle, &_nsdl_handle->server_address, &coap_response) >= 0) {
// Update msgid, this will be used to track server response
resp->msg_id = coap_response.msg_id;
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_SENT, M2MBase::DELAYED_POST_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_POST_RESPONSE, M2MBase::MESSAGE_STATUS_SENT);
} else {
// Failed to create a message
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_SEND_FAILED, M2MBase::DELAYED_POST_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_POST_RESPONSE, M2MBase::MESSAGE_STATUS_SEND_FAILED);
// Remove stored response from the list
remove_item_from_response_list(resource->uri_path(), UNDEFINED_MSG_ID);
}
@@ -1416,7 +1512,7 @@ void M2MNsdlInterface::send_asynchronous_response(M2MBase *base,
if (sn_nsdl_send_coap_message(_nsdl_handle, &_nsdl_handle->server_address, coap_response) >= 0) {
// Update msgid, this will be used to track server response
resp->msg_id = coap_response->msg_id;
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_SENT, M2MBase::DELAYED_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_RESPONSE, M2MBase::MESSAGE_STATUS_SENT);
msg_sent = true;
if (M2MBase::is_blockwise_needed(_nsdl_handle, payload_len)) {
resp->blockwise_used = true;
@@ -1430,7 +1526,7 @@ void M2MNsdlInterface::send_asynchronous_response(M2MBase *base,
if (!msg_sent) {
// Failed to create a message
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_SEND_FAILED, M2MBase::DELAYED_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_RESPONSE, M2MBase::MESSAGE_STATUS_SEND_FAILED);
// Remove stored response from the list
remove_item_from_response_list(base->uri_path(), UNDEFINED_MSG_ID);
}
@@ -2088,7 +2184,8 @@ void M2MNsdlInterface::send_object_observation(M2MObject *object,
int32_t msgid = sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
sn_coap_observe_e(obs_number), object->report_handler()->is_confirmable(),
sn_coap_content_format_e(object->coap_content_type()), -1, object->max_age());
- execute_notification_delivery_status_cb(object, msgid);
+
+ handle_observation_response(object, msgid);
memory_free(value);
}
@@ -2114,7 +2211,7 @@ void M2MNsdlInterface::send_object_instance_observation(M2MObjectInstance *objec
sn_coap_observe_e(obs_number), object_instance->report_handler()->is_confirmable(),
sn_coap_content_format_e(object_instance->coap_content_type()), -1, object_instance->max_age());
- execute_notification_delivery_status_cb(object_instance, msgid);
+ handle_observation_response(object_instance, msgid);
memory_free(value);
}
@@ -2148,7 +2245,7 @@ void M2MNsdlInterface::send_resource_observation(M2MResource *resource,
sn_coap_observe_e(obs_number),
resource->report_handler()->is_confirmable(),
sn_coap_content_format_e(content_type), -1, resource->max_age());
- execute_notification_delivery_status_cb(resource, msgid);
+ handle_observation_response(resource, msgid);
memory_free(value);
}
@@ -2198,7 +2295,7 @@ void M2MNsdlInterface::handle_bootstrap_put_message(sn_coap_hdr_s *coap_header,
else if (resource_name.compare(0, 1, "3") == 0) {
M2MDevice *dev = M2MInterfaceFactory::create_device();
// Not mandatory resource, that's why it must be created first
- M2MResource *res = dev->create_resource(M2MDevice::CurrentTime, 0);
+ (void)dev->create_resource(M2MDevice::CurrentTime, 0);
object_type = M2MNsdlInterface::DEVICE;
success = true;
}
@@ -2243,10 +2340,12 @@ void M2MNsdlInterface::handle_bootstrap_put_message(sn_coap_hdr_s *coap_header,
response_code);
if (coap_response) {
+#if (MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE == 0)
// Set the correct message type. Must be confirmable since this is a separate response.
// Clear the message id so CoAP will add a new one.
coap_response->msg_type = coap_header->msg_type;
coap_response->msg_id = 0;
+#endif // MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response);
sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response);
@@ -2424,7 +2523,11 @@ void M2MNsdlInterface::handle_bootstrap_finished(sn_coap_hdr_s *coap_header, sn_
// In ok case send response as a separate response
if (msg_code == COAP_MSG_CODE_RESPONSE_CHANGED) {
_waiting_for_bs_finish_ack = true;
+
+#if (MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE == 0)
send_empty_ack(coap_header, address);
+#endif // MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
+
// In error case use piggybacked response
} else {
coap_response = sn_nsdl_build_response(_nsdl_handle, coap_header, msg_code);
@@ -2447,7 +2550,7 @@ void M2MNsdlInterface::handle_bootstrap_finished(sn_coap_hdr_s *coap_header, sn_
memory_free(_endpoint->endpoint_name_ptr);
_endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t *)_endpoint_name.c_str(), _endpoint_name.length());
if (_endpoint->endpoint_name_ptr) {
- if (!_event.data.event_data) {
+ if (!_event.data.event_id) {
_endpoint->endpoint_name_len = _endpoint_name.length();
nsdl_coap_data_s *nsdl_coap_data = create_coap_event_data(coap_message,
address,
@@ -2455,7 +2558,7 @@ void M2MNsdlInterface::handle_bootstrap_finished(sn_coap_hdr_s *coap_header, sn_
(sn_coap_msg_code_e)msg_code);
if (nsdl_coap_data) {
alloc_failed = false;
- _event.data.event_data = true;
+ _event.data.event_id = true;
_event.data.event_type = MBED_CLIENT_NSDLINTERFACE_BS_EVENT;
_event.data.data_ptr = (void *)nsdl_coap_data;
eventOS_event_send_user_allocated(&_event);
@@ -2727,6 +2830,13 @@ void M2MNsdlInterface::start_nsdl_execution_timer()
false);
}
+void M2MNsdlInterface::stop_nsdl_execution_timer()
+{
+ tr_debug("M2MNsdlInterface::stop_nsdl_execution_timer");
+ _nsdl_execution_timer_running = false;
+ _nsdl_execution_timer.stop_timer();
+}
+
M2MSecurity *M2MNsdlInterface::get_security_object()
{
return _security;
@@ -2734,9 +2844,9 @@ M2MSecurity *M2MNsdlInterface::get_security_object()
void M2MNsdlInterface::update_trigger_callback(void */*argument*/)
{
- if (!send_update_registration()) {
- // Most likely case would be memory allocation failure
- _observer.registration_error(M2MInterface::MemoryFail, false);
+ if (is_registered()) {
+ _registration_timer.stop_timer();
+ _registration_timer.start_timer(REGISTRATION_UPDATE_DELAY, M2MTimerObserver::Registration, true);
}
}
@@ -2752,23 +2862,22 @@ bool M2MNsdlInterface::lifetime_value_changed() const
return false;
}
-void M2MNsdlInterface::execute_notification_delivery_status_cb(M2MBase *object, int32_t msgid)
+void M2MNsdlInterface::handle_observation_response(M2MBase *object, int32_t msgid)
{
+ uint8_t status;
if (msgid > 0) {
- object->send_message_delivery_status(*object,
- M2MBase::MESSAGE_STATUS_SENT,
- M2MBase::NOTIFICATION);
+ status = (uint8_t)M2MBase::MESSAGE_STATUS_SENT;
if (object->report_handler()->is_confirmable()) {
store_to_response_list(object->uri_path(), msgid, M2MBase::NOTIFICATION);
} else {
_notification_send_ongoing = false;
}
} else {
- object->send_message_delivery_status(*object,
- M2MBase::MESSAGE_STATUS_BUILD_ERROR,
- M2MBase::NOTIFICATION);
+ status = (uint8_t)M2MBase::MESSAGE_STATUS_BUILD_ERROR;
_notification_send_ongoing = false;
}
+
+ handle_message_status_callback(object, M2MBase::NOTIFICATION, (M2MBase::MessageDeliveryStatus)status);
}
uint8_t M2MNsdlInterface::find_auto_obs_token(const char *path, uint8_t *token) const
@@ -2937,16 +3046,16 @@ void M2MNsdlInterface::calculate_new_coap_ping_send_time()
_next_coap_ping_send_time = _counter_for_nsdl + MBED_CLIENT_TCP_KEEPALIVE_INTERVAL;
}
-void M2MNsdlInterface::send_next_notification(bool clear_token)
+void M2MNsdlInterface::send_next_notification(NotificationQueueOption option)
{
- tr_debug("M2MNsdlInterface::send_next_notification");
+ tr_info("M2MNsdlInterface::send_next_notification - option %d", option);
claim_mutex();
if (!_base_list.empty()) {
M2MBaseList::const_iterator base_iterator;
base_iterator = _base_list.begin();
for (; base_iterator != _base_list.end(); base_iterator++) {
if ((*base_iterator)->base_type() == M2MBase::Object) {
- if (send_next_notification_for_object(*(M2MObject *)*base_iterator, clear_token)) {
+ if (send_next_notification_for_object(*(M2MObject *)*base_iterator, option)) {
release_mutex();
return;
}
@@ -2960,7 +3069,7 @@ void M2MNsdlInterface::send_next_notification(bool clear_token)
object_iterator = object_list.begin();
// Object level
for (; object_iterator != object_list.end(); object_iterator++) {
- if (send_next_notification_for_object(**object_iterator, clear_token)) {
+ if (send_next_notification_for_object(**object_iterator, option)) {
release_mutex();
return;
}
@@ -2972,24 +3081,16 @@ void M2MNsdlInterface::send_next_notification(bool clear_token)
}
_notification_send_ongoing = false;
+ _last_notif_queue_event = option;
release_mutex();
tr_debug("M2MNsdlInterface::send_next_notification - nothing to send");
}
-bool M2MNsdlInterface::send_next_notification_for_object(M2MObject &object, bool clear_token)
+bool M2MNsdlInterface::send_next_notification_for_object(M2MObject &object, NotificationQueueOption option)
{
const M2MObjectInstanceList &object_instance_list = object.instances();
- M2MReportHandler *reporter = object.report_handler();
- if (reporter) {
- // Auto obs token can't be cleared
- if (clear_token && !object.get_nsdl_resource()->auto_observable) {
- reporter->set_observation_token(NULL, 0);
- object.cancel_observation(M2MBase::MESSAGE_STATUS_SEND_FAILED);
- } else if (reporter->is_under_observation() &&
- (reporter->notification_in_queue() || reporter->notification_send_in_progress())) {
- reporter->schedule_report(true);
- return true;
- }
+ if (handle_notification_queue(object, option)) {
+ return true;
}
// Object instance level
@@ -2997,17 +3098,8 @@ bool M2MNsdlInterface::send_next_notification_for_object(M2MObject &object, bool
M2MObjectInstanceList::const_iterator object_instance_iterator;
object_instance_iterator = object_instance_list.begin();
for (; object_instance_iterator != object_instance_list.end(); object_instance_iterator++) {
- reporter = (*object_instance_iterator)->report_handler();
- if (reporter) {
- // Auto obs token can't be cleared
- if (clear_token && !(*object_instance_iterator)->get_nsdl_resource()->auto_observable) {
- reporter->set_observation_token(NULL, 0);
- (*object_instance_iterator)->cancel_observation(M2MBase::MESSAGE_STATUS_SEND_FAILED);
- } else if (reporter->is_under_observation() &&
- (reporter->notification_in_queue() || reporter->notification_send_in_progress())) {
- reporter->schedule_report(true);
- return true;
- }
+ if (handle_notification_queue(*(M2MObject *)*object_instance_iterator, option)) {
+ return true;
}
// Resource level
@@ -3016,26 +3108,8 @@ bool M2MNsdlInterface::send_next_notification_for_object(M2MObject &object, bool
M2MResourceList::const_iterator resource_iterator;
resource_iterator = resource_list.begin();
for (; resource_iterator != resource_list.end(); resource_iterator++) {
- reporter = (*resource_iterator)->report_handler();
- if (reporter) {
- // Auto obs token can't be cleared
- if (clear_token) {
- if ((*resource_iterator)->get_nsdl_resource()->auto_observable) {
- sn_nsdl_dynamic_resource_parameters_s *res = (*resource_iterator)->get_nsdl_resource();
- // Do not send unnecessary notification since resource value is going to be part of registration message
- if (res->publish_value != 0) {
- reporter->set_notification_in_queue(false);
- reporter->set_notification_send_in_progress(false);
- }
- } else {
- reporter->set_observation_token(NULL, 0);
- (*resource_iterator)->cancel_observation(M2MBase::MESSAGE_STATUS_SEND_FAILED);
- }
- } else if (reporter->is_under_observation() &&
- (reporter->notification_in_queue() || reporter->notification_send_in_progress())) {
- reporter->schedule_report(true);
- return true;
- }
+ if (handle_notification_queue(*(M2MObject *)*resource_iterator, option)) {
+ return true;
}
}
}
@@ -3064,6 +3138,20 @@ void M2MNsdlInterface::store_bs_finished_response_id(uint16_t msg_id)
{
tr_debug("M2MNsdlInterface::store_bs_finished_response_id - id %d", msg_id);
_bootstrap_id = msg_id;
+
+ // Fire event to continue with BS flow since empty ack is not coming in this case.
+#if (MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE == 1)
+ if (!_event.data.event_id) {
+ tr_debug("M2MNsdlInterface::store_bs_finished_response_id - send finish event");
+ _event.data.event_id = true;
+ _event.data.event_type = MBED_CLIENT_NSDLINTERFACE_BS_FINISH_EVENT;
+ _event.data.event_data = msg_id;
+ _event.data.data_ptr = _nsdl_handle;
+ _observer.bootstrap_wait();
+ _waiting_for_bs_finish_ack = false;
+ eventOS_event_send_user_allocated(&_event);
+ }
+#endif // MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE
}
#endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
@@ -3235,7 +3323,7 @@ void M2MNsdlInterface::handle_register_update_response(const sn_coap_hdr_s *coap
_observer.registration_error(M2MInterface::NetworkError, true);
} else {
// Clear observation tokens and do a full registration
- send_next_notification(true);
+ send_next_notification(M2MNsdlInterface::CLEAR_NOTIFICATION_TOKEN);
bool msg_sent = false;
if (_server_address) {
@@ -3477,7 +3565,8 @@ void M2MNsdlInterface::handle_empty_ack(const sn_coap_hdr_s *coap_header, bool i
handle_bootstrap_error(M2MInterface::BootstrapFailed, ERROR_REASON_28, false);
} else {
tr_debug("M2MNsdlInterface::handle_empty_ack - sending finish event - status %d", coap_header->coap_status);
- if (!_event.data.event_data) {
+ if (!_event.data.event_id) {
+ _event.data.event_id = true;
_event.data.event_type = MBED_CLIENT_NSDLINTERFACE_BS_FINISH_EVENT;
tr_debug("M2MNsdlInterface::handle_empty_ack - sending finish event - msg id %d", coap_header->msg_id);
_event.data.event_data = coap_header->msg_id;
@@ -3503,11 +3592,11 @@ void M2MNsdlInterface::handle_empty_ack(const sn_coap_hdr_s *coap_header, bool i
_notification_send_ongoing = false;
_notification_handler->send_notification(this);
} else if (resp->type == M2MBase::DELAYED_POST_RESPONSE) {
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_REJECTED, M2MBase::DELAYED_POST_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_POST_RESPONSE, M2MBase::MESSAGE_STATUS_REJECTED);
}
#ifdef ENABLE_ASYNC_REST_RESPONSE
else if (resp->type == M2MBase::DELAYED_RESPONSE) {
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_REJECTED, M2MBase::DELAYED_RESPONSE);
+ handle_message_status_callback(base, M2MBase::DELAYED_RESPONSE, M2MBase::MESSAGE_STATUS_REJECTED);
}
#endif // ENABLE_ASYNC_REST_RESPONSE
remove_item_from_response_list(resp->uri_path, coap_header->msg_id);
@@ -3528,7 +3617,7 @@ void M2MNsdlInterface::handle_empty_ack(const sn_coap_hdr_s *coap_header, bool i
if (report) {
if (!data->blockwise_used) {
- handle_message_delivered(base, data->type);
+ handle_message_status_callback(base, data->type, M2MBase::MESSAGE_STATUS_DELIVERED);
remove_item_from_response_list(NULL, coap_header->msg_id);
}
}
@@ -3555,16 +3644,32 @@ void M2MNsdlInterface::handle_bootstrap_finish_ack(uint16_t msg_id)
}
#endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
-void M2MNsdlInterface::handle_message_delivered(M2MBase *base, const M2MBase::MessageType type)
+void M2MNsdlInterface::handle_message_status_callback(M2MBase *base, const M2MBase::MessageType type, const M2MBase::MessageDeliveryStatus status)
{
- if (M2MBase::NOTIFICATION == type) {
+ if (M2MBase::NOTIFICATION == type && status == M2MBase::MESSAGE_STATUS_DELIVERED) {
base->report_handler()->set_notification_send_in_progress(false);
_notification_send_ongoing = false;
_notification_handler->send_notification(this);
}
- base->send_message_delivery_status(*base, M2MBase::MESSAGE_STATUS_DELIVERED, type);
+ uint16_t data = (uint8_t)status << 8 | (uint8_t)type;
+ arm_event_s event = {
+ .receiver = M2MNsdlInterface::_tasklet_id, // ID we got when creating our handler
+ .sender = 0,
+ .event_type = MBED_CLIENT_NSDLINTERFACE_MESSAGE_STATUS_CB_EVENT,
+ .event_id = 0,
+ .data_ptr = base,
+ .priority = ARM_LIB_HIGH_PRIORITY_EVENT, // Application level priority
+ .event_data = data,
+ };
+
+ if (eventOS_event_send(&event) < 0) {
+ tr_warn("M2MNsdlInterface::handle_message_status_callback - failed to allocate event!");
+ base->send_message_delivery_status(*base,
+ status,
+ type);
+ }
}
void M2MNsdlInterface::set_retransmission_parameters()
@@ -3581,11 +3686,11 @@ void M2MNsdlInterface::set_retransmission_parameters()
reconnection_total_time = total_retransmission_time(--resend_count);
}
- tr_info("M2MNsdlInterface::set_retransmission_parameters() - setting max resend count to %" PRIu32 " with total time: %" PRIu32,
+ tr_info("M2MNsdlInterface::set_retransmission_parameters() - setting max resend count to %" PRIu8 " with total time: %" PRIu32,
resend_count, reconnection_total_time);
sn_nsdl_set_retransmission_parameters(_nsdl_handle, resend_count, _network_rtt_estimate);
#else
- tr_info("M2MNsdlInterface::set_retransmission_parameters() - setting resend count to %" PRIu32 " with initial retransmission time: %" PRIu32,
+ tr_info("M2MNsdlInterface::set_retransmission_parameters() - setting resend count to %" PRIu8 " with initial retransmission time: %" PRIu8,
sn_nsdl_get_retransmission_count(_nsdl_handle),
_network_rtt_estimate);
sn_nsdl_set_retransmission_parameters(_nsdl_handle,
@@ -3840,26 +3945,41 @@ bool M2MNsdlInterface::handle_delayed_response_store(const char *uri_path,
uint16_t M2MNsdlInterface::estimate_stagger_data_amount(bool bootstrap, bool using_cid) const
{
- // The full TLS/DTLS handshake amounts to roughly 5 KiB data.
- // Boostrap takes roughly 4 KiB.
- // Registration goes to roughly 5 KiB.
- // On top of this we need to calculate 300 byte overhead per packet in transit.
- // ~30 for bootstrap, ~25 for registration. 10 for DTLS.
- const static uint16_t bootstrap_amount = 4 + 9;
- const static uint16_t registration_amount = 5 + 8;
- const static uint16_t handshake = 8;
+ const static uint16_t bs_handshake_amount = 5;
+ // 10 messages * 300 bytes
+ const static uint16_t bs_handshake_overhead = 3;
+
+#if (MBED_CLIENT_BOOTSTRAP_PIGGYBACKED_RESPONSE == 1)
+ const static uint16_t bootstrap_amount = 4;
+ // 17 messages * 300 bytes
+ const static uint16_t bootstrap_overhead = 5;
+#else
+ const static uint16_t bootstrap_amount = 5;
+ // 23 messages * 300 bytes
+ const static uint16_t bootstrap_overhead = 7
+#endif
+
+ // 6 messages * 300 bytes
+ const static uint16_t mds_handshake_amount = 3;
+ const static uint16_t mds_handshake_overhead = 2;
+ const static uint16_t registration_amount = 2;
+ // 4 messages * 300 bytes
+ const static uint16_t registration_overhead = 2;
+ // registration traffic overhead.
+ // this considers initial customer data generated traffic on the network.
+ const static uint16_t registration_extra_overhead = 4;
if (using_cid) {
// Bootstrap and registration handshake done, thus doing registration
- return registration_amount;
+ return registration_amount + registration_overhead + registration_extra_overhead;
}
if (bootstrap) {
// Doing bootstrap stagger
- return bootstrap_amount + handshake;
+ return bootstrap_amount + bootstrap_overhead + bs_handshake_amount + bs_handshake_overhead;
} else {
// Doing register stagger
- return registration_amount + handshake;
+ return registration_amount + registration_overhead + registration_extra_overhead + mds_handshake_amount + mds_handshake_overhead;
}
}
@@ -3900,3 +4020,58 @@ void M2MNsdlInterface::set_cid_value(const uint8_t *data_ptr, const size_t data_
{
_connection_handler.set_cid_value(data_ptr, data_len);
}
+
+bool M2MNsdlInterface::handle_notification_queue(M2MObject &object, M2MNsdlInterface::NotificationQueueOption option)
+{
+ M2MReportHandler *reporter = object.report_handler();
+ if (!reporter) {
+ return false;
+ }
+
+ bool scheduled = false;
+ switch (option) {
+ case SEND_NOTIFICATION:
+ // Alert mode will clear the queue and stop the timers, so we need to start the timers again in that case
+ if (_last_notif_queue_event == REMOVE_NOTIFICATION) {
+ reporter->start_timers();
+ }
+
+ if (reporter->is_under_observation() &&
+ (reporter->notification_in_queue() || reporter->notification_send_in_progress())) {
+ reporter->schedule_report(true);
+ scheduled = true;
+ }
+
+ break;
+
+ case CLEAR_NOTIFICATION_TOKEN:
+ if (object.base_type() == M2MBase::Resource &&
+ object.get_nsdl_resource()->auto_observable) {
+ sn_nsdl_dynamic_resource_parameters_s *res = object.get_nsdl_resource();
+ // Do not send unnecessary notification since resource value is going to be part of registration message
+ if (res->publish_value != 0) {
+ reporter->set_notification_in_queue(false);
+ reporter->set_notification_send_in_progress(false);
+ }
+ }
+
+ if (!object.get_nsdl_resource()->auto_observable) {
+ reporter->set_observation_token(NULL, 0);
+ object.cancel_observation(M2MBase::MESSAGE_STATUS_SEND_FAILED, reporter->notification_in_queue());
+ }
+
+ break;
+
+ case REMOVE_NOTIFICATION:
+ reporter->set_notification_in_queue(false);
+ reporter->set_notification_send_in_progress(false);
+ reporter->stop_timers();
+
+ break;
+
+ default:
+ break;
+ }
+
+ return scheduled;
+}
diff --git a/mbed-client/source/m2mobjectinstance.cpp b/mbed-client/source/m2mobjectinstance.cpp
index aa26b26e2..81b3b917a 100644
--- a/mbed-client/source/m2mobjectinstance.cpp
+++ b/mbed-client/source/m2mobjectinstance.cpp
@@ -728,8 +728,8 @@ sn_coap_hdr_s *M2MObjectInstance::handle_post_request(nsdl_s *nsdl,
break;
}
} else {
- msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
- } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
+ msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE;
+ }
} else {
// Operation is not allowed.
tr_error("M2MObjectInstance::handle_post_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
diff --git a/mbed-client/source/m2mresource.cpp b/mbed-client/source/m2mresource.cpp
index de3912a77..c0b21fd61 100644
--- a/mbed-client/source/m2mresource.cpp
+++ b/mbed-client/source/m2mresource.cpp
@@ -405,20 +405,22 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
tr_info("M2MResource::handle_put_request()");
sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
sn_coap_hdr_s * coap_response = NULL;
- if(supports_multiple_instances()) {
+ if (supports_multiple_instances() ||
+ (received_coap_header->content_format == COAP_CONTENT_OMA_TLV_TYPE ||
+ received_coap_header->content_format == COAP_CONTENT_OMA_TLV_TYPE_OLD)) {
coap_response = sn_nsdl_build_response(nsdl,
received_coap_header,
msg_code);
// process the PUT if we have registered a callback for it
- if(received_coap_header) {
+ if (received_coap_header) {
uint16_t coap_content_type = 0;
bool content_type_present = false;
- if(received_coap_header->content_format != COAP_CT_NONE && coap_response) {
+ if (received_coap_header->content_format != COAP_CT_NONE && coap_response) {
content_type_present = true;
coap_content_type = received_coap_header->content_format;
}
- if(received_coap_header->options_list_ptr &&
- received_coap_header->options_list_ptr->uri_query_ptr) {
+ if (received_coap_header->options_list_ptr &&
+ received_coap_header->options_list_ptr->uri_query_ptr) {
char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr,
received_coap_header->options_list_ptr->uri_query_len);
if (query){
@@ -436,7 +438,7 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
free(query);
}
} else if ((operation() & M2MBase::PUT_ALLOWED) != 0) {
- if(!content_type_present &&
+ if (!content_type_present &&
(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE ||
M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) {
coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
@@ -444,17 +446,28 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
tr_debug("M2MResource::handle_put_request() - Request Content-type: %d", coap_content_type);
- if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type ||
- COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_content_type) {
+ if (COAP_CONTENT_OMA_TLV_TYPE == coap_content_type || COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_content_type) {
set_coap_content_type(coap_content_type);
M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
- error = M2MTLVDeserializer::deserialize_resource_instances(received_coap_header->payload_ptr,
+ if (supports_multiple_instances()) {
+ error = M2MTLVDeserializer::deserialize_resource_instances(received_coap_header->payload_ptr,
received_coap_header->payload_len,
*this,
M2MTLVDeserializer::Put);
- switch(error) {
+ } else {
+ if ((strcmp(uri_path(), FIRMWARE_PACKAGE_URI_PATH) == 0) && received_coap_header->payload_len > MAX_FIRMWARE_PACKAGE_URI_PATH_LEN) {
+ // Firmware object uri path is limited to be max MAX_FIRMWARE_PACKAGE_URI_PATH_LEN bytes
+ error = M2MTLVDeserializer::NotAccepted;
+ } else {
+ error = M2MTLVDeserializer::deserialize_resource(received_coap_header->payload_ptr,
+ received_coap_header->payload_len,
+ *this,
+ M2MTLVDeserializer::Put);
+ }
+ }
+ switch (error) {
case M2MTLVDeserializer::None:
- if(observation_handler) {
+ if (observation_handler) {
String value = "";
if (received_coap_header->uri_path_ptr != NULL &&
received_coap_header->uri_path_len > 0) {
@@ -477,10 +490,13 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
case M2MTLVDeserializer::OutOfMemory:
msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE;
break;
+ case M2MTLVDeserializer::NotAccepted:
+ msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE;
+ break;
}
} else {
msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
- } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
+ }
} else {
// Operation is not allowed.
tr_error("M2MResource::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
@@ -489,7 +505,7 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
} else {
msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
}
- if(coap_response) {
+ if (coap_response) {
coap_response->msg_code = msg_code;
}
} else {
diff --git a/mbed-client/source/m2mresourcebase.cpp b/mbed-client/source/m2mresourcebase.cpp
index 2b9477e98..9636417fe 100644
--- a/mbed-client/source/m2mresourcebase.cpp
+++ b/mbed-client/source/m2mresourcebase.cpp
@@ -135,6 +135,8 @@ M2MResourceBase::~M2MResourceBase()
M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MResourceBaseValueReadCallback);
+ M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MResourceBaseValueReadSizeCallback);
+
M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MResourceBaseValueWriteCallback);
M2MCallbackStorage::remove_callback(*this, M2MCallbackAssociation::M2MResourceInstanceReadCallback);
@@ -598,14 +600,22 @@ sn_coap_hdr_s *M2MResourceBase::handle_get_request(nsdl_s *nsdl,
}
if (received_coap_header && (operation() & M2MBase::GET_ALLOWED) != 0) {
- bool content_type_present = false;
coap_response->payload_ptr = NULL;
- size_t payload_len = 0;
-
- if (received_coap_header->options_list_ptr &&
- received_coap_header->options_list_ptr->accept != COAP_CT_NONE) {
- coap_response->content_format = received_coap_header->options_list_ptr->accept;
- set_coap_content_type(coap_response->content_format);
+ uint32_t payload_len = 0;
+
+ if (received_coap_header->options_list_ptr && received_coap_header->options_list_ptr->accept != COAP_CT_NONE) {
+ if ((received_coap_header->options_list_ptr->accept == COAP_CONTENT_OMA_OPAQUE_TYPE) ||
+ (received_coap_header->options_list_ptr->accept == COAP_CONTENT_OMA_PLAIN_TEXT_TYPE) ||
+ (received_coap_header->options_list_ptr->accept == COAP_CONTENT_OMA_TLV_TYPE_OLD) ||
+ (received_coap_header->options_list_ptr->accept == COAP_CONTENT_OMA_TLV_TYPE)) {
+ coap_response->content_format = received_coap_header->options_list_ptr->accept;
+ set_coap_content_type(coap_response->content_format);
+ } else {
+ // Invalid accept or json which we don't support
+ tr_error("M2MResourceBase::handle_get_request() - invalid or unsupported accept: %d", received_coap_header->options_list_ptr->accept);
+ coap_response->msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE;
+ return coap_response;
+ }
} else {
if (resource_instance_type() == M2MResourceInstance::OPAQUE) {
coap_response->content_format = sn_coap_content_format_e(COAP_CONTENT_OMA_OPAQUE_TYPE);
@@ -631,17 +641,19 @@ sn_coap_hdr_s *M2MResourceBase::handle_get_request(nsdl_s *nsdl,
received_coap_header->uri_path_len > 0) {
name.append_raw((char *)received_coap_header->uri_path_ptr, received_coap_header->uri_path_len);
}
- (*outgoing_block_message_cb)(name, coap_response->payload_ptr, (uint32_t &)payload_len);
+ (*outgoing_block_message_cb)(name, coap_response->payload_ptr, payload_len);
}
#endif
// Read resource data from application
M2MCallbackAssociation *item = M2MCallbackStorage::get_association_item(*this, M2MCallbackAssociation::M2MResourceInstanceReadCallback);
if (item) {
- read_data_from_application(item, nsdl, received_coap_header, coap_response, payload_len);
+ size_t len = 0;
+ read_data_from_application(item, nsdl, received_coap_header, coap_response, len);
+ payload_len = len;
} else {
if (coap_response->content_format == COAP_CONTENT_OMA_TLV_TYPE ||
coap_response->content_format == COAP_CONTENT_OMA_TLV_TYPE_OLD) {
- coap_response->payload_ptr = M2MTLVSerializer::serialize(&get_parent_resource(), (uint32_t &)payload_len);
+ coap_response->payload_ptr = M2MTLVSerializer::serialize(&get_parent_resource(), payload_len);
} else {
get_value(coap_response->payload_ptr, (uint32_t &)payload_len);
}
@@ -752,8 +764,8 @@ sn_coap_hdr_s *M2MResourceBase::handle_put_request(nsdl_s *nsdl,
}
#endif
// Firmware object uri path is limited to be max 255 bytes
- if ((strcmp(uri_path(), FIRMAWARE_PACKAGE_URI_PATH) == 0) &&
- received_coap_header->payload_len > 255) {
+ if ((strcmp(uri_path(), FIRMWARE_PACKAGE_URI_PATH) == 0) &&
+ received_coap_header->payload_len > MAX_FIRMWARE_PACKAGE_URI_PATH_LEN) {
msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE;
} else if ((strcmp(uri_path(), SERVER_LIFETIME_PATH) == 0)) {
// Check that lifetime can't go below 60s
diff --git a/mbed-client/source/m2mserver.cpp b/mbed-client/source/m2mserver.cpp
index 8c9b31d6b..aa8e82ba9 100644
--- a/mbed-client/source/m2mserver.cpp
+++ b/mbed-client/source/m2mserver.cpp
@@ -32,7 +32,7 @@ M2MServer::M2MServer()
_server_instance = object_instance();
- if(_server_instance) {
+ if (_server_instance) {
_server_instance->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
_server_instance->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
@@ -40,51 +40,59 @@ M2MServer::M2MServer()
OMA_RESOURCE_TYPE,
M2MResourceInstance::INTEGER,
true);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::GET_PUT_ALLOWED);
}
res = _server_instance->create_dynamic_resource(SERVER_LIFETIME,
OMA_RESOURCE_TYPE,
M2MResourceInstance::INTEGER,
true);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
}
+
+ res = _server_instance->create_dynamic_resource(SERVER_DISABLE,
+ OMA_RESOURCE_TYPE,
+ M2MResourceInstance::OPAQUE,
+ false);
+ if (res) {
+ res->set_operation(M2MBase::POST_ALLOWED);
+ }
+
res = _server_instance->create_dynamic_resource(SERVER_NOTIFICATION_STORAGE,
OMA_RESOURCE_TYPE,
M2MResourceInstance::BOOLEAN,
true);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
}
res = _server_instance->create_dynamic_resource(SERVER_BINDING,
OMA_RESOURCE_TYPE,
M2MResourceInstance::STRING,
true);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
}
res = _server_instance->create_dynamic_resource(SERVER_REGISTRATION_UPDATE,
OMA_RESOURCE_TYPE,
M2MResourceInstance::OPAQUE,
false);
- if(res) {
- res->set_operation(M2MBase::POST_ALLOWED);
+ if (res) {
+ res->set_operation(M2MBase::POST_ALLOWED);
}
}
}
M2MServer::~M2MServer()
{
-
}
M2MResource* M2MServer::create_resource(ServerResource resource, uint32_t value)
{
M2MResource* res = NULL;
const char* server_id_ptr = "";
- if(!is_resource_present(resource)) {
- switch(resource) {
+ if (!is_resource_present(resource)) {
+ switch (resource) {
case DefaultMinPeriod:
server_id_ptr = SERVER_DEFAULT_MIN_PERIOD;
break;
@@ -99,16 +107,15 @@ M2MResource* M2MServer::create_resource(ServerResource resource, uint32_t value)
}
}
String server_id(server_id_ptr);
-
- if(!server_id.empty()) {
- if(_server_instance) {
+
+ if (!server_id.empty()) {
+ if (_server_instance) {
res = _server_instance->create_dynamic_resource(server_id,
OMA_RESOURCE_TYPE,
M2MResourceInstance::INTEGER,
true);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
-
res->set_value(value);
}
}
@@ -119,14 +126,14 @@ M2MResource* M2MServer::create_resource(ServerResource resource, uint32_t value)
M2MResource* M2MServer::create_resource(ServerResource resource)
{
M2MResource* res = NULL;
- if(!is_resource_present(resource)) {
- if(M2MServer::Disable == resource) {
- if(_server_instance) {
+ if (!is_resource_present(resource)) {
+ if (M2MServer::Disable == resource) {
+ if (_server_instance) {
res = _server_instance->create_dynamic_resource(SERVER_DISABLE,
OMA_RESOURCE_TYPE,
M2MResourceInstance::OPAQUE,
false);
- if(res) {
+ if (res) {
res->set_operation(M2MBase::POST_ALLOWED);
}
}
@@ -139,7 +146,7 @@ bool M2MServer::delete_resource(ServerResource resource)
{
bool success = false;
const char* server_id_ptr;
- switch(resource) {
+ switch (resource) {
case DefaultMinPeriod:
server_id_ptr = SERVER_DEFAULT_MIN_PERIOD;
break;
@@ -157,8 +164,8 @@ bool M2MServer::delete_resource(ServerResource resource)
break;
}
- if(server_id_ptr) {
- if(_server_instance) {
+ if (server_id_ptr) {
+ if (_server_instance) {
success = _server_instance->remove_resource(server_id_ptr);
}
}
@@ -170,8 +177,8 @@ bool M2MServer::set_resource_value(ServerResource resource,
{
bool success = false;
M2MResource* res = get_resource(resource);
- if(res && (M2MServer::Binding == resource)) {
- success = res->set_value((const uint8_t*)value.c_str(),(uint32_t)value.length());
+ if (res && (M2MServer::Binding == resource)) {
+ success = res->set_value((const uint8_t*)value.c_str(), (uint32_t)value.length());
}
return success;
}
@@ -181,17 +188,16 @@ bool M2MServer::set_resource_value(ServerResource resource,
{
bool success = false;
M2MResource* res = get_resource(resource);
- if(res) {
- if(M2MServer::ShortServerID == resource ||
- M2MServer::Lifetime == resource ||
- M2MServer::DefaultMinPeriod == resource ||
- M2MServer::DefaultMaxPeriod == resource ||
- M2MServer::DisableTimeout == resource ||
- M2MServer::NotificationStorage == resource) {
- // If it is any of the above resource
- // set the value of the resource.
-
- success = res->set_value(value);
+ if (res) {
+ if (M2MServer::ShortServerID == resource ||
+ M2MServer::Lifetime == resource ||
+ M2MServer::DefaultMinPeriod == resource ||
+ M2MServer::DefaultMaxPeriod == resource ||
+ M2MServer::DisableTimeout == resource ||
+ M2MServer::NotificationStorage == resource) {
+ // If it is any of the above resource
+ // set the value of the resource.
+ success = res->set_value(value);
}
}
return success;
@@ -201,27 +207,24 @@ String M2MServer::resource_value_string(ServerResource resource) const
{
String value = "";
M2MResource* res = get_resource(resource);
- if(res && (M2MServer::Binding == resource)) {
-
+ if (res && (M2MServer::Binding == resource)) {
value = res->get_value_string();
}
return value;
}
-
uint32_t M2MServer::resource_value_int(ServerResource resource) const
{
uint32_t value = 0;
M2MResource* res = get_resource(resource);
- if(res) {
- if(M2MServer::ShortServerID == resource ||
- M2MServer::Lifetime == resource ||
- M2MServer::DefaultMinPeriod == resource ||
- M2MServer::DefaultMaxPeriod == resource ||
- M2MServer::DisableTimeout == resource ||
- M2MServer::NotificationStorage == resource) {
-
- value = res->get_value_int();
+ if (res) {
+ if (M2MServer::ShortServerID == resource ||
+ M2MServer::Lifetime == resource ||
+ M2MServer::DefaultMinPeriod == resource ||
+ M2MServer::DefaultMaxPeriod == resource ||
+ M2MServer::DisableTimeout == resource ||
+ M2MServer::NotificationStorage == resource) {
+ value = res->get_value_int();
}
}
return value;
@@ -231,7 +234,7 @@ bool M2MServer::is_resource_present(ServerResource resource) const
{
bool success = false;
M2MResource *res = get_resource(resource);
- if(res) {
+ if (res) {
success = true;
}
return success;
@@ -240,8 +243,8 @@ bool M2MServer::is_resource_present(ServerResource resource) const
uint16_t M2MServer::total_resource_count() const
{
uint16_t total_count = 0;
- if(_server_instance) {
- total_count = _server_instance->resources().size();
+ if (_server_instance) {
+ total_count = _server_instance->resources().size();
}
return total_count;
}
@@ -250,38 +253,38 @@ M2MResource* M2MServer::get_resource(ServerResource res) const
{
M2MResource* res_object = NULL;
const char* res_name_ptr = NULL;
- switch(res) {
- case ShortServerID:
- res_name_ptr = SERVER_SHORT_SERVER_ID;
- break;
- case Lifetime:
- res_name_ptr = SERVER_LIFETIME;
- break;
- case DefaultMinPeriod:
- res_name_ptr = SERVER_DEFAULT_MIN_PERIOD;
- break;
- case DefaultMaxPeriod:
- res_name_ptr = SERVER_DEFAULT_MAX_PERIOD;
- break;
- case Disable:
- res_name_ptr = SERVER_DISABLE;
- break;
- case DisableTimeout:
- res_name_ptr = SERVER_DISABLE_TIMEOUT;
- break;
- case NotificationStorage:
- res_name_ptr = SERVER_NOTIFICATION_STORAGE;
- break;
- case Binding:
- res_name_ptr = SERVER_BINDING;
- break;
- case RegistrationUpdate:
- res_name_ptr = SERVER_REGISTRATION_UPDATE;
- break;
- }
+ switch (res) {
+ case ShortServerID:
+ res_name_ptr = SERVER_SHORT_SERVER_ID;
+ break;
+ case Lifetime:
+ res_name_ptr = SERVER_LIFETIME;
+ break;
+ case DefaultMinPeriod:
+ res_name_ptr = SERVER_DEFAULT_MIN_PERIOD;
+ break;
+ case DefaultMaxPeriod:
+ res_name_ptr = SERVER_DEFAULT_MAX_PERIOD;
+ break;
+ case Disable:
+ res_name_ptr = SERVER_DISABLE;
+ break;
+ case DisableTimeout:
+ res_name_ptr = SERVER_DISABLE_TIMEOUT;
+ break;
+ case NotificationStorage:
+ res_name_ptr = SERVER_NOTIFICATION_STORAGE;
+ break;
+ case Binding:
+ res_name_ptr = SERVER_BINDING;
+ break;
+ case RegistrationUpdate:
+ res_name_ptr = SERVER_REGISTRATION_UPDATE;
+ break;
+ }
- if(res_name_ptr) {
- if(_server_instance) {
+ if (res_name_ptr) {
+ if (_server_instance) {
res_object = _server_instance->resource(res_name_ptr);
}
}
diff --git a/mbed-client/source/m2mtlvdeserializer.cpp b/mbed-client/source/m2mtlvdeserializer.cpp
index e1b86f29c..8528c2652 100755
--- a/mbed-client/source/m2mtlvdeserializer.cpp
+++ b/mbed-client/source/m2mtlvdeserializer.cpp
@@ -53,17 +53,17 @@ bool M2MTLVDeserializer::is_resource_instance(const uint8_t *tlv)
return is_resource_instance(tlv, 0);
}
-M2MTLVDeserializer::Error M2MTLVDeserializer::deserialise_object_instances(const uint8_t* tlv,
+M2MTLVDeserializer::Error M2MTLVDeserializer::deserialise_object_instances(const uint8_t *tlv,
uint32_t tlv_size,
M2MObject &object,
M2MTLVDeserializer::Operation operation)
{
M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
- if (is_object_instance(tlv) ) {
+ if (is_object_instance(tlv)) {
tr_debug("M2MTLVDeserializer::deserialise_object_instances");
- error = deserialize_object_instances(tlv, tlv_size, 0, object,operation,false);
- if(M2MTLVDeserializer::None == error) {
- error = deserialize_object_instances(tlv, tlv_size, 0, object,operation,true);
+ error = deserialize_object_instances(tlv, tlv_size, 0, object, operation, false);
+ if (M2MTLVDeserializer::None == error) {
+ error = deserialize_object_instances(tlv, tlv_size, 0, object, operation, true);
}
} else {
tr_debug("M2MTLVDeserializer::deserialise_object_instances ::NotValid");
@@ -81,17 +81,34 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(const uint8_
if (!is_resource(tlv) && !is_multiple_resource(tlv)) {
error = M2MTLVDeserializer::NotValid;
} else {
- error = deserialize_resources(tlv, tlv_size, 0, object_instance, operation,false);
- if(M2MTLVDeserializer::None == error) {
+ error = deserialize_resources(tlv, tlv_size, 0, object_instance, operation, false);
+ if (M2MTLVDeserializer::None == error) {
if (M2MTLVDeserializer::Put == operation) {
remove_resources(tlv, tlv_size, object_instance, 0);
}
- error = deserialize_resources(tlv, tlv_size, 0, object_instance, operation,true);
+ error = deserialize_resources(tlv, tlv_size, 0, object_instance, operation, true);
}
}
return error;
}
+M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource(const uint8_t *tlv,
+ uint32_t tlv_size,
+ M2MResource &resource,
+ M2MTLVDeserializer::Operation operation)
+{
+ M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
+ if (!is_resource(tlv)) {
+ error = M2MTLVDeserializer::NotValid;
+ } else if (operation != M2MTLVDeserializer::Put) {
+ error = M2MTLVDeserializer::NotValid;
+ } else {
+ error = deserialize_resource(tlv, tlv_size, resource, operation, true);
+ }
+
+ return error;
+}
+
M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(const uint8_t *tlv,
uint32_t tlv_size,
M2MResource &resource,
@@ -107,21 +124,21 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
((tlv[0] & 0x20) == 0) ? offset : offset++;
uint8_t length = tlv[0] & 0x18;
- if(length == 0x08) {
+ if (length == 0x08) {
offset += 1;
- } else if(length == 0x10) {
+ } else if (length == 0x10) {
offset += 2;
- } else if(length == 0x18) {
+ } else if (length == 0x18) {
offset += 3;
}
tr_debug("M2MTLVDeserializer::deserialize_resource_instances() Offset %d", offset);
- error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation,false);
- if(M2MTLVDeserializer::None == error) {
+ error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation, false);
+ if (M2MTLVDeserializer::None == error) {
if (M2MTLVDeserializer::Put == operation) {
remove_resource_instances(tlv, tlv_size, resource, offset);
}
- error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation,true);
+ error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation, true);
}
}
return error;
@@ -145,14 +162,14 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_object_instances(const
it = list.begin();
if (TYPE_OBJECT_INSTANCE == til._type) {
- for (; it!=list.end(); it++) {
- if((*it)->instance_id() == til._id) {
- error = deserialize_resources(tlv, tlv_size, offset, (**it),operation, update_value);
+ for (; it != list.end(); it++) {
+ if ((*it)->instance_id() == til._id) {
+ error = deserialize_resources(tlv, tlv_size, offset, (**it), operation, update_value);
}
}
offset += til._length;
- if(offset < tlv_size) {
+ if (offset < tlv_size) {
error = deserialize_object_instances(tlv, tlv_size, offset, object, operation, update_value);
}
}
@@ -180,14 +197,14 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(const uint8_
bool multi = false;
if (TYPE_RESOURCE == til._type || TYPE_RESOURCE_INSTANCE == til._type) {
multi = false;
- for (; it!=list.end(); it++) {
- if((*it)->name_id() == til._id){
+ for (; it != list.end(); it++) {
+ if ((*it)->name_id() == til._id) {
tr_debug("M2MTLVDeserializer::deserialize_resources() - Resource ID %d ", til._id);
found = true;
- if(update_value) {
- if(til._length > 0) {
+ if (update_value) {
+ if (til._length > 0) {
tr_debug("M2MTLVDeserializer::deserialize_resources() - Update value");
- if (!set_resource_instance_value((*it), tlv+offset, til._length)) {
+ if (!set_resource_instance_value((*it), tlv + offset, til._length)) {
error = M2MTLVDeserializer::OutOfMemory;
break;
}
@@ -196,7 +213,7 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(const uint8_
(*it)->clear_value();
}
break;
- } else if(0 == ((*it)->operation() & M2MBase::PUT_ALLOWED)) {
+ } else if (0 == ((*it)->operation() & M2MBase::PUT_ALLOWED)) {
tr_debug("M2MTLVDeserializer::deserialize_resources() - NOT_ALLOWED");
error = M2MTLVDeserializer::NotAllowed;
break;
@@ -205,8 +222,8 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(const uint8_
}
} else if (TYPE_MULTIPLE_RESOURCE == til._type) {
multi = true;
- for (; it!=list.end(); it++) {
- if((*it)->supports_multiple_instances() &&
+ for (; it != list.end(); it++) {
+ if ((*it)->supports_multiple_instances() &&
(*it)->name_id() == til._id) {
found = true;
error = deserialize_resource_instances(tlv, tlv_size, offset, (**it), object_instance, operation, update_value);
@@ -225,7 +242,7 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(const uint8_
M2MResource *resource = object_instance.create_dynamic_resource(id, "", M2MResourceInstance::OPAQUE, true, multi);
if (resource) {
resource->set_operation(M2MBase::GET_PUT_POST_DELETE_ALLOWED);
- if (TYPE_MULTIPLE_RESOURCE == til._type) {
+ if (TYPE_MULTIPLE_RESOURCE == til._type) {
error = deserialize_resource_instances(tlv, tlv_size, offset, (*resource), object_instance, operation, update_value);
}
}
@@ -243,6 +260,42 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resources(const uint8_
return error;
}
+M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource(const uint8_t *tlv,
+ uint32_t tlv_size,
+ M2MResource &resource,
+ M2MTLVDeserializer::Operation operation,
+ bool update_value)
+{
+ M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
+ if (resource.operation() & M2MBase::PUT_ALLOWED) {
+ int offset = 0;
+ TypeIdLength til(tlv, offset);
+ til.deserialize();
+ offset = til._offset;
+
+ if (resource.resource_instance_type() == M2MResourceBase::INTEGER) {
+ int64_t value = String::convert_array_to_integer(tlv + offset, til._length);
+ if ((strcmp(resource.uri_path(), SERVER_LIFETIME_PATH) == 0) && (value < MINIMUM_REGISTRATION_TIME)) {
+ // Check that lifetime can't go below 60s
+ return M2MTLVDeserializer::NotAccepted;
+ } else {
+ if (!resource.set_value(value)) {
+ error = M2MTLVDeserializer::OutOfMemory;
+ }
+ }
+ }
+
+ tr_debug("M2MTLVDeserializer::deserialize_resource() - Update value");
+ if (!set_resource_instance_value(&resource, tlv + offset, til._length)) {
+ error = M2MTLVDeserializer::OutOfMemory;
+ }
+ } else {
+ error = M2MTLVDeserializer::NotAllowed;
+ }
+
+ return error;
+}
+
M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(const uint8_t *tlv,
uint32_t tlv_size,
uint32_t offset,
@@ -261,12 +314,12 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
M2MResourceInstanceList::const_iterator it;
it = list.begin();
bool found = false;
- for (; it!=list.end(); it++) {
- if((*it)->instance_id() == til._id && TYPE_RESOURCE_INSTANCE == til._type) {
+ for (; it != list.end(); it++) {
+ if ((*it)->instance_id() == til._id && TYPE_RESOURCE_INSTANCE == til._type) {
found = true;
- if(update_value) {
- if(til._length > 0) {
- if (!set_resource_instance_value((*it), tlv+offset, til._length)) {
+ if (update_value) {
+ if (til._length > 0) {
+ if (!set_resource_instance_value((*it), tlv + offset, til._length)) {
error = M2MTLVDeserializer::OutOfMemory;
break;
}
@@ -274,24 +327,24 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
(*it)->clear_value();
}
break;
- } else if(0 == ((*it)->operation() & M2MBase::PUT_ALLOWED)) {
+ } else if (0 == ((*it)->operation() & M2MBase::PUT_ALLOWED)) {
error = M2MTLVDeserializer::NotAllowed;
break;
}
}
}
- if(!found) {
- if(M2MTLVDeserializer::Post == operation) {
+ if (!found) {
+ if (M2MTLVDeserializer::Post == operation) {
// Create a new Resource Instance
- M2MResourceInstance *res_instance = object_instance.create_dynamic_resource_instance(resource.name(),"",
- resource.resource_instance_type(),
- true,
- til._id);
- if(res_instance) {
+ M2MResourceInstance *res_instance = object_instance.create_dynamic_resource_instance(resource.name(), "",
+ resource.resource_instance_type(),
+ true,
+ til._id);
+ if (res_instance) {
res_instance->set_operation(M2MBase::GET_PUT_POST_DELETE_ALLOWED);
}
- } else if(M2MTLVDeserializer::Put == operation) {
+ } else if (M2MTLVDeserializer::Put == operation) {
error = M2MTLVDeserializer::NotFound;
}
}
@@ -302,8 +355,8 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
offset += til._length;
- if(offset < tlv_size) {
- error = deserialize_resource_instances(tlv, tlv_size, offset, resource, object_instance, operation, update_value);
+ if (offset < tlv_size) {
+ error = deserialize_resource_instances(tlv, tlv_size, offset, resource, object_instance, operation, update_value);
}
return error;
}
@@ -315,6 +368,9 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
M2MTLVDeserializer::Operation operation,
bool update_value)
{
+ if (tlv_size < offset + 1) {
+ return M2MTLVDeserializer::NotValid;
+ }
M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
TypeIdLength til(tlv, offset);
til.deserialize();
@@ -325,12 +381,12 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
M2MResourceInstanceList::const_iterator it;
it = list.begin();
bool found = false;
- for (; it!=list.end(); it++) {
- if((*it)->instance_id() == til._id) {
+ for (; it != list.end(); it++) {
+ if ((*it)->instance_id() == til._id) {
found = true;
- if(update_value) {
- if(til._length > 0) {
- if (!set_resource_instance_value((*it),tlv+offset, til._length)) {
+ if (update_value) {
+ if (til._length > 0) {
+ if (!set_resource_instance_value((*it), tlv + offset, til._length)) {
error = M2MTLVDeserializer::OutOfMemory;
break;
}
@@ -338,24 +394,24 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
(*it)->clear_value();
}
break;
- } else if(0 == ((*it)->operation() & M2MBase::PUT_ALLOWED)) {
+ } else if (0 == ((*it)->operation() & M2MBase::PUT_ALLOWED)) {
error = M2MTLVDeserializer::NotAllowed;
break;
}
}
}
- if(!found) {
- if(M2MTLVDeserializer::Post == operation) {
+ if (!found) {
+ if (M2MTLVDeserializer::Post == operation) {
error = M2MTLVDeserializer::NotAllowed;
- } else if(M2MTLVDeserializer::Put == operation) {
+ } else if (M2MTLVDeserializer::Put == operation) {
// Create a new Resource Instance
M2MResourceInstance *res_instance = resource.get_parent_object_instance().create_dynamic_resource_instance(
- resource.name(),
- "",
- resource.resource_instance_type(),
- true,
- til._id);
- if(res_instance) {
+ resource.name(),
+ "",
+ resource.resource_instance_type(),
+ true,
+ til._id);
+ if (res_instance) {
res_instance->set_operation(M2MBase::GET_PUT_DELETE_ALLOWED);
}
}
@@ -368,8 +424,8 @@ M2MTLVDeserializer::Error M2MTLVDeserializer::deserialize_resource_instances(con
offset += til._length;
- if(offset < tlv_size) {
- error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation, update_value);
+ if (offset < tlv_size) {
+ error = deserialize_resource_instances(tlv, tlv_size, offset, resource, operation, update_value);
}
return error;
}
@@ -425,22 +481,22 @@ bool M2MTLVDeserializer::set_resource_instance_value(M2MResourceBase *res, const
switch (res->resource_instance_type()) {
case M2MResourceBase::INTEGER:
case M2MResourceBase::BOOLEAN:
- case M2MResourceBase::TIME:
- {
+ case M2MResourceBase::TIME: {
int64_t value = String::convert_array_to_integer(tlv, size);
success = res->set_value(value);
break;
- // Todo! implement conversion for other types as well
+ // Todo! implement conversion for other types as well
}
case M2MResourceBase::STRING:
case M2MResourceBase::OPAQUE:
case M2MResourceBase::OBJLINK:
success = res->set_value(tlv, size);
break;
- case M2MResourceBase::FLOAT:
- {
+ case M2MResourceBase::FLOAT: {
uint32_t value = common_read_32_bit(tlv);
- success = res->set_value_float(*(float*)&value);
+ float float_value = 0;
+ memcpy(&float_value, &value, size);
+ success = res->set_value_float(float_value);
break;
}
default:
@@ -460,14 +516,14 @@ void M2MTLVDeserializer::remove_resources(const uint8_t *tlv,
M2MResourceList::const_iterator it;
it = list.begin();
- for (; it!=list.end();) {
+ for (; it != list.end();) {
bool found = false;
- while(offset < tlv_size) {
+ while (offset < tlv_size) {
TypeIdLength til(tlv, offset);
til.deserialize();
offset = til._offset;
offset += til._length;
- if((*it)->name_id() == til._id){
+ if ((*it)->name_id() == til._id) {
offset = offset_size;
found = true;
break;
@@ -486,9 +542,9 @@ void M2MTLVDeserializer::remove_resources(const uint8_t *tlv,
}
void M2MTLVDeserializer::remove_resource_instances(const uint8_t *tlv,
- uint32_t tlv_size,
- M2MResource &resource,
- uint32_t offset_size)
+ uint32_t tlv_size,
+ M2MResource &resource,
+ uint32_t offset_size)
{
tr_debug("M2MTLVDeserializer::remove_resource_instances");
uint32_t offset = offset_size;
@@ -496,14 +552,14 @@ void M2MTLVDeserializer::remove_resource_instances(const uint8_t *tlv,
M2MResourceInstanceList::const_iterator it;
it = list.begin();
- for (; it!=list.end();) {
+ for (; it != list.end();) {
bool found = false;
while (offset < tlv_size) {
TypeIdLength til(tlv, offset);
til.deserialize();
offset = til._offset;
offset += til._length;
- if ((*it)->instance_id() == til._id){
+ if ((*it)->instance_id() == til._id) {
offset = offset_size;
found = true;
break;
@@ -522,7 +578,7 @@ void M2MTLVDeserializer::remove_resource_instances(const uint8_t *tlv,
}
TypeIdLength::TypeIdLength(const uint8_t *tlv, uint32_t offset)
-: _tlv(tlv), _offset(offset), _type(tlv[offset] & 0xC0), _id(0), _length(0)
+ : _tlv(tlv), _offset(offset), _type(tlv[offset] & 0xC0), _id(0), _length(0)
{
}
diff --git a/mbed-client/source/m2mtlvserializer.cpp b/mbed-client/source/m2mtlvserializer.cpp
index 1815bf94e..eb9602ede 100644
--- a/mbed-client/source/m2mtlvserializer.cpp
+++ b/mbed-client/source/m2mtlvserializer.cpp
@@ -25,57 +25,57 @@
#define MAX_TLV_ID_SIZE 2
#define TLV_TYPE_SIZE 1
-uint8_t* M2MTLVSerializer::serialize(const M2MObjectInstanceList &object_instance_list, uint32_t &size)
+uint8_t *M2MTLVSerializer::serialize(const M2MObjectInstanceList &object_instance_list, uint32_t &size)
{
return serialize_object_instances(object_instance_list, size);
}
-uint8_t* M2MTLVSerializer::serialize(const M2MResourceList &resource_list, uint32_t &size)
+uint8_t *M2MTLVSerializer::serialize(const M2MResourceList &resource_list, uint32_t &size)
{
bool valid = true;
- return serialize_resources(resource_list, size,valid);
+ return serialize_resources(resource_list, size, valid);
}
-uint8_t* M2MTLVSerializer::serialize(const M2MResource *resource, uint32_t &size)
+uint8_t *M2MTLVSerializer::serialize(const M2MResource *resource, uint32_t &size)
{
- uint8_t* data = NULL;
+ uint8_t *data = NULL;
serialize(resource, data, size);
return data;
}
-uint8_t* M2MTLVSerializer::serialize_object_instances(const M2MObjectInstanceList &object_instance_list, uint32_t &size)
+uint8_t *M2MTLVSerializer::serialize_object_instances(const M2MObjectInstanceList &object_instance_list, uint32_t &size)
{
uint8_t *data = NULL;
- if(!object_instance_list.empty()) {
+ if (!object_instance_list.empty()) {
M2MObjectInstanceList::const_iterator it;
it = object_instance_list.begin();
- for (; it!=object_instance_list.end(); it++) {
+ for (; it != object_instance_list.end(); it++) {
uint16_t id = (*it)->instance_id();
- serialize(id, *it, data, size);
+ serialize(id, *it, data, size);
}
}
return data;
}
-uint8_t* M2MTLVSerializer::serialize_resources(const M2MResourceList &resource_list, uint32_t &size, bool &valid)
+uint8_t *M2MTLVSerializer::serialize_resources(const M2MResourceList &resource_list, uint32_t &size, bool &valid)
{
uint8_t *data = NULL;
- if(!resource_list.empty()) {
+ if (!resource_list.empty()) {
M2MResourceList::const_iterator it;
it = resource_list.begin();
- for (; it!=resource_list.end(); it++) {
- if((*it)->name_id() == -1) {
+ for (; it != resource_list.end(); it++) {
+ if ((*it)->name_id() == -1) {
valid = false;
break;
}
}
- if(valid) {
+ if (valid) {
it = resource_list.begin();
- for (; it!=resource_list.end(); it++) {
+ for (; it != resource_list.end(); it++) {
if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) {
- if(!serialize(*it, data, size)) {
+ if (!serialize(*it, data, size)) {
/* serializing has failed */
/* free data so far */
free(data);
@@ -98,9 +98,9 @@ bool M2MTLVSerializer::serialize(uint16_t id, const M2MObjectInstance *object_in
bool success;
bool valid = true;
- resource_data = serialize_resources(object_instance->resources(),resource_size,valid);
- if(valid) {
- if(serialize_TILV(TYPE_OBJECT_INSTANCE, id, resource_data, resource_size, data, size)) {
+ resource_data = serialize_resources(object_instance->resources(), resource_size, valid);
+ if (valid) {
+ if (serialize_TILV(TYPE_OBJECT_INSTANCE, id, resource_data, resource_size, data, size)) {
success = true;
} else {
/* serializing object instance failed */
@@ -117,10 +117,10 @@ bool M2MTLVSerializer::serialize(uint16_t id, const M2MObjectInstance *object_in
bool M2MTLVSerializer::serialize(const M2MResource *resource, uint8_t *&data, uint32_t &size)
{
bool success = false;
- if(resource->name_id() != -1) {
+ if (resource->name_id() != -1) {
success = resource->supports_multiple_instances() ?
- serialize_multiple_resource(resource, data, size) :
- serialize_resource(resource, data, size);
+ serialize_multiple_resource(resource, data, size) :
+ serialize_resource(resource, data, size);
}
return success;
}
@@ -128,18 +128,16 @@ bool M2MTLVSerializer::serialize(const M2MResource *resource, uint8_t *&data, ui
bool M2MTLVSerializer::serialize_resource(const M2MResource *resource, uint8_t *&data, uint32_t &size)
{
bool success = false;
- if(resource->name_id() != -1) {
- if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) ||
- (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) ||
- (resource->resource_instance_type() == M2MResourceBase::TIME) ) {
+ if (resource->name_id() != -1) {
+ if ((resource->resource_instance_type() == M2MResourceBase::INTEGER) ||
+ (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) ||
+ (resource->resource_instance_type() == M2MResourceBase::TIME)) {
success = serialize_TLV_binary_int(resource, TYPE_RESOURCE, resource->name_id(), data, size);
- }
- else if (resource->resource_instance_type() == M2MResourceBase::FLOAT) {
+ } else if (resource->resource_instance_type() == M2MResourceBase::FLOAT) {
success = serialize_TLV_binary_float(resource, TYPE_RESOURCE, resource->name_id(), data, size);
- }
- else {
- success = serialize_TILV(TYPE_RESOURCE, resource->name_id(),
- resource->value(), resource->value_length(), data, size);
+ } else {
+ success = serialize_TILV(TYPE_RESOURCE, resource->name_id(),
+ resource->value(), resource->value_length(), data, size);
}
}
return success;
@@ -152,13 +150,13 @@ bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource,
uint32_t nested_data_size = 0;
const M2MResourceInstanceList &instance_list = resource->resource_instances();
- if(!instance_list.empty()) {
+ if (!instance_list.empty()) {
M2MResourceInstanceList::const_iterator it;
it = instance_list.begin();
- for (; it!=instance_list.end(); it++) {
+ for (; it != instance_list.end(); it++) {
uint16_t id = (*it)->instance_id();
if (((*it)->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) {
- if(!serialize_resource_instance(id, (*it), nested_data, nested_data_size)) {
+ if (!serialize_resource_instance(id, (*it), nested_data, nested_data_size)) {
/* serializing instance has failed */
/* free data so far allocated */
free(nested_data);
@@ -169,10 +167,10 @@ bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource,
}
}
}
- if(resource->name_id() != -1 &&
+ if (resource->name_id() != -1 &&
(resource->operation() & M2MBase::GET_ALLOWED) == M2MBase::GET_ALLOWED) {
success = serialize_TILV(TYPE_MULTIPLE_RESOURCE, resource->name_id(),
- nested_data, nested_data_size, data, size);
+ nested_data, nested_data_size, data, size);
}
free(nested_data);
@@ -183,16 +181,14 @@ bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourc
{
bool success;
- if ( (resource->resource_instance_type() == M2MResourceBase::INTEGER) ||
- (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) ||
- (resource->resource_instance_type() == M2MResourceBase::TIME) ) {
- success=serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size);
- }
- else if (resource->resource_instance_type() == M2MResourceBase::FLOAT) {
- success=serialize_TLV_binary_float(resource, TYPE_RESOURCE_INSTANCE, id, data, size);
- }
- else {
- success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size);
+ if ((resource->resource_instance_type() == M2MResourceBase::INTEGER) ||
+ (resource->resource_instance_type() == M2MResourceBase::BOOLEAN) ||
+ (resource->resource_instance_type() == M2MResourceBase::TIME)) {
+ success = serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size);
+ } else if (resource->resource_instance_type() == M2MResourceBase::FLOAT) {
+ success = serialize_TLV_binary_float(resource, TYPE_RESOURCE_INSTANCE, id, data, size);
+ } else {
+ success = serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size);
}
return success;
@@ -226,7 +222,7 @@ bool M2MTLVSerializer::serialize_TLV_binary_float(const M2MResourceBase *resourc
/* max len 8 bytes */
uint8_t buffer[4];
- common_write_32_bit(*(uint32_t*)&valueFloat, buffer);
+ common_write_32_bit(valueFloat, buffer);
return serialize_TILV(type, id, buffer, 4, data, size);
}
@@ -251,21 +247,21 @@ bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value,
uint8_t length_array[MAX_TLV_LENGTH_SIZE];
serialize_length(value_length, length_size, length_array);
- tlv = (uint8_t*)malloc(size + type_length + id_size + length_size + value_length);
+ tlv = (uint8_t *)malloc(size + type_length + id_size + length_size + value_length);
if (!tlv) {
/* memory allocation has failed */
/* return failure immediately */
return false;
/* eventually NULL will be returned to serializer public method caller */
}
- if(data) {
+ if (data) {
memcpy(tlv, data, size);
free(data);
}
- memcpy(tlv+size, &tlv_type, type_length);
- memcpy(tlv+size+type_length, id_array, id_size);
- memcpy(tlv+size+type_length+id_size, length_array, length_size);
- memcpy(tlv+size+type_length+id_size+length_size, value, value_length);
+ memcpy(tlv + size, &tlv_type, type_length);
+ memcpy(tlv + size + type_length, id_array, id_size);
+ memcpy(tlv + size + type_length + id_size, length_array, length_size);
+ memcpy(tlv + size + type_length + id_size + length_size, value, value_length);
data = tlv;
size += type_length + id_size + length_size + value_length;
@@ -274,12 +270,12 @@ bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value,
void M2MTLVSerializer::serialize_id(uint16_t id, uint32_t &size, uint8_t *id_ptr)
{
- if(id > 255) {
- size=2;
+ if (id > 255) {
+ size = 2;
id_ptr[0] = (id & 0xFF00) >> 8;
id_ptr[1] = id & 0xFF;
} else {
- size=1;
+ size = 1;
id_ptr[0] = id & 0xFF;
}
}
@@ -299,7 +295,7 @@ void M2MTLVSerializer::serialize_length(uint32_t length, uint32_t &size, uint8_t
size = 1;
length_ptr[0] = length & 0xFF;
} else {
- size=0;
+ size = 0;
}
}
diff --git a/mbed-cloud-client/MbedCloudClient.h b/mbed-cloud-client/MbedCloudClient.h
index 1e50ca414..497de02f9 100644
--- a/mbed-cloud-client/MbedCloudClient.h
+++ b/mbed-cloud-client/MbedCloudClient.h
@@ -46,22 +46,6 @@
#include "multicast.h"
#endif // MBED_CLOUD_CLIENT_SUPPORT_MULTICAST_UPDATE
-#if MBED_CLOUD_CLIENT_STL_API
-#include