This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC3235SF: CC3235SF – MQTT connect fails (-2023) after AP → STA switch, works in direct STA mode

Part Number: LAUNCHXL-CC3235SF
Other Parts Discussed in Thread: CC3235SF, SYSBIOS

Tool/software:

I am working on a CC3235SF application using TI SimpleLink SDK 7.10.00.13 and TI-RTOS7.
The device performs AP provisioning via an HTTP server, then switches to STA mode and should connect to a local MQTT broker at 192.168.0.50:1883.

Workflow:

  1. On first boot, device starts in AP mode (SmartPi-Config SSID), accepts Wi-Fi + MQTT broker details over HTTP POST, saves them to flash.

  2. Device switches to STA mode, connects to given Wi-Fi SSID.

  3. After STA IP is acquired, device calls MqttClient_ConnectToLocalBroker() using the stored broker IP and port.

  4. Local broker sends AWS endpoint + certs back to device.

  5. Device then connects to AWS MQTT broker over TLS.

Problem:

  • When device connects to broker immediately after AP → STA switch, MQTTClient_connect() fails with error -2023 (“Unknown MQTT error”).

  • Raspberry Pi Mosquitto logs show:

    pgsql
    CopyEdit
    New connection from 192.168.0.77 on port 1883. Socket error on client <unknown>, disconnecting.
  • If I flash TI’s default mqtt_client_app.c example in STA mode (with static config), connection works fine to the same broker.

  • My ESP32 implementation with the same broker works perfectly.

  • So broker side is confirmed working.

Code details:

  • I am using TI’s native MQTTClient_* API (not MQTT_IF).

  • Before MQTTClient_connect(), I do a TCP connectivity test to ensure broker IP/port is reachable — that passes.

  • Client ID is generated from MAC address, e.g. CC3235SF_7C5701010000.

  • No TLS for local broker (plain TCP).

  • SDK: SimpleLink CC32xx 7.10.00.13, Toolchain: GCC 9.2.1, Board: CC3235SF-LAUNCHXL.

Observation:

  • If I reboot the device and start directly in STA mode (bypassing AP mode), MQTT connects successfully.

  • The problem appears only on first run after AP → STA switch without reboot.

Questions:

  1. Is there a required cleanup/reset step after AP → STA mode before starting MQTTClient_connect()?

  2. Could NWP sockets from AP mode be interfering with the MQTT connection?

  3. Any recommended sequence to reliably start MQTT immediately after switching modes?

Logs (failing case):  

Application Started
Device MAC Address: 645801010000
[NETAPP EVENT] IP Acquired
Satellite No configuration found. Starting in AP mode.
[NETAPP EVENT] IP Acquired
Device in AP mode. SSID: SmartPi-Config, IP: 192.168.4.1, Port: 5000
[HTTP POST] Received data: {"wifi_password":"Macb00k@20","wifi_ssid":"IOT_WiFi"}
[HTTP POST] Received data: {"host_addr":"192.168.0.50","keepalive":60,"port":188 3,"qos":2}
[HTTP POST] Received data: {"node_data":"gateway:1\nnode:s\npoint:s"}
White check mark Provisioning complete. Saving configuration...
Configuration file saved.
Satellite Device is configured. Switching to STA mode...
Satellite Switching device to STA mode...
White check mark Wi-Fi profile added for SSID: IOT_WiFi
White check mark Device restarted in STA mode.
Hourglass Waiting for IP from router...
[WLAN EVENT] STA Connected to AP
[NETAPP EVENT] IP Acquired
White check mark Got IP: 192.168.0.77
White check mark Got STA IP: 192.168.0.77
[MQTT] White check mark MQTT client init (native API)
[MQTT] Id MAC-based Client ID: clientId3403de5bb8d
Satellite Connecting to local MQTT broker...
[MQTT] Mag Testing network connectivity to 192.168.0.50:1883...
[MQTT] White check mark Using static IP: 192.168.0.50 -> 192.168.0.50
[MQTT] Link Attempting TCP connection...
[MQTT] White check mark TCP connection successful
[MQTT] Id MAC-based Client ID: clientId3403de5bb8d
[MQTT] Id Using Client ID: clientId3403de5bb8d
[MQTT] Lock Security: Plain TCP (no TLS)
[MQTT] Satellite Creating MQTT client...
[MQTT] Satellite Connecting to broker...
[MQTT] X Connection failed: Unknown MQTT error (-2023)
[MQTT] Electric plug Disconnected and deleted client
X Failed to connect to local broker.
[MQTT] X No active MQTT connection

 this is my code:  

/*
* mqtt_client_app.c – Enhanced TI MQTT Client Implementation
 * White check mark Fixed static IP parsing for CC3235SF (no byte swap bug)
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <ti/net/mqtt/mqttclient.h>
#include <ti/drivers/net/wifi/simplelink.h>
#include "uart_term.h"
#include "app_config.h"

// AWS cert filenames stored in CC3235SF flash
#define AWS_ROOT_CA_FILENAME "/certs/aws_ca.pem"
#define AWS_CLIENT_CERT_FILENAME "/certs/aws_client.pem"
#define AWS_PRIVATE_KEY_FILENAME "/certs/aws_key.pem"

// MQTT Client configuration
#define MQTT_CLIENT_USERNAME NULL
#define MQTT_CLIENT_PASSWORD NULL
#define MQTT_KEEP_ALIVE_SEC 60
#define MQTT_CLEAN_SESSION true

// Global MQTT Client handle
MQTTClient_Handle g_mqttClient = NULL;
int g_switchToAws = 0;

char g_awsCaCertBuf[2048];
char g_awsClientCertBuf[2048];
char g_awsClientKeyBuf[2048];

char ClientId[32] = {0};


// Optional topics
char record_topic_buf[128];
char transmit_topic_buf[128];
char factory_reset_topic_buf[128];

/* ================= Error Strings ================= */
const char* getMqttErrorString(int32_t errorCode)
{
switch(errorCode) {
case MQTTCLIENT_ERR_FNPARAM: return "Invalid function parameter";
case MQTTCLIENT_ERR_NETWORK: return "Network error";
case MQTTCLIENT_ERR_PKT_AVL: return "Packet availability error";
case MQTTCLIENT_ERR_TIMEOUT: return "Operation timeout";
case MQTTCLIENT_ERR_BADCALL: return "Invalid function call";
case MQTTCLIENT_ERR_CONTENT: return "Content error";
case MQTTCLIENT_ERR_NOTCONN: return "Not connected";
default:
return (errorCode < 0) ? "Unknown MQTT error" : "Operation successful";
}
}

/* ================= FIXED: Network Connectivity Test ================= */
int32_t testNetworkConnectivity(const char* serverAddr, uint16_t port)
{
SlSockAddrIn_t addr;
int16_t sockId;
int32_t status;

UART_PRINT("[MQTT] Mag Testing network connectivity to %s:%d...\n\r", serverAddr, port);

sockId = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0);
if (sockId < 0) {
 UART_PRINT("[MQTT] X Failed to create socket (error: %d)\n\r", sockId);
return -1;
}

addr.sin_family = SL_AF_INET;
addr.sin_port = sl_Htons(port);

unsigned long resolvedIP;

/* White check mark FIX: If serverAddr is already an IPv4 address, parse it manually */
if (isdigit((unsigned char)serverAddr[0])) {
unsigned int b1, b2, b3, b4;
sscanf(serverAddr, "%u.%u.%u.%u", &b1, &b2, &b3, &b4);
resolvedIP = sl_Htonl(SL_IPV4_VAL(b1, b2, b3, b4));
 UART_PRINT("[MQTT] White check mark Using static IP: %s -> %u.%u.%u.%u\n\r",
serverAddr, b1, b2, b3, b4);
} else {
// Resolve hostname via DNS
status = sl_NetAppDnsGetHostByName((signed char*)serverAddr,
strlen(serverAddr),
&resolvedIP, SL_AF_INET);
if (status < 0) {
 UART_PRINT("[MQTT] X DNS resolution failed for %s (err: %d)\n\r",
serverAddr, status);
sl_Close(sockId);
return -1;
}
}

addr.sin_addr.s_addr = resolvedIP;

// Timeout options
struct SlTimeval_t timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
sl_SetSockOpt(sockId, SL_SOL_SOCKET, SL_SO_RCVTIMEO, &timeout, sizeof(timeout));
sl_SetSockOpt(sockId, SL_SOL_SOCKET, SL_SO_SNDTIMEO, &timeout, sizeof(timeout));

UART_PRINT("[MQTT] Link Attempting TCP connection...\n\r");

status = sl_Connect(sockId, (SlSockAddr_t*)&addr, sizeof(SlSockAddrIn_t));
if (status < 0) {
 UART_PRINT("[MQTT] X TCP connection failed (error: %d)\n\r", status);
 if (status == -111) UART_PRINT("[MQTT] Mag ECONNREFUSED: Broker refused connection\n\r");
sl_Close(sockId);
return -1;
}

UART_PRINT("[MQTT] White check mark TCP connection successful\n\r");
sl_Close(sockId);
return 0;
}

/* ================= MQTT Callback ================= */
void mqttClientCb(int32_t event, void *metaData, uint32_t metaDataLen,
void *data, uint32_t dataLen)
{
switch(event) {
case MQTTClient_OPERATION_CB_EVENT:
 UART_PRINT("[MQTT] Inbox tray Operation callback received\n\r");
break;
case MQTTClient_RECV_CB_EVENT:
 UART_PRINT("[MQTT] Envelope with arrow Message received: %.*s\n\r", dataLen, (char*)data);
break;
case MQTTClient_DISCONNECT_CB_EVENT:
 UART_PRINT("[MQTT] Warning Disconnected from broker\n\r");
break;
default:
UART_PRINT("[MQTT] Unknown event: %d\n\r", event);
break;
}
}

/* ================= Disconnect Helper ================= */
void MqttClient_Disconnect(void)
{
if (g_mqttClient) {
MQTTClient_disconnect(g_mqttClient);
MQTTClient_delete(g_mqttClient);
g_mqttClient = NULL;
 UART_PRINT("[MQTT] Electric plug Disconnected and deleted client\n\r");
}
}

/* ================= Init ================= */
void MqttClient_Init(void)
{
 UART_PRINT("[MQTT] White check mark MQTT client init (native API)\n\r");
}
/* ================= Test MQTT Publish ================= */
int32_t MqttClient_Publish(const char* topic, const char* payload, int qos)
{
if (!g_mqttClient) {
 UART_PRINT("[MQTT] X No active MQTT connection\n\r");
return -1;
}

UART_PRINT("[MQTT] Outbox tray Publishing to '%s': %s\n\r", topic, payload);

int32_t rc = MQTTClient_publish(g_mqttClient,
(char*)topic, strlen(topic),
(char*)payload, strlen(payload),
0); // QoS0 only
if (rc < 0) {
 UART_PRINT("[MQTT] X Publish failed (code %d)\n\r", rc);
return rc;
}

UART_PRINT("[MQTT] White check mark Publish OK\n\r");
return 0;
}
int32_t SetClientIdNamefromMacAddress(void)
{
 _u16 macAddressLen = SL_MAC_ADDR_LEN; // White check mark correct type for sl_NetCfgGet
_u8 macAddress[SL_MAC_ADDR_LEN];

int32_t ret = sl_NetCfgGet(SL_NETCFG_MAC_ADDRESS_GET, NULL, &macAddressLen, macAddress);
if (ret < 0) {
 UART_PRINT("[MQTT] X Failed to get MAC address (error %d)\n\r", ret);
return -1;
}

snprintf(g_macAddressStr, 20, "clientId%02x%02x%02x%02x%02x%02x",
macAddress[0], macAddress[1], macAddress[2],
macAddress[3], macAddress[4], macAddress[5]);

UART_PRINT("[MQTT] Id MAC-based Client ID: %s\n\r", g_macAddressStr);
return 0;
}


/* ================= Connect to Local MQTT Broker - MINIMAL FIX ================= */
int32_t MqttClient_ConnectToLocalBroker(void)
{
MqttClient_Disconnect(); // safety

if (testNetworkConnectivity(g_appConfig.local_mqtt_host, g_appConfig.local_mqtt_port) < 0) {
 UART_PRINT("[MQTT] X Network connectivity test failed\n\r");
return -1;
}

MQTTClient_Params clientParams;
MQTTClient_ConnParams connParams;

memset(&clientParams, 0, sizeof(clientParams));
memset(&connParams, 0, sizeof(connParams));


static char forcedClientId[32];
if (SetClientIdNamefromMacAddress() == 0) {
snprintf(forcedClientId, sizeof(forcedClientId), "%s", g_macAddressStr);
} else {
strcpy(forcedClientId, "clientIdDefault");
}
 UART_PRINT("[MQTT] Id Using Client ID: %s\n\r", forcedClientId);

clientParams.clientId = forcedClientId;

clientParams.blockingSend = true;
clientParams.connParams = &connParams;

// White check mark Force MQTT protocol to 3.1.1 (Mosquitto default)
// clientParams.mqttVersion = MQTT_3_1_1;

// White check mark Connection parameters
connParams.serverAddr = g_appConfig.local_mqtt_host;
connParams.port = g_appConfig.local_mqtt_port;
connParams.netconnFlags = MQTTCLIENT_NETCONN_IP4; // IPv4 only
connParams.nFiles = 0;
connParams.secureFiles = NULL;

UART_PRINT("[MQTT] Lock Security: Plain TCP (no TLS)\n\r");

UART_PRINT("[MQTT] Satellite Creating MQTT client...\n\r");
g_mqttClient = MQTTClient_create(mqttClientCb, &clientParams);
if (!g_mqttClient) {
 UART_PRINT("[MQTT] X MQTTClient_create failed\n\r");
return -1;
}

UART_PRINT("[MQTT] Satellite Connecting to broker...\n\r");
int32_t rc = MQTTClient_connect(g_mqttClient);
if (rc < 0) {
 UART_PRINT("[MQTT] X Connection failed: %s (%d)\n\r",
getMqttErrorString(rc), rc);
MqttClient_Disconnect();
return rc;
}

UART_PRINT("[MQTT] White check mark Connected to local broker\n\r");
return 0;
}

/* ================= Test MQTT Publish ================= */
/*int32_t MqttClient_TestPublish(void)
{
if (!g_mqttClient) {
 UART_PRINT("[MQTT] X No active MQTT connection\n\r");
return -1;
}

const char* topic = "test/connection";
const char* message = "Hello from CC3235SF!";
 UART_PRINT("[MQTT] Outbox tray Publishing to '%s'\n\r", topic);
int32_t rc = MQTTClient_publish(g_mqttClient, (char*)topic, strlen(topic),
(char*)message, strlen(message), 0);
if (rc < 0) {
 UART_PRINT("[MQTT] X Publish failed: %s (%d)\n\r", getMqttErrorString(rc), rc);
return rc;
}
 UART_PRINT("[MQTT] White check mark Test message published successfully\n\r");
return 0;
} */

/* ================= Subscribe to Topic ================= */
int32_t MqttClient_Subscribe(const char* topic)
{
if (!g_mqttClient) {
 UART_PRINT("[MQTT] X No active MQTT connection\n\r");
return -1;
}

UART_PRINT("[MQTT] Inbox tray Subscribing to topic: %s\n\r", topic);

MQTTClient_SubscribeParams subParams;
memset(&subParams, 0, sizeof(subParams));

subParams.topic = (char*)topic;
subParams.qos = MQTT_QOS_0;

int32_t rc = MQTTClient_subscribe(g_mqttClient, &subParams, 1);
if (rc < 0) {
 UART_PRINT("[MQTT] X Subscribe failed: %s (code %d)\n\r", getMqttErrorString(rc), rc);
return rc;
}

UART_PRINT("[MQTT] White check mark Successfully subscribed to %s\n\r", topic);
return 0;
}

/* ================= Connect to AWS MQTT Broker ================= */
int32_t MqttClient_ConnectToAws(void)
{
MqttClient_Disconnect();

// Save certs received via local broker
sl_FsDel((unsigned char *)AWS_ROOT_CA_FILENAME, 0);
sl_FsDel((unsigned char *)AWS_CLIENT_CERT_FILENAME, 0);
sl_FsDel((unsigned char *)AWS_PRIVATE_KEY_FILENAME, 0);

UART_PRINT("[MQTT] Page facing up AWS certs prepared.\n\r");

MQTTClient_Params clientParams;
MQTTClient_ConnParams connParams;
memset(&clientParams, 0, sizeof(clientParams));
memset(&connParams, 0, sizeof(connParams));

clientParams.clientId = g_macAddressStr;
clientParams.blockingSend = true;
clientParams.connParams = &connParams;

connParams.serverAddr = "a2y0oc86fl7cm.iot.us-east-2.amazonaws.com"; // Change to your AWS endpoint
connParams.port = 8883;
connParams.netconnFlags = MQTTCLIENT_NETCONN_URL | MQTTCLIENT_NETCONN_SEC;

// Secure files
static char *secureFiles[] = {
(char*)AWS_PRIVATE_KEY_FILENAME,
(char*)AWS_CLIENT_CERT_FILENAME,
(char*)AWS_ROOT_CA_FILENAME,
NULL
};

connParams.nFiles = 3;
connParams.secureFiles = secureFiles;

UART_PRINT("[MQTT] Lock Connecting to AWS MQTT Broker...\n\r");

g_mqttClient = MQTTClient_create(mqttClientCb, &clientParams);
if (!g_mqttClient) {
 UART_PRINT("[MQTT] X MQTTClient_create failed for AWS\n\r");
return -1;
}

int32_t rc = MQTTClient_connect(g_mqttClient);
if (rc < 0) {
 UART_PRINT("[MQTT] X AWS connect failed: %s (code %d)\n\r", getMqttErrorString(rc), rc);
MqttClient_Disconnect();
return rc;
}

UART_PRINT("[MQTT] White check mark Connected to AWS MQTT broker\n\r");
return 0;
}   

provisioning:   

// provisioning.c

/* Standard Includes */
#include <mqtt_client_app.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

/* TI-DRIVERS Header files */
#include <ti/drivers/net/wifi/simplelink.h>
#include <ti/drivers/SPI.h>
#include <ti/drivers/GPIO.h>
#include <uart_term.h>
#include <ti/net/slnetif.h>
#include <ti/net/slnetsock.h>
#include <ti/net/slnetutils.h>

/* Custom Application Includes */
#include "app_config.h"
#include "ir_app.h"
#include "cJSON.h"

/* TI-RTOS Headers */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/hal/Seconds.h>

//#include "ifmod/mqtt_if.h"
//#include "ifmod/debug_if.h"
//#include "ifmod/uart_if.h"
//#include "ifmod/wifi_if.h"
//#include "ifmod/mqtt_if.h"
//#include "ifmod/debug_if.h"
//#include "ifmod/ota_if.h"
//#include "ifmod/utils_if.h"
//#include "ifmod/ota_vendors.h"


#define SPAWN_TASK_PRIORITY (9)
// *** CRITICAL FIX #1: Increased stack size for tasks that use networking libraries ***
#define TASK_STACK_SIZE (8192)
#define SL_STOP_TIMEOUT (200)

#define LOG_MESSAGE UART_PRINT

/* Global Variables */
AppConfig_t g_appConfig;
/* ============================================================================
* GLOBAL VARIABLES
* ============================================================================ */
char g_macAddressStr[13] = {0}; // Global MAC address (12 hex chars + null)


// Flag to signal completion from the event handler to the main thread
volatile uint8_t g_isProvisioningComplete = 0;


/* Forward Declarations */
void *mainApplicationThread(void *arg);
int32_t startApMode(void);
int32_t connectAsSta(void);
int32_t saveConfiguration(void);
int32_t loadConfiguration(void);

//=============================================================================
// SimpleLink Event Handlers
//=============================================================================
void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) {
if(!pWlanEvent) return;
if(pWlanEvent->Id == SL_WLAN_EVENT_CONNECT) {
LOG_MESSAGE("[WLAN EVENT] STA Connected to AP\n\r");
} else if (pWlanEvent->Id == SL_WLAN_EVENT_DISCONNECT) {
LOG_MESSAGE("[WLAN EVENT] STA Disconnected from AP\n\r");
}
}
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) {
if(pNetAppEvent && pNetAppEvent->Id == SL_NETAPP_EVENT_IPV4_ACQUIRED) {
LOG_MESSAGE("[NETAPP EVENT] IP Acquired\n\r");
}
}
void SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t *p, SlNetAppHttpServerResponse_t *r) {}
void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) {}
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) {}
void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent) {}
void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer) {}

void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest, SlNetAppResponse_t *pNetAppResponse)
{
if (pNetAppRequest->Type == SL_NETAPP_REQUEST_HTTP_POST && pNetAppRequest->requestData.PayloadLen > 0)
{
char* bodyCopy = (char*)malloc(pNetAppRequest->requestData.PayloadLen + 1);
if (bodyCopy)
{
memcpy(bodyCopy, pNetAppRequest->requestData.pPayload, pNetAppRequest->requestData.PayloadLen);
bodyCopy[pNetAppRequest->requestData.PayloadLen] = '\0';

cJSON *root = cJSON_Parse(bodyCopy);
if (root) {
LOG_MESSAGE("[HTTP POST] Received data: %s\n\r", bodyCopy);
if (cJSON_GetObjectItem(root, "wifi_ssid")) {
strncpy(g_appConfig.wifi_ssid, cJSON_GetObjectItem(root, "wifi_ssid")->valuestring, sizeof(g_appConfig.wifi_ssid) - 1);
strncpy(g_appConfig.wifi_password, cJSON_GetObjectItem(root, "wifi_password")->valuestring, sizeof(g_appConfig.wifi_password) - 1);
} else if (cJSON_GetObjectItem(root, "host_addr")) {
strncpy(g_appConfig.local_mqtt_host, cJSON_GetObjectItem(root, "host_addr")->valuestring, sizeof(g_appConfig.local_mqtt_host) - 1);
g_appConfig.local_mqtt_port = cJSON_GetObjectItem(root, "port")->valueint;
} else if (cJSON_GetObjectItem(root, "node_data")) {
g_isProvisioningComplete = 1;
}
cJSON_Delete(root);
}
free(bodyCopy);
}
}
sl_NetAppSend(pNetAppRequest->Handle, 0, NULL, SL_NETAPP_HTTP_RESPONSE_200_OK);
}

//=============================================================================
// Helper Functions
//=============================================================================
int32_t startApMode(void) {
sl_WlanSetMode(ROLE_AP);

uint8_t sec_type = SL_WLAN_SEC_TYPE_WPA_WPA2;
sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_SSID, strlen(AP_SSID_PREFIX), (unsigned char*)AP_SSID_PREFIX);
sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_SECURITY_TYPE, 1, &sec_type);
sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_PASSWORD, strlen(AP_PASSWORD), (unsigned char*)AP_PASSWORD);

SlNetCfgIpV4Args_t ipV4;
ipV4.Ip = SL_IPV4_VAL(192, 168, 4, 1);
ipV4.IpMask = SL_IPV4_VAL(255, 255, 255, 0);
ipV4.IpGateway = SL_IPV4_VAL(192, 168, 4, 1);
ipV4.IpDnsServer = SL_IPV4_VAL(0,0,0,0);
sl_NetCfgSet(SL_NETCFG_IPV4_AP_ADDR_MODE, SL_NETCFG_ADDR_STATIC, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4);

sl_Stop(SL_STOP_TIMEOUT);
sl_Start(NULL, NULL, NULL);

SlNetAppDhcpServerBasicOpt_t dhcp_server_info;
dhcp_server_info.lease_time = 3600;
dhcp_server_info.ipv4_addr_start = SL_IPV4_VAL(192, 168, 4, 100);
dhcp_server_info.ipv4_addr_last = SL_IPV4_VAL(192, 168, 4, 110);
sl_NetAppSet(SL_NETAPP_DHCP_SERVER_ID, SL_NETAPP_DHCP_SRV_BASIC_OPT, sizeof(dhcp_server_info), (_u8*)&dhcp_server_info);

sl_NetAppStart(SL_NETAPP_HTTP_SERVER_ID | SL_NETAPP_DHCP_SERVER_ID);

uint16_t port = 5000;
sl_NetAppSet(SL_NETAPP_HTTP_SERVER_ID, SL_NETAPP_HTTP_PRIMARY_PORT_NUMBER, sizeof(port), (uint8_t *)&port);

LOG_MESSAGE("Device in AP mode. SSID: %s, IP: 192.168.4.1, Port: 5000\n\r", AP_SSID_PREFIX);
return 0;
}

int32_t connectAsSta(void)
{
int32_t ret;
_i32 role;
_u16 len;
_u16 configOpt;
SlNetCfgIpV4Args_t ipV4 = {0};

LOG_MESSAGE("Satellite Switching device to STA mode...\n\r");

// 1️⃣ Stop HTTP & DHCP servers (cleanup AP)
sl_NetAppStop(SL_NETAPP_HTTP_SERVER_ID | SL_NETAPP_DHCP_SERVER_ID);

// 2️⃣ Set the mode to STA BEFORE stopping the network processor
ret = sl_WlanSetMode(ROLE_STA);
if (ret < 0) {
 LOG_MESSAGE("X Error setting STA mode: %ld\n\r", ret);
return ret;
}

// 3️⃣ Add Wi-Fi credentials to profiles
SlWlanSecParams_t secParams = {0};
secParams.Key = (_i8*)g_appConfig.wifi_password;
secParams.KeyLen = strlen(g_appConfig.wifi_password);
secParams.Type = SL_WLAN_SEC_TYPE_WPA_WPA2;

// Remove all old profiles (optional but avoids wrong AP reconnects)
sl_WlanProfileDel(0xFF);

ret = sl_WlanProfileAdd((_i8*)g_appConfig.wifi_ssid,
strlen(g_appConfig.wifi_ssid),
0, // no BSSID
&secParams,
NULL,
1, // priority
0);
if (ret < 0) {
 LOG_MESSAGE("X Failed to add Wi-Fi profile: %ld\n\r", ret);
return ret;
}

LOG_MESSAGE("White check mark Wi-Fi profile added for SSID: %s\n\r", g_appConfig.wifi_ssid);

// 4️⃣ Restart the network processor so STA mode takes effect
sl_Stop(SL_STOP_TIMEOUT);
sleep(1); // allow hardware settle time

// Satellite sl_Start() return value = current role
role = sl_Start(NULL, NULL, NULL);

if (role != ROLE_STA) {
 LOG_MESSAGE("X Device did NOT switch to STA mode (role=%ld)\n\r", role);
return -1;
}
 LOG_MESSAGE("White check mark Device restarted in STA mode.\n\r");

// 5️⃣ Wait for IP address (DHCP)
 LOG_MESSAGE("Hourglass Waiting for IP from router...\n\r");
len = sizeof(SlNetCfgIpV4Args_t);
configOpt = 0;

int retries = 0;
while (ipV4.Ip == 0 && retries < 30) {
sl_NetCfgGet(SL_NETCFG_IPV4_STA_ADDR_MODE,
&configOpt,
&len,
(_u8*)&ipV4);
sleep(1);
retries++;
}

if (ipV4.Ip == 0) {
 LOG_MESSAGE("X Failed to get IP address after 30 seconds.\n\r");
return -1;
}

LOG_MESSAGE("White check mark Got IP: %d.%d.%d.%d\n\r",
SL_IPV4_BYTE(ipV4.Ip, 3),
SL_IPV4_BYTE(ipV4.Ip, 2),
SL_IPV4_BYTE(ipV4.Ip, 1),
SL_IPV4_BYTE(ipV4.Ip, 0));

return 0;
}

int32_t saveConfiguration() {
long fileHandle = sl_FsOpen((unsigned char *)CONFIG_FILENAME, SL_FS_CREATE | SL_FS_OVERWRITE | SL_FS_CREATE_MAX_SIZE(sizeof(AppConfig_t)), 0);
sl_FsWrite(fileHandle, 0, (unsigned char *)&g_appConfig, sizeof(AppConfig_t));
sl_FsClose(fileHandle, 0, 0, 0);
LOG_MESSAGE("Configuration file saved.\n\r");
return 0;
}
int32_t loadConfiguration() {
long fileHandle = sl_FsOpen((unsigned char *)CONFIG_FILENAME, SL_FS_READ, 0);
if (fileHandle < 0) return -1;
sl_FsRead(fileHandle, 0, (unsigned char *)&g_appConfig, sizeof(AppConfig_t));
sl_FsClose(fileHandle, 0, 0, 0);
LOG_MESSAGE("Configuration file loaded.\n\r");
return 0;
}

/* ============================================================================
* GET MAC ADDRESS
* ============================================================================ */
void getMacAddress(void)
{
uint16_t macAddressLen = SL_MAC_ADDR_LEN;
uint8_t macAddress[SL_MAC_ADDR_LEN];

// Get the device Mac address (requires sl_Task to be running)
sl_NetCfgGet(SL_NETCFG_MAC_ADDRESS_GET, 0, &macAddressLen, &macAddress[0]);

// Format the MAC into global string
snprintf(g_macAddressStr, sizeof(g_macAddressStr),
"%02X%02X%02X%02X%02X%02X",
macAddress[0], macAddress[1], macAddress[2],
macAddress[3], macAddress[4], macAddress[5]);

UART_PRINT("Device MAC Address: %s\n\r", g_macAddressStr);
}

/* ============================================================================
* MAIN APPLICATION THREAD
* ============================================================================ */
void *mainApplicationThread(void *arg)
{
/* 1️⃣ Start Wi-Fi */
sl_Start(NULL, NULL, NULL);
 UART_PRINT("White check mark SimpleLink Wi-Fi driver started\n\r");

/* 2️⃣ Init SlNet for MQTT & BSD Sockets */
SlNetIf_init(0);
SlNetSock_init(0);
SlNetUtil_init(0);
 UART_PRINT("White check mark SlNet layer initialized\n\r");

/* 3️⃣ Load Wi-Fi/MQTT config or start AP mode */
if (loadConfiguration() < 0) {
 UART_PRINT("Satellite No configuration found. Starting in AP mode.\n\r");
startApMode();

while (!g_isProvisioningComplete) {
sleep(1);
}

UART_PRINT("White check mark Provisioning complete. Saving configuration...\n\r");
saveConfiguration();
sleep(1);
}

/* 4️⃣ Switch to STA mode */
 UART_PRINT("Satellite Device is configured. Switching to STA mode...\n\r");
connectAsSta();

/* 5️⃣ Wait for STA IP */
_u16 len = sizeof(SlNetCfgIpV4Args_t);
_u16 configOpt = 0;
SlNetCfgIpV4Args_t ipV4 = {0};
int retries = 0;

while (ipV4.Ip == 0 && retries < 30) {
sl_NetCfgGet(SL_NETCFG_IPV4_STA_ADDR_MODE, &configOpt, &len, (_u8 *)&ipV4);
sleep(1);
retries++;
}

if (ipV4.Ip == 0) {
 UART_PRINT("X Failed to acquire an IP address.\n\r");
while (1); // Stop for debugging
}

UART_PRINT("White check mark Got STA IP: %d.%d.%d.%d\n\r",
SL_IPV4_BYTE(ipV4.Ip, 3),
SL_IPV4_BYTE(ipV4.Ip, 2),
SL_IPV4_BYTE(ipV4.Ip, 1),
SL_IPV4_BYTE(ipV4.Ip, 0));

/* 6️⃣ Init MQTT */
MqttClient_Init();

/* 7️⃣ Build and set Client ID */
if (SetClientIdNamefromMacAddress() != 0) {
 UART_PRINT("Warning️ Using default Client ID due to MAC fetch error\n\r");
strcpy(ClientId, "clientIdDefault");
}

/* 8️⃣ Connect to Local MQTT broker */
 UART_PRINT("Satellite Connecting to local MQTT broker...\n\r");
if (MqttClient_ConnectToLocalBroker() < 0) {
 UART_PRINT("X Failed to connect to local broker.\n\r");
} else {
 UART_PRINT("White check mark Local MQTT active.\n\r");
}

/* 9️⃣ Main loop */
while (1)
{
static uint32_t lastPublish = 0;
uint32_t currentTime = Seconds_get();

if (currentTime - lastPublish > 30) {
lastPublish = currentTime;
MqttClient_Publish("device/heartbeat", "{\"status\":\"online\"}", MQTT_QOS_0);
}

if (g_switchToAws) {
 UART_PRINT("Globe with meridians Switching to AWS MQTT...\n\r");
if (MqttClient_ConnectToAws() == 0) {
 UART_PRINT("White check mark AWS MQTT active.\n\r");
g_switchToAws = 0;
} else {
 UART_PRINT("X AWS MQTT connection failed. Retrying...\n\r");
sleep(10);
}
}

sleep(1);
}
}

/* ============================================================================
* MAIN ENTRY POINT
* ============================================================================ */
int main(void) {
pthread_t spawnThread = (pthread_t)NULL;
pthread_t appThread = (pthread_t)NULL;
pthread_attr_t pAttrs;
struct sched_param priParam;

GPIO_init();
SPI_init();
InitTerm();
UART_PRINT("Application Started\n\r");

/* Start sl_Task thread */
pthread_attr_init(&pAttrs);
priParam.sched_priority = SPAWN_TASK_PRIORITY;
pthread_attr_setschedparam(&pAttrs, &priParam);
pthread_attr_setstacksize(&pAttrs, TASK_STACK_SIZE);
pthread_create(&spawnThread, &pAttrs, sl_Task, NULL);

/* White check mark Read MAC Address now that SimpleLink driver is active */
getMacAddress();

/* Launch main application thread */
priParam.sched_priority = 1;
pthread_attr_setschedparam(&pAttrs, &priParam);
pthread_attr_setstacksize(&pAttrs, TASK_STACK_SIZE);
pthread_create(&appThread, &pAttrs, mainApplicationThread, NULL);

BIOS_start();
return 0;
}   

app_config:- 

#ifndef APP_CONFIG_H_
#define APP_CONFIG_H_

#include <ti/drivers/net/wifi/simplelink.h>
#include <ti/net/mqtt/mqttclient.h>
#include <pthread.h>

/* =================================================================
1. APPLICATION STATE AND EVENT TYPE DEFINITIONS
================================================================= */
typedef enum {
APP_STATE_INIT,
APP_STATE_AP_CONFIG_MODE,
APP_STATE_STA_CONNECTING,
APP_STATE_OPERATIONAL,
APP_STATE_ERROR
} AppState_e;

typedef enum {
AppEvent_STARTED,
AppEvent_CONNECTED,
AppEvent_IP_ACQUIRED,
AppEvent_DISCONNECT,
AppEvent_CONFIG_FOUND,
AppEvent_CONFIG_NOT_FOUND,
AppEvent_PROVISIONING_STOPPED,
AppEvent_ERROR
} AppEvent;

/* =================================================================
2. CONFIGURATION STRUCT DEFINITION
================================================================= */
typedef struct {
char wifi_ssid[33]; // Wi-Fi SSID (up to 32 chars + null)
char wifi_password[65]; // Wi-Fi Password (up to 64 chars + null)
char local_mqtt_host[64]; // Local MQTT broker IP/hostname
uint16_t local_mqtt_port; // Local MQTT broker port
char node_gateway[33]; // Node gateway identifier
int node_id; // Node ID for device identification
} AppConfig_t;

/* =================================================================
3. SHARED GLOBAL VARIABLES (extern)
================================================================= */
extern volatile AppState_e g_CurrentState; // Current application state
extern AppConfig_t g_appConfig; // Global application configuration
extern MQTTClient_Handle g_mqttClient; // MQTT client handle
extern char g_macAddressStr[]; // Device MAC address (string)
extern uint8_t g_macAddress[6];
extern int g_switchToAws; // Flag to trigger AWS MQTT switch

/* =================================================================
4. SHARED FUNCTION DECLARATIONS (extern)
================================================================= */
extern int16_t SignalEvent(AppEvent event); // Event signaling
extern int32_t MqttClient_ConnectToAws(void); // Connect to AWS MQTT
extern void MqttClient_Init(void); // Initialize MQTT client
extern char ClientId[32];
extern int32_t SetClientIdNamefromMacAddress(void);


/* =================================================================
5. FILESYSTEM AND CONSTANT DEFINES
================================================================= */
#define CONFIG_FILENAME "/config.cfg"
#define AWS_ROOT_CA_FILENAME "/certs/aws_ca.pem"
#define AWS_CLIENT_CERT_FILENAME "/certs/aws_client.pem"
#define AWS_PRIVATE_KEY_FILENAME "/certs/aws_key.pem"

#define AP_SSID_PREFIX "SmartPi-Config" // AP mode SSID prefix
#define AP_PASSWORD "12345678" // AP mode password

#define MQTT_TOPIC_MAX_LEN 64
#define AWS_MQTT_URL "your-aws-endpoint.amazonaws.com"

#endif /* APP_CONFIG_H_ */

  • Hi Thanuj,

    For your first question, switching modes requires a reset as stated in the Network Processor Manual. You can find additional details regarding your question on page 45. 

    I will provide updates to other questions by next Tuesday if the answer to the first question doesn't cover everything.

    Thank you.

  • Hi Thanuj,

    For your remaining questions, when you switch from AP mode to STA mode without reset, your NWP will attempt to act as an MQTT client as an access point. To properly start your MQTT connection as a client, please reset the NWP (the manual I previously sent includes code to reset the device) so that it properly switches from AP mode to STA mode. 

    I hope this helps.

  • Hi Brandon,

    Thanks for your detailed explanation earlier. I followed your suggestion and ensured that the NWP is reset during the AP → STA mode switch. The mode switching and STA connection seem to be working fine now (device acquires IP successfully on STA mode).

    However, I’m still running into an issue with MQTT connection. Below is the relevant log output:

    less
    CopyEdit
    [NWP] White check mark Successfully switched to STA mode (role=0) [WLAN] White check mark Got STA IP: 192.168.0.77 [MQTT] White check mark TCP connection successful [MQTT] Satellite Connecting to broker with MQTT 3.1.1... [MQTT] X Connection failed: Unknown MQTT error (-2023)

    The device retries, but the connection consistently fails with error -2023 even though the TCP socket connects successfully.

    Do you know what this error indicates in the context of the TI MQTT client? Is there something additional I should configure on the broker side (authentication, client ID, QoS, etc.) or on the device side before calling MQTTClient_connect?

    Thanks again for your support!

  • Hi Thanuj,

    Just out of curiosity, did you get this error when you "flash TI’s default mqtt_client_app.c example in STA mode (with static config)?" I know you said "connection works fine to the same broker."