Some quick code to use UDP-only (no TCP) with mBed. Echos received packets and sends packets when a button is pressed
HTTPClient.cpp
00001 #include "HTTPClient.h" 00002 #include "NetServer.h" 00003 #include "iputil.h" 00004 00005 using namespace mbed; 00006 using namespace std; 00007 00008 #define POST 0x1 00009 #define FDATA 0x2 00010 #define FRES 0x4 00011 #define GET 0x0 00012 #define CDATA 0x0 00013 #define CRES 0x0 00014 00015 long fleft(FILE *fd) { 00016 long len, cur; 00017 cur = ftell(fd); 00018 fseek(fd, 0, SEEK_END); 00019 len = ftell(fd); 00020 fseek(fd, cur, SEEK_SET); 00021 return len; 00022 } 00023 00024 00025 HTTPClient::HTTPClient(const char *hostname, struct ip_addr ip, struct ip_addr nm, struct ip_addr gw, struct ip_addr dns) 00026 : TCPConnection(), _auth(NULL), _timeout(0), _data(NULL), _headerfields(NULL), _timeout_max(60000) { 00027 NetServer *net = NULL; 00028 if(ip.addr != ip_addr_any.addr && nm.addr != ip_addr_any.addr && gw.addr != ip_addr_any.addr) { 00029 net = NetServer::create(ip, nm, gw); 00030 if(dns.addr != ip_addr_any.addr) { 00031 net->setDNS1(dns); 00032 } 00033 } else if(hostname) { 00034 net = NetServer::create(); 00035 } 00036 if(hostname) { 00037 net->setHostname(hostname); 00038 } 00039 } 00040 00041 void HTTPClient::timeout(int value) { 00042 _timeout_max = value; 00043 } 00044 00045 void HTTPClient::err(err_t err) { 00046 release_callbacks(); 00047 } 00048 00049 err_t HTTPClient::poll() { 00050 if(NetServer::time() - _timeout > _timeout_max) { 00051 release_callbacks(); 00052 close(); 00053 printf("TIMEOUT\n"); 00054 _ready = true; 00055 _state = 99; 00056 } 00057 return ERR_OK; 00058 } 00059 00060 void HTTPClient::dnsreply(const char *hostname, struct ip_addr *ipaddr) { 00061 _ready = true; 00062 _ipaddr = *ipaddr; 00063 _state = (ipaddr==NULL)? 99 : 0; 00064 _timeout = NetServer::time(); 00065 } 00066 00067 err_t HTTPClient::connected(err_t err) { 00068 TCPConnection::connected(err); 00069 _ready = false; 00070 _state = 0; 00071 _resultoff = 0; 00072 if(_mode&POST) { 00073 write((void *)"POST ", 5, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00074 } else { 00075 write((void *)"GET ", 4, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00076 } 00077 if(strlen(_path) == 0) { 00078 write((void *)"/", 1, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00079 } else { 00080 write((void *)_path, strlen(_path), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00081 } 00082 write((void *)" HTTP/1.1\r\nHost: ", 17, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00083 write((void *)_host, _hostlen, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00084 if(_auth&&(*_auth!='\0')) { 00085 write((void *)"\r\nAuthorization: Basic ", 23, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00086 write((void *)_auth, strlen(_auth), TCP_WRITE_FLAG_COPY |TCP_WRITE_FLAG_MORE); 00087 } 00088 if(_headerfields&&(*_headerfields!='\0')) { 00089 write((void *)"\r\n", 2, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00090 write((void *)_headerfields, strlen(_headerfields), TCP_WRITE_FLAG_COPY |TCP_WRITE_FLAG_MORE); 00091 } 00092 write((void *)"\r\nConnection: Close\r\n", 21, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_COPY); 00093 if(_data) { 00094 char clen[256]; 00095 int len, blen; 00096 if(_mode&FDATA) { 00097 //printf("Send file\n"); 00098 len = fleft((FILE *)_data); 00099 sprintf(clen, "Content-Length: %d\r\n\r\n\0", len); 00100 write((void *)clen, strlen(clen), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_COPY); 00101 if(len) { 00102 do { 00103 int sb = sndbuf(); 00104 blen = fread(clen, sizeof(char), (int)min(sb, 100), (FILE *)_data); 00105 write(clen, blen, (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE)); 00106 len -= blen; 00107 } while(len > 1 && blen); 00108 } 00109 } else { 00110 len = strlen((const char *)_data); 00111 sprintf(clen, "Content-Length: %d\r\n\r\n\0", len); 00112 write((void *)clen, strlen(clen), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_COPY); 00113 write((void *)_data, len, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); 00114 } 00115 } 00116 write((void *)"\r\n", 2, TCP_WRITE_FLAG_COPY); 00117 _timeout = NetServer::time(); 00118 return ERR_OK; 00119 } 00120 00121 #define _min(x, y) (((x)<(y))?(x):(y)) 00122 err_t HTTPClient::recv(struct pbuf *p, err_t err) { 00123 if(err == ERR_OK && p != NULL&&_state<10) { 00124 _timeout = NetServer::time(); 00125 struct pbuf *q = p; 00126 char *d = (char *)q->payload; 00127 recved(p->tot_len); 00128 00129 while(q&&_state<10) { 00130 unsigned int end = ((unsigned int)(q->payload)+(unsigned int)(q->len)); 00131 switch(_state) { 00132 case 0: { 00133 for(; _state==0 && ((unsigned int)d < end); d++) { 00134 if((*((char *)(d-0))=='\n')&&(*((char *)(d-1))=='\r')&& 00135 (*((char *)(d-2))=='\n')&&(*((char *)(d-3))=='\r')) { 00136 _state = 1; 00137 d += 1; 00138 break; 00139 } 00140 } 00141 } break; 00142 case 1: { 00143 if(_result) { 00144 if(_mode&FRES) { 00145 fwrite(d, sizeof(char), end - (unsigned int)d, (FILE *)_result); 00146 _resultoff += (end - (unsigned int)d); 00147 d = (char *)end; 00148 } else { 00149 unsigned int len = _min(_resultleft, (end-(unsigned int)d)); 00150 memcpy((char *)_result + _resultoff, d, len); 00151 _resultleft -= len; 00152 _resultoff += len; 00153 d += len; 00154 00155 if(!_resultleft) { 00156 _state = 10; 00157 } 00158 } 00159 } else { 00160 _state = 10; 00161 } 00162 } break; 00163 default: { 00164 break; 00165 } 00166 } 00167 if(_state<10&&(unsigned int)d==end) { 00168 q = q->next; 00169 if(q) { 00170 d = static_cast<char *>(q->payload); 00171 } 00172 } 00173 } 00174 } 00175 00176 if(p!=NULL) { 00177 pbuf_free(p); 00178 } 00179 00180 if(_state>10||p==NULL||err!=ERR_OK) { 00181 release_callbacks(); 00182 close(); 00183 _ready = true; 00184 } 00185 return ERR_OK; 00186 } 00187 00188 unsigned int HTTPClient::make(const char *request) { 00189 _request = request; 00190 _resultoff = 0; 00191 _ready = false; 00192 _state = 0; 00193 _hostlen = 0; 00194 _port = 0; 00195 _timeout = NetServer::time(); 00196 NetServer::ready(); 00197 00198 int hostlen = 0; 00199 if(strlen(_request)<10||strncmp("http://", _request, 7)!=0) { 00200 printf("Only http requests are allowed\n"); 00201 return 0; 00202 } 00203 _path = _host = _request + 6; 00204 _host++; 00205 while(!_state == 1) { 00206 switch(*(++_path)) { 00207 case ':': 00208 _port = atoi(_path+1); 00209 break; 00210 case '/': 00211 case '\0': 00212 _port = (_port)?_port:80; 00213 _state = 1; 00214 break; 00215 default: 00216 break; 00217 } 00218 if(!_port) { 00219 hostlen++; 00220 } 00221 if(!_state == 1) { 00222 _hostlen++; 00223 } 00224 } 00225 _state = 0; 00226 00227 if(hostlen>256) { 00228 printf("Hostname longer than allowed\n"); 00229 return 0; 00230 } 00231 00232 char host[257]; 00233 memcpy(host, _host, hostlen); 00234 host[hostlen] = 0; 00235 _timeout = NetServer::time(); 00236 struct in_addr in; 00237 if(!inet_aton(host, &in)) { 00238 _ready = false; 00239 if(dnsrequest(host, &_ipaddr)==ERR_INPROGRESS) { 00240 while(!_ready) { 00241 NetServer::poll(); 00242 wait_ms(10); 00243 } 00244 if(_state==99) { 00245 printf("Server not found\n"); 00246 return 0; 00247 } 00248 } 00249 } else { 00250 _ipaddr.addr = in.s_addr; 00251 } 00252 00253 _ready = false; 00254 _timeout = NetServer::time(); 00255 connect(); 00256 set_poll_interval(10); 00257 tcp_setprio(_pcb, TCP_PRIO_MIN); 00258 while(!_ready) { 00259 NetServer::poll(); 00260 wait_ms(10); 00261 } 00262 //release_callbacks(); 00263 close(); 00264 if(_state==99) { 00265 printf("Connection error\n"); 00266 return 0; 00267 } 00268 00269 if(!_mode&FRES&&_result) { 00270 ((char *)_result)[_resultoff+1] = '\0'; 00271 } 00272 return ((!_mode&FRES)&&!_result)?1:_resultoff; 00273 00274 } 00275 00276 void HTTPClient::auth(const char *user, const char *password) { 00277 if(user) { 00278 char up[256]; 00279 sprintf(up, "%s:%s", user, password); 00280 _auth = new char[base64enc_len(up)+1]; 00281 base64enc(up, strlen(up), _auth); 00282 } else if(_auth) { 00283 delete _auth; 00284 _auth = NULL; 00285 } 00286 } 00287 00288 void HTTPClient::headers(const char *fields) { 00289 _headerfields = fields; 00290 } 00291 00292 unsigned int HTTPClient::get(const char *url, char *result, int rsize) { 00293 _mode = GET | CDATA | CRES; 00294 _data = (void *)NULL; 00295 _result = (void *)result; 00296 _resultleft = rsize -1; 00297 00298 return make(url); 00299 } 00300 00301 unsigned int HTTPClient::get(const char *url, FILE *result) { 00302 _mode = GET | CDATA | FRES; 00303 _data = (void *)NULL; 00304 _result = (void *)result; 00305 _resultleft = 0; 00306 00307 return make(url); 00308 } 00309 00310 unsigned int HTTPClient::post(const char *url, const char *data, char *result, int rsize) { 00311 _mode = POST | CDATA | CRES; 00312 _data = (void *)data; 00313 _result = (void *)result; 00314 _resultleft = rsize -1; 00315 00316 return make(url); 00317 } 00318 00319 unsigned int HTTPClient::post(const char *url, const char *data, FILE *result) { 00320 _mode = POST | CDATA | FRES; 00321 _data = (void *)data; 00322 _result = (void *)result; 00323 _resultleft = 0; 00324 00325 return make(url); 00326 } 00327 00328 unsigned int HTTPClient::post(const char *url, FILE *data, FILE *result) { 00329 _mode = POST | FDATA | FRES; 00330 _data = (void *)data; 00331 _result = (void *)result; 00332 _resultleft = 0; 00333 00334 return make(url); 00335 } 00336 00337 unsigned int HTTPClient::post(const char *url, FILE *data, char *result, int rsize) { 00338 _mode = POST | FDATA | CRES; 00339 _data = (void *)data; 00340 _result = (void *)result; 00341 _resultleft = rsize -1; 00342 00343 return make(url); 00344 } 00345
Generated on Tue Jul 12 2022 19:17:23 by 1.7.2