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: mbed EthernetNetIf
Revision 2:764ecec3dc59, committed 2011-07-28
- Comitter:
- okini3939
- Date:
- Thu Jul 28 16:35:09 2011 +0000
- Parent:
- 1:9f15e579d914
- Commit message:
Changed in this revision
--- a/TinyHTTP.cpp Wed Jul 27 16:19:14 2011 +0000
+++ b/TinyHTTP.cpp Thu Jul 28 16:35:09 2011 +0000
@@ -13,21 +13,19 @@
#include "TCPSocket.h"
#include "DNSRequest.h"
#include "TinyHTTP.h"
-
-#define STATUS_NONE 0
-#define STATUS_READABLE 1
-#define STATUS_CONNECTED 2
-#define STATUS_ERROR 3
-#define STATUS_DISCONNECTED 4
+#include <ctype.h>
TCPSocket *http;
-volatile int tcp_status = 0, dns_status = 0;
+volatile int tcp_ready, tcp_readable, tcp_writable;
+volatile int dns_status;
// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
-void base64enc(const char *input, unsigned int length, char *output) {
+int base64enc(const char *input, unsigned int length, char *output, int len) {
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int c, c1, c2, c3;
+
+ if (len < ((((length-1)/3)+1)<<2)) return -1;
for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
@@ -43,26 +41,32 @@
output[j+3] = (length>i+2)?base64[c]:'=';
}
output[(((length-1)/3)+1)<<2] = '\0';
+ return 0;
}
-/*
+
// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
-int url_encode(char *str, char *buf, int len) {
+int urlencode(char *str, char *buf, int len) {
+ static const char to_hex[] = "0123456789ABCDEF";
// char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
- if (len < strlen(str) * 3 + 1) return -1;
char *pstr = str, *pbuf = buf;
+
+ if (len < (strlen(str) * 3 + 1)) return -1;
while (*pstr) {
- if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
+ if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') {
*pbuf++ = *pstr;
- else if (*pstr == ' ')
+ } else if (*pstr == ' ') {
*pbuf++ = '+';
- else
- *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+ } else {
+ *pbuf++ = '%';
+ *pbuf++ = to_hex[(*pstr >> 4) & 0x0f];
+ *pbuf++ = to_hex[*pstr & 0x0f];
+ }
pstr++;
}
*pbuf = '\0';
return 0;
}
-*/
+
void isr_http (TCPSocketEvent e) {
@@ -70,37 +74,42 @@
printf("tcp(%d)\r\n", e);
#endif
switch(e) {
- case TCPSOCKET_READABLE: //Incoming data
- tcp_status = STATUS_READABLE;
+ case TCPSOCKET_CONNECTED:
+ tcp_ready = 1;
break;
- case TCPSOCKET_CONNECTED:
+ case TCPSOCKET_READABLE: //Incoming data
+ tcp_readable = 1;
+ break;
+
case TCPSOCKET_WRITEABLE: //We can send data
- tcp_status = STATUS_CONNECTED;
+ tcp_writable = 1;
break;
case TCPSOCKET_CONTIMEOUT:
case TCPSOCKET_CONRST:
case TCPSOCKET_CONABRT:
case TCPSOCKET_ERROR:
- tcp_status = STATUS_ERROR;
- break;
-
case TCPSOCKET_DISCONNECTED:
- tcp_status = STATUS_DISCONNECTED;
+ tcp_ready = 0;
break;
}
}
-void createauth (char *user, char *pwd, char *buf) {
+void createauth (char *user, char *pwd, char *buf, int len) {
char tmp[80];
- snprintf(tmp, sizeof(tmp), "Authorization: Basic %s:%s\n", user, pwd);
- base64enc(tmp, strlen(tmp), buf);
+ strncpy(buf, "Authorization: Basic ", len);
+ snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
+ base64enc(tmp, strlen(tmp), &buf[strlen(buf)], len - strlen(buf));
+ strncat(buf, "\r\n", len - strlen(buf));
}
void isr_dns (DNSReply r) {
+#ifdef DEBUG
+ printf("dns(%d)\r\n", r);
+#endif
if (DNS_FOUND) {
dns_status = 1;
} else {
@@ -110,26 +119,35 @@
int httpRequest (int method, Host *host, char *uri, char *head, char *body) {
TCPSocketErr err;
- char buf[500];
+ Timer timeout;
+ char buf[1500];
int i, ret = -1;
http = new TCPSocket;
- tcp_status = STATUS_NONE;
+ tcp_ready = 0;
+ tcp_readable = 0;
+ tcp_writable = 0;
http->setOnEvent(isr_http);
// connect
if (host->getIp().isNull()) {
+ // resolv
DNSRequest dns;
dns_status = 0;
dns.setOnReply(isr_dns);
if (dns.resolve(host) != DNS_OK) goto exit;
- for (i = 0; i < HTTP_TIMEOUT / 10; i ++) {
+ timeout.reset();
+ timeout.start();
+ while (timeout.read_ms() < HTTP_TIMEOUT) {
if (dns_status) break;
Net::poll();
- wait_ms(10);
}
- while (dns_status < 0) goto exit;
+ timeout.stop();
+ if (dns_status <= 0) goto exit;
+#ifdef DEBUG
+ printf("%s [%d.%d.%d.%d]\r\n", host->getName(), (unsigned char)host->getIp()[0], (unsigned char)host->getIp()[1], (unsigned char)host->getIp()[2], (unsigned char)host->getIp()[3]);
+#endif
}
if (! host->getPort()) {
host->setPort(HTTP_PORT);
@@ -138,12 +156,14 @@
if (err != TCPSOCKET_OK) goto exit;
// wait connect
- for (i = 0; i < HTTP_TIMEOUT / 10; i ++) {
- if (tcp_status != STATUS_NONE) break;
+ timeout.reset();
+ timeout.start();
+ while (timeout.read_ms() < HTTP_TIMEOUT) {
+ if (tcp_ready) break;
Net::poll();
- wait_ms(10);
}
- if (tcp_status != STATUS_CONNECTED) goto exit;
+ timeout.stop();
+ if (! tcp_ready) goto exit;
// send request
if (method == METHOD_POST) {
@@ -171,17 +191,20 @@
}
// wait responce
- for (i = 0; i < 1500; i ++) {
- if (tcp_status != STATUS_CONNECTED) break;
+ timeout.reset();
+ timeout.start();
+ while (timeout.read_ms() < HTTP_TIMEOUT) {
+ if (tcp_readable) break;
Net::poll();
- wait_ms(10);
}
- if (tcp_status != STATUS_READABLE) goto exit;
+ timeout.stop();
+ if (! tcp_readable) goto exit;
// recv responce
- i = http->recv(buf, sizeof(buf));
+ i = http->recv(buf, sizeof(buf) - 1);
buf[i] = 0;
- if (strncmp(buf, "HTTP", 4) == 0) {
+ if (i < sizeof(buf) - 1) tcp_readable = 0;
+ if (strncmp(buf, "HTTP/", 5) == 0) {
ret = atoi(&buf[9]);
}
#ifdef DEBUG
@@ -189,23 +212,24 @@
#endif
// recv dummy
- for (i = 0; i < HTTP_TIMEOUT / 10; i ++) {
- switch (tcp_status) {
- case STATUS_READABLE:
- int n = http->recv(buf, sizeof(buf));
- buf[n] = 0;
- i = 0;
+ timeout.reset();
+ timeout.start();
+ while (timeout.read_ms() < HTTP_TIMEOUT) {
+ if (tcp_readable) {
+ i = http->recv(buf, sizeof(buf) - 1);
+ buf[i] = 0;
+ if (i < sizeof(buf) - 1) tcp_readable = 0;
#ifdef DEBUG
printf(buf);
#endif
+ timeout.reset();
+ } else
+ if (! tcp_ready) {
break;
- case STATUS_DISCONNECTED:
- case STATUS_ERROR:
- goto exit;
}
Net::poll();
- wait_ms(10);
}
+ timeout.stop();
exit:
http->resetOnEvent();
--- a/TinyHTTP.h Wed Jul 27 16:19:14 2011 +0000 +++ b/TinyHTTP.h Thu Jul 28 16:35:09 2011 +0000 @@ -29,4 +29,10 @@ */ int httpRequest (int method, Host *host, char *uri, char *head, char *body); +void createauth (char *user, char *pwd, char *buf, int len); + +int base64enc(const char *input, unsigned int length, char *output, int len); + +int urlencode(char *str, char *buf, int len); + #endif
--- a/main.cpp Wed Jul 27 16:19:14 2011 +0000
+++ b/main.cpp Thu Jul 28 16:35:09 2011 +0000
@@ -7,12 +7,46 @@
Serial pc(USBTX, USBRX);
EthernetNetIf eth;
+
+int pachube (int feedid, char *apikey, char *buf) {
+ Host host;
+ char uri[40], head[160];
+
+ // header
+ snprintf(head, sizeof(head), "Content-type: text/csv\r\nX-PachubeApiKey: %s\r\n", apikey);
+
+ // uri
+ snprintf(uri, sizeof(uri), "/v1/feeds/%d.csv?_method=put", feedid);
+
+ host.setName("api.pachube.com");
+ host.setPort(HTTP_PORT);
+ return httpRequest(METHOD_POST, &host, uri, head, buf) == 200 ? 0 : -1;
+}
+
+int twitter (char *msg, char *user, char *pwd) {
+ Host host;
+ char buf[300], head[160];
+
+ // header
+ createauth(user, pwd, head, sizeof(head));
+ strncat(head, "Content-type: application/x-www-form-urlencoded\r\n", sizeof(head) - strlen(head));
+
+ // post data
+ strcpy(buf, "status=");
+ urlencode(msg, &buf[strlen(buf)], sizeof(buf) - strlen(buf));
+
+ host.setName("api.supertweet.net");
+ host.setPort(HTTP_PORT);
+ return httpRequest(METHOD_POST, &host, "/1/statuses/update.xml", head, buf) == 200 ? 0 : -1;
+}
+
int main () {
EthernetErr ethErr;
Host host;
int r;
myled = 1;
+// pc.baud(115200);
ethErr = eth.setup();
if(ethErr) {
@@ -21,6 +55,11 @@
host.setName("mbed.org");
r = httpRequest(METHOD_GET, &host, "/", NULL, NULL);
+
+// r = twitter("test from #mbed TinyHTTP", "username", "password");
+
+// r = pachube(99999, "api key", "1000,30,70");
+
/*
host.setName("www.domain.name");
r = httpRequest(METHOD_POST, &host, "/xxx.cgi", "Content-Type: application/x-www-form-urlencoded\r\n", "key=value&key2=value2");