From 4a637a6e9a1943af48cafa4239598401b03d3823 Mon Sep 17 00:00:00 2001
From: Deomid Ryabkov <rojer@cesanta.com>
Date: Thu, 31 Mar 2016 22:02:07 +0100
Subject: [PATCH] Refactor CC3200 example

Move data collection out of main.c

PUBLISHED_FROM=0340ebcea62a12275e915f325483603e72ff4183
---
 examples/CC3200/Makefile.build |   4 +-
 examples/CC3200/data.c         | 193 ++++++++++++++++++++++++
 examples/CC3200/data.h         |  15 ++
 examples/CC3200/main.c         | 266 +++++----------------------------
 examples/CC3200/wifi.c         |  86 +++++++++++
 examples/CC3200/wifi.h         |  14 ++
 6 files changed, 347 insertions(+), 231 deletions(-)
 create mode 100644 examples/CC3200/data.c
 create mode 100644 examples/CC3200/data.h
 create mode 100644 examples/CC3200/wifi.c
 create mode 100644 examples/CC3200/wifi.h

diff --git a/examples/CC3200/Makefile.build b/examples/CC3200/Makefile.build
index 31153e03c..f9a534a4f 100644
--- a/examples/CC3200/Makefile.build
+++ b/examples/CC3200/Makefile.build
@@ -38,6 +38,7 @@ SDK_FLAGS = -DUSE_FREERTOS -DSL_PLATFORM_MULTI_THREADED
 
 CFLAGS += -Os -Wall -Werror \
           $(SDK_FLAGS) -DCS_PLATFORM=4 -DCC3200_FS_SLFS \
+          -DFS_SLFS_MAX_FILE_SIZE=131072 \
           $(MONGOOSE_FEATURES) $(CFLAGS_EXTRA)
 
 FW_ELF = $(FW_DIR)/$(PROG).axf
@@ -101,7 +102,8 @@ VPATH += $(SDK_PATH)/driverlib $(SDK_PATH)/example/common $(SDK_PATH)/oslib \
          $(SDK_PATH)/third_party/FreeRTOS/source/portable/GCC/ARM_CM4 \
          $(SDK_PATH)/third_party/FreeRTOS/source/portable/MemMang \
 
-APP_SRCS = main.c bm222.c tmp006.c mongoose.c $(CC3200_PLATFORM_SRCS) $(SDK_SRCS)
+APP_SRCS = main.c bm222.c data.c mongoose.c tmp006.c wifi.c \
+           $(CC3200_PLATFORM_SRCS) $(SDK_SRCS)
 APP_OBJS = $(addprefix $(OBJDIR)/,$(patsubst %.c,%.o,$(APP_SRCS)))
 
 $(FW_ELF): $(APP_OBJS)
diff --git a/examples/CC3200/data.c b/examples/CC3200/data.c
new file mode 100644
index 000000000..978186d7e
--- /dev/null
+++ b/examples/CC3200/data.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014-2016 Cesanta Software Limited
+ * All rights reserved
+ */
+
+#include "data.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gpio_if.h"
+
+#include "bm222.h"
+#include "tmp006.h"
+
+struct temp_data {
+  double ts;
+  double volt;
+  double temp;
+};
+
+struct conn_state {
+  struct temp_data td;
+  double last_sent_td;
+  unsigned char led;
+  double last_sent_led;
+  double last_sent_acc;
+};
+
+static int s_tmp006_addr;
+static struct temp_data s_temp_data;
+static struct bm222_ctx *s_accel_ctx;
+
+void data_init_sensors(int tmp006_addr, int bm222_addr) {
+  s_tmp006_addr = tmp006_addr;
+  if (!tmp006_init(tmp006_addr, TMP006_CONV_2, false)) {
+    LOG(LL_ERROR, ("Failed to init temperature sensor"));
+  } else {
+    LOG(LL_INFO, ("Temperature sensor initialized"));
+  }
+  s_accel_ctx = bm222_init(bm222_addr);
+  if (s_accel_ctx == NULL) {
+    LOG(LL_ERROR, ("Failed to init accelerometer"));
+  } else {
+    LOG(LL_INFO, ("Accelerometer initialized"));
+  }
+}
+
+void data_collect() {
+  double volt = tmp006_read_sensor_voltage(s_tmp006_addr);
+  double temp = tmp006_read_die_temp(s_tmp006_addr);
+  if (volt != TMP006_INVALID_READING && temp != TMP006_INVALID_READING) {
+    s_temp_data.temp = temp;
+    s_temp_data.volt = volt;
+    s_temp_data.ts = mg_time();
+    LOG(LL_DEBUG, ("V = %lf mV, T = %lf C", volt, temp));
+  }
+  bm222_get_data(s_accel_ctx);
+}
+
+static void send_temp(struct mg_connection *nc, const struct temp_data *td) {
+  if (td->ts == 0) return;
+  mg_printf_websocket_frame(nc, WEBSOCKET_OP_TEXT,
+                            "{\"t\": 0, \"ts\": %lf, \"sv\": %lf, \"dt\": %lf}",
+                            td->ts, td->volt, td->temp);
+}
+
+static void send_led(struct mg_connection *nc, double ts, unsigned char led) {
+  if (ts == 0) return;
+  mg_printf_websocket_frame(nc, WEBSOCKET_OP_TEXT,
+                            "{\"t\": 1, \"ts\": %lf, \"v\": %d}", ts, led);
+}
+
+static void send_acc_sample(struct mg_connection *nc,
+                            const struct bm222_sample *s) {
+  if (s->ts == 0) return;
+  mg_printf_websocket_frame(
+      nc, WEBSOCKET_OP_TEXT,
+      "{\"t\": 2, \"ts\": %lf, \"x\": %d, \"y\": %d, \"z\": %d}", s->ts, s->x,
+      s->y, s->z);
+}
+
+static double send_acc_data_since(struct mg_connection *nc,
+                                  const struct bm222_ctx *ctx, double since) {
+  int i = (ctx->last_index + 1) % BM222_NUM_SAMPLES, n = BM222_NUM_SAMPLES;
+  double last_sent_ts = 0;
+  for (; n > 0; i = (i + 1) % BM222_NUM_SAMPLES, n--) {
+    const struct bm222_sample *s = ctx->data + i;
+    if (s->ts <= since) continue;
+    send_acc_sample(nc, s);
+    last_sent_ts = s->ts;
+  }
+  return last_sent_ts;
+}
+
+static void process_command(struct mg_connection *nc, unsigned char *data,
+                            size_t len) {
+  struct json_token *toks = parse_json2((const char *) data, len);
+  if (toks == NULL) {
+    LOG(LL_ERROR, ("Invalid command: %.*s", (int) len, data));
+    return;
+  }
+  struct json_token *t = find_json_token(toks, "t");
+  if (t == NULL) {
+    LOG(LL_ERROR, ("Missing type field: %.*s", (int) len, data));
+    goto out_free;
+  }
+  if (t->len == 1 && *t->ptr == '1') {
+    struct json_token *v = find_json_token(toks, "v");
+    if (v == NULL) {
+      LOG(LL_ERROR, ("Missing value: %.*s", (int) len, data));
+      goto out_free;
+    }
+    if (v->len != 1) {
+      LOG(LL_ERROR, ("Invalid value: %.*s", (int) len, data));
+      goto out_free;
+    }
+    switch (*v->ptr) {
+      case '0': {
+        GPIO_IF_LedOff(MCU_RED_LED_GPIO);
+        break;
+      }
+      case '1': {
+        GPIO_IF_LedOn(MCU_RED_LED_GPIO);
+        break;
+      }
+      case '2': {
+        GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
+        break;
+      }
+      default: {
+        LOG(LL_ERROR, ("Invalid value: %.*s", (int) len, data));
+        goto out_free;
+      }
+    }
+  } else {
+    LOG(LL_ERROR, ("Unknown command: %.*s", (int) t->len, t->ptr));
+    goto out_free;
+  }
+out_free:
+  free(toks);
+}
+
+void data_conn_handler(struct mg_connection *nc, int ev, void *ev_data) {
+  struct conn_state *cs = (struct conn_state *) nc->user_data;
+  if (cs == NULL) {
+    cs = (struct conn_state *) calloc(1, sizeof(*cs));
+    nc->user_data = cs;
+  }
+  switch (ev) {
+    case MG_EV_POLL:
+    case MG_EV_TIMER: {
+      const double now = mg_time();
+      const unsigned char led = GPIO_IF_LedStatus(MCU_RED_LED_GPIO);
+      /* Send if there was a change or repeat last data every second. */
+      if (s_temp_data.volt != cs->td.volt || s_temp_data.temp != cs->td.temp ||
+          now > cs->last_sent_td + 1.0) {
+        memcpy(&cs->td, &s_temp_data, sizeof(cs->td));
+        send_temp(nc, &cs->td);
+        cs->last_sent_td = now;
+      }
+      if (led != cs->led || now > cs->last_sent_led + 1.0) {
+        send_led(nc, now, led);
+        cs->led = led;
+        cs->last_sent_led = now;
+      }
+      if (s_accel_ctx != NULL) {
+        const struct bm222_sample *ls =
+            s_accel_ctx->data + s_accel_ctx->last_index;
+        if (cs->last_sent_acc == 0) {
+          send_acc_sample(nc, ls);
+          cs->last_sent_acc = ls->ts;
+        } else {
+          double last_sent_ts =
+              send_acc_data_since(nc, s_accel_ctx, cs->last_sent_acc);
+          if (last_sent_ts > 0) cs->last_sent_acc = last_sent_ts;
+        }
+      }
+      nc->ev_timer_time = now + 0.05;
+      break;
+    }
+    case MG_EV_WEBSOCKET_FRAME: {
+      struct websocket_message *wm = (struct websocket_message *) ev_data;
+      process_command(nc, wm->data, wm->size);
+      break;
+    }
+    case MG_EV_CLOSE: {
+      LOG(LL_INFO, ("%p closed", nc));
+      free(cs);
+      break;
+    }
+  }
+}
diff --git a/examples/CC3200/data.h b/examples/CC3200/data.h
new file mode 100644
index 000000000..e9e8cf9c2
--- /dev/null
+++ b/examples/CC3200/data.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014-2016 Cesanta Software Limited
+ * All rights reserved
+ */
+
+#ifndef CS_MONGOOSE_EXAMPLES_CC3200_DATA_H_
+#define CS_MONGOOSE_EXAMPLES_CC3200_DATA_H_
+
+#include "mongoose.h"
+
+void data_collect();
+void data_init_sensors(int tmp006_addr, int bm222_addr);
+void data_conn_handler(struct mg_connection *nc, int ev, void *p);
+
+#endif /* CS_MONGOOSE_EXAMPLES_CC3200_DATA_H_ */
diff --git a/examples/CC3200/main.c b/examples/CC3200/main.c
index cd0ad9d83..172c7bd21 100644
--- a/examples/CC3200/main.c
+++ b/examples/CC3200/main.c
@@ -30,19 +30,22 @@
 
 #include "osi.h"
 
+#include "data.h"
 #include "mongoose.h"
+#include "wifi.h"
 
-#include "bm222.h"
-#include "tmp006.h"
+/* Set up an AP or connect to existing WiFi network. */
+//#define WIFI_AP_SSID "Mongoose"
+//#define WIFI_AP_PASS ""
+//#define WIFI_AP_CHAN 6
+#define WIFI_STA_SSID "YourWiFi"
+#define WIFI_STA_PASS "YourPass"
 
-#define WIFI_SSID "YourWiFi"
-#define WIFI_PASS "YourPassword"
+#define DATA_COLLECTION_INTERVAL_MS 20
 
-#define DATA_SAMPLING_INTERVAL_MS 20
 #define CONSOLE_BAUD_RATE 115200
 #define CONSOLE_UART UARTA0_BASE
 #define CONSOLE_UART_PERIPH PRCM_UARTA0
-#define SYS_CLK 80000000
 #define MG_TASK_STACK_SIZE 8192
 
 #define BM222_ADDR 0x18
@@ -58,37 +61,8 @@ struct event {
 OsiMsgQ_t s_v7_q;
 struct mg_mgr mg_mgr;
 
-static struct bm222_ctx *s_accel_ctx;
-
-void SimpleLinkWlanEventHandler(SlWlanEvent_t *e) {
-  if (e->Event == SL_WLAN_CONNECT_EVENT) {
-    LOG(LL_INFO, ("WiFi: connected"));
-  } else {
-    LOG(LL_INFO, ("WiFi: event %d", e->Event));
-  }
-}
-
-void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *e) {
-  if (e->Event == SL_NETAPP_IPV4_IPACQUIRED_EVENT) {
-    SlIpV4AcquiredAsync_t *ed = &e->EventData.ipAcquiredV4;
-    LOG(LL_INFO, ("IP: %lu.%lu.%lu.%lu", SL_IPV4_BYTE(ed->ip, 3),
-                  SL_IPV4_BYTE(ed->ip, 2), SL_IPV4_BYTE(ed->ip, 1),
-                  SL_IPV4_BYTE(ed->ip, 0)));
-    GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
-  }
-}
-
-static void data_ev_handler(struct mg_connection *nc, int ev, void *p);
-
-struct temp_data {
-  double ts;
-  double volt;
-  double temp;
-};
-
-static struct temp_data s_temp_data;
-
-static struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {
+static struct mg_str upload_fname(struct mg_connection *nc,
+                                  struct mg_str fname) {
   struct mg_str lfn;
   lfn.len = fname.len + 3;
   lfn.p = malloc(lfn.len);
@@ -101,20 +75,18 @@ static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
   switch (ev) {
     case MG_EV_ACCEPT: {
       char addr[32];
-      mg_conn_addr_to_str(
-          nc, addr, sizeof(addr),
-          MG_SOCK_STRINGIFY_REMOTE | MG_SOCK_STRINGIFY_IP |
-          MG_SOCK_STRINGIFY_PORT);
+      mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
+                                                      MG_SOCK_STRINGIFY_IP |
+                                                      MG_SOCK_STRINGIFY_PORT);
       LOG(LL_INFO, ("%p conn from %s", nc, addr));
       break;
     }
     case MG_EV_HTTP_REQUEST: {
       char addr[32];
       struct http_message *hm = (struct http_message *) p;
-      mg_conn_addr_to_str(
-          nc, addr, sizeof(addr),
-          MG_SOCK_STRINGIFY_REMOTE | MG_SOCK_STRINGIFY_IP |
-          MG_SOCK_STRINGIFY_PORT);
+      mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
+                                                      MG_SOCK_STRINGIFY_IP |
+                                                      MG_SOCK_STRINGIFY_PORT);
       LOG(LL_INFO,
           ("HTTP request from %s: %.*s %.*s", addr, (int) hm->method.len,
            hm->method.p, (int) hm->uri.len, hm->uri.p));
@@ -130,21 +102,13 @@ static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
     }
     case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
       LOG(LL_INFO, ("%p switching to data mode", nc));
-      nc->handler = data_ev_handler;
+      nc->handler = data_conn_handler;
       nc->ev_timer_time = mg_time(); /* Immediately */
       break;
     }
     case MG_EV_TIMER: {
-      double volt = tmp006_read_sensor_voltage(TMP006_ADDR);
-      double temp = tmp006_read_die_temp(TMP006_ADDR);
-      if (volt != TMP006_INVALID_READING && temp != TMP006_INVALID_READING) {
-        s_temp_data.temp = temp;
-        s_temp_data.volt = volt;
-        s_temp_data.ts = mg_time();
-        LOG(LL_DEBUG, ("V = %lf mV, T = %lf C", volt, temp));
-      }
-      bm222_get_data(s_accel_ctx);
-      nc->ev_timer_time = mg_time() + (DATA_SAMPLING_INTERVAL_MS * 0.001);
+      data_collect();
+      nc->ev_timer_time = mg_time() + (DATA_COLLECTION_INTERVAL_MS * 0.001);
     }
     case MG_EV_HTTP_PART_BEGIN:
     case MG_EV_HTTP_PART_DATA:
@@ -154,190 +118,31 @@ static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
   }
 }
 
-struct conn_state {
-  struct temp_data td;
-  double last_sent_td;
-  unsigned char led;
-  double last_sent_led;
-  double last_sent_acc;
-};
-
-static void send_temp(struct mg_connection *nc, const struct temp_data *td) {
-  if (td->ts == 0) return;
-  mg_printf_websocket_frame(nc, WEBSOCKET_OP_TEXT,
-                            "{\"t\": 0, \"ts\": %lf, \"sv\": %lf, \"dt\": %lf}",
-                            td->ts, td->volt, td->temp);
-}
-
-static void send_led(struct mg_connection *nc, double ts, unsigned char led) {
-  if (ts == 0) return;
-  mg_printf_websocket_frame(nc, WEBSOCKET_OP_TEXT,
-                            "{\"t\": 1, \"ts\": %lf, \"v\": %d}", ts, led);
-}
-
-static void send_acc_sample(struct mg_connection *nc,
-                            const struct bm222_sample *s) {
-  if (s->ts == 0) return;
-  mg_printf_websocket_frame(
-      nc, WEBSOCKET_OP_TEXT,
-      "{\"t\": 2, \"ts\": %lf, \"x\": %d, \"y\": %d, \"z\": %d}", s->ts, s->x,
-      s->y, s->z);
-}
-
-static double send_acc_data_since(struct mg_connection *nc,
-                                  const struct bm222_ctx *ctx, double since) {
-  int i = (ctx->last_index + 1) % BM222_NUM_SAMPLES, n = BM222_NUM_SAMPLES;
-  double last_sent_ts = 0;
-  for (; n > 0; i = (i + 1) % BM222_NUM_SAMPLES, n--) {
-    const struct bm222_sample *s = ctx->data + i;
-    if (s->ts <= since) continue;
-    send_acc_sample(nc, s);
-    last_sent_ts = s->ts;
-  }
-  return last_sent_ts;
-}
-
-static void process_command(struct mg_connection *nc, unsigned char *data,
-                            size_t len) {
-  struct json_token *toks = parse_json2((const char *) data, len);
-  if (toks == NULL) {
-    LOG(LL_ERROR, ("Invalid command: %.*s", (int) len, data));
-    return;
-  }
-  struct json_token *t = find_json_token(toks, "t");
-  if (t == NULL) {
-    LOG(LL_ERROR, ("Missing type field: %.*s", (int) len, data));
-    goto out_free;
-  }
-  if (t->len == 1 && *t->ptr == '1') {
-    struct json_token *v = find_json_token(toks, "v");
-    if (v == NULL) {
-      LOG(LL_ERROR, ("Missing value: %.*s", (int) len, data));
-      goto out_free;
-    }
-    if (v->len != 1) {
-      LOG(LL_ERROR, ("Invalid value: %.*s", (int) len, data));
-      goto out_free;
-    }
-    switch (*v->ptr) {
-      case '0': {
-        GPIO_IF_LedOff(MCU_RED_LED_GPIO);
-        break;
-      }
-      case '1': {
-        GPIO_IF_LedOn(MCU_RED_LED_GPIO);
-        break;
-      }
-      case '2': {
-        GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
-        break;
-      }
-      default: {
-        LOG(LL_ERROR, ("Invalid value: %.*s", (int) len, data));
-        goto out_free;
-      }
-    }
-  } else {
-    LOG(LL_ERROR, ("Unknown command: %.*s", (int) t->len, t->ptr));
-    goto out_free;
-  }
-out_free:
-  free(toks);
-}
-
-static void data_ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
-  struct conn_state *cs = (struct conn_state *) nc->user_data;
-  if (cs == NULL) {
-    cs = (struct conn_state *) calloc(1, sizeof(*cs));
-    nc->user_data = cs;
-  }
-  switch (ev) {
-    case MG_EV_POLL:
-    case MG_EV_TIMER: {
-      const double now = mg_time();
-      const unsigned char led = GPIO_IF_LedStatus(MCU_RED_LED_GPIO);
-      /* Send if there was a change or repeat last data every second. */
-      if (s_temp_data.volt != cs->td.volt || s_temp_data.temp != cs->td.temp ||
-          now > cs->last_sent_td + 1.0) {
-        memcpy(&cs->td, &s_temp_data, sizeof(cs->td));
-        send_temp(nc, &cs->td);
-        cs->last_sent_td = now;
-      }
-      if (led != cs->led || now > cs->last_sent_led + 1.0) {
-        send_led(nc, now, led);
-        cs->led = led;
-        cs->last_sent_led = now;
-      }
-      if (s_accel_ctx != NULL) {
-        const struct bm222_sample *ls =
-            s_accel_ctx->data + s_accel_ctx->last_index;
-        if (cs->last_sent_acc == 0) {
-          send_acc_sample(nc, ls);
-          cs->last_sent_acc = ls->ts;
-        } else {
-          double last_sent_ts =
-              send_acc_data_since(nc, s_accel_ctx, cs->last_sent_acc);
-          if (last_sent_ts > 0) cs->last_sent_acc = last_sent_ts;
-        }
-      }
-      nc->ev_timer_time = now + 0.05;
-      break;
-    }
-    case MG_EV_WEBSOCKET_FRAME: {
-      struct websocket_message *wm = (struct websocket_message *) ev_data;
-      process_command(nc, wm->data, wm->size);
-      break;
-    }
-    case MG_EV_CLOSE: {
-      LOG(LL_INFO, ("%p closed", nc));
-      free(cs);
-      break;
-    }
-  }
-}
-
 static void mg_task(void *arg) {
   LOG(LL_INFO, ("MG task running"));
   GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
 
-  osi_MsgQCreate(&s_v7_q, "V7", sizeof(struct event), 32 /* len */);
+  osi_MsgQCreate(&s_v7_q, "MG", sizeof(struct event), 32 /* len */);
 
   sl_Start(NULL, NULL, NULL);
-  if (!tmp006_init(TMP006_ADDR, TMP006_CONV_2, false)) {
-    LOG(LL_ERROR, ("Failed to init temperature sensor"));
-  } else {
-    LOG(LL_INFO, ("Temperature sensor initialized"));
-  }
-  s_accel_ctx = bm222_init(BM222_ADDR);
-  if (s_accel_ctx == NULL) {
-    LOG(LL_ERROR, ("Failed to init accelerometer"));
-  } else {
-    LOG(LL_INFO, ("Accelerometer initialized"));
-  }
+
+  data_init_sensors(TMP006_ADDR, BM222_ADDR);
 
   cc3200_fs_init();
 
-  if (strlen(WIFI_SSID) > 0) {
-    int ret;
-    SlSecParams_t sp;
-    sl_WlanSetMode(ROLE_STA);
-    sl_Stop(0);
-    sl_Start(NULL, NULL, NULL);
-    sl_WlanDisconnect();
-    LOG(LL_INFO, ("WiFi: connecting to %s", WIFI_SSID));
-    sp.Key = (_i8 *) WIFI_PASS;
-    sp.KeyLen = strlen(WIFI_PASS);
-    sp.Type = sp.KeyLen ? SL_SEC_TYPE_WPA : SL_SEC_TYPE_OPEN;
-    ret = sl_WlanConnect((const _i8 *) WIFI_SSID, strlen(WIFI_SSID), 0, &sp, 0);
-    if (ret != 0) {
-      LOG(LL_ERROR, ("WlanConnect error: %d\n", ret));
-    }
-  } else {
-    LOG(LL_INFO, ("Not connecting to WiFi."));
-    sl_Start(NULL, NULL, NULL);
+#if defined(WIFI_STA_SSID)
+  if (!wifi_setup_sta(WIFI_STA_SSID, WIFI_STA_PASS)) {
+    LOG(LL_ERROR, ("Error setting up WiFi station"));
+  }
+#elif defined(WIFI_AP_SSID)
+  if (!wifi_setup_ap(WIFI_AP_SSID, WIFI_AP_PASS, WIFI_AP_CHAN)) {
+    LOG(LL_ERROR, ("Error setting up WiFi AP"));
   }
+#else
+#error WiFi not configured
+#endif
 
-  /* We don't need TI's web server. */
+  /* We don't need SimpleLink's web server. */
   sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID);
 
   mg_mgr_init(&mg_mgr, NULL);
@@ -408,7 +213,8 @@ int main() {
   if (VStartSimpleLinkSpawnTask(8) != 0) {
     LOG(LL_ERROR, ("Failed to create SL task"));
   }
-  if (osi_TaskCreate(mg_task, (const signed char *) "mg", MG_TASK_STACK_SIZE, NULL, 3, NULL) != 0) {
+  if (osi_TaskCreate(mg_task, (const signed char *) "mg", MG_TASK_STACK_SIZE,
+                     NULL, 3, NULL) != 0) {
     LOG(LL_ERROR, ("Failed to create MG task"));
   }
 
diff --git a/examples/CC3200/wifi.c b/examples/CC3200/wifi.c
new file mode 100644
index 000000000..e48c5e902
--- /dev/null
+++ b/examples/CC3200/wifi.c
@@ -0,0 +1,86 @@
+#include "wifi.h"
+
+#include "simplelink.h"
+#include "wlan.h"
+
+#include "gpio_if.h"
+
+#include "mongoose.h"
+
+void SimpleLinkWlanEventHandler(SlWlanEvent_t *e) {
+  switch (e->Event) {
+    case SL_WLAN_CONNECT_EVENT:
+      LOG(LL_INFO, ("WiFi: connected"));
+      break;
+    case SL_WLAN_STA_CONNECTED_EVENT:
+      LOG(LL_INFO, ("WiFi: station connected"));
+      break;
+    case SL_WLAN_STA_DISCONNECTED_EVENT:
+      LOG(LL_INFO, ("WiFi: station disconnected"));
+      break;
+    default:
+      LOG(LL_INFO, ("WiFi: event %d", e->Event));
+  }
+}
+
+void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *e) {
+  if (e->Event == SL_NETAPP_IPV4_IPACQUIRED_EVENT) {
+    SlIpV4AcquiredAsync_t *ed = &e->EventData.ipAcquiredV4;
+    LOG(LL_INFO, ("IP: %lu.%lu.%lu.%lu", SL_IPV4_BYTE(ed->ip, 3),
+                  SL_IPV4_BYTE(ed->ip, 2), SL_IPV4_BYTE(ed->ip, 1),
+                  SL_IPV4_BYTE(ed->ip, 0)));
+    GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
+  }
+}
+
+bool wifi_setup_ap(const char *ssid, const char *pass, int channel) {
+  uint8_t v;
+  LOG(LL_INFO, ("WiFi: configuring AP %s", ssid));
+  sl_WlanSetMode(ROLE_AP);
+  if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(ssid),
+                 (const uint8_t *) ssid) != 0) {
+    return false;
+  }
+  v = strlen(pass) > 0 ? SL_SEC_TYPE_WPA : SL_SEC_TYPE_OPEN;
+  if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, &v) != 0) {
+    return false;
+  }
+  if (v == SL_SEC_TYPE_WPA &&
+      sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, strlen(pass),
+                 (const uint8_t *) pass) != 0) {
+    return false;
+  }
+  v = channel;
+  if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, &v) != 0) {
+    return false;
+  }
+  {
+    SlNetCfgIpV4Args_t ipcfg;
+    memset(&ipcfg, 0, sizeof(ipcfg));
+    if (!inet_pton(AF_INET, "192.168.4.1", &ipcfg.ipV4) ||
+        !inet_pton(AF_INET, "255.255.255.0", &ipcfg.ipV4Mask) ||
+        sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4,
+                     sizeof(ipcfg), (uint8_t *) &ipcfg) != 0) {
+      return false;
+    }
+  }
+  sl_Stop(0);
+  sl_Start(NULL, NULL, NULL);
+  return true;
+}
+
+bool wifi_setup_sta(const char *ssid, const char *pass) {
+  SlSecParams_t sp;
+  LOG(LL_INFO, ("WiFi: connecting to %s", ssid));
+  if (sl_WlanSetMode(ROLE_STA) != 0) return false;
+  sl_Stop(0);
+  sl_Start(NULL, NULL, NULL);
+  sl_WlanDisconnect();
+  sp.Key = (_i8 *) pass;
+  sp.KeyLen = strlen(pass);
+  sp.Type = sp.KeyLen ? SL_SEC_TYPE_WPA : SL_SEC_TYPE_OPEN;
+  if (sl_WlanConnect((const _i8 *) ssid, strlen(ssid), 0, &sp, 0) != 0) {
+    return false;
+  }
+  return true;
+}
diff --git a/examples/CC3200/wifi.h b/examples/CC3200/wifi.h
new file mode 100644
index 000000000..e300cbf49
--- /dev/null
+++ b/examples/CC3200/wifi.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014-2016 Cesanta Software Limited
+ * All rights reserved
+ */
+
+#ifndef CS_MONGOOSE_EXAMPLES_CC3200_WIFI_H_
+#define CS_MONGOOSE_EXAMPLES_CC3200_WIFI_H_
+
+#include <stdbool.h>
+
+bool wifi_setup_ap(const char *ssid, const char *pass, int channel);
+bool wifi_setup_sta(const char *ssid, const char *pass);
+
+#endif /* CS_MONGOOSE_EXAMPLES_CC3200_WIFI_H_ */
-- 
GitLab