各ピンへのread/writeを提供するサーバサンプル
Dependencies: NySNICInterface mbed-rtos mbed
Revision 0:998e2e00df0c, committed 2015-02-10
- Comitter:
- komoritan
- Date:
- Tue Feb 10 12:15:47 2015 +0000
- Commit message:
- Fixed
Changed in this revision
diff -r 000000000000 -r 998e2e00df0c HTTPServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPServer.cpp Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,145 @@ +#include "HTTPServer.h" +#include "mbed.h" + + +bool cmp(char* a, char* b) +{ + return strcmp(a,b) < 0; +} + + +HTTPServer::HTTPServer(): +handlers(&cmp), +reply() +{ +} + + +HTTPServer::~HTTPServer() +{ +} + + +bool HTTPServer::init(int port) +{ + DigitalOut led4(LED4); + + socketserver.set_blocking(true); + if(socketserver.bind(port)) + { + printf("Could not bind on port %d.\n", port); + return false; + } + + if(socketserver.listen()) + { + printf("Could not listen %d.\n", port); + return false; + } + + led4 = 1; // server is ready + + return true; +} + + +void HTTPServer::run() +{ + char buffer[1024]; + TCPSocketConnection c; + + while(true) + { + while(socketserver.accept(&c)); + c.set_blocking(false, 1000); + + while(c.is_connected()) + { + int n = c.receive(buffer, sizeof(buffer)-1); + if(n == 0) + { + c.close(); + break; + } + else if(n != -1) + { + buffer[n] = '\0'; + printf("Received data -- %s --. \r\n", buffer); + handle_request(buffer); + create_response(buffer); + printf("Sending data -- %s --. \r\n", buffer); + c.send_all(buffer, strlen(buffer)); + printf("done. \r\n"); + c.close(); + break; + } + else { + printf("Error while receiving data. \r\n"); + c.close(); + break; + } + } + } +} + + +void HTTPServer::handle_request(char *buffer) +{ + char* request_type = strtok(buffer, " "); + char* request = strtok(NULL, " "); + + reply[0] = '\0'; + response_code = HTTP_404_NOTFOUND; + + if(!object.decode(request, reply)){ + return; + } + + std::map<char*, RequestHandler*>::iterator itor = handlers.find(request_type); + if(itor == handlers.end()) + { + printf("No request handler found for this type of request.\r\n"); + return; + } + if(itor->second != NULL) + response_code = itor->second->handle(object, reply); + else + printf("Invalid request handler\r\n"); +} + + +void HTTPServer::create_response(char *buffer) +{ + char content_length[30] = ""; + buffer[0] = '\0'; + + /* HTTP Status Code */ + strcat(buffer, "HTTP/1.1 "); + switch(response_code){ + case HTTP_200_OK: + strcat(buffer, "200 OK\r\n"); + break; + case HTTP_404_NOTFOUND: + strcat(buffer, "404 Not Found\r\n"); + break; + default: + strcat(buffer, "500 Internal Server Error\r\n"); + break; + } + + /* add header */ + strcat(buffer, "Access-Control-Allow-Origin: *\r\n"); + sprintf(content_length, "Content-Length: %d\r\n", strlen(reply)); + strncat(buffer, content_length, strlen(content_length)); + strcat(buffer, "Content-Type: text/plain\r\n\r\n"); + + /* add content */ + strcat(buffer, reply); +} + + +void HTTPServer::add_request_handler(char *name, RequestHandler* handler) +{ + handlers[name] = handler; + printf("%s request hander.\r\n", name); +}
diff -r 000000000000 -r 998e2e00df0c HTTPServer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPServer.h Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,42 @@ +#ifndef HTTP_SERVER +#define HTTP_SERVER + +#include <map> +#include "mbed.h" +#include "SNIC_WifiInterface.h" +#include "TCPSocketServer.h" +#include "TCPSocketConnection.h" +#include "RequestHandler.h" +#include "RPCObject.h" + +#define HTTP_REPLY_MAX_STRING 1024 + +enum +{ + HTTP_200_OK = 200, + HTTP_400_BADREQUEST = 400, + HTTP_404_NOTFOUND = 404 +}; + + +class HTTPServer +{ + public : + HTTPServer(); + virtual ~HTTPServer(); + bool init(int port); + void run(); + void add_request_handler(char *name, RequestHandler* handler); + + private : + void handle_request(char* buffer); + void create_response(char* buffer); + TCPSocketServer socketserver; + std::map<char*, RequestHandler*, bool(*)(char*, char*)> handlers; + RPCObject object; + char reply[HTTP_REPLY_MAX_STRING]; + int response_code; +}; + +#endif +
diff -r 000000000000 -r 998e2e00df0c NySNICInterface.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NySNICInterface.lib Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/KDDI-Fx0-hackathon/code/NySNICInterface/#680ab480d0e3
diff -r 000000000000 -r 998e2e00df0c RPCObject.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCObject.cpp Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,87 @@ +#include "RPCObject.h" +#include "parse_pins.h" +#include "mbed.h" +#include "HTTPServer.h" + + +RPCObject::RPCObject() +{ +} + + +int RPCObject::decode(char* request, char* reply) +{ + char* clz = strtok(request+1,"/"); + char* pin = strtok(NULL, "/"); + char* val = strtok(NULL, "/"); + + if(!strcmp(clz, "DigitalIn")){ + type = RPC_PIN_DIGITAL_IN; + printf(" type is DigitalIn. \r\n"); + } else if(!strcmp(clz, "DigitalOut")){ + type = RPC_PIN_DIGITAL_OUT; + printf(" type is DigitalOut. \r\n"); + } else if(!strcmp(clz, "DigitalInOut")){ + type = RPC_PIN_DIGITAL_INOUT; + printf(" type is DigitalInOut. \r\n"); + } else { + type = RPC_PIN_UNKNOWN; + printf("Unsupported type name: %s. \r\n", clz); + sprintf(reply, "Unsupported type name: %s. \r\n", clz); + return HTTP_400_BADREQUEST; + } + + pin_name = parse_pins(pin); + if(pin_name == NC){ + printf("Unsupported pin name: %s. \n", pin); + sprintf(reply, "Unsupported pin name: %s. \r\n", pin); + return HTTP_400_BADREQUEST; + } + + if(!val || val[0] == '\0'){ + value = -1; + } + else if(!strcmp(val, "delete")){ + value = -2; + } + else { + value = (val[0] - '0') ? 1 : 0; + } + + return 0; +} + + +bool RPCObject::create_pin_object(char* reply) +{ + RPCClass* pinobj; + + if(pinObjects.find(pin_name) != pinObjects.end()){ + printf("The pin already exists.\r\n"); + strcat(reply, "The pin already exists. "); + return false; + } + + switch(type){ + case RPC_PIN_DIGITAL_IN: + printf("DigitalIn.\r\n"); + pinobj = new RPCDigitalIn(pin_name); + break; + case RPC_PIN_DIGITAL_OUT: + printf("DigitalOut.\r\n"); + pinobj = new RPCDigitalOut(pin_name); + break; + case RPC_PIN_DIGITAL_INOUT: + printf("DigitalInOut.\r\n"); + pinobj = new RPCDigitalInOut(pin_name); + break; + default: + printf(" Unsupported type.\r\n"); + strcat(reply, "Unsupported type. "); + return false; + } + + pinObjects[pin_name] = pinobj; + + return true; +}
diff -r 000000000000 -r 998e2e00df0c RPCObject.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCObject.h Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,79 @@ +#ifndef RPCOBJECT +#define RPCOBJECT + +#include <map> +#include "mbed.h" + +enum RPC_PIN_TYPE { + RPC_PIN_DIGITAL_IN, + RPC_PIN_DIGITAL_OUT, + RPC_PIN_DIGITAL_INOUT, + RPC_PIN_UNKNOWN +}; + +struct rpc_arg +{ + char *name; + char *val; +}; + +class RPCClass +{ + public : + virtual int read()= 0; + virtual void write(int value) = 0; +}; + +class RPCDigitalIn : public RPCClass +{ + public : + RPCDigitalIn(PinName pin) :i(pin){} + virtual int read(void){return i.read();} + virtual void write(int value){} + + private : + DigitalIn i; +}; + +class RPCDigitalOut : public RPCClass +{ + public : + RPCDigitalOut(PinName pin) :o(pin){} + virtual int read(void){return o.read();} + virtual void write(int value){o.write(value);} + + private : + DigitalOut o; +}; + +class RPCDigitalInOut : public RPCClass +{ + public : + RPCDigitalInOut(PinName pin) :o(pin){} + virtual int read(void){return o.read();} + virtual void write(int value){o.write(value);} + + private : + DigitalInOut o; +}; + +class RPCObject +{ + public : + RPCObject(); + int decode(char *request, char* reply); + + RPC_PIN_TYPE get_type() const { return type; } + PinName get_pin_name() const { return pin_name; } + int get_value() const { return value; } + bool create_pin_object(char* reply); + std::map<PinName, RPCClass*> pinObjects; + + private : + RPC_PIN_TYPE type; + char obj_name[20]; + PinName pin_name; + int value; +}; +#endif +
diff -r 000000000000 -r 998e2e00df0c RequestHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RequestHandler.cpp Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,86 @@ +#include "mbed.h" +#include "RequestHandler.h" +#include "RPCObject.h" +#include "HTTPServer.h" + + +int GetRequestHandler::handle(RPCObject& cmd, char* reply) +{ + int value; + std::map<PinName, RPCClass*>::iterator itor; + + printf("handling GET request.\r\n"); + itor = cmd.pinObjects.find(cmd.get_pin_name()); + if(itor == cmd.pinObjects.end()){ + printf("The pin is not created.\r\n"); + return HTTP_404_NOTFOUND; + } + value = itor->second->read(); + + reply[0] = '0' + value; + reply[1] = '\0'; + + return HTTP_200_OK; +} + + +int PostRequestHandler::handle(RPCObject& cmd, char* reply) +{ + int value = cmd.get_value(); + std::map<PinName, RPCClass*>::iterator itor; + + printf("handling POST request.\r\n"); + switch(value){ + case 0: + case 1: + //update + printf("now updating the object to %d.\r\n", value); + itor = cmd.pinObjects.find(cmd.get_pin_name()); + if(itor == cmd.pinObjects.end()){ + printf("The pin is not created.\r\n"); + return HTTP_404_NOTFOUND; + } + itor->second->write(value); + break; + case -1: + //create + printf("now createing the object.\r\n"); + if(!cmd.create_pin_object(reply)){ + return -1; + } + break; + case -2: + // delete + itor = cmd.pinObjects.find(cmd.get_pin_name()); + if(itor == cmd.pinObjects.end()){ + printf("The pin is not created.\r\n"); + return HTTP_404_NOTFOUND; + } + delete itor->second; + cmd.pinObjects.erase(cmd.pinObjects.find(cmd.get_pin_name())); + break; + default: + return -1; + } + + return HTTP_200_OK; +} + + +int DeleteRequestHandler::handle(RPCObject& cmd, char* reply) +{ + std::map<PinName, RPCClass*>::iterator itor; + + printf("handling DELETE request.\r\n"); + itor = cmd.pinObjects.find(cmd.get_pin_name()); + if(itor == cmd.pinObjects.end()){ + printf("The pin is not created.\r\n"); + return HTTP_404_NOTFOUND; + } + delete itor->second; + cmd.pinObjects.erase(cmd.pinObjects.find(cmd.get_pin_name())); + + return HTTP_200_OK; +} + +
diff -r 000000000000 -r 998e2e00df0c RequestHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RequestHandler.h Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,45 @@ +#ifndef REQUEST_HANDLER +#define REQUEST_HANDLER + +#include "RPCObject.h" + + + +class RequestHandler +{ + public : + + virtual int handle(RPCObject& cmd, char* reply) = 0; + + protected : +}; + +class GetRequestHandler : public RequestHandler +{ + public : + + virtual int handle(RPCObject& cmd, char* reply); + +}; + +class PostRequestHandler : public RequestHandler +{ + public : + + virtual int handle(RPCObject& cmd, char* reply); + +}; + + +class DeleteRequestHandler : public RequestHandler +{ + public : + + virtual int handle(RPCObject& cmd, char* reply); + +}; + + + +#endif +
diff -r 000000000000 -r 998e2e00df0c main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,83 @@ +#include "mbed.h" +#include "SNIC_WifiInterface.h" +#include "HTTPServer.h" + +/** + * Wifi AP parameter + */ + +/* Set this */ +#define WIFI_SSID "" +#define WIFI_SECUTIRY_KEY "" +//#define WIFI_SECURITY_TYPE e_SEC_OPEN +//#define WIFI_SECURITY_TYPE e_SEC_WEP +//#define WIFI_SECURITY_TYPE e_SEC_WPA_TKIP +#define WIFI_SECURITY_TYPE e_SEC_WPA2_AES +//#define WIFI_SECURITY_TYPE e_SEC_WPA2_MIXED +//#define WIFI_SECURITY_TYPE e_SEC_WPA_AES + + +#define IP_ADDRESS "192.168.0.44" +#define NET_MASK "255.255.255.0" +#define DEFAULT_GATEWAY "192.168.0.1" +#define PORT_NUMBER 80 + + +Serial pc(USBTX, USBRX); // This is required when defined "_DEBUG" +/** Wi-Fi SNIC UART Interface*/ +C_SNIC_WifiInterface mSNICwifi( p13, p14, p12, p11, p20 ); + + + + +void wifi_connect() +{ + // Initialize Wi-Fi interface + if(mSNICwifi.init()!=0){ + printf("Wi-Fi initial failed\r\n"); + mbed_die(); + } + wait(0.5); + + if(mSNICwifi.disconnect()!= 0 ) + { + printf("on the disconnect state\r\n"); + mbed_die(); + } + wait(0.3); + + // Connect to AP + if(mSNICwifi.connect( WIFI_SSID,strlen(WIFI_SSID), + WIFI_SECURITY_TYPE, + WIFI_SECUTIRY_KEY, + strlen(WIFI_SECUTIRY_KEY))!=0) + { + printf("Connect AP is failed\r\n"); + mbed_die(); + } + wait(0.5); + + int retIp = mSNICwifi.setIPConfig(false, IP_ADDRESS, NET_MASK, DEFAULT_GATEWAY); +} + + +int main() +{ + // for debug + pc.baud( 115200 ); + + wifi_connect(); + + HTTPServer srv; + + pc.printf("server init.\r\n"); + srv.init(PORT_NUMBER); + + srv.add_request_handler("GET", new GetRequestHandler()); + srv.add_request_handler("DELETE", new DeleteRequestHandler()); + srv.add_request_handler("POST", new PostRequestHandler()); + + wait(1); + pc.printf("server running.\r\n"); + srv.run(); +}
diff -r 000000000000 -r 998e2e00df0c mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#5dfe422a963d
diff -r 000000000000 -r 998e2e00df0c mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/0b3ab51c8877 \ No newline at end of file
diff -r 000000000000 -r 998e2e00df0c parse_pins.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parse_pins.cpp Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "port_api.h" + +namespace mbed { + +PinName parse_pins(const char *str) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) + static const PinName pin_names[] = {p5, p6, p7, p8, p9, p10, p11, p12, p13, p14 + , p15, p16, p17, p18, p19, p20, p21, p22, p23 + , p24, p25, p26, p27, p28, p29, p30}; +#endif + +#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC812) || defined(TARGET_LPC4088) + if (str[0] == 'P') { // Pn_n + uint32_t port = str[1] - '0'; + uint32_t pin = str[3] - '0'; // Pn_n + uint32_t pin2 = str[4] - '0'; // Pn_nn + if (pin2 <= 9) { + pin = pin * 10 + pin2; + } + return port_pin((PortName)port, pin); + +#elif defined(TARGET_KL25Z) + if (str[0] == 'P' && str[1] == 'T') { // PTx_n + uint32_t port = str[2] - 'A'; + uint32_t pin = str[3] - '0'; // PTxn + uint32_t pin2 = str[4] - '0'; // PTxnn + + if (pin2 <= 9) { + pin = pin * 10 + pin2; + } + return port_pin((PortName)port, pin); +#endif + +#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) + } else if (str[0] == 'p') { // pn + uint32_t pin = str[1] - '0'; // pn + uint32_t pin2 = str[2] - '0'; // pnn + if (pin2 <= 9) { + pin = pin * 10 + pin2; + } + if (pin < 5 || pin > 30) { + return NC; + } + return pin_names[pin - 5]; +#endif + + } else if (str[0] == 'L') { // LEDn + switch (str[3]) { + case '1' : return LED1; + case '2' : return LED2; + case '3' : return LED3; + case '4' : return LED4; + } + + } else if (str[0] == 'U') { // USB?X + switch (str[3]) { + case 'T' : return USBTX; + case 'R' : return USBRX; + } + } + + return NC; +} + +}
diff -r 000000000000 -r 998e2e00df0c parse_pins.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parse_pins.h Tue Feb 10 12:15:47 2015 +0000 @@ -0,0 +1,27 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINMAP_H +#define MBED_PINMAP_H + +#include "PinNames.h" + +namespace mbed { + +PinName parse_pins(const char *str); + +} + +#endif