データの保存、更新、取得ができるWebサービス「milkcocoa」に接続し、データのプッシュ、送信、取得ができるライブラリです。 https://mlkcca.com/
Fork of Milkcocoa by
Revision 0:23e533c4b1ec, committed 2015-12-15
- Comitter:
- jksoft
- Date:
- Tue Dec 15 09:56:32 2015 +0000
- Child:
- 1:4a634c06c5dc
- Commit message:
- ??; Subscribe?1?????; ?Milkcocoa::on???????????????????????
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266/CBuffer.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,75 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef CIRCBUFFER_H_
+#define CIRCBUFFER_H_
+
+template <class T>
+class CircBuffer {
+public:
+ CircBuffer(int length) {
+ write = 0;
+ read = 0;
+ size = length + 1;
+ buf = (T *)malloc(size * sizeof(T));
+ };
+
+ bool isFull() {
+ return (((write + 1) % size) == read);
+ };
+
+ bool isEmpty() {
+ return (read == write);
+ };
+
+ void queue(T k) {
+ if (isFull()) {
+ read++;
+ read %= size;
+ }
+ buf[write++] = k;
+ write %= size;
+ }
+
+ void flush() {
+ read = 0;
+ write = 0;
+ }
+
+
+ uint32_t available() {
+ return (write >= read) ? write - read : size - read + write;
+ };
+
+ bool dequeue(T * c) {
+ bool empty = isEmpty();
+ if (!empty) {
+ *c = buf[read++];
+ read %= size;
+ }
+ return(!empty);
+ };
+
+private:
+ volatile uint32_t write;
+ volatile uint32_t read;
+ uint32_t size;
+ T * buf;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266/ESP8266.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,523 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+#include "ESP8266.h"
+#include "Endpoint.h"
+#include "SoftSerialSendOnry.h"
+
+extern SoftSerialSendOnry pc;
+
+//#include <string>
+//#include <algorithm>
+
+//Debug is disabled by default
+#if 0
+#define DBG(x, ...) pc.printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#define WARN(x, ...) pc.printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#define ERR(x, ...) pc.printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#else
+#define DBG(x, ...) //wait_us(10);
+#define WARN(x, ...) //wait_us(10);
+#define ERR(x, ...)
+#endif
+
+#if 0
+#define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#else
+#define INFO(x, ...)
+#endif
+
+#define ESP_MAX_TRY_JOIN 3
+#define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible)
+
+ESP8266 * ESP8266::inst;
+char* ip = NULL;
+
+ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *phrase, uint32_t baud) :
+ wifi(tx, rx), reset_pin(reset), buf_ESP8266(ESP_MBUFFE_MAX)
+{
+ INFO("Initializing ESP8266 object");
+ memset(&state, 0, sizeof(state));
+
+
+ strcpy(this->ssid, ssid);
+ strcpy(this->phrase, phrase);
+ inst = this;
+ attach_rx(false);
+
+ wifi.baud(baud); // initial baud rate of the ESP8266
+
+ state.associated = false;
+ state.cmdMode = false;
+}
+
+bool ESP8266::join()
+{
+ char cmd[100];
+ sendCommand( "AT+CWMODE=1", "change", NULL, 1000);
+ //string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\"";
+ sprintf(cmd,"AT+CWJAP=\"%s\",\"%s\"",this->ssid,this->phrase);
+ if( sendCommand( cmd, "OK", NULL, 10000) ) {
+ // successfully joined the network
+ state.associated = true;
+ INFO("ssid: %s, phrase: %s", this->ssid, this->phrase);
+ return true;
+ }
+ return false;
+}
+
+bool ESP8266::connect()
+{
+ sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode
+ return ESP8266::join();
+}
+
+bool ESP8266::is_connected()
+{
+ return true;
+}
+
+bool ESP8266::start(bool type,char* ip, int port, int id)
+{
+ char cmd[256];
+ // Error Check
+ if(id > ESP_MAXID) {
+ ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id);
+ return false;
+ }
+ // Single Connection Mode
+ if(id < 0) {
+ DBG("Start Single Connection Mode");
+ //char portstr[5];
+ bool check [3] = {0};
+ //sprintf(portstr, "%d", port);
+ switch(type) {
+ case ESP_UDP_TYPE : //UDP
+ sprintf(cmd,"AT+CIPSTART=\"UDP\",\"%s\",%d",ip,port);
+ check[0] = sendCommand(cmd, "OK", NULL, 10000);
+ //check[0] = sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
+ break;
+ case ESP_TCP_TYPE : //TCP
+ sprintf(cmd,"AT+CIPSTART=\"TCP\",\"%s\",%d",ip,port);
+ check[0] = sendCommand(cmd, "OK", NULL, 10000);
+ //check[0] = sendCommand(( "AT+CIPSTART=\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
+ break;
+ default:
+ ERR("Default hit for starting connection, this shouldnt be possible!!");
+ break;
+ }
+ check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode
+ check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode
+ // check that all commands were sucessful
+ if(check[0] and check[1] and check[2]) {
+ state.cmdMode = false;
+ return true;
+ } else {
+ ERR("startUDPTransparent Failed for ip:%s, port:%d",ip,port);
+ return false;
+ }
+ }
+ // Multi Connection Mode
+ else {
+ //TODO: impliment Multi Connection Mode
+ ERR("Not currently Supported!");
+ return false;
+ }
+}
+
+bool ESP8266::startUDP(char* ip, int port, int id, int length)
+{
+ char cmd[256];
+ char portstr[5];
+ char idstr[1];
+ char lenstr[2];
+
+ sprintf(portstr, "%d", port);
+ sprintf(idstr, "%d", id);
+ sprintf(lenstr, "%d", length);
+
+ sendCommand("AT+CIPMUX=1", "OK", NULL, 1000);
+ sprintf(cmd,"AT+CIPSTART=%d,\"UDP\",\"%s\",%d,1112,0",id,ip,port);
+ sendCommand(cmd, "OK", NULL, 10000);
+ //sendCommand(( "AT+CIPSTART=" + string(idstr) + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr + ",1112,0").c_str(), "OK", NULL, 10000);
+ sprintf(cmd,"AT+CIPSEND=%d,%d",id,length);
+ sendCommand(cmd, ">", NULL, 1000);// go into transparent mode
+ //sendCommand(("AT+CIPSEND=" + (string)idstr + "," + (string)lenstr).c_str(), ">", NULL, 1000);// go into transparent mode
+ DBG("Data Mode\r\n");
+ state.cmdMode = false;
+
+ return true;
+}
+
+bool ESP8266::startTCPServer(int port)
+{
+ char cmd[100];
+ bool command_results[3];
+ command_results[0]=sendCommand("AT+CWMODE=3", "OK", NULL, 1000);
+ command_results[1]=sendCommand("AT+CIPMUX=1", "OK", NULL, 1000);
+ if(port == 333){
+ command_results[2]=sendCommand("AT+CIPSERVER=1", "OK", NULL, 1000);
+ }
+ else{
+ sprintf(cmd,"AT+CIPSERVER=1,%d",port);
+ command_results[2]=sendCommand(cmd, "OK", NULL, 1000);
+ }
+ //sendCommand("AT+CIFSR", "OK", NULL, 1000);
+ DBG("Data Mode\r\n");
+ state.cmdMode = false;
+ if (command_results[0] and command_results[1] and command_results[2]){
+ return true;
+ }
+ else{
+ return false;
+ }
+}
+
+bool ESP8266::close()
+{
+ wait(0.1f);
+ send("+++",3);
+ wait(1.0f);
+ state.cmdMode = true;
+ sendCommand("AT+CIPCLOSE","OK", NULL, 10000);
+ return true;
+}
+
+bool ESP8266::disconnect()
+{
+ // if already disconnected, return
+ if (!state.associated)
+ return true;
+ // send command to quit AP
+ sendCommand("AT+CWQAP", "OK", NULL, 10000);
+ state.associated = false;
+ return true;
+}
+
+int ESP8266::strfind(const char *str,const char *chkstr,int pos)
+{
+ if( (strlen(str)-pos) < strlen(chkstr) ) return(-1);
+
+
+ for(int i=pos;i<strlen(str);i++)
+ {
+ if(memcmp(chkstr,&str[i],strlen(chkstr))==0)
+ {
+ return(i);
+ }
+ }
+ return(-1);
+}
+
+char* ESP8266::substr(const char *str , char *outstr , int pos1 , int pos2 )
+{
+ int size = pos2 - pos1;
+
+ memcpy(outstr , &str[pos1] , size );
+ outstr[size] = '\0';
+
+ return(outstr);
+}
+
+int ESP8266::strcount(const char *str , char countstr )
+{
+ int ret = 0;
+
+ for(int i = 0 ; i < strlen(str) ; i++)
+ {
+ if( str[i] == countstr )
+ {
+ ret++;
+ }
+
+ }
+
+ return(ret);
+}
+
+/*
+ Assuming Returned data looks like this:
+ +CIFSR:STAIP,"192.168.11.2"
+ +CIFSR:STAMAC,"18:fe:34:9f:3a:f5"
+ grabbing IP from first set of quotation marks
+*/
+char* ESP8266::getIPAddress()
+{
+ char result[30] = {0};
+ char tmp[30] = {0};
+ int check = 0;
+ check = sendCommand("AT+CIFSR", NULL, result, 1000);
+ //pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result);
+ ip = ipString;
+ if(check) {
+ // Success
+ uint8_t pos1 = 0, pos2 = 0;
+ //uint8_t pos3 = 0, pos4 = 0;
+ pos1 = strfind(result,"+CIFSR:STAIP",0);
+ //pos1 = resultString.find("+CIFSR:STAIP");
+ pos1 = strfind(result,"\"",pos1);
+ //pos1 = resultString.find('"',pos1);
+ pos2 = strfind(result,"\"",pos1+1);
+ //pos2 = resultString.find('"',pos1+1);
+ //pos3 = resultString.find('"',pos2+1); //would find mac address
+ //pos4 = resultString.find('"',pos3+1);
+ strncpy(ipString,substr(result,tmp,pos1,pos2),sizeof(ipString));
+ INFO("IP: %s",ipString);
+ ip = ipString;
+
+ } else {
+ // Failure
+ ERR("getIPAddress() failed");
+ ip = NULL;
+ }
+ return ip;
+}
+
+bool ESP8266::gethostbyname(const char * host, char * ip)
+{
+ int nb_digits = 0;
+ char tmp[100];
+
+ strcpy(ip,host);
+
+ return true;
+#if 0
+ // no dns needed
+ int pos = strfind(host,".",0);
+ if (pos != -1) {
+ nb_digits = atoi(substr(host,tmp,0,pos));
+ }
+ //printf("substrL %s\r\n", sub.c_str());
+ if (strcount(host,'.') == 3 && nb_digits > 0) {
+ strcpy(ip, host);
+ return true;
+ } else {
+ // dns needed, not currently available
+ ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!");
+ return false;
+ }
+#endif
+}
+
+void ESP8266::reset()
+{
+ reset_pin = 0;
+ wait_us(20);
+ reset_pin = 1;
+ //wait(1);
+ //reset_pin = !reset_pin
+ //send("+++",3);
+ wait(1);
+ state.cmdMode = true;
+ sendCommand("AT", "OK", NULL, 1000);
+ sendCommand("AT+RST", "ready", NULL, 10000);
+ state.associated = false;
+
+}
+
+bool ESP8266::reboot()
+{
+ reset();
+ return true;
+}
+
+void ESP8266::handler_rx(void)
+{
+ //read characters
+ char c;
+ while (wifi.readable()) {
+ c=wifi.getc();
+ buf_ESP8266.queue(c);
+ //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns
+ }
+}
+
+void ESP8266::attach_rx(bool callback)
+{
+ if (!callback) {
+ wifi.attach(NULL);
+ }
+ else {
+ wifi.attach(this, &ESP8266::handler_rx);
+ }
+}
+
+int ESP8266::readable()
+{
+ return buf_ESP8266.available();
+}
+
+int ESP8266::writeable()
+{
+ return wifi.writeable();
+}
+
+char ESP8266::getc()
+{
+ char c=0;
+ while (!buf_ESP8266.available());
+ buf_ESP8266.dequeue(&c);
+ return c;
+}
+
+int ESP8266::putc(char c)
+{
+ while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first
+ return wifi.putc(c);
+}
+
+void ESP8266::flush()
+{
+ buf_ESP8266.flush();
+}
+
+int ESP8266::send(const char * buf, int len)
+{
+ //TODO: need to add handler for data > 2048B, this is the max packet size of the ESP8266.
+ if(len >= 2048){
+ WARN("send buffer >= 2048B, need to chunk this up to be less.");
+ }
+ const char* bufptr=buf;
+ for(int i=0; i<len; i++) {
+ putc((int)*bufptr++);
+ }
+ return len;
+}
+
+bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout)
+{
+ char read;
+ char checking[512] = "";
+ int checking_size = 0;
+ int fond = -1;
+ Timer tmr;
+ int result = 0;
+
+ DBG("sendCmd:\t %s",cmd);
+
+ attach_rx(true);
+
+ //We flush the buffer
+ while (readable())
+ getc();
+
+ if (!ACK || !strcmp(ACK, "NO")) {
+ for (int i = 0; i < strlen(cmd); i++) {
+ result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
+ wait(0.005f); // prevents stuck recieve ready (?) need to let echoed character get read first
+ }
+ putc(13); //CR
+ wait(0.005f); // wait for echo
+ putc(10); //LF
+
+ } else {
+ //We flush the buffer
+ while (readable())
+ getc();
+
+ tmr.start();
+ for (int i = 0; i < strlen(cmd); i++) {
+ result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
+ wait(.005); // wait for echo
+ }
+ putc(13); //CR
+ wait(0.005f); // wait for echo
+ putc(10); //LF
+
+ while (1) {
+ if (tmr.read_ms() > timeout) {
+ //We flush the buffer
+ while (readable())
+ getc();
+
+ DBG("check:\t %s", checking);
+
+ attach_rx(true);
+ return -1;
+ } else if (readable()) {
+ read = getc();
+ //pc.printf("%c",read); //debug echo
+ if ( read != '\r' && read != '\n') {
+ checking[checking_size] = read;
+ checking_size++;
+ checking[checking_size] = '\0';
+ fond = strfind(checking,ACK,0);
+ if (fond != -1) {
+ wait(0.01f);
+
+ //We flush the buffer
+ while (readable())
+ read = getc();
+ //printf("%c",read); //debug echo
+ break;
+ }
+ }
+ }
+ }
+ DBG("check: %s", checking);
+
+ attach_rx(true);
+ return result;
+ }
+
+ //the user wants the result from the command (ACK == NULL, res != NULL)
+ if (res != NULL) {
+ int i = 0;
+ Timer timeout;
+ timeout.start();
+ tmr.reset();
+ while (1) {
+ if (timeout.read() > 2) {
+ if (i == 0) {
+ res = NULL;
+ break;
+ }
+ res[i] = '\0';
+ DBG("user str 1: %s", res);
+
+ break;
+ } else {
+ if (tmr.read_ms() > 300) {
+ res[i] = '\0';
+ DBG("user str: %s", res);
+
+ break;
+ }
+ if (readable()) {
+ tmr.start();
+ read = getc();
+
+ // we drop \r and \n
+ if ( read != '\r' && read != '\n') {
+ res[i++] = read;
+ }
+ }
+ }
+ }
+ DBG("user str: %s", res);
+ }
+
+ //We flush the buffer
+ while (readable())
+ getc();
+
+ attach_rx(true);
+ DBG("result: %d", result)
+ return result;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266/ESP8266.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,235 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * ESP8266 serial wifi module
+ *
+ * Datasheet:
+ *
+ * http://www.electrodragon.com/w/Wi07c
+ */
+
+#ifndef ESP8266_H
+#define ESP8266_H
+
+#include "mbed.h"
+#include "CBuffer.h"
+
+#define DEFAULT_WAIT_RESP_TIMEOUT 500
+#define ESP_TCP_TYPE 1
+#define ESP_UDP_TYPE 0
+#define ESP_MBUFFE_MAX 256
+
+/**
+ * The ESP8266 class
+ */
+class ESP8266
+{
+
+public:
+ /**
+ * Constructor
+ *
+ * @param tx mbed pin to use for tx line of Serial interface
+ * @param rx mbed pin to use for rx line of Serial interface
+ * @param reset reset pin of the wifi module ()
+ * @param ssid ssid of the network
+ * @param phrase WEP, WPA or WPA2 key
+ * @param baud the baudrate of the serial connection
+ */
+ ESP8266( PinName tx, PinName rx, PinName reset, const char * ssid, const char * phrase, uint32_t baud );
+
+ /**
+ * Connect the wifi module to the ssid contained in the constructor.
+ *
+ * @return true if connected, false otherwise
+ */
+ bool join();
+
+ /**
+ * Same as Join: connect to the ssid and get DHCP settings
+ * @return true if successful
+ */
+ bool connect();
+
+ /**
+ * Check connection to the access point
+ * @return true if successful
+ */
+ bool is_connected();
+
+ /**
+ * Disconnect the ESP8266 module from the access point
+ *
+ * @return true if successful
+ */
+ bool disconnect();
+
+ /*
+ * Start up a UDP or TCP Connection
+ * @param type 0 for UDP, 1 for TCP
+ * @param ip A string that contains the IP, no quotes
+ * @param port Numerical port number to connect to
+ * @param id number between 0-4, if defined it denotes ID to use in multimode (Default to Single connection mode with -1)
+ * @return true if sucessful, 0 if fail
+ */
+ bool start(bool type, char* ip, int port, int id = -1);
+
+ /*
+ * Legacy Start for UDP only connection in transparent mode
+ * @param ip A string that contains the IP, no quotes
+ * @param id number between 0-4
+ * @param port Numerical port number to connect to
+ * @param length number of characters in the message being sent
+ */
+ bool startUDP(char* ip, int port, int id, int length);
+
+ /*
+ * Legacy Start for UDP only connection in transparent mode
+ * @param ip A string that contains the IP, no quotes
+ * @param id number between 0-4
+ * @param port Numerical port number to connect to
+ * @param length number of characters in the message being sent
+ */
+ //bool startUDP(char* ip, int port, int id, int length);
+
+ /*
+ *Starts the ESP chip as a TCP Server
+ *@param port Numerical port of the server, default is 333
+ */
+ bool startTCPServer(int port = 333);
+
+ /**
+ * Close a connection
+ *
+ * @return true if successful
+ */
+ bool close();
+
+ /**
+ * Return the IP address
+ * @return IP address as a string
+ */
+ char* getIPAddress();
+
+ /**
+ * Return the IP address from host name
+ * @return true on success, false on failure
+ */
+ bool gethostbyname(const char * host, char * ip);
+
+ /**
+ * Reset the wifi module
+ */
+ void reset();
+
+ /**
+ * Reboot the wifi module
+ */
+ bool reboot();
+
+ /**
+ * Check if characters are available
+ *
+ * @return number of available characters
+ */
+ int readable();
+
+ /**
+ * Check if characters are available
+ *
+ * @return number of available characters
+ */
+ int writeable();
+
+ /**
+ * Read a character
+ *
+ * @return the character read
+ */
+ char getc();
+
+ /**
+ * Write a character
+ *
+ * @param the character which will be written
+ */
+ int putc(char c);
+
+ /**
+ * Flush the buffer
+ */
+ void flush();
+
+ /**
+ * Send a command to the wifi module. Check if the module is in command mode. If not enter in command mode
+ *
+ * @param str string to be sent
+ * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknowledged. (default: "NO")
+ * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL)
+ *
+ * @return true if successful
+ */
+ bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+
+ /**
+ * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module.
+ * Useful to send a command to the module and wait a response.
+ *
+ *
+ * @param str string to be sent
+ * @param len string length
+ * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO")
+ * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL)
+ *
+ * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s.
+ */
+ int send(const char * buf, int len);
+
+ static ESP8266 * getInstance() {
+ return inst;
+ };
+
+protected:
+ int strfind(const char *str,const char *chkstr,int pos=0);
+ char* substr(const char *str , char *outstr , int pos1 , int pos2 );
+ int strcount(const char *str , char countstr );
+
+
+ RawSerial wifi;
+ DigitalOut reset_pin;
+ char phrase[30];
+ char ssid[30];
+ char ipString[20];
+ CircBuffer<char> buf_ESP8266;
+
+ static ESP8266 * inst;
+
+ void attach_rx(bool null);
+ void handler_rx(void);
+
+
+ typedef struct STATE {
+ bool associated;
+ bool cmdMode;
+ } State;
+
+ State state;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266Interface.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,28 @@
+#include "ESP8266Interface.h"
+
+ESP8266Interface::ESP8266Interface( PinName tx, PinName rx, PinName reset,
+ const char * ssid, const char * phrase, uint32_t baud ) :
+ ESP8266(tx, rx, reset, ssid, phrase, baud )
+{
+}
+
+int ESP8266Interface::init()
+{
+ ESP8266::reset();
+ return 0;
+}
+
+bool ESP8266Interface::connect()
+{
+ return ESP8266::connect();
+}
+
+int ESP8266Interface::disconnect()
+{
+ return ESP8266::disconnect();
+}
+
+char * ESP8266Interface::getIPAddress()
+{
+ return ESP8266::getIPAddress();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266Interface.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,73 @@
+/* ESP8266Interface.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ESP8266INTERFACE_H_
+#define ESP8266INTERFACE_H_
+
+#include "ESP8266.h"
+#include "Endpoint.h"
+
+ /**
+ * Interface using ESP8266 to connect to an IP-based network
+ */
+class ESP8266Interface: public ESP8266 {
+public:
+
+ /**
+ * Constructor
+ *
+ * \param tx mbed pin to use for tx line of Serial interface
+ * \param rx mbed pin to use for rx line of Serial interface
+ * \param reset reset pin of the wifi module ()
+ * \param ssid ssid of the network
+ * \param phrase WEP or WPA key
+ * \param baud the baudrate of the serial connection (defaults to 115200, diff revs of the firmware use diff baud rates
+ */
+ ESP8266Interface(PinName tx, PinName rx, PinName reset, const char * ssid, const char * phrase, uint32_t baud = 115200 );
+
+ /** Initialize the interface with DHCP.
+ * Initialize the interface and configure it to use DHCP (no connection at this point).
+ * \return 0 on success, a negative number on failure
+ */
+ int init(); //With DHCP
+
+ /** Connect
+ * Bring the interface up, start DHCP if needed.
+ * \return 0 on success, a negative number on failure
+ */
+ bool connect();
+
+ /** Disconnect
+ * Bring the interface down
+ * \return 0 on success, a negative number on failure
+ */
+ int disconnect();
+
+ /** Get IP address
+ *
+ * \return ip address
+ */
+ char* getIPAddress();
+
+private:
+};
+
+#include "UDPSocket.h"
+
+#endif /* ESP8266INTERFACE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ESP8266InterfaceTiny/Helper/def.h Tue Dec 15 09:56:32 2015 +0000 @@ -0,0 +1,28 @@ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef DEF_H +#define DEF_H + +#include "cmsis.h" +#define htons(x) __REV16(x) +#define ntohs(x) __REV16(x) +#define htonl(x) __REV(x) +#define ntohl(x) __REV(x) + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Endpoint.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,64 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "Socket/Socket.h"
+#include "Socket/Endpoint.h"
+#include <cstring>
+
+using std::memset;
+
+Endpoint::Endpoint()
+{
+ ESP8266 = ESP8266::getInstance();
+ if (ESP8266 == NULL)
+ error("Endpoint constructor error: no ESP8266 instance available!\r\n");
+ reset_address();
+}
+Endpoint::~Endpoint() {}
+
+void Endpoint::reset_address(void)
+{
+ _ipAddress[0] = '\0';
+ _port = 0;
+ _id = -1;
+}
+
+int Endpoint::set_address(const char* host, const int port)
+{
+ //Resolve DNS address or populate hard-coded IP address
+ if(ESP8266->gethostbyname(host, _ipAddress)) {
+ _port = port;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+char* Endpoint::get_address()
+{
+ return _ipAddress;
+}
+
+int Endpoint::get_port()
+{
+ return _port;
+}
+
+int Endpoint::get_id()
+{
+ return _id;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Endpoint.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,72 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef ENDPOINT_H
+#define ENDPOINT_H
+
+#include "ESP8266.h"
+
+class UDPSocket;
+
+/**
+IP Endpoint (address, port)
+*/
+class Endpoint {
+ friend class UDPSocket;
+
+public:
+ /** IP Endpoint (address, port)
+ */
+ Endpoint(void);
+
+ ~Endpoint(void);
+
+ /** Reset the address of this endpoint
+ */
+ void reset_address(void);
+
+ /** Set the address of this endpoint
+ \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
+ \param port The endpoint port
+ \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
+ */
+ int set_address(const char* host, const int port);
+
+ /** Get the IP address of this endpoint
+ \return The IP address of this endpoint.
+ */
+ char* get_address(void);
+
+ /** Get the port of this endpoint
+ \return The port of this endpoint
+ */
+ int get_port(void);
+
+ /** Get the id of this endpoint
+ \return The id of this endpoint
+ */
+ int get_id(void);
+
+protected:
+ char _ipAddress[64];
+ int _port;
+ int _id;
+
+ ESP8266 * ESP8266;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Socket.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,57 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "Socket.h"
+#include <cstring>
+
+//Debug is disabled by default
+#if 0
+//Enable debug
+#include <cstdio>
+#define DBG(x, ...) std::printf("[Socket : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#define WARN(x, ...) std::printf("[Socket : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#define ERR(x, ...) std::printf("[Socket : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+
+#else
+//Disable debug
+#define DBG(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+
+#endif
+
+Socket::Socket() : _blocking(true), _timeout(1500) {
+ wifi = ESP8266::getInstance();
+ if (wifi == NULL)
+ ERR("Socket constructor error: no ESP8266 instance available!");
+}
+
+void Socket::set_blocking(bool blocking, unsigned int timeout) {
+ DBG("set blocking: %d %d", blocking, timeout);
+ _blocking = blocking;
+ _timeout = timeout;
+}
+
+int Socket::close() {
+
+ return (wifi->close()) ? 0 : -1;
+}
+
+Socket::~Socket() {
+ close(); //Don't want to leak
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Socket.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,51 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SOCKET_H_
+#define SOCKET_H_
+
+#include "ESP8266.h"
+
+/** Socket file descriptor and select wrapper
+ */
+class Socket {
+public:
+ /** Socket
+ */
+ Socket();
+
+ /** Set blocking or non-blocking mode of the socket and a timeout on
+ blocking socket operations
+ \param blocking true for blocking mode, false for non-blocking mode.
+ \param timeout timeout in ms [Default: (1500)ms].
+ */
+ void set_blocking(bool blocking, unsigned int timeout=1500);
+
+ /** Close the socket file descriptor
+ */
+ int close();
+
+ ~Socket();
+
+protected:
+ bool _blocking;
+ int _timeout;
+ ESP8266 * wifi;
+};
+
+
+#endif /* SOCKET_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketConnection.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,249 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "TCPSocketConnection.h"
+#include <cstring>
+#include <algorithm>
+#include "SoftSerialSendOnry.h"
+
+extern SoftSerialSendOnry pc;
+
+using std::memset;
+using std::memcpy;
+
+//Debug is disabled by default
+#if 0
+#define DBG(x, ...) pc.printf("[TCPConnection : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#define WARN(x, ...) pc.printf("[TCPConnection: WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#define ERR(x, ...) pc.printf("[TCPConnection : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
+#else
+#define DBG(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
+
+TCPSocketConnection::TCPSocketConnection() :
+ _is_connected(false)
+{
+}
+
+int TCPSocketConnection::connect(const char* host, const int port)
+{
+// if (init_socket(SOCK_STREAM) < 0)
+// return -1;
+//
+ if (set_address(host, port) != 0)
+ return -1;
+//
+// if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
+// close();
+// return -1;
+// }
+// _is_connected = true;
+
+ _is_connected = ESP8266->start(ESP_TCP_TYPE,_ipAddress,_port);
+ if(_is_connected) { //success
+ return 0;
+ } else { // fail
+ return -1;
+ }
+}
+
+bool TCPSocketConnection::is_connected(void)
+{
+ return _is_connected;
+}
+
+int TCPSocketConnection::send(char* data, int length)
+{
+ if (!_is_connected) {
+ ERR("TCPSocketConnection::receive() - _is_connected is false : you cant receive data until you connect to a socket!");
+ return -1;
+ }
+ Timer tmr;
+ int idx = 0;
+ tmr.start();
+ while ((tmr.read_ms() < _timeout) || _blocking) {
+
+ idx += wifi->send(data, length);
+
+ if (idx == length)
+ return idx;
+ }
+ return (idx == 0) ? -1 : idx;
+
+ //return wifi->send(data,length);
+//
+// if (!_blocking) {
+// TimeInterval timeout(_timeout);
+// if (wait_writable(timeout) != 0)
+// return -1;
+// }
+//
+// int n = lwip_send(_sock_fd, data, length, 0);
+// _is_connected = (n != 0);
+//
+// return n;
+
+}
+
+// -1 if unsuccessful, else number of bytes written
+int TCPSocketConnection::send_all(char* data, int length)
+{
+// if ((_sock_fd < 0) || !_is_connected)
+// return -1;
+//
+// int writtenLen = 0;
+// TimeInterval timeout(_timeout);
+// while (writtenLen < length) {
+// if (!_blocking) {
+// // Wait for socket to be writeable
+// if (wait_writable(timeout) != 0)
+// return writtenLen;
+// }
+//
+// int ret = lwip_send(_sock_fd, data + writtenLen, length - writtenLen, 0);
+// if (ret > 0) {
+// writtenLen += ret;
+// continue;
+// } else if (ret == 0) {
+// _is_connected = false;
+// return writtenLen;
+// } else {
+// return -1; //Connnection error
+// }
+// }
+// return writtenLen;
+ return send(data,length); // just remap to send
+}
+
+int TCPSocketConnection::receive(char* buffer, int length)
+{
+ if (!_is_connected) {
+ ERR("TCPSocketConnection::receive() - _is_connected is false : you cant receive data until you connect to a socket!");
+ return -1;
+ }
+ Timer tmr;
+ int idx = 0;
+ int nb_available = 0;
+ int time = -1;
+
+ //make this the non-blocking case and return if <= 0
+ // remember to change the config to blocking
+ // if ( ! _blocking) {
+ // if ( wifi.readable <= 0 ) {
+ // return (wifi.readable);
+ // }
+ // }
+ //---
+ tmr.start();
+ if (_blocking) {
+ while (1) {
+ nb_available = wifi->readable();
+ if (nb_available != 0) {
+ break;
+ }
+ }
+ }
+ //---
+ // blocking case
+ else {
+ tmr.reset();
+
+ while (time < _timeout) {
+ nb_available = wifi->readable();
+ if (nb_available < 0) return nb_available;
+ if (nb_available > 0) break ;
+ time = tmr.read_ms();
+ }
+
+ if (nb_available == 0) return nb_available;
+ }
+
+ // change this to < 20 mS timeout per byte to detect end of packet gap
+ // this may not work due to buffering at the UART interface
+ tmr.reset();
+ // while ( tmr.read_ms() < 20 ) {
+ // if ( wifi.readable() && (idx < length) ) {
+ // buffer[idx++] = wifi->getc();
+ // tmr.reset();
+ // }
+ // if ( idx == length ) {
+ // break;
+ // }
+ // }
+ //---
+ while (time < _timeout) {
+
+ nb_available = wifi->readable();
+ //for (int i = 0; i < min(nb_available, length); i++) {
+ for (int i = 0; i < min(nb_available, (length-idx)); i++) {
+ buffer[idx] = wifi->getc();
+ idx++;
+ }
+ if (idx == length) {
+ break;
+ }
+ time = tmr.read_ms();
+ }
+ //---
+ return (idx == 0) ? -1 : idx;
+
+//************************ original code below
+//
+// if (!_blocking) {
+// TimeInterval timeout(_timeout);
+// if (wait_readable(timeout) != 0)
+// return -1;
+// }
+//
+// int n = lwip_recv(_sock_fd, data, length, 0);
+// _is_connected = (n != 0);
+//
+// return n;
+
+}
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive_all(char* data, int length)
+{
+ //ERR("receive_all() not yet implimented");
+ // if ((_sock_fd < 0) || !_is_connected)
+// return -1;
+//
+// int readLen = 0;
+// TimeInterval timeout(_timeout);
+// while (readLen < length) {
+// if (!_blocking) {
+// //Wait for socket to be readable
+// if (wait_readable(timeout) != 0)
+// return readLen;
+// }
+//
+// int ret = lwip_recv(_sock_fd, data + readLen, length - readLen, 0);
+// if (ret > 0) {
+// readLen += ret;
+// } else if (ret == 0) {
+// _is_connected = false;
+// return readLen;
+// } else {
+// return -1; //Connnection error
+// }
+// }
+// return readLen;
+ receive(data,length);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketConnection.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,82 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TCPSOCKET_H
+#define TCPSOCKET_H
+
+#include "Socket/Socket.h"
+#include "Socket/Endpoint.h"
+
+/**
+TCP socket connection
+*/
+class TCPSocketConnection : public Socket, public Endpoint {
+ friend class TCPSocketServer;
+
+public:
+ /** TCP socket connection
+ */
+ TCPSocketConnection();
+
+ /** Connects this TCP socket to the server
+ \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
+ \param port The host's port to connect to.
+ \return 0 on success, -1 on failure.
+ */
+ int connect(const char* host, const int port);
+
+ /** Check if the socket is connected
+ \return true if connected, false otherwise.
+ */
+ bool is_connected(void);
+
+ /** Send data to the remote host.
+ \param data The buffer to send to the host.
+ \param length The length of the buffer to send.
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int send(char* data, int length);
+
+ /** Send all the data to the remote host.
+ \param data The buffer to send to the host.
+ \param length The length of the buffer to send.
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int send_all(char* data, int length);
+
+ /** Receive data from the remote host.
+ \param data The buffer in which to store the data received from the host.
+ \param length The maximum length of the buffer.
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receive(char* data, int length);
+
+ /** Receive all the data from the remote host.
+ \param data The buffer in which to store the data received from the host.
+ \param length The maximum length of the buffer.
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receive_all(char* data, int length);
+
+private:
+ bool _is_connected;
+
+};
+
+#endif
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketServer.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,44 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "TCPSocketServer.h"
+
+#include <cstring>
+
+using std::memset;
+using std::memcpy;
+
+TCPSocketServer::TCPSocketServer() {
+
+}
+
+int TCPSocketServer::bind(int port) {
+ if(!wifi->startTCPServer(port)) {
+ return(-1);
+ }
+ _port = port;
+ return 0;
+}
+
+int TCPSocketServer::listen(int max) {
+
+ return 0;
+}
+
+int TCPSocketServer::accept(TCPSocketConnection& connection) {
+ return 0;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketServer.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,55 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef TCPSOCKETSERVER_H
+#define TCPSOCKETSERVER_H
+
+#include "Socket/Socket.h"
+#include "TCPSocketConnection.h"
+
+/** TCP Server.
+ */
+class TCPSocketServer : public Socket {
+ friend class TCPSocketConnection;
+ public:
+ /** Instantiate a TCP Server.
+ */
+ TCPSocketServer();
+
+ /** Bind a socket to a specific port.
+ \param port The port to listen for incoming connections on.
+ \return 0 on success, -1 on failure.
+ */
+ int bind(int port);
+
+ /** Start listening for incoming connections.
+ \param backlog number of pending connections that can be queued up at any
+ one time [Default: 1].
+ \return 0 on success, -1 on failure.
+ */
+ int listen(int backlog=1);
+
+ /** Accept a new connection.
+ \param connection A TCPSocketConnection instance that will handle the incoming connection.
+ \return 0 on success, -1 on failure.
+ */
+ int accept(TCPSocketConnection& connection);
+private:
+ int _port;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/UDPSocket.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,154 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "UDPSocket.h"
+
+#include <string>
+#include <algorithm>
+
+UDPSocket::UDPSocket()
+{
+ endpoint_configured = false;
+ endpoint_read = false;
+ Endpoint currentEndpoint;
+}
+
+int UDPSocket::init(void)
+{
+ return 0;
+}
+
+// Server initialization
+int UDPSocket::bind(int port)
+{
+ return 0;
+}
+
+// -1 if unsuccessful, else number of bytes written
+int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
+{
+ Timer tmr;
+ int idx = 0;
+
+
+ confEndpoint(remote);
+
+ // initialize transparent mode if not already done
+ if(!endpoint_configured) {
+ // initialize UDP (default id of -1 means transparent mode)
+ //!wifi->start(ESP_UDP_TYPE, remote._ipAddress, remote._port, remote._id
+ if(!wifi->startUDP(remote._ipAddress, remote._port, 0,length)) {
+ return(-1);
+ }
+ endpoint_configured = true;
+ }
+
+ tmr.start();
+
+ while ((tmr.read_ms() < _timeout) || _blocking) {
+
+ idx += wifi->send(packet, length);
+
+ if (idx == length)
+ return idx;
+ }
+ return (idx == 0) ? -1 : idx;
+}
+
+// -1 if unsuccessful, else number of bytes received
+int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length)
+{
+ Timer tmr;
+ int idx = 0;
+ int nb_available = 0;
+ int time = -1;
+
+ //make this the non-blocking case and return if <= 0
+ // remember to change the config to blocking
+ // if ( ! _blocking) {
+ // if ( wifi.readable <= 0 ) {
+ // return (wifi.readable);
+ // }
+ // }
+ //---
+ tmr.start();
+ if (_blocking) {
+ while (1) {
+ nb_available = wifi->readable();
+ if (nb_available != 0) {
+ break;
+ }
+ }
+ }
+ //---
+ // blocking case
+ else {
+ tmr.reset();
+
+ while (time < _timeout) {
+ nb_available = wifi->readable();
+ if (nb_available < 0) return nb_available;
+ if (nb_available > 0) break ;
+ time = tmr.read_ms();
+ }
+
+ if (nb_available == 0) return nb_available;
+ }
+
+ // change this to < 20 mS timeout per byte to detect end of packet gap
+ // this may not work due to buffering at the UART interface
+ tmr.reset();
+ // while ( tmr.read_ms() < 20 ) {
+ // if ( wifi.readable() && (idx < length) ) {
+ // buffer[idx++] = wifi->getc();
+ // tmr.reset();
+ // }
+ // if ( idx == length ) {
+ // break;
+ // }
+ // }
+ //---
+ while (time < _timeout) {
+
+ nb_available = wifi->readable();
+ //for (int i = 0; i < min(nb_available, length); i++) {
+ for (int i = 0; i < min(nb_available, (length-idx)); i++) {
+ buffer[idx] = wifi->getc();
+ idx++;
+ }
+ if (idx == length) {
+ break;
+ }
+ time = tmr.read_ms();
+ }
+ //---
+ readEndpoint(remote);
+ return (idx == 0) ? -1 : idx;
+}
+
+bool UDPSocket::confEndpoint(Endpoint & ep)
+{
+ currentEndpoint = ep;
+ return true;
+}
+
+bool UDPSocket::readEndpoint(Endpoint & ep)
+{
+ ep = currentEndpoint;
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/UDPSocket.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,76 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef UDPSOCKET_H
+#define UDPSOCKET_H
+
+#include "Endpoint.h"
+#include "Socket.h"
+
+#include <cstdint>
+
+/**
+UDP Socket
+*/
+class UDPSocket: public Socket {
+
+public:
+ /** Instantiate an UDP Socket.
+ */
+ UDPSocket();
+
+ /** Init the UDP Client Socket without binding it to any specific port
+ \return 0 on success, -1 on failure.
+ */
+ int init(void);
+
+ /** Bind a UDP Server Socket to a specific port
+ \param port The port to listen for incoming connections on
+ \return 0 on success, -1 on failure.
+ */
+ int bind(int port = -1);
+
+ /** Send a packet to a remote endpoint
+ \param remote The remote endpoint
+ \param packet The packet to be sent
+ \param length The length of the packet to be sent
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int sendTo(Endpoint &remote, char *packet, int length);
+
+ /** Receive a packet from a remote endpoint
+ \param remote The remote endpoint
+ \param buffer The buffer for storing the incoming packet data. If a packet
+ is too long to fit in the supplied buffer, excess bytes are discarded
+ \param length The length of the buffer
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receiveFrom(Endpoint &remote, char *buffer, int length);
+
+private:
+ bool confEndpoint(Endpoint & ep);
+ bool readEndpoint(Endpoint & ep);
+ bool endpoint_configured;
+ bool endpoint_read;
+ Endpoint currentEndpoint;
+
+};
+
+#include "def.h"
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MQTT.lib Tue Dec 15 09:56:32 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/mqtt/code/MQTT/#e335fcc1a663
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTTESP8266.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,44 @@
+
+#if !defined(MQTTESP8266_H)
+#define MQTTESP8266_H
+
+#include "MQTTmbed.h"
+#include "ESP8266Interface.h"
+#include "MQTTSocket.h"
+
+// This struct is only used to workaround the order that the interfaces are initialized
+// MQTTSocket contains a TCPSocketConnection which needs the ESP8266Interface to be
+// instantiated first. Unfortunately the only way to instantiate a member before a superclass
+// is through another superclass.
+struct MQTTESP8266Holder {
+ MQTTESP8266Holder(PinName tx, PinName rx, PinName reset, const char *ssid, const char *pass) :
+ _wifi(tx, rx, reset, ssid, pass) {}
+
+ ESP8266Interface _wifi;
+};
+
+// Straightforward implementation of a MQTT interface
+class MQTTESP8266 : public MQTTESP8266Holder, public MQTTSocket {
+private:
+ MQTTESP8266Holder::_wifi;
+ //ESP8266Interface _wifi;
+
+public:
+ MQTTESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *pass) :
+ MQTTESP8266Holder(tx, rx, reset, ssid, pass) {
+ _wifi.init();
+ _wifi.connect();
+ }
+
+ ESP8266Interface& getInterface() {
+ return _wifi;
+ }
+
+ void reconnect() {
+ _wifi.disconnect();
+ _wifi.connect();
+ }
+};
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Milkcocoa.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,197 @@
+#include "Milkcocoa.h"
+
+#if 1
+#include "SoftSerialSendOnry.h"
+extern SoftSerialSendOnry pc;
+#define DBG(x) x
+#else
+#define DBG(x)
+#endif
+
+DataElement::DataElement() {
+ json_msg[0] = '\0';
+ strcpy(json_msg,"{\"params\":{");
+}
+
+DataElement::DataElement(char *json_string) {
+ json_msg[0] = '\0';
+ strcpy(json_msg,json_string);
+}
+
+void DataElement::setValue(const char *key, const char *v) {
+ char json_string[64];
+ if( json_msg[strlen(json_msg)-1] != '{' )
+ {
+ strcat(json_msg,",");
+ }
+ sprintf(json_string,"\"%s\":\"%s\"",key,v);
+ strcat(json_msg,json_string);
+}
+
+void DataElement::setValue(const char *key, int v) {
+ char json_string[64];
+ if( json_msg[strlen(json_msg)-1] != '{' )
+ {
+ strcat(json_msg,",");
+ }
+ sprintf(json_string,"\"%s\":\"%d\"",key,v);
+ strcat(json_msg,json_string);
+}
+
+void DataElement::setValue(const char *key, double v) {
+ char json_string[64];
+ if( json_msg[strlen(json_msg)-1] != '{' )
+ {
+ strcat(json_msg,",");
+ }
+ sprintf(json_string,"\"%s\":\"%f\"",key,v);
+ strcat(json_msg,json_string);
+}
+
+char *DataElement::getString(const char *key) {
+ static char _word[64];
+ char *p;
+ int i=0;
+
+ strcpy(_word , "\"\0");
+ strcat(_word , key );
+ strcat(_word , "\"" );
+
+ p = strstr( (char*)json_msg , _word ) + 2 + strlen(_word);
+
+ while( (p[i] != ',')&&(p[i] != '\n')&&(p[i] != '\"') )
+ {
+ _word[i] = p[i];
+ i++;
+ }
+ _word[i] = '\0';
+
+ return _word;
+}
+
+int DataElement::getInt(const char *key) {
+ return atoi(getString(key));
+}
+
+float DataElement::getFloat(const char *key) {
+ return atof(getString(key));
+}
+
+char *DataElement::toCharArray() {
+ if( json_msg[strlen(json_msg)-1] != '{' )
+ {
+ strcat(json_msg,"}");
+ }
+ strcat(json_msg,"}");
+
+ return(json_msg);
+}
+
+Milkcocoa::Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id) : client(MQTT::Client<MQTTESP8266, Countdown>(*ipstack)) {
+
+ _ipstack = ipstack;
+ strcpy(servername,host);
+ portnum = port;
+ app_id = _app_id;
+ strcpy(_clientid,client_id);
+ strcpy(username,"sdammy");
+ strcpy(password,app_id);
+
+}
+
+Milkcocoa::Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session) : client(MQTT::Client<MQTTESP8266, Countdown>(*ipstack)) {
+
+ _ipstack = ipstack;
+ strcpy(servername,host);
+ portnum = port;
+ app_id = _app_id;
+ strcpy(_clientid,client_id);
+ strcpy(username,_session);
+ strcpy(password,app_id);
+
+}
+
+Milkcocoa* Milkcocoa::createWithApiKey(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret) {
+ char session[60];
+ sprintf(session, "k%s:%s", key, secret);
+ return new Milkcocoa(ipstack, host, port, _app_id, client_id, session);
+}
+
+void Milkcocoa::connect() {
+
+ if(client.isConnected())
+ return;
+
+ if(_ipstack->connect(servername, portnum)!=0) {
+ DBG(pc.printf("Network connect err\r\n");)
+ return;
+ }
+
+ MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+ data.keepAliveInterval = 20;
+ data.cleansession = 1;
+ data.MQTTVersion = 4;
+ data.clientID.cstring = _clientid;
+ data.username.cstring = username;
+ data.password.cstring = password;
+
+ if (client.connect(data) != 0) {
+ DBG(pc.printf("Milkcocoa connect err\r\n");)
+ return;
+ }
+}
+
+bool Milkcocoa::push(const char *path, DataElement dataelement) {
+ char topic[100];
+ char *buf;
+ MQTT::Message message;
+
+ sprintf(topic, "%s/%s/push", app_id, path);
+
+ message.qos = MQTT::QOS0;
+ message.retained = 0;
+ message.dup = false;
+ buf = dataelement.toCharArray();
+ message.payload = (void*)buf;
+ message.payloadlen = strlen(buf);
+ if(client.publish(topic, message)!=0)
+ return(false);
+
+ return true;
+}
+
+bool Milkcocoa::send(const char *path, DataElement dataelement) {
+ char topic[100];
+ char *buf;
+ MQTT::Message message;
+
+ sprintf(topic, "%s/%s/send", app_id, path);
+ message.qos = MQTT::QOS0;
+ message.retained = 0;
+ message.dup = false;
+ buf = dataelement.toCharArray();
+ message.payload = (void*)buf;
+ message.payloadlen = strlen(buf);
+ if(client.publish(topic, message)!=0)
+ return false;
+
+ return true;
+}
+
+void Milkcocoa::loop() {
+ connect();
+ client.yield(RECV_TIMEOUT);
+}
+
+bool Milkcocoa::on(const char *path, const char *event, GeneralFunction cb) {
+ static char topic[100];
+
+ sprintf(topic, "%s/%s/%s", app_id, path, event);
+
+ if (client.subscribe(topic, MQTT::QOS0, cb) != 0) {
+ DBG(pc.printf("Milkcocoa subscribe err\r\n");)
+ return false;
+ }
+ return true;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Milkcocoa.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,54 @@
+#ifndef _MILKCOCOA_H_
+#define _MILKCOCOA_H_
+
+#include "mbed.h"
+#include "MQTTESP8266.h"
+#include "MQTTClient.h"
+
+#define RECV_TIMEOUT 500
+
+class DataElement {
+ public:
+ DataElement();
+ DataElement(char *json_string);
+ void setValue(const char *key, const char *v);
+ void setValue(const char *key, int v);
+ void setValue(const char *key, double v);
+ char *toCharArray();
+ char *getString(const char *key);
+ int getInt(const char *key);
+ float getFloat(const char *key);
+
+ private:
+ char json_msg[256];
+};
+
+typedef void (*GeneralFunction) (MQTT::MessageData& elem);
+
+class Milkcocoa {
+ public:
+
+ Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id);
+ Milkcocoa(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session);
+ static Milkcocoa* createWithApiKey(MQTTESP8266 *ipstack, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret);
+ void connect();
+ void loop();
+ bool push(const char *path, DataElement dataelement);
+ bool send(const char *path, DataElement dataelement);
+ bool on(const char *path, const char *event, GeneralFunction cb);
+
+private:
+ char servername[64];
+ int16_t portnum;
+ char _clientid[64];
+ char username[32];
+ char password[32];
+ const char *app_id;
+
+ MQTTESP8266 *_ipstack;
+ MQTT::Client<MQTTESP8266, Countdown> client;
+ GeneralFunction _cb;
+};
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerialSendOnry.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,36 @@
+#include "SoftSerialSendOnry.h"
+
+SoftSerialSendOnry::SoftSerialSendOnry(PinName TX, const char* name) {
+ tx_en = false;
+ if (TX != NC) {
+ tx = new DigitalOut(TX);
+ tx_en = true;
+ tx->write(1);
+ tx_bit = -1;
+ txticker.attach(this, &SoftSerialSendOnry::tx_handler);
+ }
+
+ baud(9600);
+ format();
+}
+
+SoftSerialSendOnry::~SoftSerialSendOnry() {
+ if (tx_en)
+ delete(tx);
+}
+
+void SoftSerialSendOnry::baud(int baudrate) {
+ bit_period = 1000000 / baudrate;
+}
+
+void SoftSerialSendOnry::format(int bits, Parity parity, int stop_bits) {
+ _bits = bits;
+ _parity = parity;
+ _stop_bits = stop_bits;
+ _total_bits = 1 + _bits + _stop_bits + (bool)_parity;
+}
+
+int SoftSerialSendOnry::_getc()
+{
+ return(0);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerialSendOnry.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,105 @@
+#ifndef SOFTSERIAL_SEND_ONRY_H
+#define SOFTSERIAL_SEND_ONRY_H
+
+#include "mbed.h"
+#include "SoftSerial_Ticker.h"
+/** A software serial implementation
+ *
+ */
+class SoftSerialSendOnry: public Stream {
+
+public:
+ /**
+ * Constructor
+ *
+ * @param TX Name of the TX pin, NC for not connected
+ * @param name Name of the connection
+ */
+ SoftSerialSendOnry(PinName TX, const char* name = NULL);
+ virtual ~SoftSerialSendOnry();
+
+ /** Set the baud rate of the serial port
+ *
+ * @param baudrate The baudrate of the serial port (default = 9600).
+ */
+ void baud(int baudrate);
+
+ enum Parity {
+ None = 0,
+ Odd,
+ Even,
+ Forced1,
+ Forced0
+ };
+
+ enum IrqType {
+ RxIrq = 0,
+ TxIrq
+ };
+
+ /** Set the transmission format used by the serial port
+ *
+ * @param bits The number of bits in a word (default = 8)
+ * @param parity The parity used (SerialBase::None, SerialBase::Odd, SerialBase::Even, SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None)
+ * @param stop The number of stop bits (default = 1)
+ */
+ void format(int bits=8, Parity parity=SoftSerialSendOnry::None, int stop_bits=1);
+
+ /** Determine if there is space available to write a character
+ *
+ * @returns
+ * 1 if there is space to write a character,
+ * 0 otherwise
+ */
+ int writeable();
+
+ /** Attach a function to call whenever a serial interrupt is generated
+ *
+ * @param fptr A pointer to a void function, or 0 to set as none
+ * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+ */
+ void attach(void (*fptr)(void), IrqType type=RxIrq) {
+ fpointer[type].attach(fptr);
+ }
+
+ /** Attach a member function to call whenever a serial interrupt is generated
+ *
+ * @param tptr pointer to the object to call the member function on
+ * @param mptr pointer to the member function to be called
+ * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+ */
+ template<typename T>
+ void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
+ fpointer[type].attach(tptr, mptr);
+ }
+
+ /** Generate a break condition on the serial line
+ */
+ void send_break();
+
+protected:
+ DigitalOut *tx;
+
+ bool tx_en;
+ int bit_period;
+ int _bits, _stop_bits, _total_bits;
+ Parity _parity;
+
+ FunctionPointer fpointer[2];
+
+ //tx
+ void tx_handler(void);
+ void prepare_tx(int c);
+ FlexTicker txticker;
+ int _char;
+ volatile int tx_bit;
+
+
+
+ virtual int _getc();
+ virtual int _putc(int c);
+};
+
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerialSendOnry_tx.cpp Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,80 @@
+#include "SoftSerialSendOnry.h"
+
+int SoftSerialSendOnry::_putc(int c)
+{
+ while(!writeable());
+ prepare_tx(c);
+ tx_bit = 0;
+ txticker.prime();
+ tx_handler();
+ return 0;
+}
+
+void SoftSerialSendOnry::send_break(void) {
+ while(!writeable());
+ tx_bit = 0; //Just to make sure it appears as non-writable to other threads/IRQs
+ tx->write(0);
+ wait_us((bit_period * _total_bits * 3) / 2);
+ tx->write(1);
+ tx_bit = -1;
+}
+
+int SoftSerialSendOnry::writeable(void)
+{
+ if (!tx_en)
+ return false;
+ if (tx_bit == -1)
+ return true;
+ return false;
+}
+
+void SoftSerialSendOnry::tx_handler(void)
+{
+ if (tx_bit == _total_bits) {
+ tx_bit = -1;
+ fpointer[TxIrq].call();
+ return;
+ }
+
+ //Flip output
+ int cur_out = tx->read();
+ tx->write(!cur_out);
+
+ //Calculate when to do it again
+ int count = bit_period;
+ tx_bit++;
+ while(((_char >> tx_bit) & 0x01) == !cur_out) {
+ count+=bit_period;
+ tx_bit++;
+ }
+
+ txticker.setNext(count);
+}
+
+void SoftSerialSendOnry::prepare_tx(int c)
+{
+ _char = c << 1;
+
+ bool parity;
+ switch (_parity) {
+ case Forced1:
+ _char |= 1 << (_bits + 1);
+ case Even:
+ parity = false;
+ for (int i = 0; i<_bits; i++) {
+ if (((_char >> i) & 0x01) == 1)
+ parity = !parity;
+ }
+ _char |= parity << (_bits + 1);
+ case Odd:
+ parity = true;
+ for (int i = 0; i<_bits; i++) {
+ if (((_char >> i) & 0x01) == 1)
+ parity = !parity;
+ }
+ _char |= parity << (_bits + 1);
+ }
+
+ _char |= 0xFFFF << (1 + _bits + (bool)_parity);
+ _char &= ~(1<<_total_bits);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerial_Ticker.h Tue Dec 15 09:56:32 2015 +0000
@@ -0,0 +1,38 @@
+//A modified version of the regular ticker/timeout libraries to allow us to do timeout without losing accuracy
+
+#ifndef FLEXTICKER_H
+#define FLEXTICKER_H
+
+#include "mbed.h"
+
+class FlexTicker: public TimerEvent {
+ public:
+ template<typename T>
+ void attach(T* tptr, void (T::*mptr)(void)) {
+ _function.attach(tptr, mptr);
+ }
+
+ /** Detach the function
+ */
+ void detach() {
+ remove();
+ }
+
+ void setNext(int delay) {
+ insert(event.timestamp + delay);
+ }
+
+ void prime(void) {
+ event.timestamp = us_ticker_read();
+ }
+
+protected:
+ virtual void handler() {
+ _function.call();
+ }
+
+ unsigned int _delay;
+ FunctionPointer _function;
+};
+
+#endif
\ No newline at end of file
