Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: NySNICInterface mbed-rtos mbed
Fork of RESTServerSample by
Revision 0:998e2e00df0c, committed 2015-02-10
- Comitter:
- komoritan
- Date:
- Tue Feb 10 12:15:47 2015 +0000
- Child:
- 1:e821c773d5f0
- Commit message:
- Fixed
Changed in this revision
--- /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);
+}
--- /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
+
--- /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
--- /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;
+}
--- /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
+
--- /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;
+}
+
+
--- /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
+
--- /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();
+}
--- /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
--- /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
--- /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;
+}
+
+}
--- /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
