From 5e31914dc13c0aabcd9eb1daa266472ede65a7b8 Mon Sep 17 00:00:00 2001
From: Deomid Ryabkov <rojer@cesanta.com>
Date: Tue, 5 Apr 2016 19:44:19 +0100
Subject: [PATCH] Fix AP configuration on CC3200

Factor out MG task for clarity and ease of reuse.

PUBLISHED_FROM=18f1aedd3c227b43a49f59a67076905917dd6cab
---
 examples/CC3200/Makefile.build |  2 +-
 examples/CC3200/main.c         | 57 +++++++++++++---------------------
 examples/CC3200/mg_task.c      | 48 ++++++++++++++++++++++++++++
 examples/CC3200/mg_task.h      | 18 +++++++++++
 examples/CC3200/wifi.c         | 36 +++++++++++++++++++--
 5 files changed, 122 insertions(+), 39 deletions(-)
 create mode 100644 examples/CC3200/mg_task.c
 create mode 100644 examples/CC3200/mg_task.h

diff --git a/examples/CC3200/Makefile.build b/examples/CC3200/Makefile.build
index 257c75377..c1d5ccefb 100644
--- a/examples/CC3200/Makefile.build
+++ b/examples/CC3200/Makefile.build
@@ -92,7 +92,7 @@ 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 data.c mongoose.c tmp006.c wifi.c $(SDK_SRCS)
+APP_SRCS = main.c bm222.c data.c mongoose.c mg_task.c tmp006.c wifi.c $(SDK_SRCS)
 APP_OBJS = $(addprefix $(OBJDIR)/,$(patsubst %.c,%.o,$(APP_SRCS)))
 
 $(FW_ELF): $(APP_OBJS)
diff --git a/examples/CC3200/main.c b/examples/CC3200/main.c
index 172c7bd21..2c82fc60a 100644
--- a/examples/CC3200/main.c
+++ b/examples/CC3200/main.c
@@ -28,24 +28,24 @@
 #include "simplelink.h"
 #include "device.h"
 
-#include "osi.h"
-
 #include "data.h"
 #include "mongoose.h"
+#include "mg_task.h"
 #include "wifi.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_AP_SSID "Mongoose"
+#define WIFI_AP_PASS ""
+#define WIFI_AP_CHAN 6
+// #define WIFI_STA_SSID "YourWiFi"
+// #define WIFI_STA_PASS "YourPass"
 
 #define DATA_COLLECTION_INTERVAL_MS 20
 
 #define CONSOLE_BAUD_RATE 115200
 #define CONSOLE_UART UARTA0_BASE
 #define CONSOLE_UART_PERIPH PRCM_UARTA0
+#define MG_TASK_PRIORITY 3
 #define MG_TASK_STACK_SIZE 8192
 
 #define BM222_ADDR 0x18
@@ -53,14 +53,6 @@
 
 extern int cc3200_fs_init();
 
-struct event {
-  int type;
-  void *data;
-};
-
-OsiMsgQ_t s_v7_q;
-struct mg_mgr mg_mgr;
-
 static struct mg_str upload_fname(struct mg_connection *nc,
                                   struct mg_str fname) {
   struct mg_str lfn;
@@ -71,7 +63,7 @@ static struct mg_str upload_fname(struct mg_connection *nc,
   return lfn;
 }
 
-static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
+static void mg_ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
   switch (ev) {
     case MG_EV_ACCEPT: {
       char addr[32];
@@ -83,7 +75,7 @@ static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
     }
     case MG_EV_HTTP_REQUEST: {
       char addr[32];
-      struct http_message *hm = (struct http_message *) p;
+      struct http_message *hm = (struct http_message *) ev_data;
       mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
                                                       MG_SOCK_STRINGIFY_IP |
                                                       MG_SOCK_STRINGIFY_PORT);
@@ -93,7 +85,7 @@ static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
       struct mg_serve_http_opts opts;
       memset(&opts, 0, sizeof(opts));
       opts.document_root = "SL:";
-      mg_serve_http(nc, (struct http_message *) p, opts);
+      mg_serve_http(nc, hm, opts);
       break;
     }
     case MG_EV_CLOSE: {
@@ -113,19 +105,22 @@ static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
     case MG_EV_HTTP_PART_BEGIN:
     case MG_EV_HTTP_PART_DATA:
     case MG_EV_HTTP_PART_END: {
-      mg_file_upload_handler(nc, ev, p, upload_fname);
+      struct mg_http_multipart_part *mp =
+          (struct mg_http_multipart_part *) ev_data;
+      if (ev == MG_EV_HTTP_PART_BEGIN) {
+        LOG(LL_INFO, ("Begin file upload: %s", mp->file_name));
+      } else if (ev == MG_EV_HTTP_PART_END) {
+        LOG(LL_INFO, ("End file upload: %s", mp->file_name));
+      }
+      mg_file_upload_handler(nc, ev, ev_data, upload_fname);
     }
   }
 }
 
-static void mg_task(void *arg) {
+static void mg_init(struct mg_mgr *mgr) {
   LOG(LL_INFO, ("MG task running"));
   GPIO_IF_LedToggle(MCU_RED_LED_GPIO);
 
-  osi_MsgQCreate(&s_v7_q, "MG", sizeof(struct event), 32 /* len */);
-
-  sl_Start(NULL, NULL, NULL);
-
   data_init_sensors(TMP006_ADDR, BM222_ADDR);
 
   cc3200_fs_init();
@@ -145,26 +140,18 @@ static void mg_task(void *arg) {
   /* We don't need SimpleLink's web server. */
   sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID);
 
-  mg_mgr_init(&mg_mgr, NULL);
-
   const char *err = "";
   struct mg_bind_opts opts;
   memset(&opts, 0, sizeof(opts));
   opts.error_string = &err;
 
-  struct mg_connection *nc = mg_bind(&mg_mgr, "80", mg_ev_handler);
+  struct mg_connection *nc = mg_bind(mgr, "80", mg_ev_handler);
   if (nc != NULL) {
     mg_set_protocol_http_websocket(nc);
     nc->ev_timer_time = mg_time(); /* Start data collection */
   } else {
     LOG(LL_ERROR, ("Failed to create listener: %s", err));
   }
-
-  while (1) {
-    struct event e;
-    mg_mgr_poll(&mg_mgr, 0);
-    if (osi_MsgQRead(&s_v7_q, &e, 1) != OSI_OK) continue;
-  }
 }
 
 #ifndef USE_TIRTOS
@@ -213,8 +200,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 (!mg_start_task(MG_TASK_PRIORITY, MG_TASK_STACK_SIZE, mg_init)) {
     LOG(LL_ERROR, ("Failed to create MG task"));
   }
 
diff --git a/examples/CC3200/mg_task.c b/examples/CC3200/mg_task.c
new file mode 100644
index 000000000..571961380
--- /dev/null
+++ b/examples/CC3200/mg_task.c
@@ -0,0 +1,48 @@
+#include "mg_task.h"
+
+#include <oslib/osi.h>
+
+enum mg_q_msg_type {
+  MG_Q_MSG_CB,
+};
+struct mg_q_msg {
+  enum mg_q_msg_type type;
+  void (*cb)(struct mg_mgr *mgr, void *arg);
+  void *arg;
+};
+static OsiMsgQ_t s_mg_q;
+static void mg_task(void *arg);
+
+bool mg_start_task(int priority, int stask_size, mg_init_cb mg_init) {
+  if (osi_MsgQCreate(&s_mg_q, "MG", sizeof(struct mg_q_msg), 16) != OSI_OK) {
+    return false;
+  }
+  if (osi_TaskCreate(mg_task, (const signed char *) "MG", stask_size,
+                     (void *) mg_init, priority, NULL) != OSI_OK) {
+    return false;
+  }
+  return true;
+}
+
+static void mg_task(void *arg) {
+  struct mg_mgr mgr;
+  mg_init_cb mg_init = (mg_init_cb) arg;
+  sl_Start(NULL, NULL, NULL);
+  mg_mgr_init(&mgr, NULL);
+  mg_init(&mgr);
+  while (1) {
+    struct mg_q_msg msg;
+    mg_mgr_poll(&mgr, 1);
+    if (osi_MsgQRead(&s_mg_q, &msg, 1) != OSI_OK) continue;
+    switch (msg.type) {
+      case MG_Q_MSG_CB: {
+        msg.cb(&mgr, msg.arg);
+      }
+    }
+  }
+}
+
+void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg) {
+  struct mg_q_msg msg = {MG_Q_MSG_CB, cb, cb_arg};
+  osi_MsgQWrite(&s_mg_q, &msg, OSI_NO_WAIT);
+}
diff --git a/examples/CC3200/mg_task.h b/examples/CC3200/mg_task.h
new file mode 100644
index 000000000..df36c0f8a
--- /dev/null
+++ b/examples/CC3200/mg_task.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2014-2016 Cesanta Software Limited
+ * All rights reserved
+ */
+
+#ifndef CS_MONGOOSE_EXAMPLES_CC3200_MG_TASK_H_
+#define CS_MONGOOSE_EXAMPLES_CC3200_MG_TASK_H_
+
+#include <stdbool.h>
+
+#include "mongoose.h"
+
+typedef void (*mg_init_cb)(struct mg_mgr *mgr);
+bool mg_start_task(int priority, int stask_size, mg_init_cb mg_init);
+
+void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);
+
+#endif /* CS_MONGOOSE_EXAMPLES_CC3200_MG_TASK_H_ */
diff --git a/examples/CC3200/wifi.c b/examples/CC3200/wifi.c
index e48c5e902..b34278f03 100644
--- a/examples/CC3200/wifi.c
+++ b/examples/CC3200/wifi.c
@@ -23,20 +23,28 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *e) {
   }
 }
 
+int ip_acquired = 0;
+
 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),
+    LOG(LL_INFO, ("IP acquired: %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);
+    ip_acquired = 1;
+  } else if (e->Event == SL_NETAPP_IP_LEASED_EVENT) {
+    LOG(LL_INFO, ("IP leased"));
+  } else {
+    LOG(LL_INFO, ("NetApp event %d", e->Event));
   }
 }
 
 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_WlanSetMode(ROLE_AP) != 0) {
+    return false;
+  }
   if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(ssid),
                  (const uint8_t *) ssid) != 0) {
     return false;
@@ -54,18 +62,40 @@ bool wifi_setup_ap(const char *ssid, const char *pass, int channel) {
   if (sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, &v) != 0) {
     return false;
   }
+  sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID);
   {
     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) ||
+        /* This means "disable". 0.0.0.0 won't do. */
+        !inet_pton(AF_INET, "255.255.255.255", &ipcfg.ipV4DnsServer) ||
+        /* We'd like to disable gateway too, but DHCP server refuses to start.
+           */
+        !inet_pton(AF_INET, "192.168.4.1", &ipcfg.ipV4Gateway) ||
         sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4,
                      sizeof(ipcfg), (uint8_t *) &ipcfg) != 0) {
       return false;
     }
   }
+  {
+    SlNetAppDhcpServerBasicOpt_t dhcpcfg;
+    memset(&dhcpcfg, 0, sizeof(dhcpcfg));
+    dhcpcfg.lease_time = 900;
+    if (!inet_pton(AF_INET, "192.168.4.20", &dhcpcfg.ipv4_addr_start) ||
+        !inet_pton(AF_INET, "192.168.4.200", &dhcpcfg.ipv4_addr_last) ||
+        sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
+                     sizeof(dhcpcfg), (uint8_t *) &dhcpcfg) != 0) {
+      return false;
+    }
+  }
   sl_Stop(0);
   sl_Start(NULL, NULL, NULL);
+  if (sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID) != 0) {
+    LOG(LL_ERROR, ("DHCP server failed to start"));
+    return false;
+  }
+  LOG(LL_INFO, ("WiFi: AP %s configured", ssid));
   return true;
 }
 
-- 
GitLab