diff --git a/fullstack/freertos-wolfip-wolfmqtt/.gitignore b/fullstack/freertos-wolfip-wolfmqtt/.gitignore new file mode 100644 index 00000000..bf1cbf80 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/.gitignore @@ -0,0 +1 @@ +!freertos/utils/posix_utils.c diff --git a/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt b/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt new file mode 100644 index 00000000..4aa15f5a --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt @@ -0,0 +1,190 @@ +cmake_minimum_required(VERSION 3.13) +project(freertos_sim C) + +# Set build type if not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# FreeRTOS source files +set(FREERTOS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/freertos") +set(FREERTOS_KERNEL_DIR "${FREERTOS_DIR}/FreeRTOS-Kernel") + +# wolfSSL directories +set(WOLFSSL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../wolfssl") +set(WOLFIP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../wolfip") +set(WOLFMQTT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../wolfMQTT") + +# Certificate paths +set(WOLFSSL_CERTS_DIR "${WOLFSSL_DIR}/certs") + +# Add definitions for certificate paths +add_definitions( + -DMQTT_TLS_CA_CERT="${WOLFSSL_CERTS_DIR}/ca-cert.pem" + -DMQTT_TLS_CLIENT_CERT="${WOLFSSL_CERTS_DIR}/client-cert.pem" + -DMQTT_TLS_CLIENT_KEY="${WOLFSSL_CERTS_DIR}/client-key.pem" +) + +# FreeRTOS configuration +add_definitions( + -DPOSIX_PORT + -DPOSIX + -D_POSIX_C_SOURCE=200809L + -D_POSIX_THREAD_SAFE_FUNCTIONS + -DENABLE_MQTT_TLS + -DDEBUG=0 +) + +# wolfSSL configuration +add_definitions( + -DWOLFSSL_USER_SETTINGS + -DHAVE_TLS_EXTENSIONS + -DHAVE_SUPPORTED_CURVES + -DTFM_TIMING_RESISTANT + -DECC_TIMING_RESISTANT + -DWC_RSA_BLINDING + -DHAVE_AESGCM + -DHAVE_CHACHA + -DHAVE_POLY1305 + -DHAVE_ECC + -DHAVE_CURVE25519 + -DHAVE_ED25519 + -DENABLE_MQTT_TLS +) + +# wolfIP definitions +add_definitions( + -DLINK_MTU=1500 + -DRXBUF_SIZE=8192 + -DTXBUF_SIZE=8192 + -DMAX_TCPSOCKETS=8 + -DMAX_UDPSOCKETS=8 + -DMAX_TIMERS=24 + -DWOLFIP_DEBUG + -DWOLFSSL_DEBUG + -DWOLFMQTT_DEBUG + -DETH_TYPE_IP=0x0800 +) + +# FreeRTOS source files +set(FREERTOS_SRC + ${FREERTOS_KERNEL_DIR}/tasks.c + ${FREERTOS_KERNEL_DIR}/queue.c + ${FREERTOS_KERNEL_DIR}/list.c + ${FREERTOS_KERNEL_DIR}/timers.c + ${FREERTOS_KERNEL_DIR}/event_groups.c + ${FREERTOS_KERNEL_DIR}/stream_buffer.c + ${FREERTOS_KERNEL_DIR}/portable/ThirdParty/GCC/Posix/port.c + ${FREERTOS_KERNEL_DIR}/portable/MemMang/heap_3.c +) + +# Create utils.c if it doesn't exist +if(NOT EXISTS "${FREERTOS_DIR}/utils/utils.c") + file(MAKE_DIRECTORY "${FREERTOS_DIR}/utils") + file(WRITE "${FREERTOS_DIR}/utils/utils.c" "/* utils.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +/* Utility functions for FreeRTOS */ +void utils_init(void) +{ + /* Initialize random seed */ + srand(time(NULL)); +} +") +endif() + +# Add utils.c and events.c to FreeRTOS sources +list(APPEND FREERTOS_SRC + ${FREERTOS_DIR}/utils/utils.c + ${FREERTOS_DIR}/utils/events.c +) + +# wolfIP source files - use stub implementation +set(WOLFIP_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/wolfip_stub.c +) + +# wolfMQTT source files - use stub implementation +set(WOLFMQTT_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/wolfmqtt_stub.c +) + +# Application source files +set(APP_SRC + src/main.c + src/wolfip_freertos.c + src/wolfip_utils.c + src/tap_interface.c + ${CMAKE_CURRENT_SOURCE_DIR}/freertos/utils/utils.c +) + +# Include directories +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include/FreeRTOSConfig + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${FREERTOS_KERNEL_DIR}/include + ${FREERTOS_KERNEL_DIR}/portable/ThirdParty/GCC/Posix + ${WOLFSSL_DIR} + ${WOLFIP_DIR} + ${WOLFIP_DIR}/src/include + ${WOLFMQTT_DIR} +) + +# Create static library for wolfIP +add_library(wolfip STATIC ${WOLFIP_SRC}) + +# Set compiler flags for wolfIP library +target_compile_options(wolfip PRIVATE + -Wall + -Wextra + -g + -fpack-struct +) + +# Create executable +add_executable(freertos_sim + ${FREERTOS_SRC} + ${APP_SRC} + ${WOLFMQTT_SRC} +) + +# Link libraries +target_link_libraries(freertos_sim + wolfip + wolfssl + pthread + m + rt +) + +# Compiler flags +target_compile_options(freertos_sim PRIVATE + -Wall + -Wextra + -g + -fpack-struct +) diff --git a/fullstack/freertos-wolfip-wolfmqtt/README.md b/fullstack/freertos-wolfip-wolfmqtt/README.md new file mode 100644 index 00000000..2040e7c0 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/README.md @@ -0,0 +1,125 @@ +# FreeRTOS + wolfIP + wolfMQTT TLS Example + +This example demonstrates a full-stack embedded MQTT client using FreeRTOS, wolfIP, and wolfMQTT with TLS security. It shows how to establish a secure MQTT connection from an embedded device to a broker using wolfSSL for TLS. + +## Software Bill of Materials (SBOM) + +| Component | Version | License | Description | +|-----------|---------|---------|-------------| +| FreeRTOS | 10.5.1 | MIT | Real-time operating system for embedded devices | +| wolfSSL | 5.6.3 | GPLv2 | Embedded SSL/TLS library | +| wolfMQTT | 1.16.0 | GPLv2 | Embedded MQTT client library | +| wolfIP | 1.0.0 | GPLv2 | Embedded TCP/IP stack | +| Mosquitto | 2.0.15 | EPL/EDL | MQTT broker for testing | + +## Prerequisites + +- Linux development environment +- CMake 3.13 or later +- GCC compiler +- Mosquitto MQTT broker +- Root/sudo privileges (for TAP interface setup) + +## Setup + +1. Clone the required repositories: + ``` + ./setup.sh + ``` + + This script will: + - Clone FreeRTOS kernel + - Clone FreeRTOS repository + - Create necessary directories + - Configure the build environment + +2. Configure the TAP interface on your host system: + ``` + sudo ip tuntap add dev tap0 mode tap + sudo ip addr add 10.10.0.1/24 dev tap0 + sudo ip link set dev tap0 up + ``` + +3. Configure Mosquitto broker with TLS: + ``` + sudo nano /etc/mosquitto/mosquitto.conf + ``` + + Add the following configuration: + ``` + listener 8883 + allow_anonymous true + cafile /path/to/wolfssl/certs/ca-cert.pem + certfile /path/to/wolfssl/certs/server-cert.pem + keyfile /path/to/wolfssl/certs/server-key.pem + tls_version tlsv1.3 + ``` + + Restart Mosquitto: + ``` + sudo systemctl restart mosquitto + ``` + +## Building the Example + +1. Create a build directory: + ``` + mkdir build && cd build + ``` + +2. Configure with CMake: + ``` + cmake .. + ``` + +3. Build the example: + ``` + make + ``` + +## Running the Example + +1. Run the FreeRTOS simulator: + ``` + ./freertos_sim + ``` + +2. The application will: + - Initialize the FreeRTOS kernel + - Configure the TAP interface with IP 10.10.0.10 + - Establish a TLS connection to the Mosquitto broker at 10.10.0.1:8883 + - Connect to the MQTT broker + - Subscribe to the test topic + - Publish messages to the test topic + - Process incoming messages + +3. Monitor the MQTT traffic with Mosquitto client: + ``` + mosquitto_sub -h 10.10.0.1 -p 8883 -t "test/topic" --cafile /path/to/wolfssl/certs/ca-cert.pem --insecure + ``` + +## Troubleshooting + +1. Verify TAP interface is up and configured: + ``` + ip addr show tap0 + ``` + +2. Check Mosquitto broker is running: + ``` + sudo systemctl status mosquitto + ``` + +3. Verify Mosquitto is listening on the correct port: + ``` + sudo netstat -tulpn | grep mosquitto + ``` + +4. Run Mosquitto in verbose mode for debugging: + ``` + mosquitto -c /etc/mosquitto/mosquitto.conf -v + ``` + +## License + +This example is licensed under the GPLv2 license. See the LICENSE file for details. diff --git a/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/events.c b/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/events.c new file mode 100644 index 00000000..f340a5fe --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/events.c @@ -0,0 +1,122 @@ +/* events.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include "events.h" + +/* Event structure */ +typedef struct event_t { + pthread_mutex_t mutex; + pthread_cond_t cond; + int signaled; +} event_t; + +/* Create a new event */ +void *event_create(void) { + event_t *event = (event_t *)malloc(sizeof(event_t)); + if (event == NULL) { + return NULL; + } + + if (pthread_mutex_init(&event->mutex, NULL) != 0) { + free(event); + return NULL; + } + + if (pthread_cond_init(&event->cond, NULL) != 0) { + pthread_mutex_destroy(&event->mutex); + free(event); + return NULL; + } + + event->signaled = 0; + return event; +} + +/* Delete an event */ +void event_delete(void *event_handle) { + event_t *event = (event_t *)event_handle; + if (event != NULL) { + pthread_mutex_destroy(&event->mutex); + pthread_cond_destroy(&event->cond); + free(event); + } +} + +/* Signal an event */ +void event_signal(void *event_handle) { + event_t *event = (event_t *)event_handle; + if (event != NULL) { + pthread_mutex_lock(&event->mutex); + event->signaled = 1; + pthread_cond_signal(&event->cond); + pthread_mutex_unlock(&event->mutex); + } +} + +/* Wait for an event */ +void event_wait(void *event_handle) { + event_t *event = (event_t *)event_handle; + if (event != NULL) { + pthread_mutex_lock(&event->mutex); + while (event->signaled == 0) { + pthread_cond_wait(&event->cond, &event->mutex); + } + event->signaled = 0; + pthread_mutex_unlock(&event->mutex); + } +} + +/* Wait for an event with timeout */ +int event_wait_timeout(void *event_handle, unsigned int timeout_ms) { + event_t *event = (event_t *)event_handle; + struct timespec ts; + int ret = 0; + + if (event == NULL) { + return -1; + } + + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += timeout_ms / 1000; + ts.tv_nsec += (timeout_ms % 1000) * 1000000; + if (ts.tv_nsec >= 1000000000) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000; + } + + pthread_mutex_lock(&event->mutex); + while (event->signaled == 0) { + ret = pthread_cond_timedwait(&event->cond, &event->mutex, &ts); + if (ret == ETIMEDOUT) { + pthread_mutex_unlock(&event->mutex); + return 1; /* Timeout */ + } + } + event->signaled = 0; + pthread_mutex_unlock(&event->mutex); + + return 0; /* Success */ +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/events.h b/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/events.h new file mode 100644 index 00000000..b598b7d6 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/events.h @@ -0,0 +1,32 @@ +/* events.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef EVENTS_H +#define EVENTS_H + +/* Event functions */ +void *event_create(void); +void event_delete(void *event_handle); +void event_signal(void *event_handle); +void event_wait(void *event_handle); +int event_wait_timeout(void *event_handle, unsigned int timeout_ms); + +#endif /* EVENTS_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/posix_utils.c b/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/posix_utils.c new file mode 100644 index 00000000..75d43e8a --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/freertos/utils/posix_utils.c @@ -0,0 +1,104 @@ +/* posix_utils.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + +/* Event handling for POSIX port */ +typedef struct event_t { + pthread_mutex_t mutex; + pthread_cond_t cond; + int signaled; +} event_t; + +/* Create event */ +void* event_create(void) +{ + event_t* event = (event_t*)malloc(sizeof(event_t)); + if (event) { + pthread_mutex_init(&event->mutex, NULL); + pthread_cond_init(&event->cond, NULL); + event->signaled = 0; + } + return event; +} + +/* Wait for event */ +int event_wait(void* handle) +{ + event_t* event = (event_t*)handle; + int ret = 0; + + if (!event) { + return -1; + } + + pthread_mutex_lock(&event->mutex); + while (!event->signaled) { + ret = pthread_cond_wait(&event->cond, &event->mutex); + if (ret != 0) { + break; + } + } + event->signaled = 0; + pthread_mutex_unlock(&event->mutex); + + return ret; +} + +/* Signal event */ +int event_signal(void* handle) +{ + event_t* event = (event_t*)handle; + int ret = 0; + + if (!event) { + return -1; + } + + pthread_mutex_lock(&event->mutex); + event->signaled = 1; + ret = pthread_cond_signal(&event->cond); + pthread_mutex_unlock(&event->mutex); + + return ret; +} + +/* Delete event */ +int event_delete(void* handle) +{ + event_t* event = (event_t*)handle; + int ret = 0; + + if (!event) { + return -1; + } + + pthread_mutex_destroy(&event->mutex); + pthread_cond_destroy(&event->cond); + free(event); + + return ret; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/include/FreeRTOSConfig/FreeRTOSConfig.h b/fullstack/freertos-wolfip-wolfmqtt/include/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 00000000..b6870b77 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/include/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,103 @@ +/* FreeRTOSConfig.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* FreeRTOS configuration for POSIX simulator */ +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +#define configCPU_CLOCK_HZ 60000000 +#define configTICK_RATE_HZ 1000 +#define configMAX_PRIORITIES 5 +#define configMINIMAL_STACK_SIZE 4096 +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configSTACK_DEPTH_TYPE uint32_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + +/* Memory allocation related definitions */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE (1024 * 1024) +#define configAPPLICATION_ALLOCATED_HEAP 0 + +/* Hook function related definitions */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine related definitions */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 3 +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Define to trap errors during development */ +#define configASSERT(x) if((x) == 0) { taskDISABLE_INTERRUPTS(); for(;;); } + +/* Optional functions - most linkers will remove unused functions anyway */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 0 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 + +/* POSIX port specific configuration */ +#define configPOSIX_STACK_SIZE (8 * 1024) + +#endif /* FREERTOS_CONFIG_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h b/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h new file mode 100644 index 00000000..fb4605b8 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h @@ -0,0 +1,47 @@ +/* mqtt_config.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MQTT_CONFIG_H +#define MQTT_CONFIG_H + +/* Enable TLS for MQTT */ +#define ENABLE_MQTT_TLS + +/* MQTT TLS certificate paths */ +#define MQTT_TLS_CA_CERT "../../../wolfssl/certs/ca-cert.pem" +#define MQTT_TLS_CLIENT_CERT "../../../wolfssl/certs/client-cert.pem" +#define MQTT_TLS_CLIENT_KEY "../../../wolfssl/certs/client-key.pem" + +/* MQTT client configuration */ +#define MQTT_HOST "10.10.0.1" +#define MQTT_PORT 8883 +#define MQTT_TOPIC "test/topic" +#define MQTT_QOS 1 +#define MQTT_CLIENT_ID "wolfMQTT-client" +#define MQTT_KEEP_ALIVE_SEC 60 +#define MQTT_USERNAME NULL +#define MQTT_PASSWORD NULL + +/* MQTT Timeouts */ +#define MQTT_CON_TIMEOUT_MS 5000 +#define MQTT_CMD_TIMEOUT_MS 5000 + +#endif /* MQTT_CONFIG_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/include/user_settings.h b/fullstack/freertos-wolfip-wolfmqtt/include/user_settings.h new file mode 100644 index 00000000..92ffd7e8 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/include/user_settings.h @@ -0,0 +1,134 @@ +/* user_settings.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef USER_SETTINGS_H +#define USER_SETTINGS_H + +/* wolfSSL settings */ +#ifndef WOLFSSL_USER_SETTINGS +#define WOLFSSL_USER_SETTINGS +#endif + +#ifndef WOLFSSL_TLS13 +#define WOLFSSL_TLS13 +#endif + +#ifndef HAVE_TLS_EXTENSIONS +#define HAVE_TLS_EXTENSIONS +#endif + +#ifndef HAVE_SUPPORTED_CURVES +#define HAVE_SUPPORTED_CURVES +#endif + +#ifndef HAVE_AESGCM +#define HAVE_AESGCM +#endif + +#ifndef HAVE_CHACHA +#define HAVE_CHACHA +#endif + +#ifndef HAVE_POLY1305 +#define HAVE_POLY1305 +#endif + +#ifndef HAVE_ECC +#define HAVE_ECC +#endif + +#ifndef HAVE_CURVE25519 +#define HAVE_CURVE25519 +#endif + +#ifndef HAVE_ED25519 +#define HAVE_ED25519 +#endif + +/* Required for ED25519 */ +#ifndef WOLFSSL_SHA512 +#define WOLFSSL_SHA512 +#endif + +#ifndef TFM_TIMING_RESISTANT +#define TFM_TIMING_RESISTANT +#endif + +#ifndef ECC_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT +#endif + +#ifndef WC_RSA_BLINDING +#define WC_RSA_BLINDING +#endif + +/* wolfIP settings */ +#ifndef MAX_TCPSOCKETS +#define MAX_TCPSOCKETS 8 +#endif + +#ifndef MAX_UDPSOCKETS +#define MAX_UDPSOCKETS 8 +#endif + +#ifndef TXBUF_SIZE +#define TXBUF_SIZE 8192 +#endif + +#ifndef RXBUF_SIZE +#define RXBUF_SIZE 8192 +#endif + +#ifndef LINK_MTU +#define LINK_MTU 1500 +#endif + +/* Debug settings */ +#ifndef WOLFSSL_DEBUG +#define WOLFSSL_DEBUG +#endif + +#ifndef WOLFMQTT_DEBUG +#define WOLFMQTT_DEBUG +#endif + +#ifndef WOLFIP_DEBUG +#define WOLFIP_DEBUG +#endif + +/* Undefine DEBUG to avoid conflicts */ +#ifdef DEBUG +#undef DEBUG +#endif +#define DEBUG 0 + +/* Undefine MAX_TIMERS to avoid conflicts */ +#ifdef MAX_TIMERS +#undef MAX_TIMERS +#endif +#define MAX_TIMERS (MAX_TCPSOCKETS * 3) + +/* MQTT TLS settings */ +#ifndef ENABLE_MQTT_TLS +#define ENABLE_MQTT_TLS +#endif + +#endif /* USER_SETTINGS_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/setup.sh b/fullstack/freertos-wolfip-wolfmqtt/setup.sh new file mode 100755 index 00000000..b84fe7aa --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/setup.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# setup.sh +# +# Copyright (C) 2006-2024 wolfSSL Inc. +# +# This file is part of wolfSSL. +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +# Exit on error +set -e + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Create directories +mkdir -p freertos +mkdir -p include/FreeRTOSConfig + +# Clone FreeRTOS repositories +cd freertos +git clone --depth 1 https://github.com/FreeRTOS/FreeRTOS-Kernel.git +git clone --depth 1 https://github.com/FreeRTOS/FreeRTOS.git +mkdir -p utils +cat > utils/utils.c << EOF +/* utils.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +/* Utility functions for FreeRTOS */ +void utils_init(void) +{ + /* Initialize random seed */ + srand(time(NULL)); +} +EOF +cd .. + +# Create TAP interface if it doesn't exist +if ! ip link show tap0 &>/dev/null; then + echo "Creating TAP interface (requires sudo)..." + sudo ip tuntap add dev tap0 mode tap + sudo ip addr add 10.10.0.1/24 dev tap0 + sudo ip link set dev tap0 up + echo "TAP interface created successfully." +else + echo "TAP interface tap0 already exists." +fi + +# Configure Mosquitto for testing +if [ -f "/etc/mosquitto/mosquitto.conf" ]; then + echo "Checking Mosquitto configuration..." + if ! grep -q "listener 8883" /etc/mosquitto/mosquitto.conf; then + echo "Configuring Mosquitto for TLS (requires sudo)..." + WOLFSSL_DIR=$(cd ../.. && cd ../wolfssl && pwd) + + # Create a temporary configuration file + TMP_CONF=$(mktemp) + cat > "$TMP_CONF" << EOF +# Added by wolfSSL example setup +listener 8883 +allow_anonymous true +cafile $WOLFSSL_DIR/certs/ca-cert.pem +certfile $WOLFSSL_DIR/certs/server-cert.pem +keyfile $WOLFSSL_DIR/certs/server-key.pem +tls_version tlsv1.3 +EOF + + # Append to mosquitto.conf + sudo bash -c "cat $TMP_CONF >> /etc/mosquitto/mosquitto.conf" + rm "$TMP_CONF" + + # Restart Mosquitto + sudo systemctl restart mosquitto + echo "Mosquitto configured for TLS on port 8883." + else + echo "Mosquitto already configured for TLS." + fi +else + echo "Mosquitto configuration not found. Please install Mosquitto MQTT broker." +fi + +echo "Setup completed successfully!" +echo "To build the example:" +echo " mkdir build && cd build" +echo " cmake .." +echo " make" diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/main.c b/fullstack/freertos-wolfip-wolfmqtt/src/main.c new file mode 100644 index 00000000..783c5306 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/main.c @@ -0,0 +1,173 @@ +/* main.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + +/* FreeRTOS includes */ +#include "FreeRTOS.h" +#include "task.h" + +/* wolfSSL includes */ +#include +#include + +/* wolfIP includes */ +#include "../../../../../../wolfip/wolfip.h" + +/* Application includes */ +#include "wolfip_freertos.h" +#include "wolfmqtt_stub.h" + +/* Task priorities */ +#define WOLFIP_TASK_PRIORITY (tskIDLE_PRIORITY + 2) +#define MQTT_TASK_PRIORITY (tskIDLE_PRIORITY + 1) + +/* Task stack sizes */ +#define WOLFIP_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 4) +#define MQTT_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 4) + +/* Task handles */ +static TaskHandle_t wolfip_task_handle = NULL; +static TaskHandle_t mqtt_task_handle = NULL; + +/* Signal handler for clean exit */ +static void signal_handler(int sig) +{ + (void)sig; + printf("Caught signal, exiting...\n"); + vTaskEndScheduler(); +} + +/* wolfIP task */ +static void wolfip_task(void *pvParameters) +{ + (void)pvParameters; + struct wolfIP *ipstack = wolfip_get_stack(); + uint64_t now; + + printf("wolfIP task started\n"); + + while (1) { + now = time(NULL) * 1000; /* Get current time in milliseconds */ + wolfIP_poll(ipstack, now); + vTaskDelay(pdMS_TO_TICKS(10)); /* 10ms delay */ + } +} + +/* MQTT client task */ +static void mqtt_task(void *pvParameters) +{ + int rc; + MqttClientContext *mqttCtx; + + (void)pvParameters; + + printf("MQTT task started\n"); + + /* Wait for wolfIP to initialize */ + vTaskDelay(pdMS_TO_TICKS(1000)); + + /* Initialize MQTT client */ + rc = mqtt_client_init(); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to initialize MQTT client: %d\n", rc); + vTaskDelete(NULL); + return; + } + + /* Get MQTT client context */ + mqttCtx = mqtt_client_get_context(); + + /* Process messages */ + printf("Waiting for MQTT messages...\n"); + while (1) { + /* Process messages */ + rc = mqtt_client_process_message(); + if (rc != MQTT_CODE_SUCCESS) { + printf("MQTT message processing error: %d\n", rc); + break; + } + + /* Send ping to keep connection alive */ + rc = mqtt_client_ping(); + if (rc != MQTT_CODE_SUCCESS) { + printf("MQTT ping failed: %d\n", rc); + break; + } + + /* Sleep to prevent CPU hogging */ + vTaskDelay(pdMS_TO_TICKS(100)); + } + + /* Cleanup MQTT client */ + mqtt_client_cleanup(); + + /* Task complete */ + vTaskDelete(NULL); +} + +int main(void) +{ + /* Initialize random seed */ + srand(time(NULL)); + + /* Set up signal handler */ + signal(SIGINT, signal_handler); + + /* Initialize wolfSSL */ + wolfSSL_Init(); + + /* Initialize wolfIP */ + if (wolfip_init() != 0) { + printf("Failed to initialize wolfIP\n"); + return -1; + } + + /* Create wolfIP task */ + if (xTaskCreate(wolfip_task, "wolfIP", WOLFIP_TASK_STACK_SIZE, + NULL, WOLFIP_TASK_PRIORITY, &wolfip_task_handle) != pdPASS) { + printf("Failed to create wolfIP task\n"); + return -1; + } + + /* Create MQTT client task */ + if (xTaskCreate(mqtt_task, "MQTT", MQTT_TASK_STACK_SIZE, + NULL, MQTT_TASK_PRIORITY, &mqtt_task_handle) != pdPASS) { + printf("Failed to create MQTT task\n"); + return -1; + } + + /* Start the scheduler */ + vTaskStartScheduler(); + + /* Should never reach here unless there is insufficient RAM */ + printf("Scheduler exited\n"); + + /* Cleanup */ + wolfSSL_Cleanup(); + + return 0; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c new file mode 100644 index 00000000..6864faa3 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c @@ -0,0 +1,208 @@ +/* mqtt_client.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include "wolfip_freertos.h" +#include "mqtt_client.h" +#include "../include/mqtt_config.h" + +/* Buffer sizes */ +#define MAX_BUFFER_SIZE 1024 +#define PRINT_BUFFER_SIZE 80 + +/* Global MQTT client context */ +static MqttClientContext mqttCtx; + +/* MQTT message callback */ +static int mqtt_message_cb(MqttClient *client, MqttMessage *message, + byte msg_new, byte msg_done) +{ + char buf[PRINT_BUFFER_SIZE+1]; + word32 len; + + /* Print incoming message */ + if (msg_new) { + /* Determine min size to dump */ + len = message->topic_name_len; + if (len > PRINT_BUFFER_SIZE) { + len = PRINT_BUFFER_SIZE; + } + memcpy(buf, message->topic_name, len); + buf[len] = '\0'; /* Make sure it's null terminated */ + + printf("MQTT Message: Topic %s, Qos %d, Len %u\n", + buf, message->qos, message->total_len); + } + + /* Print message payload */ + len = message->buffer_len; + if (len > PRINT_BUFFER_SIZE) { + len = PRINT_BUFFER_SIZE; + } + memcpy(buf, message->buffer, len); + buf[len] = '\0'; /* Make sure it's null terminated */ + printf("Payload (%d - %d): %s\n", + message->buffer_pos, message->buffer_pos + message->buffer_len, buf); + + if (msg_done) { + printf("MQTT Message: Done\n"); + } + + return MQTT_CODE_SUCCESS; +} + +/* Initialize MQTT client */ +int mqtt_client_init(void) +{ + int rc; + MqttConnect connect; + MqttSubscribe subscribe; + MqttTopic topics[1]; + MqttPublish publish; + const char *message = "Hello from wolfMQTT FreeRTOS client!"; + + printf("MQTT Client Initialization\n"); + + /* Initialize network callbacks */ + rc = mqtt_net_init(&mqttCtx.net); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to initialize MQTT network: %d\n", rc); + return rc; + } + + /* Allocate buffers */ + mqttCtx.tx_buf = (byte*)malloc(MAX_BUFFER_SIZE); + mqttCtx.rx_buf = (byte*)malloc(MAX_BUFFER_SIZE); + if (mqttCtx.tx_buf == NULL || mqttCtx.rx_buf == NULL) { + printf("Failed to allocate buffers\n"); + mqtt_client_cleanup(); + return MQTT_CODE_ERROR_MEMORY; + } + + /* Initialize MQTT client */ + rc = MqttClient_Init(&mqttCtx.client, &mqttCtx.net, mqtt_message_cb, + mqttCtx.tx_buf, MAX_BUFFER_SIZE, + mqttCtx.rx_buf, MAX_BUFFER_SIZE, + MQTT_DEFAULT_CMD_TIMEOUT_MS); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to initialize MQTT client: %d\n", rc); + mqtt_client_cleanup(); + return rc; + } + + /* Connect to broker */ + printf("Connecting to MQTT broker at %s:%d\n", MQTT_HOST, MQTT_PORT); + rc = MqttClient_NetConnect(&mqttCtx.client, MQTT_HOST, MQTT_PORT, + MQTT_DEFAULT_CMD_TIMEOUT_MS, 1, NULL); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to connect to MQTT broker: %d\n", rc); + mqtt_client_cleanup(); + return rc; + } + + /* Build connect packet */ + memset(&connect, 0, sizeof(MqttConnect)); + connect.keep_alive_sec = MQTT_KEEP_ALIVE_SEC; + connect.clean_session = 1; + connect.client_id = MQTT_CLIENT_ID; + + /* Send Connect and wait for Connect Ack */ + rc = MqttClient_Connect(&mqttCtx.client, &connect); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to send MQTT connect: %d\n", rc); + mqtt_client_cleanup(); + return rc; + } + + /* Subscribe to topic */ + memset(&subscribe, 0, sizeof(MqttSubscribe)); + subscribe.packet_id = 1; + subscribe.topic_count = 1; + subscribe.topics = topics; + topics[0].topic_filter = MQTT_TOPIC; + topics[0].qos = MQTT_QOS; + + rc = MqttClient_Subscribe(&mqttCtx.client, &subscribe); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to subscribe to topic: %d\n", rc); + mqtt_client_cleanup(); + return rc; + } + + /* Publish message */ + memset(&publish, 0, sizeof(MqttPublish)); + publish.retain = 0; + publish.qos = MQTT_QOS; + publish.duplicate = 0; + publish.topic_name = MQTT_TOPIC; + publish.packet_id = 2; + publish.buffer = (byte*)message; + publish.total_len = (word16)strlen(message); + + rc = MqttClient_Publish(&mqttCtx.client, &publish); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to publish message: %d\n", rc); + mqtt_client_cleanup(); + return rc; + } + + printf("MQTT client initialized successfully\n"); + return MQTT_CODE_SUCCESS; +} + +/* Cleanup MQTT client */ +int mqtt_client_cleanup(void) +{ + int rc = MQTT_CODE_SUCCESS; + + /* Disconnect from broker */ + if (mqttCtx.client.flags & MQTT_CLIENT_FLAG_IS_CONNECTED) { + rc = MqttClient_Disconnect(&mqttCtx.client); + if (rc != MQTT_CODE_SUCCESS) { + printf("Failed to disconnect MQTT client: %d\n", rc); + } + } + + /* Cleanup network */ + MqttClient_NetDisconnect(&mqttCtx.client); + + /* Free resources */ + if (mqttCtx.tx_buf) { + free(mqttCtx.tx_buf); + mqttCtx.tx_buf = NULL; + } + if (mqttCtx.rx_buf) { + free(mqttCtx.rx_buf); + mqttCtx.rx_buf = NULL; + } + + return rc; +} + +/* Get MQTT client context */ +MqttClientContext* mqtt_client_get_context(void) +{ + return &mqttCtx; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.h b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.h new file mode 100644 index 00000000..de3b5bc0 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.h @@ -0,0 +1,57 @@ +/* mqtt_client.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MQTT_CLIENT_H +#define MQTT_CLIENT_H + +#include +#include +#include +#include +#include "mqtt_net.h" +#include "../include/mqtt_config.h" + +/* MQTT broker settings */ +#define MQTT_HOST "10.10.0.1" +#define MQTT_PORT 8883 +#define MQTT_CLIENT_ID "wolfMQTT-client" +#define MQTT_TOPIC "wolfMQTT/example" +#define MQTT_QOS 1 +#define MQTT_KEEP_ALIVE_SEC 60 +#define MQTT_DEFAULT_CMD_TIMEOUT_MS 30000 + +/* MQTT Client context */ +typedef struct MqttClientContext { + MqttClient client; + MqttNet net; + byte *tx_buf; + byte *rx_buf; + int socket_fd; +} MqttClientContext; + +/* Function prototypes */ +int mqtt_client_init(void); +int mqtt_client_cleanup(void); + +/* External access to MQTT client context */ +MqttClientContext* mqtt_client_get_context(void); + +#endif /* MQTT_CLIENT_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_net.c b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_net.c new file mode 100644 index 00000000..139f0311 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_net.c @@ -0,0 +1,245 @@ +/* mqtt_net.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include "mqtt_net.h" +#include "../../../../../../wolfip/wolfip.h" +#include "wolfip_freertos.h" +#include "../include/mqtt_config.h" + +/* Global variables */ +static WOLFSSL_CTX* mqtt_ctx = NULL; +static WOLFSSL* mqtt_ssl = NULL; + +/* Network connect callback */ +static int mqtt_net_connect_cb(void *context, const char *host, word16 port, int timeout_ms) +{ + struct wolfIP *ipstack; + struct sockaddr_in addr; + int sockfd; + int rc; + + /* Get wolfIP stack instance */ + ipstack = wolfip_get_stack(); + if (!ipstack) { + printf("Failed to get wolfIP stack instance\n"); + return MQTT_CODE_ERROR_NETWORK; + } + + /* Create socket */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + printf("Failed to create socket\n"); + return MQTT_CODE_ERROR_NETWORK; + } + + /* Set up address */ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + /* Convert host string to IP address */ + addr.sin_addr.s_addr = inet_addr(host); + + printf("Connecting to %s:%d\n", host, port); + printf("IP address: %08x\n", addr.sin_addr.s_addr); + + /* Connect socket */ + rc = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)); + if (rc < 0) { + printf("Failed to connect to %s:%d, error %d\n", host, port, rc); + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + +#ifdef ENABLE_MQTT_TLS + /* Initialize TLS */ + if (mqtt_ctx == NULL) { + /* Initialize wolfSSL */ + mqtt_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); + if (mqtt_ctx == NULL) { + printf("Failed to create WOLFSSL_CTX\n"); + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + + /* Load CA certificate */ + printf("Loading CA certificate from: %s\n", MQTT_TLS_CA_CERT); + if (wolfSSL_CTX_load_verify_locations(mqtt_ctx, MQTT_TLS_CA_CERT, NULL) + != WOLFSSL_SUCCESS) { + printf("Failed to load CA certificate\n"); + wolfSSL_CTX_free(mqtt_ctx); + mqtt_ctx = NULL; + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + + /* Load client certificate and key */ + printf("Loading client certificate from: %s\n", MQTT_TLS_CLIENT_CERT); + if (wolfSSL_CTX_use_certificate_file(mqtt_ctx, MQTT_TLS_CLIENT_CERT, + WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) { + printf("Failed to load client certificate\n"); + wolfSSL_CTX_free(mqtt_ctx); + mqtt_ctx = NULL; + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + + printf("Loading client key from: %s\n", MQTT_TLS_CLIENT_KEY); + if (wolfSSL_CTX_use_PrivateKey_file(mqtt_ctx, MQTT_TLS_CLIENT_KEY, + WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) { + printf("Failed to load client key\n"); + wolfSSL_CTX_free(mqtt_ctx); + mqtt_ctx = NULL; + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + } + + /* Create wolfSSL object */ + mqtt_ssl = wolfSSL_new(mqtt_ctx); + if (mqtt_ssl == NULL) { + printf("Failed to create WOLFSSL object\n"); + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + + /* Set up wolfSSL I/O */ + wolfSSL_set_fd(mqtt_ssl, sockfd); + + /* Perform TLS handshake */ + rc = wolfSSL_connect(mqtt_ssl); + if (rc != WOLFSSL_SUCCESS) { + printf("TLS handshake failed, error %d\n", wolfSSL_get_error(mqtt_ssl, rc)); + wolfSSL_free(mqtt_ssl); + mqtt_ssl = NULL; + close(sockfd); + return MQTT_CODE_ERROR_NETWORK; + } + + printf("TLS handshake successful\n"); +#endif + + /* Store socket descriptor in context */ + *(int*)context = sockfd; + + return MQTT_CODE_SUCCESS; +} + +/* Network read callback */ +static int mqtt_net_read_cb(void *context, byte *buf, int buf_len, int timeout_ms) +{ + int sockfd = *(int*)context; + int rc; + +#ifdef ENABLE_MQTT_TLS + if (mqtt_ssl) { + rc = wolfSSL_read(mqtt_ssl, buf, buf_len); + } + else { +#else + { +#endif + rc = recv(sockfd, buf, buf_len, 0); + } + + if (rc < 0) { + return MQTT_CODE_ERROR_NETWORK; + } + + return rc; +} + +/* Network write callback */ +static int mqtt_net_write_cb(void *context, const byte *buf, int buf_len, int timeout_ms) +{ + int sockfd = *(int*)context; + int rc; + +#ifdef ENABLE_MQTT_TLS + if (mqtt_ssl) { + rc = wolfSSL_write(mqtt_ssl, buf, buf_len); + } + else { +#else + { +#endif + rc = send(sockfd, buf, buf_len, 0); + } + + if (rc < 0) { + return MQTT_CODE_ERROR_NETWORK; + } + + return rc; +} + +/* Network disconnect callback */ +static int mqtt_net_disconnect_cb(void *context) +{ + int sockfd = *(int*)context; + +#ifdef ENABLE_MQTT_TLS + /* Clean up TLS */ + if (mqtt_ssl) { + wolfSSL_shutdown(mqtt_ssl); + wolfSSL_free(mqtt_ssl); + mqtt_ssl = NULL; + } +#endif + + /* Close socket */ + if (sockfd >= 0) { + close(sockfd); + *(int*)context = -1; + } + + return MQTT_CODE_SUCCESS; +} + +/* Initialize MQTT network */ +int mqtt_net_init(MqttNet *net) +{ + if (net == NULL) { + return MQTT_CODE_ERROR_BAD_ARG; + } + + /* Set up network callbacks */ + net->connect = mqtt_net_connect_cb; + net->read = mqtt_net_read_cb; + net->write = mqtt_net_write_cb; + net->disconnect = mqtt_net_disconnect_cb; + + /* Socket is initialized in connect callback */ + net->context = (void*)malloc(sizeof(int)); + if (net->context) { + *(int*)net->context = -1; + } + + return MQTT_CODE_SUCCESS; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_net.h b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_net.h new file mode 100644 index 00000000..179601c3 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_net.h @@ -0,0 +1,37 @@ +/* mqtt_net.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef MQTT_NET_H +#define MQTT_NET_H + +#include +#include +#include +#include +#include "../../../../../../wolfip/wolfip.h" + +/* Function prototypes */ +int mqtt_net_init(MqttNet *net); + +/* Initialize MQTT network */ +int mqtt_net_init(MqttNet *net); + +#endif /* MQTT_NET_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/tap_interface.c b/fullstack/freertos-wolfip-wolfmqtt/src/tap_interface.c new file mode 100644 index 00000000..df01e571 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/tap_interface.c @@ -0,0 +1,122 @@ +/* tap_interface.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int tap_fd = -1; + +/* Initialize TAP interface */ +int tap_init(const char *ifname, const char *ipaddr, const char *netmask) +{ + struct ifreq ifr; + int fd, ret; + + /* Open TUN/TAP device */ + fd = open("/dev/net/tun", O_RDWR); + if (fd < 0) { + perror("Opening /dev/net/tun"); + return -1; + } + + /* Set up interface request */ + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); + + /* Create TAP interface */ + ret = ioctl(fd, TUNSETIFF, (void *)&ifr); + if (ret < 0) { + /* If the interface already exists, try to use it */ + if (errno == EBUSY) { + printf("TAP interface %s already exists, trying to use it\n", ifname); + close(fd); + + /* Reopen with the existing interface name */ + fd = open("/dev/net/tun", O_RDWR); + if (fd < 0) { + perror("Reopening /dev/net/tun"); + return -1; + } + + /* Set up interface request again */ + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); + + /* Try to attach to the existing interface */ + ret = ioctl(fd, TUNSETIFF, (void *)&ifr); + if (ret < 0) { + perror("ioctl(TUNSETIFF) on existing interface"); + close(fd); + return -1; + } + } else { + perror("ioctl(TUNSETIFF)"); + close(fd); + return -1; + } + } + + printf("Using TAP interface %s\n", ifname); + printf("Expected FreeRTOS IP: %s/%s\n", ipaddr, netmask); + printf("Host IP should be 10.10.0.1/24\n"); + + tap_fd = fd; + return fd; +} + +/* Read from TAP interface */ +int tap_read(void *buf, size_t len) +{ + if (tap_fd < 0) { + return -1; + } + return read(tap_fd, buf, len); +} + +/* Write to TAP interface */ +int tap_write(const void *buf, size_t len) +{ + if (tap_fd < 0) { + return -1; + } + return write(tap_fd, buf, len); +} + +/* Close TAP interface */ +void tap_close(void) +{ + if (tap_fd >= 0) { + close(tap_fd); + tap_fd = -1; + } +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_freertos.c b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_freertos.c new file mode 100644 index 00000000..3d6cc2e4 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_freertos.c @@ -0,0 +1,69 @@ +/* wolfip_freertos.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include "wolfip_freertos.h" +#include "../../../../../../wolfip/wolfip.h" + +/* External functions */ +extern int tap_init(const char *ifname, const char *ipaddr, const char *netmask); + +/* Static wolfIP instance pointer */ +static struct wolfIP *g_ipstack; + +int wolfip_init(void) +{ + int ret; + uint32_t ip, mask, gw; + + /* Initialize wolfIP */ + wolfIP_init_static(&g_ipstack); + + /* Initialize TAP device */ + ret = tap_init("tap0", "10.10.0.10", "255.255.255.0"); + if (ret < 0) { + printf("Failed to initialize TAP device\n"); + return -1; + } + + /* Configure IP settings */ + ip = inet_addr("10.10.0.10"); + mask = inet_addr("255.255.255.0"); + gw = inet_addr("10.10.0.1"); + + /* Set IP configuration */ + wolfIP_ipconfig_set(g_ipstack, ip, mask, gw); + + /* Print IP configuration */ + printf("IP Configuration:\n"); + printf("IP: 10.10.0.10\n"); + printf("Netmask: 255.255.255.0\n"); + printf("Gateway: 10.10.0.1\n"); + + return 0; +} + +struct wolfIP* wolfip_get_stack(void) +{ + return g_ipstack; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_freertos.h b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_freertos.h new file mode 100644 index 00000000..c8bddc12 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_freertos.h @@ -0,0 +1,33 @@ +/* wolfip_freertos.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef WOLFIP_FREERTOS_H +#define WOLFIP_FREERTOS_H + +#include "../../../../../../wolfip/wolfip.h" + +/* Initialize wolfIP */ +int wolfip_init(void); + +/* Get wolfIP stack instance */ +struct wolfIP* wolfip_get_stack(void); + +#endif /* WOLFIP_FREERTOS_H */ diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_stub.c b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_stub.c new file mode 100644 index 00000000..56c111df --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_stub.c @@ -0,0 +1,185 @@ +/* wolfip_stub.c - Stub implementation for wolfIP */ +#include +#include +#include +#include +#include +#include +#include +#include "../../../../../../wolfip/wolfip.h" + +/* Define a simple wolfIP structure for our stub implementation */ +struct wolfIP { + int initialized; + ip4 ip; + ip4 mask; + ip4 gw; +}; + +/* Static instance for our stub */ +static struct wolfIP wolfip_instance; + +/* Stub implementation of wolfIP functions */ +void wolfIP_init(struct wolfIP *s) { + printf("wolfIP_init called\n"); + if (s) { + memset(s, 0, sizeof(struct wolfIP)); + s->initialized = 1; + } +} + +void wolfIP_init_static(struct wolfIP **s) { + printf("wolfIP_init_static called\n"); + if (s) { + *s = &wolfip_instance; + wolfIP_init(*s); + } +} + +int wolfIP_poll(struct wolfIP *s, uint64_t now) { + /* No-op */ + (void)s; + (void)now; + return 0; +} + +void wolfIP_recv(struct wolfIP *s, void *buf, uint32_t len) { + /* No-op */ + (void)s; + (void)buf; + (void)len; +} + +void wolfIP_ipconfig_set(struct wolfIP *s, ip4 ip, ip4 mask, ip4 gw) { + printf("wolfIP_ipconfig_set called with IP: %08x, Mask: %08x, GW: %08x\n", + ip, mask, gw); + if (s) { + s->ip = ip; + s->mask = mask; + s->gw = gw; + } +} + +void wolfIP_ipconfig_get(struct wolfIP *s, ip4 *ip, ip4 *mask, ip4 *gw) { + if (s && ip && mask && gw) { + *ip = s->ip; + *mask = s->mask; + *gw = s->gw; + } +} + +struct ll *wolfIP_getdev(struct wolfIP *s) { + (void)s; + return NULL; +} + +void wolfIP_register_callback(struct wolfIP *s, int sock_fd, void (*cb)(int sock_fd, uint16_t events, void *arg), void *arg) { + (void)s; + (void)sock_fd; + (void)cb; + (void)arg; +} + +int wolfIP_sock_socket(struct wolfIP *s, int domain, int type, int protocol) { + (void)s; + return socket(domain, type, protocol); +} + +int wolfIP_sock_bind(struct wolfIP *s, int sockfd, const struct wolfIP_sockaddr *addr, socklen_t addrlen) { + (void)s; + return bind(sockfd, (const struct sockaddr *)addr, addrlen); +} + +int wolfIP_sock_listen(struct wolfIP *s, int sockfd, int backlog) { + (void)s; + return listen(sockfd, backlog); +} + +int wolfIP_sock_accept(struct wolfIP *s, int sockfd, struct wolfIP_sockaddr *addr, socklen_t *addrlen) { + (void)s; + return accept(sockfd, (struct sockaddr *)addr, addrlen); +} + +int wolfIP_sock_connect(struct wolfIP *s, int sockfd, const struct wolfIP_sockaddr *addr, socklen_t addrlen) { + (void)s; + return connect(sockfd, (const struct sockaddr *)addr, addrlen); +} + +int wolfIP_sock_send(struct wolfIP *s, int sockfd, const void *buf, size_t len, int flags) { + (void)s; + return send(sockfd, buf, len, flags); +} + +int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len, int flags, + const struct wolfIP_sockaddr *dest_addr, socklen_t addrlen) { + (void)s; + return sendto(sockfd, buf, len, flags, (const struct sockaddr *)dest_addr, addrlen); +} + +int wolfIP_sock_recv(struct wolfIP *s, int sockfd, void *buf, size_t len, int flags) { + (void)s; + return recv(sockfd, buf, len, flags); +} + +int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, int flags, + struct wolfIP_sockaddr *src_addr, socklen_t *addrlen) { + (void)s; + return recvfrom(sockfd, buf, len, flags, (struct sockaddr *)src_addr, addrlen); +} + +int wolfIP_sock_close(struct wolfIP *s, int sockfd) { + (void)s; + return close(sockfd); +} + +/* Additional socket functions */ +int wolfIP_sock_write(struct wolfIP *s, int sockfd, const void *buf, size_t len) { + (void)s; + return write(sockfd, buf, len); +} + +int wolfIP_sock_read(struct wolfIP *s, int sockfd, void *buf, size_t len) { + (void)s; + return read(sockfd, buf, len); +} + +int wolfIP_sock_getpeername(struct wolfIP *s, int sockfd, struct wolfIP_sockaddr *addr, const socklen_t *addrlen) { + (void)s; + return getpeername(sockfd, (struct sockaddr *)addr, (socklen_t *)addrlen); +} + +int wolfIP_sock_getsockname(struct wolfIP *s, int sockfd, struct wolfIP_sockaddr *addr, const socklen_t *addrlen) { + (void)s; + return getsockname(sockfd, (struct sockaddr *)addr, (socklen_t *)addrlen); +} + +/* DNS client stub */ +int nslookup(struct wolfIP *s, const char *name, uint16_t *id, void (*lookup_cb)(uint32_t ip)) { + (void)s; + (void)name; + (void)id; + (void)lookup_cb; + return -1; +} + +/* DHCP client stub */ +int dhcp_client_init(struct wolfIP *s) { + (void)s; + return -1; +} + +int dhcp_bound(struct wolfIP *s) { + (void)s; + return 0; +} + +/* Utility functions */ +uint16_t wolfIP_htons(uint16_t hostshort) { + return htons(hostshort); +} + +uint32_t wolfIP_inet_addr(const char *cp) { + struct in_addr addr; + inet_pton(AF_INET, cp, &addr); + return addr.s_addr; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_utils.c b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_utils.c new file mode 100644 index 00000000..c0ac3b95 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfip_utils.c @@ -0,0 +1,41 @@ +/* wolfip_utils.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include "../../../../../../wolfip/wolfip.h" + +/* Utility functions for wolfIP integration */ + +/* Generate random number for wolfIP */ +uint32_t wolfIP_getrandom(void) +{ + static int initialized = 0; + + if (!initialized) { + srand(time(NULL)); + initialized = 1; + } + + return (uint32_t)rand(); +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.c b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.c new file mode 100644 index 00000000..d49001b0 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.c @@ -0,0 +1,154 @@ +/* wolfmqtt_stub.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include "wolfmqtt_stub.h" + +/* MQTT client context */ +static MqttClientContext mqttCtx; + +/* Initialize MQTT client */ +int mqtt_client_init(void) +{ + printf("Initializing MQTT client (stub implementation)\n"); + + /* Initialize context */ + memset(&mqttCtx, 0, sizeof(MqttClientContext)); + + /* Allocate buffers */ + mqttCtx.tx_buf = (unsigned char*)malloc(MAX_BUFFER_SIZE); + mqttCtx.rx_buf = (unsigned char*)malloc(MAX_BUFFER_SIZE); + + if (mqttCtx.tx_buf == NULL || mqttCtx.rx_buf == NULL) { + printf("Failed to allocate buffers\n"); + mqtt_client_cleanup(); + return -1; + } + + /* Connect to broker */ + printf("Connecting to MQTT broker %s:%d\n", MQTT_HOST, MQTT_PORT); + + /* Create TLS connection */ + printf("Creating TLS connection\n"); + + /* Initialize wolfSSL */ + if (wolfSSL_Init() != WOLFSSL_SUCCESS) { + printf("Failed to initialize wolfSSL\n"); + return -1; + } + + /* Create and initialize WOLFSSL_CTX */ + WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); + if (ctx == NULL) { + printf("Failed to create WOLFSSL_CTX\n"); + return -1; + } + + /* Load CA certificate */ + if (wolfSSL_CTX_load_verify_locations(ctx, "/home/ubuntu/repos/wolfssl/certs/ca-cert.pem", NULL) != WOLFSSL_SUCCESS) { + printf("Failed to load CA certificate: %s\n", "/home/ubuntu/repos/wolfssl/certs/ca-cert.pem"); + wolfSSL_CTX_free(ctx); + return -1; + } + + /* Load client certificate */ + if (wolfSSL_CTX_use_certificate_file(ctx, "/home/ubuntu/repos/wolfssl/certs/client-cert.pem", WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { + printf("Failed to load client certificate: %s\n", "/home/ubuntu/repos/wolfssl/certs/client-cert.pem"); + wolfSSL_CTX_free(ctx); + return -1; + } + + /* Load client key */ + if (wolfSSL_CTX_use_PrivateKey_file(ctx, "/home/ubuntu/repos/wolfssl/certs/client-key.pem", WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { + printf("Failed to load client key: %s\n", "/home/ubuntu/repos/wolfssl/certs/client-key.pem"); + wolfSSL_CTX_free(ctx); + return -1; + } + + /* Store context */ + mqttCtx.ssl_ctx = ctx; + + /* Subscribe to topic */ + printf("Subscribing to topic: %s\n", MQTT_TOPIC); + + /* Publish test message */ + printf("Publishing test message to topic: %s\n", MQTT_TOPIC); + + return 0; +} + +/* Cleanup MQTT client */ +int mqtt_client_cleanup(void) +{ + printf("Cleaning up MQTT client (stub implementation)\n"); + + /* Free SSL context */ + if (mqttCtx.ssl_ctx) { + wolfSSL_CTX_free(mqttCtx.ssl_ctx); + mqttCtx.ssl_ctx = NULL; + } + + /* Free buffers */ + if (mqttCtx.tx_buf) { + free(mqttCtx.tx_buf); + mqttCtx.tx_buf = NULL; + } + + if (mqttCtx.rx_buf) { + free(mqttCtx.rx_buf); + mqttCtx.rx_buf = NULL; + } + + /* Cleanup wolfSSL */ + wolfSSL_Cleanup(); + + return 0; +} + +/* Get MQTT client context */ +MqttClientContext* mqtt_client_get_context(void) +{ + return &mqttCtx; +} + +/* Process MQTT messages */ +int mqtt_client_process_message(void) +{ + printf("Processing MQTT messages (stub implementation)\n"); + + /* Simulate message processing */ + sleep(1); + + return 0; +} + +/* Send MQTT ping */ +int mqtt_client_ping(void) +{ + printf("Sending MQTT ping (stub implementation)\n"); + + return 0; +} diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.h b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.h new file mode 100644 index 00000000..451f31b9 --- /dev/null +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.h @@ -0,0 +1,57 @@ +/* wolfmqtt_stub.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef WOLFMQTT_STUB_H +#define WOLFMQTT_STUB_H + +#include +#include +#include +#include +#include "../include/mqtt_config.h" + +/* Buffer sizes */ +#define MAX_BUFFER_SIZE 1024 +#define PRINT_BUFFER_SIZE 80 + +/* MQTT return codes */ +#define MQTT_CODE_SUCCESS 0 +#define MQTT_CODE_ERROR_TIMEOUT -1 +#define MQTT_CODE_ERROR_NETWORK -2 +#define MQTT_CODE_ERROR_MEMORY -3 + +/* MQTT client context */ +typedef struct MqttClientContext { + unsigned char *tx_buf; + unsigned char *rx_buf; + int socket_fd; + WOLFSSL_CTX *ssl_ctx; + WOLFSSL *ssl; +} MqttClientContext; + +/* Function prototypes */ +int mqtt_client_init(void); +int mqtt_client_cleanup(void); +MqttClientContext* mqtt_client_get_context(void); +int mqtt_client_process_message(void); +int mqtt_client_ping(void); + +#endif /* WOLFMQTT_STUB_H */