Web server based weather station using Sparkfun Weather Meters.
Dependencies: FatFileSystem mbed WeatherMeters SDFileSystem
main.cpp@1:c7958aa34fa1, 2012-02-25 (annotated)
- Committer:
- AdamGreen
- Date:
- Sat Feb 25 03:28:05 2012 +0000
- Revision:
- 1:c7958aa34fa1
- Parent:
- 0:616601bde9fb
Use published libraries where possible.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AdamGreen | 0:616601bde9fb | 1 | /* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/) |
AdamGreen | 0:616601bde9fb | 2 | |
AdamGreen | 0:616601bde9fb | 3 | Licensed under the Apache License, Version 2.0 (the "License"); |
AdamGreen | 0:616601bde9fb | 4 | you may not use this file except in compliance with the License. |
AdamGreen | 0:616601bde9fb | 5 | You may obtain a copy of the License at |
AdamGreen | 0:616601bde9fb | 6 | |
AdamGreen | 0:616601bde9fb | 7 | http://www.apache.org/licenses/LICENSE-2.0 |
AdamGreen | 0:616601bde9fb | 8 | |
AdamGreen | 0:616601bde9fb | 9 | Unless required by applicable law or agreed to in writing, software |
AdamGreen | 0:616601bde9fb | 10 | distributed under the License is distributed on an "AS IS" BASIS, |
AdamGreen | 0:616601bde9fb | 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AdamGreen | 0:616601bde9fb | 12 | See the License for the specific language governing permissions and |
AdamGreen | 0:616601bde9fb | 13 | limitations under the License. |
AdamGreen | 0:616601bde9fb | 14 | */ |
AdamGreen | 0:616601bde9fb | 15 | /* Provides a simple web interface to these weather meters from Sparkfun: |
AdamGreen | 0:616601bde9fb | 16 | http://www.sparkfun.com/products/8942 |
AdamGreen | 0:616601bde9fb | 17 | */ |
AdamGreen | 0:616601bde9fb | 18 | #include <stdarg.h> |
AdamGreen | 0:616601bde9fb | 19 | #include <mbed.h> |
AdamGreen | 0:616601bde9fb | 20 | #include "SDFileSystem.h" |
AdamGreen | 0:616601bde9fb | 21 | #include "network.h" |
AdamGreen | 0:616601bde9fb | 22 | #include "HTTPServer.h" |
AdamGreen | 0:616601bde9fb | 23 | #include "debug.h" |
AdamGreen | 0:616601bde9fb | 24 | #include "homepage.h" |
AdamGreen | 0:616601bde9fb | 25 | #include "WeatherMeters.h" |
AdamGreen | 0:616601bde9fb | 26 | |
AdamGreen | 0:616601bde9fb | 27 | |
AdamGreen | 0:616601bde9fb | 28 | // Name of this sample |
AdamGreen | 0:616601bde9fb | 29 | #define APPLICATION_NAME "WindMeter" |
AdamGreen | 0:616601bde9fb | 30 | |
AdamGreen | 0:616601bde9fb | 31 | // Set to appropriate "#.#.#.#" string for static IP addresses or |
AdamGreen | 0:616601bde9fb | 32 | // set to NULL for DHCP to be used instead. |
AdamGreen | 0:616601bde9fb | 33 | #define HTTP_STATIC_IP_ADDRESS "192.168.0.127" |
AdamGreen | 0:616601bde9fb | 34 | #define HTTP_STATIC_SUBNET_MASK "255.255.255.0" |
AdamGreen | 0:616601bde9fb | 35 | #define HTTP_STATIC_GATEWAY_ADDRESS "192.168.0.1" |
AdamGreen | 0:616601bde9fb | 36 | |
AdamGreen | 0:616601bde9fb | 37 | // Name of this device to be use with DHCP server. |
AdamGreen | 0:616601bde9fb | 38 | #define HTTP_HOST_NAME "WindMeter" |
AdamGreen | 0:616601bde9fb | 39 | |
AdamGreen | 0:616601bde9fb | 40 | // Port to which the HTTP server is to be bound. The well known port number |
AdamGreen | 0:616601bde9fb | 41 | // for HTTP is 80. |
AdamGreen | 0:616601bde9fb | 42 | #define HTTP_PORT 80 |
AdamGreen | 0:616601bde9fb | 43 | |
AdamGreen | 0:616601bde9fb | 44 | // String used to identify this sample HTTP server to the client. |
AdamGreen | 0:616601bde9fb | 45 | #define HTTP_SERVER_NAME "lwIPHTTPServer/1.0" |
AdamGreen | 0:616601bde9fb | 46 | |
AdamGreen | 0:616601bde9fb | 47 | // Root name of filesystem to be used for HTTP server sample. |
AdamGreen | 0:616601bde9fb | 48 | #define ROOT_FILESYSTEM_NAME "SD/webfs" |
AdamGreen | 0:616601bde9fb | 49 | |
AdamGreen | 0:616601bde9fb | 50 | // Where the SHttpServer structure containing the HTTP_BUFFER_POOL should be |
AdamGreen | 0:616601bde9fb | 51 | // placed in the device's memory. |
AdamGreen | 0:616601bde9fb | 52 | #define HTTP_MEM_POSITION __attribute((section("AHBSRAM0"),aligned)) |
AdamGreen | 0:616601bde9fb | 53 | |
AdamGreen | 0:616601bde9fb | 54 | // Utility macro to determine the element count of an array. |
AdamGreen | 0:616601bde9fb | 55 | #define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0])) |
AdamGreen | 0:616601bde9fb | 56 | |
AdamGreen | 0:616601bde9fb | 57 | |
AdamGreen | 0:616601bde9fb | 58 | |
AdamGreen | 0:616601bde9fb | 59 | // GET request handler context which bases HTML on printf() substituion. |
AdamGreen | 0:616601bde9fb | 60 | class CPrintfGetRequestHandlerContext : public IHTTPRequestHandlerContext |
AdamGreen | 0:616601bde9fb | 61 | { |
AdamGreen | 0:616601bde9fb | 62 | public: |
AdamGreen | 0:616601bde9fb | 63 | // Constructors / Destructors |
AdamGreen | 0:616601bde9fb | 64 | CPrintfGetRequestHandlerContext(const char* pStatusLine, |
AdamGreen | 0:616601bde9fb | 65 | size_t StatusLineSize, |
AdamGreen | 0:616601bde9fb | 66 | const char* pHeaders, |
AdamGreen | 0:616601bde9fb | 67 | size_t HeaderSize) |
AdamGreen | 0:616601bde9fb | 68 | { |
AdamGreen | 0:616601bde9fb | 69 | m_pContent = NULL; |
AdamGreen | 0:616601bde9fb | 70 | m_pCurrent = NULL; |
AdamGreen | 0:616601bde9fb | 71 | m_ContentSize = 0; |
AdamGreen | 0:616601bde9fb | 72 | m_pStatusLine = pStatusLine; |
AdamGreen | 0:616601bde9fb | 73 | m_StatusLineSize = StatusLineSize; |
AdamGreen | 0:616601bde9fb | 74 | m_pHeaders = pHeaders; |
AdamGreen | 0:616601bde9fb | 75 | m_HeaderSize = HeaderSize; |
AdamGreen | 0:616601bde9fb | 76 | } |
AdamGreen | 0:616601bde9fb | 77 | ~CPrintfGetRequestHandlerContext() |
AdamGreen | 0:616601bde9fb | 78 | { |
AdamGreen | 0:616601bde9fb | 79 | free(m_pContent); |
AdamGreen | 0:616601bde9fb | 80 | m_pContent = NULL; |
AdamGreen | 0:616601bde9fb | 81 | m_pCurrent = NULL; |
AdamGreen | 0:616601bde9fb | 82 | m_pHeaders = NULL; |
AdamGreen | 0:616601bde9fb | 83 | m_pStatusLine = NULL; |
AdamGreen | 0:616601bde9fb | 84 | m_ContentSize = 0; |
AdamGreen | 0:616601bde9fb | 85 | m_HeaderSize = 0; |
AdamGreen | 0:616601bde9fb | 86 | m_StatusLineSize = 0; |
AdamGreen | 0:616601bde9fb | 87 | } |
AdamGreen | 0:616601bde9fb | 88 | |
AdamGreen | 0:616601bde9fb | 89 | int printf(const char* pFormat, ...) |
AdamGreen | 0:616601bde9fb | 90 | { |
AdamGreen | 0:616601bde9fb | 91 | va_list ArgList; |
AdamGreen | 0:616601bde9fb | 92 | int RequiredBufferSize; |
AdamGreen | 0:616601bde9fb | 93 | |
AdamGreen | 0:616601bde9fb | 94 | // Only expect this to be called once. |
AdamGreen | 0:616601bde9fb | 95 | assert ( NULL == m_pContent && 0 == m_ContentSize ); |
AdamGreen | 0:616601bde9fb | 96 | |
AdamGreen | 0:616601bde9fb | 97 | // How big does the HTML content buffer need to be? |
AdamGreen | 0:616601bde9fb | 98 | va_start(ArgList, pFormat); |
AdamGreen | 0:616601bde9fb | 99 | RequiredBufferSize = vsnprintf(NULL, 0, pFormat, ArgList); |
AdamGreen | 0:616601bde9fb | 100 | va_end(ArgList); |
AdamGreen | 0:616601bde9fb | 101 | |
AdamGreen | 0:616601bde9fb | 102 | // Check for error. |
AdamGreen | 0:616601bde9fb | 103 | if (RequiredBufferSize < 0) |
AdamGreen | 0:616601bde9fb | 104 | { |
AdamGreen | 0:616601bde9fb | 105 | return RequiredBufferSize; |
AdamGreen | 0:616601bde9fb | 106 | } |
AdamGreen | 0:616601bde9fb | 107 | |
AdamGreen | 0:616601bde9fb | 108 | // Allow space for the NULL terminator. |
AdamGreen | 0:616601bde9fb | 109 | RequiredBufferSize++; |
AdamGreen | 0:616601bde9fb | 110 | |
AdamGreen | 0:616601bde9fb | 111 | // Attempt to allocate a buffer of adequate size. |
AdamGreen | 0:616601bde9fb | 112 | m_pContent = (char*)malloc(RequiredBufferSize); |
AdamGreen | 0:616601bde9fb | 113 | if (!m_pContent) |
AdamGreen | 0:616601bde9fb | 114 | { |
AdamGreen | 0:616601bde9fb | 115 | return -1; |
AdamGreen | 0:616601bde9fb | 116 | } |
AdamGreen | 0:616601bde9fb | 117 | m_ContentSize = RequiredBufferSize; |
AdamGreen | 0:616601bde9fb | 118 | m_pCurrent = m_pContent; |
AdamGreen | 0:616601bde9fb | 119 | |
AdamGreen | 0:616601bde9fb | 120 | // Place the HTML content into the newly allocated buffer. |
AdamGreen | 0:616601bde9fb | 121 | va_start(ArgList, pFormat); |
AdamGreen | 0:616601bde9fb | 122 | RequiredBufferSize = vsnprintf(m_pContent, m_ContentSize, pFormat, ArgList); |
AdamGreen | 0:616601bde9fb | 123 | va_end(ArgList); |
AdamGreen | 0:616601bde9fb | 124 | |
AdamGreen | 0:616601bde9fb | 125 | // Make sure that nothing has changed out from underneath us. |
AdamGreen | 0:616601bde9fb | 126 | assert ( (int)m_ContentSize == RequiredBufferSize+1 ); |
AdamGreen | 0:616601bde9fb | 127 | |
AdamGreen | 0:616601bde9fb | 128 | return RequiredBufferSize + 1; |
AdamGreen | 0:616601bde9fb | 129 | } |
AdamGreen | 0:616601bde9fb | 130 | |
AdamGreen | 0:616601bde9fb | 131 | // IHTTPRequestHandlerContext interface methods. |
AdamGreen | 0:616601bde9fb | 132 | virtual int BeginRequestHeaders() |
AdamGreen | 0:616601bde9fb | 133 | { |
AdamGreen | 0:616601bde9fb | 134 | // Ignore request headers. |
AdamGreen | 0:616601bde9fb | 135 | return 0; |
AdamGreen | 0:616601bde9fb | 136 | } |
AdamGreen | 0:616601bde9fb | 137 | virtual void WriteRequestHeader(const char* pHeaderName, |
AdamGreen | 0:616601bde9fb | 138 | const char* pHeaderValue) |
AdamGreen | 0:616601bde9fb | 139 | { |
AdamGreen | 0:616601bde9fb | 140 | // Unused parameters. |
AdamGreen | 0:616601bde9fb | 141 | (void)pHeaderName; |
AdamGreen | 0:616601bde9fb | 142 | (void)pHeaderValue; |
AdamGreen | 0:616601bde9fb | 143 | |
AdamGreen | 0:616601bde9fb | 144 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 145 | } |
AdamGreen | 0:616601bde9fb | 146 | |
AdamGreen | 0:616601bde9fb | 147 | virtual void EndRequestHeaders() |
AdamGreen | 0:616601bde9fb | 148 | { |
AdamGreen | 0:616601bde9fb | 149 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 150 | } |
AdamGreen | 0:616601bde9fb | 151 | |
AdamGreen | 0:616601bde9fb | 152 | virtual int BeginRequestContent(size_t ContentSize) |
AdamGreen | 0:616601bde9fb | 153 | { |
AdamGreen | 0:616601bde9fb | 154 | // Ignore request content body. |
AdamGreen | 0:616601bde9fb | 155 | (void)ContentSize; |
AdamGreen | 0:616601bde9fb | 156 | return 0; |
AdamGreen | 0:616601bde9fb | 157 | } |
AdamGreen | 0:616601bde9fb | 158 | |
AdamGreen | 0:616601bde9fb | 159 | virtual void WriteRequestContentBlock(const void* pBlockBuffer, |
AdamGreen | 0:616601bde9fb | 160 | size_t BlockBufferSize) |
AdamGreen | 0:616601bde9fb | 161 | { |
AdamGreen | 0:616601bde9fb | 162 | (void)pBlockBuffer; |
AdamGreen | 0:616601bde9fb | 163 | (void)BlockBufferSize; |
AdamGreen | 0:616601bde9fb | 164 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 165 | } |
AdamGreen | 0:616601bde9fb | 166 | |
AdamGreen | 0:616601bde9fb | 167 | virtual void EndRequestContent() |
AdamGreen | 0:616601bde9fb | 168 | { |
AdamGreen | 0:616601bde9fb | 169 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 170 | } |
AdamGreen | 0:616601bde9fb | 171 | |
AdamGreen | 0:616601bde9fb | 172 | virtual const char* GetStatusLine(size_t* pStatusLineLength) |
AdamGreen | 0:616601bde9fb | 173 | { |
AdamGreen | 0:616601bde9fb | 174 | *pStatusLineLength = m_StatusLineSize; |
AdamGreen | 0:616601bde9fb | 175 | return m_pStatusLine; |
AdamGreen | 0:616601bde9fb | 176 | } |
AdamGreen | 0:616601bde9fb | 177 | |
AdamGreen | 0:616601bde9fb | 178 | virtual const char* GetResponseHeaders(size_t* pResponseHeaderLength) |
AdamGreen | 0:616601bde9fb | 179 | { |
AdamGreen | 0:616601bde9fb | 180 | *pResponseHeaderLength = m_HeaderSize; |
AdamGreen | 0:616601bde9fb | 181 | return m_pHeaders; |
AdamGreen | 0:616601bde9fb | 182 | } |
AdamGreen | 0:616601bde9fb | 183 | |
AdamGreen | 0:616601bde9fb | 184 | virtual int BeginResponseContent() |
AdamGreen | 0:616601bde9fb | 185 | { |
AdamGreen | 0:616601bde9fb | 186 | assert (m_pContent); |
AdamGreen | 0:616601bde9fb | 187 | |
AdamGreen | 0:616601bde9fb | 188 | // We have data to be sent back to client. |
AdamGreen | 0:616601bde9fb | 189 | m_pCurrent = m_pContent; |
AdamGreen | 0:616601bde9fb | 190 | return 1; |
AdamGreen | 0:616601bde9fb | 191 | } |
AdamGreen | 0:616601bde9fb | 192 | |
AdamGreen | 0:616601bde9fb | 193 | virtual size_t ReadResponseContentBlock(char* pBuffer, |
AdamGreen | 0:616601bde9fb | 194 | size_t BytesToRead) |
AdamGreen | 0:616601bde9fb | 195 | { |
AdamGreen | 0:616601bde9fb | 196 | size_t BytesAlreadyRead = m_pCurrent - m_pContent; |
AdamGreen | 0:616601bde9fb | 197 | size_t BytesLeft = m_ContentSize - BytesAlreadyRead; |
AdamGreen | 0:616601bde9fb | 198 | |
AdamGreen | 0:616601bde9fb | 199 | if (BytesToRead > BytesLeft) |
AdamGreen | 0:616601bde9fb | 200 | { |
AdamGreen | 0:616601bde9fb | 201 | BytesToRead = BytesLeft; |
AdamGreen | 0:616601bde9fb | 202 | } |
AdamGreen | 0:616601bde9fb | 203 | |
AdamGreen | 0:616601bde9fb | 204 | memcpy(pBuffer, m_pCurrent, BytesToRead); |
AdamGreen | 0:616601bde9fb | 205 | m_pCurrent += BytesToRead; |
AdamGreen | 0:616601bde9fb | 206 | |
AdamGreen | 0:616601bde9fb | 207 | return BytesToRead; |
AdamGreen | 0:616601bde9fb | 208 | } |
AdamGreen | 0:616601bde9fb | 209 | |
AdamGreen | 0:616601bde9fb | 210 | virtual void EndResponseContent() |
AdamGreen | 0:616601bde9fb | 211 | { |
AdamGreen | 0:616601bde9fb | 212 | } |
AdamGreen | 0:616601bde9fb | 213 | |
AdamGreen | 0:616601bde9fb | 214 | virtual void Release() |
AdamGreen | 0:616601bde9fb | 215 | { |
AdamGreen | 0:616601bde9fb | 216 | delete this; |
AdamGreen | 0:616601bde9fb | 217 | } |
AdamGreen | 0:616601bde9fb | 218 | |
AdamGreen | 0:616601bde9fb | 219 | protected: |
AdamGreen | 0:616601bde9fb | 220 | char* m_pContent; |
AdamGreen | 0:616601bde9fb | 221 | const char* m_pCurrent; |
AdamGreen | 0:616601bde9fb | 222 | const char* m_pStatusLine; |
AdamGreen | 0:616601bde9fb | 223 | const char* m_pHeaders; |
AdamGreen | 0:616601bde9fb | 224 | size_t m_ContentSize; |
AdamGreen | 0:616601bde9fb | 225 | size_t m_StatusLineSize; |
AdamGreen | 0:616601bde9fb | 226 | size_t m_HeaderSize; |
AdamGreen | 0:616601bde9fb | 227 | }; |
AdamGreen | 0:616601bde9fb | 228 | |
AdamGreen | 0:616601bde9fb | 229 | |
AdamGreen | 0:616601bde9fb | 230 | // Request handler context which pulls content from file handle. |
AdamGreen | 0:616601bde9fb | 231 | class CFileRequestHandlerContext : public IHTTPRequestHandlerContext |
AdamGreen | 0:616601bde9fb | 232 | { |
AdamGreen | 0:616601bde9fb | 233 | public: |
AdamGreen | 0:616601bde9fb | 234 | // Constructors / Destructors |
AdamGreen | 0:616601bde9fb | 235 | CFileRequestHandlerContext(FILE* pFile, |
AdamGreen | 0:616601bde9fb | 236 | const char* pStatusLine, |
AdamGreen | 0:616601bde9fb | 237 | size_t StatusLineSize, |
AdamGreen | 0:616601bde9fb | 238 | const char* pHeaders, |
AdamGreen | 0:616601bde9fb | 239 | size_t HeaderSize) |
AdamGreen | 0:616601bde9fb | 240 | { |
AdamGreen | 0:616601bde9fb | 241 | m_pFile = pFile; |
AdamGreen | 0:616601bde9fb | 242 | m_pStatusLine = pStatusLine; |
AdamGreen | 0:616601bde9fb | 243 | m_StatusLineSize = StatusLineSize; |
AdamGreen | 0:616601bde9fb | 244 | m_pHeaders = pHeaders; |
AdamGreen | 0:616601bde9fb | 245 | m_HeaderSize = HeaderSize; |
AdamGreen | 0:616601bde9fb | 246 | } |
AdamGreen | 0:616601bde9fb | 247 | ~CFileRequestHandlerContext() |
AdamGreen | 0:616601bde9fb | 248 | { |
AdamGreen | 0:616601bde9fb | 249 | // Make sure that file handle isn't being leaked. |
AdamGreen | 0:616601bde9fb | 250 | assert ( !m_pFile ); |
AdamGreen | 0:616601bde9fb | 251 | m_pHeaders = NULL; |
AdamGreen | 0:616601bde9fb | 252 | m_pStatusLine = NULL; |
AdamGreen | 0:616601bde9fb | 253 | m_HeaderSize = 0; |
AdamGreen | 0:616601bde9fb | 254 | m_StatusLineSize = 0; |
AdamGreen | 0:616601bde9fb | 255 | } |
AdamGreen | 0:616601bde9fb | 256 | |
AdamGreen | 0:616601bde9fb | 257 | // IHTTPRequestHandlerContext interface methods. |
AdamGreen | 0:616601bde9fb | 258 | virtual int BeginRequestHeaders() |
AdamGreen | 0:616601bde9fb | 259 | { |
AdamGreen | 0:616601bde9fb | 260 | // Ignore request headers. |
AdamGreen | 0:616601bde9fb | 261 | return 0; |
AdamGreen | 0:616601bde9fb | 262 | } |
AdamGreen | 0:616601bde9fb | 263 | virtual void WriteRequestHeader(const char* pHeaderName, |
AdamGreen | 0:616601bde9fb | 264 | const char* pHeaderValue) |
AdamGreen | 0:616601bde9fb | 265 | { |
AdamGreen | 0:616601bde9fb | 266 | (void)pHeaderName; |
AdamGreen | 0:616601bde9fb | 267 | (void)pHeaderValue; |
AdamGreen | 0:616601bde9fb | 268 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 269 | } |
AdamGreen | 0:616601bde9fb | 270 | |
AdamGreen | 0:616601bde9fb | 271 | virtual void EndRequestHeaders() |
AdamGreen | 0:616601bde9fb | 272 | { |
AdamGreen | 0:616601bde9fb | 273 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 274 | } |
AdamGreen | 0:616601bde9fb | 275 | |
AdamGreen | 0:616601bde9fb | 276 | virtual int BeginRequestContent(size_t ContentSize) |
AdamGreen | 0:616601bde9fb | 277 | { |
AdamGreen | 0:616601bde9fb | 278 | // Ignore request content body. |
AdamGreen | 0:616601bde9fb | 279 | (void)ContentSize; |
AdamGreen | 0:616601bde9fb | 280 | return 0; |
AdamGreen | 0:616601bde9fb | 281 | } |
AdamGreen | 0:616601bde9fb | 282 | |
AdamGreen | 0:616601bde9fb | 283 | virtual void WriteRequestContentBlock(const void* pBlockBuffer, |
AdamGreen | 0:616601bde9fb | 284 | size_t BlockBufferSize) |
AdamGreen | 0:616601bde9fb | 285 | { |
AdamGreen | 0:616601bde9fb | 286 | (void)pBlockBuffer; |
AdamGreen | 0:616601bde9fb | 287 | (void)BlockBufferSize; |
AdamGreen | 0:616601bde9fb | 288 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 289 | } |
AdamGreen | 0:616601bde9fb | 290 | |
AdamGreen | 0:616601bde9fb | 291 | virtual void EndRequestContent() |
AdamGreen | 0:616601bde9fb | 292 | { |
AdamGreen | 0:616601bde9fb | 293 | assert ( FALSE ); |
AdamGreen | 0:616601bde9fb | 294 | } |
AdamGreen | 0:616601bde9fb | 295 | |
AdamGreen | 0:616601bde9fb | 296 | virtual const char* GetStatusLine(size_t* pStatusLineLength) |
AdamGreen | 0:616601bde9fb | 297 | { |
AdamGreen | 0:616601bde9fb | 298 | *pStatusLineLength = m_StatusLineSize; |
AdamGreen | 0:616601bde9fb | 299 | return m_pStatusLine; |
AdamGreen | 0:616601bde9fb | 300 | } |
AdamGreen | 0:616601bde9fb | 301 | |
AdamGreen | 0:616601bde9fb | 302 | virtual const char* GetResponseHeaders(size_t* pResponseHeaderLength) |
AdamGreen | 0:616601bde9fb | 303 | { |
AdamGreen | 0:616601bde9fb | 304 | *pResponseHeaderLength = m_HeaderSize; |
AdamGreen | 0:616601bde9fb | 305 | return m_pHeaders; |
AdamGreen | 0:616601bde9fb | 306 | } |
AdamGreen | 0:616601bde9fb | 307 | |
AdamGreen | 0:616601bde9fb | 308 | virtual int BeginResponseContent() |
AdamGreen | 0:616601bde9fb | 309 | { |
AdamGreen | 0:616601bde9fb | 310 | assert (m_pFile); |
AdamGreen | 0:616601bde9fb | 311 | |
AdamGreen | 0:616601bde9fb | 312 | // We have data to be sent back to client. |
AdamGreen | 0:616601bde9fb | 313 | return 1; |
AdamGreen | 0:616601bde9fb | 314 | } |
AdamGreen | 0:616601bde9fb | 315 | |
AdamGreen | 0:616601bde9fb | 316 | virtual size_t ReadResponseContentBlock(char* pBuffer, |
AdamGreen | 0:616601bde9fb | 317 | size_t BytesToRead) |
AdamGreen | 0:616601bde9fb | 318 | { |
AdamGreen | 0:616601bde9fb | 319 | return fread(pBuffer, 1, BytesToRead, m_pFile); |
AdamGreen | 0:616601bde9fb | 320 | } |
AdamGreen | 0:616601bde9fb | 321 | |
AdamGreen | 0:616601bde9fb | 322 | virtual void EndResponseContent() |
AdamGreen | 0:616601bde9fb | 323 | { |
AdamGreen | 0:616601bde9fb | 324 | if (m_pFile) |
AdamGreen | 0:616601bde9fb | 325 | { |
AdamGreen | 0:616601bde9fb | 326 | fclose(m_pFile); |
AdamGreen | 0:616601bde9fb | 327 | m_pFile = NULL; |
AdamGreen | 0:616601bde9fb | 328 | } |
AdamGreen | 0:616601bde9fb | 329 | } |
AdamGreen | 0:616601bde9fb | 330 | |
AdamGreen | 0:616601bde9fb | 331 | virtual void Release() |
AdamGreen | 0:616601bde9fb | 332 | { |
AdamGreen | 0:616601bde9fb | 333 | EndResponseContent(); |
AdamGreen | 0:616601bde9fb | 334 | delete this; |
AdamGreen | 0:616601bde9fb | 335 | } |
AdamGreen | 0:616601bde9fb | 336 | |
AdamGreen | 0:616601bde9fb | 337 | protected: |
AdamGreen | 0:616601bde9fb | 338 | FILE* m_pFile; |
AdamGreen | 0:616601bde9fb | 339 | const char* m_pStatusLine; |
AdamGreen | 0:616601bde9fb | 340 | const char* m_pHeaders; |
AdamGreen | 0:616601bde9fb | 341 | size_t m_StatusLineSize; |
AdamGreen | 0:616601bde9fb | 342 | size_t m_HeaderSize; |
AdamGreen | 0:616601bde9fb | 343 | }; |
AdamGreen | 0:616601bde9fb | 344 | |
AdamGreen | 0:616601bde9fb | 345 | |
AdamGreen | 0:616601bde9fb | 346 | // Class to test application request handler overrides. |
AdamGreen | 0:616601bde9fb | 347 | class CWindMeterRequestHandler : public IHTTPRequestHandler |
AdamGreen | 0:616601bde9fb | 348 | { |
AdamGreen | 0:616601bde9fb | 349 | public: |
AdamGreen | 0:616601bde9fb | 350 | // Constructors/Destructors |
AdamGreen | 0:616601bde9fb | 351 | CWindMeterRequestHandler(); |
AdamGreen | 0:616601bde9fb | 352 | |
AdamGreen | 0:616601bde9fb | 353 | // IHTTPRequestHandler interface methods. |
AdamGreen | 0:616601bde9fb | 354 | virtual IHTTPRequestHandlerContext* HandleGetRequest(const char* pURI); |
AdamGreen | 0:616601bde9fb | 355 | virtual IHTTPRequestHandlerContext* HandleHeadRequest(const char* pURI); |
AdamGreen | 0:616601bde9fb | 356 | virtual IHTTPRequestHandlerContext* HandlePostRequest(const char* pURI); |
AdamGreen | 0:616601bde9fb | 357 | virtual IHTTPRequestHandlerContext* HandleBadRequest(const char* pRequest); |
AdamGreen | 0:616601bde9fb | 358 | |
AdamGreen | 0:616601bde9fb | 359 | protected: |
AdamGreen | 0:616601bde9fb | 360 | IHTTPRequestHandlerContext* HandleRequest(const char* pURI); |
AdamGreen | 0:616601bde9fb | 361 | void MinuteTickerISR(); |
AdamGreen | 0:616601bde9fb | 362 | |
AdamGreen | 0:616601bde9fb | 363 | CWeatherMeters m_WeatherMeters; |
AdamGreen | 0:616601bde9fb | 364 | Ticker m_MinuteTicker; |
AdamGreen | 0:616601bde9fb | 365 | }; |
AdamGreen | 0:616601bde9fb | 366 | |
AdamGreen | 0:616601bde9fb | 367 | |
AdamGreen | 0:616601bde9fb | 368 | CWindMeterRequestHandler::CWindMeterRequestHandler() |
AdamGreen | 0:616601bde9fb | 369 | : m_WeatherMeters(p9, p10, p15) |
AdamGreen | 0:616601bde9fb | 370 | { |
AdamGreen | 0:616601bde9fb | 371 | m_MinuteTicker.attach_us<CWindMeterRequestHandler>(this, &CWindMeterRequestHandler::MinuteTickerISR, 60000000); |
AdamGreen | 0:616601bde9fb | 372 | } |
AdamGreen | 0:616601bde9fb | 373 | |
AdamGreen | 0:616601bde9fb | 374 | |
AdamGreen | 0:616601bde9fb | 375 | void CWindMeterRequestHandler::MinuteTickerISR() |
AdamGreen | 0:616601bde9fb | 376 | { |
AdamGreen | 0:616601bde9fb | 377 | CWeatherMeters::SMeasurements Measurements; |
AdamGreen | 0:616601bde9fb | 378 | |
AdamGreen | 0:616601bde9fb | 379 | m_WeatherMeters.GetMeasurements(&Measurements); |
AdamGreen | 0:616601bde9fb | 380 | } |
AdamGreen | 0:616601bde9fb | 381 | |
AdamGreen | 0:616601bde9fb | 382 | |
AdamGreen | 0:616601bde9fb | 383 | IHTTPRequestHandlerContext* CWindMeterRequestHandler::HandleGetRequest(const char* pURI) |
AdamGreen | 0:616601bde9fb | 384 | { |
AdamGreen | 0:616601bde9fb | 385 | return HandleRequest(pURI); |
AdamGreen | 0:616601bde9fb | 386 | } |
AdamGreen | 0:616601bde9fb | 387 | |
AdamGreen | 0:616601bde9fb | 388 | IHTTPRequestHandlerContext* CWindMeterRequestHandler::HandleHeadRequest(const char* pURI) |
AdamGreen | 0:616601bde9fb | 389 | { |
AdamGreen | 0:616601bde9fb | 390 | return HandleRequest(pURI); |
AdamGreen | 0:616601bde9fb | 391 | } |
AdamGreen | 0:616601bde9fb | 392 | |
AdamGreen | 0:616601bde9fb | 393 | IHTTPRequestHandlerContext* CWindMeterRequestHandler::HandleRequest(const char* pURI) |
AdamGreen | 0:616601bde9fb | 394 | { |
AdamGreen | 0:616601bde9fb | 395 | // Generate content for root home page. |
AdamGreen | 0:616601bde9fb | 396 | if (0 == strcmp(pURI, "/")) |
AdamGreen | 0:616601bde9fb | 397 | { |
AdamGreen | 0:616601bde9fb | 398 | CWeatherMeters::SMeasurements Measurements; |
AdamGreen | 0:616601bde9fb | 399 | |
AdamGreen | 0:616601bde9fb | 400 | CPrintfGetRequestHandlerContext* pContext = new CPrintfGetRequestHandlerContext(g_OkStatusLine, |
AdamGreen | 0:616601bde9fb | 401 | sizeof(g_OkStatusLine)-1, |
AdamGreen | 0:616601bde9fb | 402 | g_HTMLHeaders, |
AdamGreen | 0:616601bde9fb | 403 | sizeof(g_HTMLHeaders)-1); |
AdamGreen | 0:616601bde9fb | 404 | if (!pContext) |
AdamGreen | 0:616601bde9fb | 405 | { |
AdamGreen | 0:616601bde9fb | 406 | return NULL; |
AdamGreen | 0:616601bde9fb | 407 | } |
AdamGreen | 0:616601bde9fb | 408 | |
AdamGreen | 0:616601bde9fb | 409 | m_WeatherMeters.GetMeasurements(&Measurements); |
AdamGreen | 0:616601bde9fb | 410 | pContext->printf(g_HomePageHTML, |
AdamGreen | 0:616601bde9fb | 411 | Measurements.WindSpeed, |
AdamGreen | 0:616601bde9fb | 412 | Measurements.MaximumWindSpeed, |
AdamGreen | 0:616601bde9fb | 413 | Measurements.WindDirectionString, |
AdamGreen | 0:616601bde9fb | 414 | Measurements.Rainfall, |
AdamGreen | 0:616601bde9fb | 415 | "? minutes"); |
AdamGreen | 0:616601bde9fb | 416 | |
AdamGreen | 0:616601bde9fb | 417 | return pContext; |
AdamGreen | 0:616601bde9fb | 418 | } |
AdamGreen | 0:616601bde9fb | 419 | |
AdamGreen | 0:616601bde9fb | 420 | return NULL; |
AdamGreen | 0:616601bde9fb | 421 | } |
AdamGreen | 0:616601bde9fb | 422 | |
AdamGreen | 0:616601bde9fb | 423 | IHTTPRequestHandlerContext* CWindMeterRequestHandler::HandlePostRequest(const char* pURI) |
AdamGreen | 0:616601bde9fb | 424 | { |
AdamGreen | 0:616601bde9fb | 425 | if (0 == strcmp(pURI, "/reset.html")) |
AdamGreen | 0:616601bde9fb | 426 | { |
AdamGreen | 0:616601bde9fb | 427 | FILE* pFile; |
AdamGreen | 0:616601bde9fb | 428 | |
AdamGreen | 0:616601bde9fb | 429 | m_WeatherMeters.Reset(); |
AdamGreen | 0:616601bde9fb | 430 | |
AdamGreen | 0:616601bde9fb | 431 | pFile = fopen("/" ROOT_FILESYSTEM_NAME "/reset.html", "r"); |
AdamGreen | 0:616601bde9fb | 432 | if (pFile) |
AdamGreen | 0:616601bde9fb | 433 | { |
AdamGreen | 0:616601bde9fb | 434 | static const char StatusLine[] = "HTTP/1.0 200 OK\r\n"; |
AdamGreen | 0:616601bde9fb | 435 | static const char Headers[] = "Content-type: text/html\r\n"; |
AdamGreen | 0:616601bde9fb | 436 | |
AdamGreen | 0:616601bde9fb | 437 | CFileRequestHandlerContext* pRequestHandlerContext = new CFileRequestHandlerContext(pFile, |
AdamGreen | 0:616601bde9fb | 438 | StatusLine, |
AdamGreen | 0:616601bde9fb | 439 | sizeof(StatusLine)-1, |
AdamGreen | 0:616601bde9fb | 440 | Headers, |
AdamGreen | 0:616601bde9fb | 441 | sizeof(Headers)-1); |
AdamGreen | 0:616601bde9fb | 442 | if (!pRequestHandlerContext) |
AdamGreen | 0:616601bde9fb | 443 | { |
AdamGreen | 0:616601bde9fb | 444 | fclose(pFile); |
AdamGreen | 0:616601bde9fb | 445 | } |
AdamGreen | 0:616601bde9fb | 446 | |
AdamGreen | 0:616601bde9fb | 447 | return pRequestHandlerContext; |
AdamGreen | 0:616601bde9fb | 448 | } |
AdamGreen | 0:616601bde9fb | 449 | } |
AdamGreen | 0:616601bde9fb | 450 | |
AdamGreen | 0:616601bde9fb | 451 | return NULL; |
AdamGreen | 0:616601bde9fb | 452 | } |
AdamGreen | 0:616601bde9fb | 453 | |
AdamGreen | 0:616601bde9fb | 454 | IHTTPRequestHandlerContext* CWindMeterRequestHandler::HandleBadRequest(const char* pRequest) |
AdamGreen | 0:616601bde9fb | 455 | { |
AdamGreen | 0:616601bde9fb | 456 | // Unused parameters. |
AdamGreen | 0:616601bde9fb | 457 | (void)pRequest; |
AdamGreen | 0:616601bde9fb | 458 | |
AdamGreen | 0:616601bde9fb | 459 | return NULL; |
AdamGreen | 0:616601bde9fb | 460 | } |
AdamGreen | 0:616601bde9fb | 461 | |
AdamGreen | 0:616601bde9fb | 462 | |
AdamGreen | 0:616601bde9fb | 463 | |
AdamGreen | 0:616601bde9fb | 464 | int main() |
AdamGreen | 0:616601bde9fb | 465 | { |
AdamGreen | 0:616601bde9fb | 466 | int Result = 1; |
AdamGreen | 0:616601bde9fb | 467 | DigitalOut ProgressLED(LED1); |
AdamGreen | 0:616601bde9fb | 468 | Timer BlinkTimer; |
AdamGreen | 0:616601bde9fb | 469 | static SNetwork Network; |
AdamGreen | 0:616601bde9fb | 470 | static HTTP_MEM_POSITION CHTTPServer HTTPServer; |
AdamGreen | 0:616601bde9fb | 471 | static CWindMeterRequestHandler WindMeterRequestHandler; |
AdamGreen | 0:616601bde9fb | 472 | |
AdamGreen | 0:616601bde9fb | 473 | printf("\r\n" APPLICATION_NAME "\r\n"); |
AdamGreen | 0:616601bde9fb | 474 | |
AdamGreen | 0:616601bde9fb | 475 | // Create the SD based file system. |
AdamGreen | 0:616601bde9fb | 476 | static SDFileSystem sd(p5, p6, p7, p8, "SD"); |
AdamGreen | 0:616601bde9fb | 477 | |
AdamGreen | 0:616601bde9fb | 478 | // Initialize the ethernet driver and lwIP network stack. |
AdamGreen | 0:616601bde9fb | 479 | Result = SNetwork_Init(&Network, |
AdamGreen | 0:616601bde9fb | 480 | HTTP_STATIC_IP_ADDRESS, |
AdamGreen | 0:616601bde9fb | 481 | HTTP_STATIC_SUBNET_MASK, |
AdamGreen | 0:616601bde9fb | 482 | HTTP_STATIC_GATEWAY_ADDRESS, |
AdamGreen | 0:616601bde9fb | 483 | HTTP_HOST_NAME); |
AdamGreen | 0:616601bde9fb | 484 | if (Result) |
AdamGreen | 0:616601bde9fb | 485 | { |
AdamGreen | 0:616601bde9fb | 486 | error("Failed to initialize network.\r\n"); |
AdamGreen | 0:616601bde9fb | 487 | } |
AdamGreen | 0:616601bde9fb | 488 | |
AdamGreen | 0:616601bde9fb | 489 | // Register test request handler for handling HTTP requests. |
AdamGreen | 0:616601bde9fb | 490 | HTTPServer.AttachRequestHandler(&WindMeterRequestHandler); |
AdamGreen | 0:616601bde9fb | 491 | |
AdamGreen | 0:616601bde9fb | 492 | // Setup a HTTP server to listen on port 80. |
AdamGreen | 0:616601bde9fb | 493 | Result = HTTPServer.Bind(ROOT_FILESYSTEM_NAME, HTTP_SERVER_NAME, HTTP_PORT); |
AdamGreen | 0:616601bde9fb | 494 | if (Result) |
AdamGreen | 0:616601bde9fb | 495 | { |
AdamGreen | 0:616601bde9fb | 496 | error("Failed to initialize for receiving HTTP requests.\r\n"); |
AdamGreen | 0:616601bde9fb | 497 | } |
AdamGreen | 0:616601bde9fb | 498 | |
AdamGreen | 0:616601bde9fb | 499 | // Enter the main application loop. |
AdamGreen | 0:616601bde9fb | 500 | BlinkTimer.start(); |
AdamGreen | 0:616601bde9fb | 501 | while(1) |
AdamGreen | 0:616601bde9fb | 502 | { |
AdamGreen | 0:616601bde9fb | 503 | // Allow the network stack to do its thing. It will callback into the |
AdamGreen | 0:616601bde9fb | 504 | // application callbacks as necessary to complete the actual work |
AdamGreen | 0:616601bde9fb | 505 | // required for a simple HTTP server implementation. |
AdamGreen | 0:616601bde9fb | 506 | SNetwork_Poll(&Network); |
AdamGreen | 0:616601bde9fb | 507 | |
AdamGreen | 0:616601bde9fb | 508 | // Blink the progress LED once each half second to let user know that |
AdamGreen | 0:616601bde9fb | 509 | // we haven't hung. |
AdamGreen | 0:616601bde9fb | 510 | if (BlinkTimer.read_ms() > 500) |
AdamGreen | 0:616601bde9fb | 511 | { |
AdamGreen | 0:616601bde9fb | 512 | BlinkTimer.reset(); |
AdamGreen | 0:616601bde9fb | 513 | ProgressLED = !ProgressLED; |
AdamGreen | 0:616601bde9fb | 514 | } |
AdamGreen | 0:616601bde9fb | 515 | } |
AdamGreen | 0:616601bde9fb | 516 | } |
AdamGreen | 0:616601bde9fb | 517 | |
AdamGreen | 0:616601bde9fb | 518 |