Statistics
| Branch: | Tag: | Revision:

mongoose / examples / CC3200 / ccs / MG_hello / main.c @ eaef5bd1

History | View | Annotate | Download (6.75 KB)

1
/*
2
 * Copyright (c) 2014-2016 Cesanta Software Limited
3
 * All rights reserved
4
 */
5

    
6
/* Set up an AP or connect to existing WiFi network. */
7
#define WIFI_AP_SSID "Mongoose"
8
#define WIFI_AP_PASS ""
9
#define WIFI_AP_CHAN 6
10
// #define WIFI_STA_SSID "YourWiFi"
11
// #define WIFI_STA_PASS "YourPass"
12

    
13
#define MGOS_TASK_PRIORITY 3
14
#define MG_TASK_STACK_SIZE 8192
15

    
16
#include <stdbool.h>
17
#include <stdio.h>
18
#include <string.h>
19

    
20
#include <stdbool.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24

    
25
#include <inc/hw_types.h>
26
#include <inc/hw_ints.h>
27
#include <inc/hw_memmap.h>
28

    
29
#include <driverlib/gpio.h>
30
#include <driverlib/interrupt.h>
31
#include <driverlib/pin.h>
32
#include <driverlib/prcm.h>
33
#include <driverlib/rom.h>
34
#include <driverlib/rom_map.h>
35

    
36
#include <example/common/gpio_if.h>
37

    
38
/* Mongoose.h brings in SimpleLink support. Do not include simplelink.h. */
39
#include <mongoose.h>
40

    
41
#include <simplelink/include/device.h>
42

    
43
#include "cs_dbg.h"
44
#include "wifi.h"
45

    
46
void fs_slfs_set_new_file_size(const char *name, size_t size);
47

    
48
static const char *upload_form =
49
    "\
50
<h1>Upload file</h1> \
51
<form action='/upload' method='POST' enctype='multipart/form-data'> \
52
  <input type='file' name='file'> \
53
  <input type='submit' value='Upload'> \
54
</form>";
55

    
56
static struct mg_str upload_fname(struct mg_connection *nc,
57
                                  struct mg_str fname) {
58
  struct mg_str lfn;
59
  char *fn = malloc(fname.len + 4);
60
  memcpy(fn, "SL:", 3);
61
  memcpy(fn + 3, fname.p, fname.len);
62
  fn[3 + fname.len] = '\0';
63
  if (nc->user_data != NULL) {
64
    intptr_t cl = (intptr_t) nc->user_data;
65
    if (cl >= 0) {
66
      fs_slfs_set_new_file_size(fn + 3, cl);
67
    }
68
  }
69
  lfn.len = fname.len + 4;
70
  lfn.p = fn;
71
  return lfn;
72
}
73

    
74
void mg_ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
75
  LOG(LL_DEBUG, ("%p ev %d", nc, ev));
76

    
77
  switch (ev) {
78
    case MG_EV_ACCEPT: {
79
      char addr[32];
80
      mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
81
                          MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
82
      LOG(LL_INFO, ("Connection %p from %s", nc, addr));
83
      break;
84
    }
85
    case MG_EV_HTTP_REQUEST: {
86
      char addr[32];
87
      struct http_message *hm = (struct http_message *) ev_data;
88
      cs_stat_t st;
89
      mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
90
                          MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
91
      LOG(LL_INFO,
92
          ("HTTP request from %s: %.*s %.*s", addr, (int) hm->method.len,
93
           hm->method.p, (int) hm->uri.len, hm->uri.p));
94
      if (mg_vcmp(&hm->uri, "/upload") == 0 ||
95
          (mg_vcmp(&hm->uri, "/") == 0 && mg_stat("SL:index.html", &st) != 0)) {
96
        mg_send(nc, upload_form, strlen(upload_form));
97
        nc->flags |= MG_F_SEND_AND_CLOSE;
98
        break;
99
      }
100
      struct mg_serve_http_opts opts;
101
      memset(&opts, 0, sizeof(opts));
102
      opts.document_root = "SL:";
103
      mg_serve_http(nc, hm, opts);
104
      break;
105
    }
106
    case MG_EV_CLOSE: {
107
      LOG(LL_INFO, ("Connection %p closed", nc));
108
      break;
109
    }
110
    /* SimpleLink FS requires pre-declaring max file size. We use Content-Length
111
     * for that purpose - it will not exactly match file size, but is guaranteed
112
     * to exceed it and should be close enough. */
113
    case MG_EV_HTTP_MULTIPART_REQUEST: {
114
      struct http_message *hm = (struct http_message *) ev_data;
115
      struct mg_str *cl_header = mg_get_http_header(hm, "Content-Length");
116
      intptr_t cl = -1;
117
      if (cl_header != NULL && cl_header->len < 20) {
118
        char buf[20];
119
        memcpy(buf, cl_header->p, cl_header->len);
120
        buf[cl_header->len] = '\0';
121
        cl = atoi(buf);
122
        if (cl < 0) cl = -1;
123
      }
124
      nc->user_data = (void *) cl;
125
      break;
126
    }
127
    case MG_EV_HTTP_PART_BEGIN:
128
    case MG_EV_HTTP_PART_DATA:
129
    case MG_EV_HTTP_PART_END: {
130
      struct mg_http_multipart_part *mp =
131
          (struct mg_http_multipart_part *) ev_data;
132
      if (ev == MG_EV_HTTP_PART_BEGIN) {
133
        LOG(LL_INFO, ("Begin file upload: %s", mp->file_name));
134
      } else if (ev == MG_EV_HTTP_PART_END) {
135
        LOG(LL_INFO, ("End file upload: %s", mp->file_name));
136
      }
137
      mg_file_upload_handler(nc, ev, ev_data, upload_fname);
138
    }
139
  }
140
}
141

    
142
static void mg_init(struct mg_mgr *mgr) {
143
  LOG(LL_INFO, ("MG task running"));
144

    
145
  stop_nwp(); /* See function description in wifi.c */
146
  LOG(LL_INFO, ("Starting NWP..."));
147
  int role = sl_Start(0, 0, 0);
148
  if (role < 0) {
149
    LOG(LL_ERROR, ("Failed to start NWP"));
150
    return;
151
  }
152

    
153
  LOG(LL_INFO, ("NWP started"));
154

    
155
  sl_fs_init();
156

    
157
#if defined(WIFI_STA_SSID)
158
  if (!wifi_setup_sta(WIFI_STA_SSID, WIFI_STA_PASS)) {
159
    LOG(LL_ERROR, ("Error setting up WiFi station"));
160
  }
161
#elif defined(WIFI_AP_SSID)
162
  if (!wifi_setup_ap(WIFI_AP_SSID, WIFI_AP_PASS, WIFI_AP_CHAN)) {
163
    LOG(LL_ERROR, ("Error setting up WiFi AP"));
164
  }
165
#else
166
#error WiFi not configured
167
#endif
168

    
169
  /* We don't need SimpleLink's web server. */
170
  sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID);
171

    
172
  const char *err = "";
173
  struct mg_bind_opts opts;
174
  memset(&opts, 0, sizeof(opts));
175
  opts.error_string = &err;
176

    
177
  struct mg_connection *nc = mg_bind(mgr, "80", mg_ev_handler);
178
  if (nc != NULL) {
179
    mg_set_protocol_http_websocket(nc);
180
  } else {
181
    LOG(LL_ERROR, ("Failed to create listener: %s", err));
182
  }
183
}
184

    
185
#ifndef USE_TIRTOS
186
/* Int vector table, defined in startup_gcc.c */
187
extern void (*const g_pfnVectors[])(void);
188
#endif
189

    
190
int main(void) {
191
#ifndef USE_TIRTOS
192
  MAP_IntVTableBaseSet((unsigned long) &g_pfnVectors[0]);
193
#endif
194
  MAP_IntEnable(FAULT_SYSTICK);
195
  MAP_IntMasterEnable();
196
  PRCMCC3200MCUInit();
197

    
198
  setvbuf(stdout, NULL, _IOLBF, 0);
199
  setvbuf(stderr, NULL, _IOLBF, 0);
200
  cs_log_set_level(LL_INFO);
201
  cs_log_set_file(stdout);
202

    
203
  LOG(LL_INFO, ("Hello, world!"));
204

    
205
  /* Set up the red LED. Note that amber and green cannot be used as they share
206
   * pins with I2C. */
207
  MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK);
208
  MAP_PinTypeGPIO(PIN_64, PIN_MODE_0, false);
209
  MAP_GPIODirModeSet(GPIOA1_BASE, 0x2, GPIO_DIR_MODE_OUT);
210
  GPIO_IF_LedConfigure(LED1);
211
  GPIO_IF_LedOn(MCU_RED_LED_GPIO);
212

    
213
  if (VStartSimpleLinkSpawnTask(8) != 0) {
214
    LOG(LL_ERROR, ("Failed to create SL task"));
215
  }
216

    
217
  if (!mg_start_task(MGOS_TASK_PRIORITY, MG_TASK_STACK_SIZE, mg_init)) {
218
    LOG(LL_ERROR, ("Failed to create MG task"));
219
  }
220

    
221
  osi_start();
222

    
223
  return 0;
224
}
225

    
226
/* These are FreeRTOS hooks for various life situations. */
227
void vApplicationMallocFailedHook(void) {
228
}
229

    
230
void vApplicationIdleHook(void) {
231
}
232

    
233
void vApplicationStackOverflowHook(OsiTaskHandle *th, signed char *tn) {
234
}
235

    
236
void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *e,
237
                                  SlHttpServerResponse_t *resp) {
238
}
239

    
240
void SimpleLinkSockEventHandler(SlSockEvent_t *e) {
241
}
242

    
243
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *e) {
244
  LOG(LL_ERROR, ("status %d sender %d", e->EventData.deviceEvent.status,
245
                 e->EventData.deviceEvent.sender));
246
}