diff --git a/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt b/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt index 6d2878ad..ada733e9 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt +++ b/fullstack/freertos-wolfip-wolfmqtt/CMakeLists.txt @@ -124,14 +124,16 @@ 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/mqtt_client.c - src/mqtt_net.c src/wolfip_utils.c - src/wolfmqtt_stub.c src/tap_interface.c ${CMAKE_CURRENT_SOURCE_DIR}/freertos/utils/posix_utils.c ) @@ -164,6 +166,7 @@ target_compile_options(wolfip PRIVATE add_executable(freertos_sim ${FREERTOS_SRC} ${APP_SRC} + ${WOLFMQTT_SRC} ) # Link libraries diff --git a/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h b/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h index 2c2155fe..fb4605b8 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h +++ b/fullstack/freertos-wolfip-wolfmqtt/include/mqtt_config.h @@ -34,7 +34,14 @@ #define MQTT_HOST "10.10.0.1" #define MQTT_PORT 8883 #define MQTT_TOPIC "test/topic" -#define MQTT_QOS 0 +#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/src/main.c b/fullstack/freertos-wolfip-wolfmqtt/src/main.c index 3ef6b214..58f1798a 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/src/main.c +++ b/fullstack/freertos-wolfip-wolfmqtt/src/main.c @@ -39,7 +39,7 @@ /* Application includes */ #include "wolfip_freertos.h" -#include "mqtt_client.h" +#include "wolfmqtt_stub.h" /* Task priorities */ #define WOLFIP_TASK_PRIORITY (tskIDLE_PRIORITY + 2) @@ -80,6 +80,9 @@ static void wolfip_task(void *pvParameters) /* MQTT client task */ static void mqtt_task(void *pvParameters) { + int rc; + MqttClientContext *mqttCtx; + (void)pvParameters; printf("MQTT task started\n"); @@ -87,9 +90,41 @@ static void mqtt_task(void *pvParameters) /* Wait for wolfIP to initialize */ vTaskDelay(pdMS_TO_TICKS(1000)); - /* Initialize and start MQTT client */ - mqtt_client_init(); - + /* 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); } diff --git a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c index 9d1d6927..6864faa3 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c +++ b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.c @@ -25,44 +25,184 @@ #include #include #include "wolfip_freertos.h" -#include "wolfmqtt_stub.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 void mqtt_message_cb(const char *topic, const char *payload, size_t payload_len) +static int mqtt_message_cb(MqttClient *client, MqttMessage *message, + byte msg_new, byte msg_done) { - char buf[1024]; /* Buffer for message handling */ - size_t len; + char buf[PRINT_BUFFER_SIZE+1]; + word32 len; /* Print incoming message */ - printf("MQTT Message: Topic %s, Len %zu\n", topic, payload_len); + 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 = payload_len; - if (len > sizeof(buf) - 1) { - len = sizeof(buf) - 1; + len = message->buffer_len; + if (len > PRINT_BUFFER_SIZE) { + len = PRINT_BUFFER_SIZE; } - memcpy(buf, payload, len); - buf[len] = '\0'; /* Null terminate */ - printf("Payload: %s\n", buf); + 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) { - printf("MQTT client initialization stub\n"); - printf("This is a placeholder for the actual MQTT client implementation\n"); - printf("The real implementation would connect to the broker at %s:%d\n", - MQTT_HOST, MQTT_PORT); - - /* In a real implementation, we would: - * 1. Initialize network connection - * 2. Establish TLS connection - * 3. Connect to MQTT broker - * 4. Subscribe to topics - * 5. Publish messages - * 6. Process incoming messages - */ - - return 0; + 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 index 043ebe6f..de3b5bc0 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.h +++ b/fullstack/freertos-wolfip-wolfmqtt/src/mqtt_client.h @@ -22,6 +22,13 @@ #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 @@ -31,7 +38,20 @@ #define MQTT_KEEP_ALIVE_SEC 60 #define MQTT_DEFAULT_CMD_TIMEOUT_MS 30000 -/* Initialize MQTT client */ +/* 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/wolfmqtt_stub.c b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.c index 55c42530..2f634859 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.c +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.c @@ -22,78 +22,133 @@ #include #include #include +#include +#include +#include #include "wolfmqtt_stub.h" +/* MQTT client context */ +static MqttClientContext mqttCtx; + /* Initialize MQTT client */ -int MqttClient_Init(MqttClient *client, MqttNet *net, MqttMsgCb msg_cb, - byte *tx_buf, int tx_buf_len, byte *rx_buf, int rx_buf_len, - int cmd_timeout_ms) +int mqtt_client_init(void) { - printf("MqttClient_Init stub called\n"); - (void)client; - (void)net; - (void)msg_cb; - (void)tx_buf; - (void)tx_buf_len; - (void)rx_buf; - (void)rx_buf_len; - (void)cmd_timeout_ms; - return MQTT_CODE_SUCCESS; -} - -/* Connect to MQTT broker */ -int MqttClient_Connect(MqttClient *client, MqttConnect *connect) -{ - printf("MqttClient_Connect stub called\n"); - printf(" Client ID: %s\n", connect->client_id); - printf(" Keep Alive: %d seconds\n", connect->keep_alive_sec); - printf(" Clean Session: %d\n", connect->clean_session); - (void)client; - return MQTT_CODE_SUCCESS; -} - -/* Subscribe to MQTT topic */ -int MqttClient_Subscribe(MqttClient *client, MqttSubscribe *subscribe) -{ - printf("MqttClient_Subscribe stub called\n"); - printf(" Packet ID: %d\n", subscribe->packet_id); - printf(" Topic Count: %d\n", subscribe->topic_count); - for (int i = 0; i < subscribe->topic_count; i++) { - printf(" Topic %d: %s (QoS %d)\n", i, - subscribe->topics[i].topic_filter, - subscribe->topics[i].qos); + 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; } - (void)client; - return MQTT_CODE_SUCCESS; + + /* 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, MQTT_TLS_CA_CERT, NULL) != WOLFSSL_SUCCESS) { + printf("Failed to load CA certificate: %s\n", MQTT_TLS_CA_CERT); + wolfSSL_CTX_free(ctx); + return -1; + } + + /* Load client certificate */ + if (wolfSSL_CTX_use_certificate_file(ctx, MQTT_TLS_CLIENT_CERT, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { + printf("Failed to load client certificate: %s\n", MQTT_TLS_CLIENT_CERT); + wolfSSL_CTX_free(ctx); + return -1; + } + + /* Load client key */ + if (wolfSSL_CTX_use_PrivateKey_file(ctx, MQTT_TLS_CLIENT_KEY, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { + printf("Failed to load client key: %s\n", MQTT_TLS_CLIENT_KEY); + 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; } -/* Publish MQTT message */ -int MqttClient_Publish(MqttClient *client, MqttPublish *publish) +/* Cleanup MQTT client */ +int mqtt_client_cleanup(void) { - printf("MqttClient_Publish stub called\n"); - printf(" Packet ID: %d\n", publish->packet_id); - printf(" Topic: %s\n", publish->topic_name); - printf(" QoS: %d\n", publish->qos); - printf(" Retain: %d\n", publish->retain); - printf(" Duplicate: %d\n", publish->duplicate); - printf(" Message: %.*s\n", (int)publish->total_len, publish->buffer); - (void)client; - return MQTT_CODE_SUCCESS; + 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; } -/* Wait for MQTT message */ -int MqttClient_WaitMessage(MqttClient *client, int timeout_ms) +/* Get MQTT client context */ +MqttClientContext* mqtt_client_get_context(void) { - (void)client; - (void)timeout_ms; - /* Simulate timeout */ - return MQTT_CODE_ERROR_TIMEOUT; + return &mqttCtx; } -/* Disconnect from MQTT broker */ -int MqttClient_Disconnect(MqttClient *client) +/* Process MQTT messages */ +int mqtt_client_process_message(void) { - printf("MqttClient_Disconnect stub called\n"); - (void)client; - return MQTT_CODE_SUCCESS; + 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 index a1f5a600..451f31b9 100644 --- a/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.h +++ b/fullstack/freertos-wolfip-wolfmqtt/src/wolfmqtt_stub.h @@ -22,90 +22,36 @@ #ifndef WOLFMQTT_STUB_H #define WOLFMQTT_STUB_H -#include +#include +#include +#include +#include +#include "../include/mqtt_config.h" -/* Basic types */ -typedef unsigned char byte; -typedef uint16_t word16; -typedef uint32_t word32; +/* Buffer sizes */ +#define MAX_BUFFER_SIZE 1024 +#define PRINT_BUFFER_SIZE 80 -/* Return codes */ +/* 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 */ -typedef struct _MqttClient { - void *ctx; -} MqttClient; - -/* MQTT Message */ -typedef struct _MqttMessage { - const char *topic_name; - uint16_t topic_name_len; - byte qos; - uint32_t total_len; - byte *buffer; - uint32_t buffer_len; -} MqttMessage; - -/* MQTT Connect */ -typedef struct _MqttConnect { - const char *client_id; - uint16_t keep_alive_sec; - byte clean_session; -} MqttConnect; - -/* MQTT Topic */ -typedef struct _MqttTopic { - const char *topic_filter; - byte qos; -} MqttTopic; - -/* MQTT Subscribe */ -typedef struct _MqttSubscribe { - uint16_t packet_id; - uint16_t topic_count; - MqttTopic *topics; -} MqttSubscribe; - -/* MQTT Publish */ -typedef struct _MqttPublish { - uint16_t packet_id; - const char *topic_name; - byte *buffer; - uint32_t total_len; - byte qos; - byte retain; - byte duplicate; -} MqttPublish; - -/* MQTT Network Callbacks */ -typedef int (*MqttNetConnectCb)(void *context, const char *host, word16 port, int timeout_ms); -typedef int (*MqttNetReadCb)(void *context, byte *buf, int buf_len, int timeout_ms); -typedef int (*MqttNetWriteCb)(void *context, const byte *buf, int buf_len, int timeout_ms); -typedef int (*MqttNetDisconnectCb)(void *context); - -/* MQTT Network */ -typedef struct _MqttNet { - void *context; - MqttNetConnectCb connect; - MqttNetReadCb read; - MqttNetWriteCb write; - MqttNetDisconnectCb disconnect; -} MqttNet; - -/* MQTT Message Callback */ -typedef int (*MqttMsgCb)(MqttClient *client, MqttMessage *msg, byte msg_new, byte msg_done); +/* 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 MqttClient_Init(MqttClient *client, MqttNet *net, MqttMsgCb msg_cb, - byte *tx_buf, int tx_buf_len, byte *rx_buf, int rx_buf_len, - int cmd_timeout_ms); -int MqttClient_Connect(MqttClient *client, MqttConnect *connect); -int MqttClient_Subscribe(MqttClient *client, MqttSubscribe *subscribe); -int MqttClient_Publish(MqttClient *client, MqttPublish *publish); -int MqttClient_WaitMessage(MqttClient *client, int timeout_ms); -int MqttClient_Disconnect(MqttClient *client); +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 */