/* * Copyright (c) 2016 Cesanta Software Limited * All rights reserved */ #include "app.h" #include "system/debug/sys_debug.h" #include "./../../../../../mongoose.h" #include "user_params.h" static struct mg_mgr mgr; static int msg_id; struct mg_mqtt_topic_expression topic_expressions[] = {{"/test", 0}}; APP_DATA appData; void APP_Initialize(void) { appData.state = APP_STATE_INIT; DRV_RTCC_Start(); mg_mgr_init(&mgr, NULL); } static void ev_handler(struct mg_connection *nc, int ev, void *p); void APP_Tasks(void) { /* * Processing CC3100 Tasks * It looks like SYS task and might be processed in SYS_Tasks * But for this demo it is here to make this call * visible */ _SlNonOsMainLoopTask(); /* Check the application's current state. */ switch (appData.state) { /* Application's initial state. */ case APP_STATE_INIT: { SYS_PRINT("\n\r*** PIC32 MQTT CLIENT ***\n\r"); SYS_PRINT("\n\rInitializing CC3100\n\r"); int res = sl_Start(NULL, NULL, NULL); if (res != 0) { SYS_PRINT("FAILED\n\r"); appData.state = APP_STATE_DONE; break; } SlSecParams_t sec_params; memset(&sec_params, 0, sizeof(sec_params)); sec_params.Key = NET_PWD; sec_params.KeyLen = sizeof(NET_PWD) - 1; sec_params.Type = NET_SECURITY; SYS_PRINT("Connecting to WiFi\n\r"); sl_WlanConnect(NET_SSID, sizeof(NET_SSID) - 1, 0, &sec_params, NULL); SYS_PRINT("Initialization done\n\r"); appData.state = APP_STATE_SERVICE_TASKS; break; } case APP_STATE_CONNECT_BROKER: { if (mg_connect(&mgr, MQTT_BROKER_ADDRESS, ev_handler) == NULL) { SYS_PRINT("Failed to create connection\n\r"); appData.state = APP_STATE_DONE; } else { appData.state = APP_STATE_SERVICE_TASKS; } break; } case APP_STATE_SERVICE_TASKS: { static uint32_t prev_poll_time = 0; uint32_t now = DRV_RTCC_TimeGet(); if (now - prev_poll_time > 100) { /* * We cannot call mg_mgr_poll every cycle * it leads to SPI overload (internaly mg_mgr_poll calls * CC3100 via SPI */ mg_mgr_poll(&mgr, 1); prev_poll_time = now; } break; } case APP_STATE_DONE: { /* Do nothing here */ break; } default: { /* TODO: Handle error in application's state machine. */ break; } } } void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) { switch (pWlanEvent->Event) { case SL_WLAN_CONNECT_EVENT: SYS_PRINT("Connected to WiFi\r\n"); break; case SL_WLAN_DISCONNECT_EVENT: SYS_PRINT("Disconnected WiFi\r\n"); break; default: SYS_PRINT("Got Wlan event %d\r\n", pWlanEvent->Event); break; } } void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) { switch (pNetAppEvent->Event) { case SL_NETAPP_IPV4_IPACQUIRED_EVENT: SYS_PRINT("Got IP\r\n"); appData.state = APP_STATE_CONNECT_BROKER; break; default: SYS_PRINT("Got NetApp Event: %d\r\n", pNetAppEvent->Event); break; } } static void ev_handler(struct mg_connection *nc, int ev, void *p) { struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p; static int count1 = 0; switch (ev) { case MG_EV_CONNECT: if (*(int *) p != 0) { SYS_PRINT("Failed to connect to %s\r\n", MQTT_BROKER_ADDRESS); } else { SYS_PRINT("Connected to %s\r\n", MQTT_BROKER_ADDRESS); } struct mg_send_mqtt_handshake_opts opts; memset(&opts, 0, sizeof(opts)); opts.user_name = MQTT_USER_NAME; opts.password = MQTT_USER_PWD; mg_set_protocol_mqtt(nc); mg_send_mqtt_handshake_opt(nc, "PIC32", opts); break; case MG_EV_MQTT_CONNACK: if (msg->connack_ret_code != MG_EV_MQTT_CONNACK_ACCEPTED) { SYS_PRINT("Got mqtt connection error %d\n\r", msg->connack_ret_code); } else { SYS_PRINT("Connected to broker\n\r"); } SYS_PRINT("Subscribing to /test\n\r"); mg_mqtt_subscribe(nc, topic_expressions, sizeof(topic_expressions) / sizeof(*topic_expressions), ++msg_id); nc->flags |= MG_F_USER_1; break; case MG_EV_MQTT_SUBACK: SYS_PRINT("Subscription acknowledged\r\n"); break; case MG_EV_MQTT_PUBLISH: SYS_PRINT("Got incoming message %s: %.*s\r\n", msg->topic, (int) msg->payload.len, msg->payload.p); break; case MG_EV_POLL: { if (nc->flags & MG_F_USER_1) { char msg[100]; static uint32_t prev_send = 0; uint32_t now = DRV_RTCC_TimeGet(); if (now - prev_send > 1000) { int len = snprintf(msg, sizeof(msg), "Current RTC value: %u", now); SYS_PRINT("Publishing message with RTC value=%u\r\n", now); mg_mqtt_publish(nc, "/stuff", ++msg_id, MG_MQTT_QOS(0), msg, len); prev_send = now; } } break; } case MG_EV_CLOSE: SYS_PRINT("Connection to broker is closed\r\n"); appData.state = APP_STATE_DONE; break; default: break; } }