Measure system

Dependencies:   EthernetNetIf mbed RF12B

Committer:
benecsj
Date:
Tue May 17 16:49:23 2011 +0000
Revision:
3:799d8c61fb03
Parent:
1:b26ab2467b1a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
benecsj 0:8d62137f7ff4 1
benecsj 0:8d62137f7ff4 2 /*
benecsj 0:8d62137f7ff4 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
benecsj 1:b26ab2467b1a 4
benecsj 0:8d62137f7ff4 5 Permission is hereby granted, free of charge, to any person obtaining a copy
benecsj 0:8d62137f7ff4 6 of this software and associated documentation files (the "Software"), to deal
benecsj 0:8d62137f7ff4 7 in the Software without restriction, including without limitation the rights
benecsj 0:8d62137f7ff4 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
benecsj 0:8d62137f7ff4 9 copies of the Software, and to permit persons to whom the Software is
benecsj 0:8d62137f7ff4 10 furnished to do so, subject to the following conditions:
benecsj 1:b26ab2467b1a 11
benecsj 0:8d62137f7ff4 12 The above copyright notice and this permission notice shall be included in
benecsj 0:8d62137f7ff4 13 all copies or substantial portions of the Software.
benecsj 1:b26ab2467b1a 14
benecsj 0:8d62137f7ff4 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
benecsj 0:8d62137f7ff4 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
benecsj 0:8d62137f7ff4 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
benecsj 0:8d62137f7ff4 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
benecsj 0:8d62137f7ff4 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
benecsj 0:8d62137f7ff4 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
benecsj 0:8d62137f7ff4 21 THE SOFTWARE.
benecsj 0:8d62137f7ff4 22 */
benecsj 0:8d62137f7ff4 23
benecsj 1:b26ab2467b1a 24 #include "MeasureSystem.h"
benecsj 0:8d62137f7ff4 25 #include "core/netservice.h"
benecsj 0:8d62137f7ff4 26 #include "HTTPRequestDispatcher.h"
benecsj 0:8d62137f7ff4 27 #include "HTTPRequestHandler.h"
benecsj 0:8d62137f7ff4 28 #include "mbed.h"
benecsj 0:8d62137f7ff4 29 #include <string.h>
benecsj 0:8d62137f7ff4 30
benecsj 0:8d62137f7ff4 31 //#define __DEBUG
benecsj 0:8d62137f7ff4 32 //#include "dbg/dbg.h"
benecsj 0:8d62137f7ff4 33
benecsj 1:b26ab2467b1a 34 HTTPRequestDispatcher::HTTPRequestDispatcher(HTTPServer* pSvr, TCPSocket* pTCPSocket) : NetService(), m_pSvr(pSvr), m_pTCPSocket(pTCPSocket), m_watchdog(), m_closed(false) {
benecsj 1:b26ab2467b1a 35 printf("1-DIS-Dispatcher started\r\n");
benecsj 1:b26ab2467b1a 36 m_pTCPSocket->setOnEvent(this, &HTTPRequestDispatcher::onTCPSocketEvent);
benecsj 1:b26ab2467b1a 37 m_watchdog.attach_us<HTTPRequestDispatcher>(this, &HTTPRequestDispatcher::onTimeout, HTTP_REQUEST_TIMEOUT * 1000);
benecsj 0:8d62137f7ff4 38 }
benecsj 0:8d62137f7ff4 39
benecsj 1:b26ab2467b1a 40 HTTPRequestDispatcher::~HTTPRequestDispatcher() {
benecsj 1:b26ab2467b1a 41 printf("1-DIS-Dispatcher closed\r\n");
benecsj 1:b26ab2467b1a 42 close();
benecsj 0:8d62137f7ff4 43 }
benecsj 0:8d62137f7ff4 44
benecsj 1:b26ab2467b1a 45 void HTTPRequestDispatcher::dispatchRequest() {
benecsj 1:b26ab2467b1a 46 string path;
benecsj 1:b26ab2467b1a 47 string meth;
benecsj 1:b26ab2467b1a 48 HTTP_METH methCode;
benecsj 1:b26ab2467b1a 49
benecsj 1:b26ab2467b1a 50 printf("1-DIS-nDispatching req\r\n");
benecsj 1:b26ab2467b1a 51
benecsj 1:b26ab2467b1a 52 if ( !getRequest(&path, &meth ) ) {
benecsj 1:b26ab2467b1a 53 HandlerActive = false;
benecsj 1:b26ab2467b1a 54 close();
benecsj 1:b26ab2467b1a 55 return; //Invalid request
benecsj 1:b26ab2467b1a 56 }
benecsj 1:b26ab2467b1a 57
benecsj 1:b26ab2467b1a 58 if ( !meth.compare("GET") ) {
benecsj 1:b26ab2467b1a 59 methCode = HTTP_GET;
benecsj 1:b26ab2467b1a 60 } else if ( !meth.compare("POST") ) {
benecsj 1:b26ab2467b1a 61 methCode = HTTP_POST;
benecsj 1:b26ab2467b1a 62 } else if ( !meth.compare("HEAD") ) {
benecsj 1:b26ab2467b1a 63 methCode = HTTP_HEAD;
benecsj 1:b26ab2467b1a 64 } else {
benecsj 1:b26ab2467b1a 65 HandlerActive = false;
benecsj 1:b26ab2467b1a 66 close(); //Parse error
benecsj 1:b26ab2467b1a 67 return;
benecsj 1:b26ab2467b1a 68 }
benecsj 1:b26ab2467b1a 69
benecsj 1:b26ab2467b1a 70 printf("1-DIS-Looking for a handler\r\n");
benecsj 1:b26ab2467b1a 71
benecsj 1:b26ab2467b1a 72 map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocket*) >::iterator it;
benecsj 0:8d62137f7ff4 73 // it = m_pSvr->m_lpHandlers.find(rootPath); //We are friends so we can do that
benecsj 1:b26ab2467b1a 74 // NEW CODE START:
benecsj 1:b26ab2467b1a 75 int root_len = 0;
benecsj 1:b26ab2467b1a 76 for (it = m_pSvr->m_lpHandlers.begin(); it != m_pSvr->m_lpHandlers.end(); it++) {
benecsj 1:b26ab2467b1a 77 printf("1-DIS-Checking %s...\r\n", (*it).first.c_str());
benecsj 1:b26ab2467b1a 78 root_len = (*it).first.length();
benecsj 1:b26ab2467b1a 79 if ( root_len &&
benecsj 1:b26ab2467b1a 80 !path.compare( 0, root_len, (*it).first ) &&
benecsj 1:b26ab2467b1a 81 (path[root_len] == '/' || path[root_len] == '\0')) {
benecsj 1:b26ab2467b1a 82 printf("1-DIS-Found (%s)\r\n", (*it).first.c_str());
benecsj 1:b26ab2467b1a 83 // Found!
benecsj 1:b26ab2467b1a 84 break; // for
benecsj 1:b26ab2467b1a 85 }
benecsj 1:b26ab2467b1a 86 }
benecsj 0:8d62137f7ff4 87 // NEW CODE END
benecsj 1:b26ab2467b1a 88 if ((it == m_pSvr->m_lpHandlers.end()) && !(m_pSvr->m_lpHandlers.empty())) {
benecsj 1:b26ab2467b1a 89 printf("1-DIS-Using default handler\r\n");
benecsj 1:b26ab2467b1a 90 it = m_pSvr->m_lpHandlers.end();
benecsj 1:b26ab2467b1a 91 it--; //Get the last element
benecsj 1:b26ab2467b1a 92 if ( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler
benecsj 1:b26ab2467b1a 93 it = m_pSvr->m_lpHandlers.end();
benecsj 1:b26ab2467b1a 94 root_len = 0;
benecsj 1:b26ab2467b1a 95 }
benecsj 1:b26ab2467b1a 96 if (it == m_pSvr->m_lpHandlers.end()) {
benecsj 1:b26ab2467b1a 97 printf("1-DIS-No handler found\r\n");
benecsj 1:b26ab2467b1a 98 HandlerActive = false;
benecsj 1:b26ab2467b1a 99 close(); //No handler found
benecsj 1:b26ab2467b1a 100 return;
benecsj 1:b26ab2467b1a 101 }
benecsj 1:b26ab2467b1a 102
benecsj 1:b26ab2467b1a 103 printf("1-DIS-Handler found.\r\n");
benecsj 1:b26ab2467b1a 104
benecsj 0:8d62137f7ff4 105 //HTTPRequestHandler* pHdlr = (*it).second(rootPath.c_str(), subPath.c_str(), m_pTCPSocket);
benecsj 0:8d62137f7ff4 106 //NEW CODE 1 LINE:
benecsj 0:8d62137f7ff4 107
benecsj 0:8d62137f7ff4 108
benecsj 1:b26ab2467b1a 109 HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, m_pTCPSocket);
benecsj 1:b26ab2467b1a 110 m_pTCPSocket = NULL; //We don't own it anymore
benecsj 1:b26ab2467b1a 111
benecsj 1:b26ab2467b1a 112 printf ("1-DIS-Calling handler...\r\n") ;
benecsj 1:b26ab2467b1a 113 switch (methCode) {
benecsj 1:b26ab2467b1a 114 case HTTP_GET:
benecsj 1:b26ab2467b1a 115 pHdlr->doGet();
benecsj 1:b26ab2467b1a 116 break;
benecsj 1:b26ab2467b1a 117 case HTTP_POST:
benecsj 1:b26ab2467b1a 118 pHdlr->doPost();
benecsj 1:b26ab2467b1a 119 break;
benecsj 1:b26ab2467b1a 120 case HTTP_HEAD:
benecsj 1:b26ab2467b1a 121 pHdlr->doHead();
benecsj 1:b26ab2467b1a 122 break;
benecsj 1:b26ab2467b1a 123 }
benecsj 1:b26ab2467b1a 124
benecsj 1:b26ab2467b1a 125 printf("1-DIS-Req handled (or being handled)\r\n");
benecsj 1:b26ab2467b1a 126 close();
benecsj 0:8d62137f7ff4 127 }
benecsj 0:8d62137f7ff4 128
benecsj 1:b26ab2467b1a 129 void HTTPRequestDispatcher::close() { //Close socket and destroy data
benecsj 1:b26ab2467b1a 130 if (m_closed)
benecsj 1:b26ab2467b1a 131 return;
benecsj 1:b26ab2467b1a 132 m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
benecsj 1:b26ab2467b1a 133 m_watchdog.detach();
benecsj 1:b26ab2467b1a 134 if (m_pTCPSocket) { //m_pTCPSocket Should only be destroyed if ownership not passed to an handler
benecsj 1:b26ab2467b1a 135 m_pTCPSocket->resetOnEvent();
benecsj 1:b26ab2467b1a 136 m_pTCPSocket->close();
benecsj 1:b26ab2467b1a 137 delete m_pTCPSocket; //This fn might have been called by this socket (through an event), so DO NOT DESTROY IT HERE
benecsj 1:b26ab2467b1a 138 }
benecsj 1:b26ab2467b1a 139 NetService::close();
benecsj 0:8d62137f7ff4 140 }
benecsj 0:8d62137f7ff4 141
benecsj 0:8d62137f7ff4 142
benecsj 1:b26ab2467b1a 143 void HTTPRequestDispatcher::onTimeout() { //Connection has timed out
benecsj 1:b26ab2467b1a 144 close();
benecsj 0:8d62137f7ff4 145 }
benecsj 0:8d62137f7ff4 146
benecsj 1:b26ab2467b1a 147 bool HTTPRequestDispatcher::getRequest(string* path, string* meth) {
benecsj 1:b26ab2467b1a 148 char req[128];
benecsj 1:b26ab2467b1a 149 char c_path[128];
benecsj 1:b26ab2467b1a 150 char c_meth[128];
benecsj 1:b26ab2467b1a 151 const int maxLen = 128;
benecsj 1:b26ab2467b1a 152 char* p = req;
benecsj 1:b26ab2467b1a 153 //Read Line
benecsj 1:b26ab2467b1a 154 int ret;
benecsj 1:b26ab2467b1a 155 int len = 0;
benecsj 1:b26ab2467b1a 156 for (int i = 0; i < maxLen - 1; i++) {
benecsj 1:b26ab2467b1a 157 ret = m_pTCPSocket->recv(p, 1);
benecsj 1:b26ab2467b1a 158 if (!ret) {
benecsj 1:b26ab2467b1a 159 break;
benecsj 1:b26ab2467b1a 160 }
benecsj 1:b26ab2467b1a 161 if ( (len > 1) && *(p-1)=='\r' && *p=='\n' ) {
benecsj 1:b26ab2467b1a 162 p--;
benecsj 1:b26ab2467b1a 163 len-=2;
benecsj 1:b26ab2467b1a 164 break;
benecsj 1:b26ab2467b1a 165 } else if ( *p=='\n' ) {
benecsj 1:b26ab2467b1a 166 len--;
benecsj 1:b26ab2467b1a 167 break;
benecsj 1:b26ab2467b1a 168 }
benecsj 1:b26ab2467b1a 169 p++;
benecsj 1:b26ab2467b1a 170 len++;
benecsj 0:8d62137f7ff4 171 }
benecsj 1:b26ab2467b1a 172 *p = 0;
benecsj 1:b26ab2467b1a 173
benecsj 1:b26ab2467b1a 174 printf("1-DIS-Parsing request : %s\r\n", req);
benecsj 1:b26ab2467b1a 175
benecsj 1:b26ab2467b1a 176 ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path);
benecsj 1:b26ab2467b1a 177 if (ret !=2)
benecsj 1:b26ab2467b1a 178 return false;
benecsj 1:b26ab2467b1a 179
benecsj 1:b26ab2467b1a 180 *meth = string(c_meth);
benecsj 0:8d62137f7ff4 181 // NEW CODE (old code removed):
benecsj 1:b26ab2467b1a 182 *path = string(c_path);
benecsj 1:b26ab2467b1a 183 return true;
benecsj 0:8d62137f7ff4 184 }
benecsj 0:8d62137f7ff4 185
benecsj 0:8d62137f7ff4 186
benecsj 0:8d62137f7ff4 187
benecsj 1:b26ab2467b1a 188 void HTTPRequestDispatcher::onTCPSocketEvent(TCPSocketEvent e) {
benecsj 1:b26ab2467b1a 189
benecsj 1:b26ab2467b1a 190 printf("1-DIS-Event %d\r\n", e);
benecsj 0:8d62137f7ff4 191
benecsj 1:b26ab2467b1a 192 if (m_closed) {
benecsj 1:b26ab2467b1a 193 printf("1-DIS-WARN: Discarded\r\n");
benecsj 1:b26ab2467b1a 194 return;
benecsj 1:b26ab2467b1a 195 }
benecsj 0:8d62137f7ff4 196
benecsj 1:b26ab2467b1a 197 switch (e) {
benecsj 1:b26ab2467b1a 198 case TCPSOCKET_READABLE:
benecsj 1:b26ab2467b1a 199 m_watchdog.detach();
benecsj 1:b26ab2467b1a 200 m_pTCPSocket->resetOnEvent();
benecsj 1:b26ab2467b1a 201 //Req arrived, dispatch :
benecsj 1:b26ab2467b1a 202 dispatchRequest();
benecsj 1:b26ab2467b1a 203 break;
benecsj 1:b26ab2467b1a 204 case TCPSOCKET_CONTIMEOUT:
benecsj 1:b26ab2467b1a 205 case TCPSOCKET_CONRST:
benecsj 1:b26ab2467b1a 206 case TCPSOCKET_CONABRT:
benecsj 1:b26ab2467b1a 207 case TCPSOCKET_ERROR:
benecsj 1:b26ab2467b1a 208 case TCPSOCKET_DISCONNECTED:
benecsj 1:b26ab2467b1a 209 HandlerActive = false;
benecsj 1:b26ab2467b1a 210 close();
benecsj 1:b26ab2467b1a 211 break;
benecsj 1:b26ab2467b1a 212 }
benecsj 1:b26ab2467b1a 213
benecsj 0:8d62137f7ff4 214 }