ported HTTP-Server with W5500 Ethernet Shield
Dependencies: W5500Interface mbed-rpc mbed
Fork of HTTP-Server by
Revision 5:8ab27ca793cd, committed 2013-07-17
- Comitter:
- feb11
- Date:
- Wed Jul 17 15:01:05 2013 +0000
- Parent:
- 4:624527ebc0fa
- Child:
- 6:d03e189ebbfe
- Commit message:
- Fixed bug in InteractiveHTMLFormatter
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Formatter.h Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,48 @@ +#ifndef FORMATTER +#define FORMATTER + + +class Formatter +{ + public : + + Formatter(int nbChunk = 1); + + char* get_page(char *reply); + + protected : + + virtual void get_chunk(const int c, char *reply); + + private : + + int currentChunk; + int nbChunk; +}; + +class SimpleHTMLFormatter : public Formatter +{ + public : + + SimpleHTMLFormatter(); + + protected : + + virtual void get_chunk(const int c, char *reply); + +}; + +class InteractiveHTMLFormatter : public Formatter +{ + public : + + InteractiveHTMLFormatter(); + + protected : + + virtual void get_chunk(const int c, char *reply); +}; + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPServer.h Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,39 @@ +#ifndef HTTP_SERVER +#define HTTP_SERVER + +#include <map> + +#include "mbed.h" +#include "mbed_rpc.h" +#include "RequestHandler.h" +#include "Formatter.h" +#include "EthernetInterface.h" +#include "RPCCommand.h" + + +class HTTPServer +{ + public : + + HTTPServer(Formatter *f = new Formatter()); + virtual ~HTTPServer(); + + bool init(int port); + + void run(); + + void add_request_handler(char *name, RequestHandler* handler); + + private : + + void handle_request(char *buffer); + + TCPSocketServer socket; + std::map<char*, RequestHandler*, bool(*)(char*, char*)> handlers; + Formatter *formatter; + char reply[RPC_MAX_STRING]; + RPCCommand command; +}; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCCommand.cpp Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,130 @@ +#include "RPCCommand.h" +#include "mbed.h" +#include "RPCType.h" + + +RPCCommand::RPCCommand(): +cmd(), +obj_name(NULL), +func_name(NULL) +{ + +} + +bool RPCCommand::decode(char *buffer) +{ + if(buffer == NULL) + return false; + if(buffer[0] != '/') + return false; + + ++buffer; + char *tmp = strchr(buffer ,'/'); + + if(tmp == NULL) + return false; + if(tmp == buffer) + return false; + + tmp[0] = '\0'; + obj_name = buffer; + + buffer = tmp+1; + + if(buffer[0] == '\0' || buffer[0] == '?') + return false; + + func_name = buffer; + + tmp = strchr(buffer, '?'); + if(tmp != NULL) + { + if(tmp[1] == '\0') + return false; + tmp[0] = '\0'; + } + + cmd[0] = '\0'; + strcat(cmd, "/"); + strcat(cmd, obj_name); + strcat(cmd, "/"); + strcat(cmd, func_name); + + if(tmp == NULL) + return true; + + buffer = tmp+1; + do + { + tmp = strchr(buffer, '&'); + + if(tmp != NULL) + { + if(tmp[1] == '\0' || buffer == tmp) + return false; + tmp[0] = '\0'; + } + + char *sep = strchr(buffer, '='); + if(sep == NULL) + return false; + if(sep == buffer) + return false; + if(sep[1] == '\0' || sep[1] == '&') + return false; + + strcat(cmd, " "); + strcat(cmd, sep+1); + + if(tmp != NULL) + buffer = tmp+1; + else + buffer = NULL; + }while(buffer); + + return true; +} + + + +char* RPCCommand::get_cmd() const +{ + return (char*)cmd; +} + +RPC_COMMAND_TYPE RPCCommand::get_type() const +{ + if(!strcmp(func_name, "new") && RPCType::instance().is_supported_type(obj_name)) + return CREATE; + + RPC* r = RPC::lookup(obj_name); + if(r == NULL) + return INVALID; + + if(!strcmp(func_name, "delete")) + return DELETE; + + const struct rpc_method *methods = r->get_rpc_methods(); + int i = 0; + while(methods[i].name != NULL) + { + if(!strcmp(func_name, methods[i].name)) + { + return FUNCTION_CALL; + } + ++i; + } + + return INVALID; +} + +char* RPCCommand::get_obj_name() const +{ + return obj_name; +} + +char* RPCCommand::get_func_name() const +{ + return func_name; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCCommand.h Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,36 @@ +#ifndef RPCCOMMAND +#define RPCCOMMAND + +#include <list> +#include "mbed_rpc.h" + +enum RPC_COMMAND_TYPE { INVALID, CREATE, DELETE, FUNCTION_CALL }; + +struct rpc_arg +{ + char *name; + char *val; +}; + +class RPCCommand +{ + public : + + RPCCommand(); + + bool decode(char *buffer); + + char* get_cmd() const; + RPC_COMMAND_TYPE get_type() const; + char* get_obj_name() const; + char* get_func_name() const; + + private : + + char cmd[RPC_MAX_STRING]; + char* obj_name; + char* func_name; +}; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCObjectManager.cpp Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,68 @@ +#include "RPCObjectManager.h" +#include "mbed.h" + +RPCObjectManager& RPCObjectManager::instance() +{ + static RPCObjectManager om; + return om; +} + +RPCObjectManager::RPCObjectManager(): +objects() +{ +} + +RPCObjectManager::~RPCObjectManager() +{ + for(std::list<char*>::iterator itor = objects.begin(); + itor != objects.end(); + ++itor) + delete *itor; +} + +void RPCObjectManager::store_object(char *obj_name) +{ + char *obj = new char[strlen(obj_name)+1]; + strcpy(obj, obj_name); + obj[strlen(obj_name)] = '\0'; + objects.push_back(obj); +} + +void RPCObjectManager::remove_object(char *obj_name) +{ + for(std::list<char*>::iterator itor = objects.begin(); + itor != objects.end(); + ++itor) + if(!strcmp(obj_name, *itor)) + { + delete *itor; + objects.erase(itor); + break; + } +} + +bool RPCObjectManager::lookup_object(char *obj_name) +{ + for(std::list<char*>::iterator itor = objects.begin(); + itor != objects.end(); + ++itor) + if(!strcmp(obj_name, *itor)) + return true; + return false; +} + +bool RPCObjectManager::is_empty() +{ + return objects.empty(); +} + +std::list<char*>::iterator RPCObjectManager::begin() +{ + return objects.begin(); +} + +std::list<char*>::iterator RPCObjectManager::end() +{ + return objects.end(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCObjectManager.h Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,29 @@ +#ifndef RPCOBJECTMANAGER +#define RPCOBJECTMANAGER + +#include <list> + +class RPCObjectManager +{ + public : + + static RPCObjectManager& instance(); + + void store_object(char *obj_name); + void remove_object(char *obj_name); + bool lookup_object(char *obj_name); + + std::list<char*>::iterator begin(); + std::list<char*>::iterator end(); + + bool is_empty(); + + private : + + RPCObjectManager(); + ~RPCObjectManager(); + + std::list<char*> objects; +}; +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCType.cpp Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,55 @@ +#include "mbed.h" +#include "mbed_rpc.h" +#include "RPCType.h" + + +RPCType::RPCType(): +supported_types() +{ +} + +RPCType& RPCType::instance() +{ + static RPCType t; + return t; +} + +void RPCType::register_types() +{ + RPCType &t = instance(); + + RPC::add_rpc_class<RpcDigitalOut>(); + t.supported_types.push_back("DigitalOut"); + RPC::add_rpc_class<RpcDigitalIn>(); + t.supported_types.push_back("DigitalIn"); + RPC::add_rpc_class<RpcDigitalInOut>(); + t.supported_types.push_back("DigitalInOut"); + + #if DEVICE_PWMOUT + RPC::add_rpc_class<RpcPwmOut>(); + t.supported_types.push_back("PwmOut"); + #endif + #if DEVICE_SPI + t.supported_types.push_back("SPI"); + RPC::add_rpc_class<RpcSPI>(); + #endif + #if DEVICE_SERIAL + t.supported_types.push_back("Serial"); + RPC::add_rpc_class<RpcSerial>(); + #endif + RPC::add_rpc_class<RpcTimer>(); + t.supported_types.push_back("Timer"); +} + +bool RPCType::is_supported_type(char *type) +{ + for(std::list<char*>::iterator itor = instance().supported_types.begin(); + itor != instance().supported_types.end(); + ++itor) + if(!strcmp(*itor,type)) + return true; + + return false; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCType.h Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,23 @@ +#ifndef RPCTYPE_H +#define RPCTYPE_H + +#include <list> + +class RPCType +{ + public : + + static RPCType& instance(); + + void register_types(); + + bool is_supported_type(char *type); + + private : + + RPCType(); + std::list<char*> supported_types; +}; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RequestHandler.cpp Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,91 @@ +#include "RequestHandler.h" +#include "mbed_rpc.h" +#include "RPCObjectManager.h" +#include "RPCCommand.h" + +void GetRequestHandler::handle(const RPCCommand& cmd, char *reply) +{ + switch(cmd.get_type()) + { + case DELETE: + strcat(reply, "You must send a DELETE request to remove an object "); + break; + case FUNCTION_CALL: + RPC::call(cmd.get_cmd(), reply); + break; + case CREATE: + strcat(reply, "You must send a PUT request to call a function"); + break; + default: + strcat(reply, "Invalid RPC command"); + break; + } +} + +void PutRequestHandler::handle(const RPCCommand& cmd, char *reply) +{ + switch(cmd.get_type()) + { + case DELETE: + strcat(reply, "You must send a DELETE request to remove an object "); + break; + case FUNCTION_CALL: + strcat(reply, "You must send a GET request to call a function"); + break; + case CREATE: + RPC::call(cmd.get_cmd(), reply); + if(strlen(reply) > 0) + { + RPCObjectManager::instance().store_object(reply); + strcat(reply, " has been created"); + } + else + strcat(reply, "Error while creating object."); + break; + default: + strcat(reply, "Invalid RPC command"); + break; + } +} + +void DeleteRequestHandler::handle(const RPCCommand& cmd, char *reply) +{ + switch(cmd.get_type()) + { + case CREATE: + strcat(reply, "You must send a PUT request to remove an object "); + break; + case FUNCTION_CALL: + strcat(reply, "You must send a GET request to call a function"); + break; + case DELETE: + RPC::call(cmd.get_cmd(), reply); + RPCObjectManager::instance().remove_object(cmd.get_obj_name()); + strcat(reply, "Deleted object "); + strcat(reply, cmd.get_obj_name()); + break; + default: + strcat(reply, "Invalid RPC command"); + break; + } +} + +void ComplexRequestHandler::handle(const RPCCommand& cmd, char *reply) +{ + switch(cmd.get_type()) + { + case CREATE : + putHandler.handle(cmd, reply); + break; + case DELETE : + deleteHandler.handle(cmd, reply); + break; + case FUNCTION_CALL : + getHandler.handle(cmd, reply); + break; + default : + strcat(reply, "Invalid RPC command"); + break; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RequestHandler.h Wed Jul 17 15:01:05 2013 +0000 @@ -0,0 +1,51 @@ +#ifndef REQUEST_HANDLER +#define REQUEST_HANDLER + +#include "RPCCommand.h" + +class RequestHandler +{ + public : + + virtual void handle(const RPCCommand& cmd, char* reply) = 0; +}; + +class GetRequestHandler : public RequestHandler +{ + public : + + virtual void handle(const RPCCommand& cmd, char* reply); +}; + +class PutRequestHandler : public RequestHandler +{ + public : + + virtual void handle(const RPCCommand& cmd, char* reply); + +}; + + +class DeleteRequestHandler : public RequestHandler +{ + public : + + virtual void handle(const RPCCommand& cmd, char* reply); + +}; + +class ComplexRequestHandler : public RequestHandler +{ + public : + + virtual void handle(const RPCCommand& cmd, char* reply); + + private : + + GetRequestHandler getHandler; + PutRequestHandler putHandler; + DeleteRequestHandler deleteHandler; +}; + +#endif +