diff --git a/component.mk b/component.mk index 0fde7ce..5f28c50 100644 --- a/component.mk +++ b/component.mk @@ -1,7 +1,7 @@ # # Component Makefile # - + # Component configuration in preprocessor defines CFLAGS += -DUSE_LWIP_SOCKET_FOR_AZURE_IOT @@ -27,7 +27,7 @@ azure-iot-sdk-c/c-utility/pal/generic \ ifndef CONFIG_TARGET_PLATFORM_ESP8266 COMPONENT_ADD_INCLUDEDIRS += azure-iot-sdk-c/certs endif - + COMPONENT_OBJS = \ azure-iot-sdk-c/c-utility/pal/freertos/lock.o \ azure-iot-sdk-c/c-utility/pal/socket_async.o \ @@ -38,6 +38,7 @@ azure-iot-sdk-c/c-utility/pal/tlsio_options.o \ port/src/agenttime_esp.o \ port/src/platform_esp.o \ port/src/tlsio_esp_tls.o \ +port/src/wsio_esp.o \ \ azure-iot-sdk-c/c-utility/src/xlogging.o \ azure-iot-sdk-c/c-utility/src/singlylinkedlist.o \ @@ -48,6 +49,7 @@ azure-iot-sdk-c/c-utility/src/constmap.o \ azure-iot-sdk-c/c-utility/src/crt_abstractions.o \ azure-iot-sdk-c/c-utility/src/doublylinkedlist.o \ azure-iot-sdk-c/c-utility/src/gballoc.o \ +azure-iot-sdk-c/c-utility/src/gb_rand.o \ azure-iot-sdk-c/c-utility/src/gb_stdio.o \ azure-iot-sdk-c/c-utility/src/gb_time.o \ azure-iot-sdk-c/c-utility/src/hmac.o \ @@ -65,7 +67,11 @@ azure-iot-sdk-c/c-utility/src/strings.o \ azure-iot-sdk-c/c-utility/src/string_tokenizer.o \ azure-iot-sdk-c/c-utility/src/urlencode.o \ azure-iot-sdk-c/c-utility/src/usha.o \ +azure-iot-sdk-c/c-utility/src/utf8_checker.o \ +azure-iot-sdk-c/c-utility/src/uws_client.o \ +azure-iot-sdk-c/c-utility/src/uws_frame_encoder.o \ azure-iot-sdk-c/c-utility/src/vector.o \ +azure-iot-sdk-c/c-utility/src/wsio.o \ azure-iot-sdk-c/c-utility/src/xio.o \ azure-iot-sdk-c/c-utility/src/azure_base64.o \ \ @@ -80,6 +86,7 @@ azure-iot-sdk-c/iothub_client/src/iothub_client_diagnostic.o \ azure-iot-sdk-c/iothub_client/src/iothub_message.o \ azure-iot-sdk-c/iothub_client/src/iothubtransport.o \ azure-iot-sdk-c/iothub_client/src/iothubtransportmqtt.o \ +azure-iot-sdk-c/iothub_client/src/iothubtransportmqtt_websockets.o \ azure-iot-sdk-c/iothub_client/src/iothubtransport_mqtt_common.o \ azure-iot-sdk-c/iothub_client/src/iothub_transport_ll_private.o \ azure-iot-sdk-c/iothub_client/src/version.o \ diff --git a/examples/iothub_client_sample_mqtt/main/Kconfig.projbuild b/examples/iothub_client_sample_mqtt/main/Kconfig.projbuild index 1d1bbb9..4e83fb3 100644 --- a/examples/iothub_client_sample_mqtt/main/Kconfig.projbuild +++ b/examples/iothub_client_sample_mqtt/main/Kconfig.projbuild @@ -36,4 +36,10 @@ config MESSAGE_COUNT messages. If the message count is set as 0 then this example will send indefinite messages to the cloud. +config SAMPLE_MQTT_OVER_WEBSOCKET + bool "MQTT over WebSocket" + default n + help + This option enables MQTT over WebSocket protocol, instead of raw MQTT. + endmenu diff --git a/examples/iothub_client_sample_mqtt/main/iothub_client_sample_mqtt.c b/examples/iothub_client_sample_mqtt/main/iothub_client_sample_mqtt.c index e7bb89d..d6b648f 100644 --- a/examples/iothub_client_sample_mqtt/main/iothub_client_sample_mqtt.c +++ b/examples/iothub_client_sample_mqtt/main/iothub_client_sample_mqtt.c @@ -12,12 +12,19 @@ #include "azure_c_shared_utility/crt_abstractions.h" #include "azure_c_shared_utility/platform.h" #include "azure_c_shared_utility/shared_util_options.h" -#include "iothubtransportmqtt.h" #include "iothub_client_options.h" #include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#if CONFIG_SAMPLE_MQTT_OVER_WEBSOCKET + #include "iothubtransportmqtt_websockets.h" + #define PROTOCOL MQTT_WebSocket_Protocol +#else + #include "iothubtransportmqtt.h" + #define PROTOCOL MQTT_Protocol +#endif + #ifdef MBED_BUILD_TIMESTAMP #define SET_TRUSTED_CERT_IN_SAMPLES #endif // MBED_BUILD_TIMESTAMP @@ -148,7 +155,7 @@ void iothub_client_sample_mqtt_run(void) } else { - if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol)) == NULL) + if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, PROTOCOL)) == NULL) { (void)printf("ERROR: iotHubClientHandle is NULL!\r\n"); } diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt index 5b82bbd..a194785 100644 --- a/port/CMakeLists.txt +++ b/port/CMakeLists.txt @@ -5,8 +5,8 @@ set (AZURE_IOT_SDK "${CMAKE_CURRENT_LIST_DIR}/../azure-iot-sdk-c") set (COMPONENT_ADD_INCLUDEDIRS - "inc" - "${AZURE_IOT_SDK}/certs" + "inc" + "${AZURE_IOT_SDK}/certs" "${AZURE_IOT_SDK}/c-utility/inc" "${AZURE_IOT_SDK}/c-utility/deps/azure-macro-utils-c/inc" "${AZURE_IOT_SDK}/c-utility/deps/umock-c/inc" @@ -27,6 +27,7 @@ set (COMPONENT_SRCS "src/agenttime_esp.c" "src/platform_esp.c" "src/tlsio_esp_tls.c" + "src/wsio_esp.c" "${AZURE_IOT_SDK}/certs/certs.c" "${AZURE_IOT_SDK}/c-utility/pal/freertos/lock.c" "${AZURE_IOT_SDK}/c-utility/pal/socket_async.c" @@ -42,6 +43,7 @@ set (COMPONENT_SRCS "${AZURE_IOT_SDK}/c-utility/src/crt_abstractions.c" "${AZURE_IOT_SDK}/c-utility/src/doublylinkedlist.c" "${AZURE_IOT_SDK}/c-utility/src/gballoc.c" + "${AZURE_IOT_SDK}/c-utility/src/gb_rand.c" "${AZURE_IOT_SDK}/c-utility/src/gb_stdio.c" "${AZURE_IOT_SDK}/c-utility/src/gb_time.c" "${AZURE_IOT_SDK}/c-utility/src/hmac.c" @@ -59,7 +61,11 @@ set (COMPONENT_SRCS "${AZURE_IOT_SDK}/c-utility/src/string_tokenizer.c" "${AZURE_IOT_SDK}/c-utility/src/urlencode.c" "${AZURE_IOT_SDK}/c-utility/src/usha.c" + "${AZURE_IOT_SDK}/c-utility/src/utf8_checker.c" + "${AZURE_IOT_SDK}/c-utility/src/uws_client.c" + "${AZURE_IOT_SDK}/c-utility/src/uws_frame_encoder.c" "${AZURE_IOT_SDK}/c-utility/src/vector.c" + "${AZURE_IOT_SDK}/c-utility/src/wsio.c" "${AZURE_IOT_SDK}/c-utility/src/xio.c" "${AZURE_IOT_SDK}/c-utility/src/azure_base64.c" "${AZURE_IOT_SDK}/iothub_client/src/iothub_device_client_ll.c" @@ -72,6 +78,7 @@ set (COMPONENT_SRCS "${AZURE_IOT_SDK}/iothub_client/src/iothub_message.c" "${AZURE_IOT_SDK}/iothub_client/src/iothubtransport.c" "${AZURE_IOT_SDK}/iothub_client/src/iothubtransportmqtt.c" + "${AZURE_IOT_SDK}/iothub_client/src/iothubtransportmqtt_websockets.c" "${AZURE_IOT_SDK}/iothub_client/src/iothubtransport_mqtt_common.c" "${AZURE_IOT_SDK}/iothub_client/src/iothub_transport_ll_private.c" "${AZURE_IOT_SDK}/iothub_client/src/version.c" diff --git a/port/src/tlsio_esp_tls.c b/port/src/tlsio_esp_tls.c index 1f5ad37..39f0fca 100644 --- a/port/src/tlsio_esp_tls.c +++ b/port/src/tlsio_esp_tls.c @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // This component was written to conform to the tlsio_requirements.md specification located -// in the Azure IoT C Utility: +// in the Azure IoT C Utility: // https://github.com/Azure/azure-c-shared-utility/blob/master/devdoc/tlsio_requirements.md // Comments throughout this code refer to requirements in that spec. @@ -19,6 +19,7 @@ #include "azure_c_shared_utility/singlylinkedlist.h" #include "azure_c_shared_utility/crt_abstractions.h" #include "azure_c_shared_utility/tlsio_options.h" +#include "azure_c_shared_utility/shared_util_options.h" #include "esp_tls.h" @@ -94,7 +95,7 @@ static bool process_and_destroy_head_message(TLS_IO_INSTANCE* tls_io_instance, I if (head_pending_io != NULL) { PENDING_TRANSMISSION* head_message = (PENDING_TRANSMISSION*)singlylinkedlist_item_get_value(head_pending_io); - // Must remove the item from the list before calling the callback because + // Must remove the item from the list before calling the callback because // SRS_TLSIO_30_091: [ If tlsio_esp_tls_dowork is able to send all the bytes in an enqueued message, it shall first dequeue the message then call the messages's on_send_complete along with its associated callback_context and IO_SEND_OK . ] if (singlylinkedlist_remove(tls_io_instance->pending_transmission_list, head_pending_io) != 0) { @@ -158,7 +159,7 @@ static void tlsio_esp_tls_destroy(CONCRETE_IO_HANDLE tls_io) { free(tls_io_instance->hostname); } - + tlsio_options_release_resources(&tls_io_instance->options); if (tls_io_instance->pending_transmission_list != NULL) @@ -407,14 +408,14 @@ static int dowork_read(TLS_IO_INSTANCE* tls_io_instance) // in the call to tlsio_esp_tls_open_async /* Codes_SRS_TLSIO_30_100: [ As long as the TLS connection is able to provide received data, tlsio_dowork shall repeatedly read this data and call on_bytes_received with the pointer to the buffer containing the data, the number of bytes received, and the on_bytes_received_context. ]*/ tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes); - + if (++rcv_count > MAX_RCV_COUNT) { // Read no more than "MAX_RCV_COUNT" times to avoid starvation of other processes. // LogInfo("Skipping further reading to avoid starvation."); break; } - + rcv_bytes = esp_tls_conn_read(tls_io_instance->esp_tls_handle, buffer, sizeof(buffer)); } /* Codes_SRS_TLSIO_30_102: [ If the TLS connection receives no data then tlsio_dowork shall not call the on_bytes_received callback. ]*/ @@ -617,18 +618,30 @@ static int tlsio_esp_tls_setoption(CONCRETE_IO_HANDLE tls_io, const char* option } else { - /* Codes_SRS_TLSIO_30_121: [ If the optionName parameter is NULL, tlsio_esp_tls_setoption shall do nothing except log an error and return FAILURE. ]*/ - /* Codes_SRS_TLSIO_30_122: [ If the value parameter is NULL, tlsio_esp_tls_setoption shall do nothing except log an error and return FAILURE. ]*/ - /* Codes_SRS_TLSIO_ESP_TLS_COMPACT_30_520 [ The tlsio_esp_tls_setoption shall do nothing and return FAILURE. ]*/ - TLSIO_OPTIONS_RESULT options_result = tlsio_options_set(&tls_io_instance->options, optionName, value); - if (options_result != TLSIO_OPTIONS_RESULT_SUCCESS) + if (strcmp(optionName, OPTION_SET_TLS_RENEGOTIATION) == 0) { - LogError("Failed tlsio_options_set"); +#ifdef CONFIG_MBEDTLS_SSL_RENEGOTIATION + result = 0; +#else + LogError("Failed tlsio_options_set, TLS renegotiation not configured"); result = MU_FAILURE; +#endif } else { - result = 0; + /* Codes_SRS_TLSIO_30_121: [ If the optionName parameter is NULL, tlsio_esp_tls_setoption shall do nothing except log an error and return FAILURE. ]*/ + /* Codes_SRS_TLSIO_30_122: [ If the value parameter is NULL, tlsio_esp_tls_setoption shall do nothing except log an error and return FAILURE. ]*/ + /* Codes_SRS_TLSIO_ESP_TLS_COMPACT_30_520 [ The tlsio_esp_tls_setoption shall do nothing and return FAILURE. ]*/ + TLSIO_OPTIONS_RESULT options_result = tlsio_options_set(&tls_io_instance->options, optionName, value); + if (options_result != TLSIO_OPTIONS_RESULT_SUCCESS) + { + LogError("Failed tlsio_options_set"); + result = MU_FAILURE; + } + else + { + result = 0; + } } } return result; diff --git a/port/src/wsio_esp.c b/port/src/wsio_esp.c new file mode 100644 index 0000000..60ede08 --- /dev/null +++ b/port/src/wsio_esp.c @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include + +#include "azure_c_shared_utility/socketio.h" +#include "azure_c_shared_utility/wsio.h" + +const IO_INTERFACE_DESCRIPTION* socketio_get_interface_description(void) +{ + return wsio_get_interface_description(); +}