GainSpan Wi-Fi library see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
Dependents: GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more
Fork of GSwifi by
GSwifi_http.cpp
00001 /* Copyright (C) 2013 gsfan, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 /** @file 00019 * @brief Gainspan wi-fi module library for mbed 00020 * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc. 00021 */ 00022 00023 #include "GSwifi_conf.h" 00024 #ifdef GS_ENABLE_HTTP 00025 00026 #include "dbg.h" 00027 #include "mbed.h" 00028 #include "GSwifi.h" 00029 #include <string.h> 00030 00031 00032 int GSwifi::httpGet (Host &host, const char *uri, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) { 00033 char cmd[GS_CMD_SIZE]; 00034 00035 if (! _connect || _status != GSSTAT_READY) return -1; 00036 00037 if (host.getIp().isNull()) { 00038 if (getHostByName(host)) { 00039 if (getHostByName(host)) return -1; 00040 } 00041 } 00042 if (host.getPort() == 0) { 00043 if (ssl) { 00044 host.setPort(443); 00045 } else { 00046 host.setPort(80); 00047 } 00048 } 00049 00050 command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection: 00051 sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName()); // Host: 00052 command(cmd, GSRES_NORMAL); 00053 if (user && pwd) { 00054 char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE]; 00055 snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd); 00056 base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2)); 00057 sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2); // Authorization: 00058 command(cmd, GSRES_NORMAL); 00059 } else { 00060 command("AT+HTTPCONFDEL=2", GSRES_NORMAL); 00061 } 00062 command("AT+HTTPCONFDEL=5", GSRES_NORMAL); 00063 command("AT+HTTPCONFDEL=7", GSRES_NORMAL); 00064 00065 sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort()); 00066 if (ssl) { 00067 strcat(cmd, ",1"); 00068 } 00069 if (command(cmd, GSRES_HTTP)) return -1; 00070 newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPGET, ponGsReceive); 00071 00072 sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", _cid, GS_TIMEOUT / 1000, uri); // GET 00073 command(cmd, GSRES_NORMAL); 00074 00075 return _cid; 00076 } 00077 00078 int GSwifi::httpPost (Host &host, const char *uri, const char *body, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) { 00079 char cmd[GS_CMD_SIZE]; 00080 int i, len; 00081 00082 if (! _connect || _status != GSSTAT_READY) return -1; 00083 00084 if (host.getIp().isNull()) { 00085 if (getHostByName(host)) { 00086 if (getHostByName(host)) return -1; 00087 } 00088 } 00089 if (host.getPort() == 0) { 00090 if (ssl) { 00091 host.setPort(443); 00092 } else { 00093 host.setPort(80); 00094 } 00095 } 00096 len = strlen(body); 00097 00098 command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection: 00099 sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName()); // Host: 00100 command(cmd, GSRES_NORMAL); 00101 sprintf(cmd, "AT+HTTPCONF=5,%d", len); // Content-Length: 00102 command(cmd, GSRES_NORMAL); 00103 command("AT+HTTPCONF=7,application/x-www-form-urlencoded", GSRES_NORMAL); // Content-type: 00104 if (user && pwd) { 00105 char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE]; 00106 snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd); 00107 base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2)); 00108 sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2); // Authorization: 00109 command(cmd, GSRES_NORMAL); 00110 } else { 00111 command("AT+HTTPCONFDEL=2", GSRES_NORMAL); 00112 } 00113 00114 sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort()); 00115 if (ssl) { 00116 strcat(cmd, ",1"); 00117 } 00118 if (command(cmd, GSRES_HTTP)) return -1; 00119 newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPPOST, ponGsReceive); 00120 00121 sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", _cid, GS_TIMEOUT / 1000, uri, len); // POST 00122 command(cmd, GSRES_NORMAL); 00123 00124 if (acquireUart()) return -1; 00125 sprintf(cmd, "\x1bH%X", _cid); 00126 _gs_puts(cmd); 00127 for (i = 0; i < len; i ++) { 00128 _gs_putc(body[i]); 00129 DBG("%c", body[i]); 00130 } 00131 releaseUart(); 00132 00133 return _cid; 00134 } 00135 00136 int GSwifi::wsOpen (Host &host, const char *uri, const char *user, const char *pwd, onGsReceiveFunc ponGsReceive) { 00137 int cid; 00138 char cmd[GS_CMD_SIZE], tmp[GS_CMD_SIZE]; 00139 00140 if (! _connect || _status != GSSTAT_READY) return -1; 00141 00142 if (host.getIp().isNull()) { 00143 if (getHostByName(host)) { 00144 if (getHostByName(host)) return -1; 00145 } 00146 } 00147 if (host.getPort() == 0) { 00148 host.setPort(80); 00149 } 00150 00151 cid = open(host, GSPROT_TCP); 00152 if (cid < 0) return -1; 00153 DBG("cid %d\r\n", cid); 00154 00155 // send request 00156 send(cid, "GET ", 4); 00157 send(cid, uri, strlen(uri)); 00158 send(cid, " HTTP/1.1\r\n", 11); 00159 if (host.getName() && host.getName()[0] != 0) { 00160 send(cid, "Host: ", 5); 00161 send(cid, host.getName(), strlen(host.getName())); 00162 send(cid, "\r\n", 2); 00163 } 00164 if (user && pwd) { 00165 snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd); 00166 base64encode(tmp, strlen(tmp), cmd, sizeof(cmd)); 00167 send(cid, "Authorization: Basic ", 21); 00168 send(cid, cmd, strlen(cmd)); 00169 send(cid, "\r\n", 2); 00170 } 00171 send(cid, "Upgrade: websocket\r\n", 20); 00172 send(cid, "Connection: Upgrade\r\n", 21); 00173 send(cid, "Sec-WebSocket-Key: ", 19); 00174 getMacAddress(tmp); 00175 memcpy(&tmp[6], host.getName(), 10); 00176 base64encode(tmp, 16, cmd, sizeof(cmd)); 00177 send(cid, cmd, strlen(cmd)); 00178 send(cid, "\r\n", 2); 00179 send(cid, "Sec-WebSocket-Version: 13\r\n", 27); 00180 send(cid, "\r\n", 2); 00181 00182 if (wait_ws(cid, 101)) { 00183 close(cid); 00184 return -1; 00185 } 00186 wait_ws(cid, 0); 00187 00188 _gs_sock[cid].onGsReceive.attach(ponGsReceive); 00189 return cid; 00190 } 00191 00192 int GSwifi::wait_ws (int cid, int code) { 00193 Timer timeout; 00194 int i, n, len; 00195 char buf[200], data[100]; 00196 00197 if (code == 0) { 00198 // dummy read 00199 timeout.start(); 00200 while (timeout.read_ms() < GS_TIMEOUT) { 00201 wait_ms(10); 00202 if (_gs_sock[cid].data->isEmpty()) break; 00203 poll(); 00204 n = recv(cid, buf, sizeof(buf)); 00205 if (n <= 0) break; 00206 } 00207 timeout.stop(); 00208 return 0; 00209 } 00210 00211 // wait responce 00212 len = 0; 00213 timeout.start(); 00214 while (timeout.read_ms() < GS_TIMEOUT) { 00215 wait_ms(10); 00216 poll(); 00217 n = recv(cid, buf, sizeof(buf)); 00218 for (i = 0; i < n; i ++) { 00219 if (buf[i] == '\r') continue; 00220 if (buf[i] == '\n') { 00221 if (len == 0) continue; 00222 goto next; 00223 } else 00224 if (len < sizeof(data) - 1) { 00225 data[len] = buf[i]; 00226 len ++; 00227 } 00228 } 00229 } 00230 next: 00231 data[len] = 0; 00232 DBG("ws: %s\r\n", data); 00233 timeout.stop(); 00234 00235 // check return code 00236 if (strncmp(data, "HTTP/1.1 ", 9) != 0) return -1; 00237 i = atoi(&data[9]); 00238 DBG("ws status %d\r\n", i); 00239 if (i == code) return 0; 00240 00241 return -1; 00242 } 00243 00244 int GSwifi::wsSend (int cid, const char *buf, int len, const char *mask) { 00245 int r; 00246 char tmp[10]; 00247 00248 tmp[0] = 0x81; // single, text frame 00249 tmp[1] = (mask == NULL) ? 0 : 0x80; 00250 00251 if (len < 126) { 00252 tmp[1] |= len; 00253 r = send(cid, tmp, 2); 00254 } else { 00255 tmp[1] |= 126; 00256 tmp[2] = (len >> 8) & 0xff; 00257 tmp[3] = len & 0xff; 00258 r = send(cid, tmp, 4); 00259 } 00260 00261 if (r == 0) { 00262 if (mask) { 00263 int i; 00264 char tmp2[len]; 00265 send(cid, mask, 4); 00266 for (i = 0; i < len; i ++) { 00267 tmp2[i] = buf[i] ^ mask[i & 0x03]; 00268 } 00269 r = send(cid, tmp2, len); 00270 } else { 00271 r = send(cid, buf, len); 00272 } 00273 } 00274 return r; 00275 } 00276 00277 00278 /* base64encode code from 00279 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00280 */ 00281 int GSwifi::base64encode (char *input, int length, char *output, int len) { 00282 static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00283 unsigned int c, c1, c2, c3; 00284 00285 if (len < ((((length-1)/3)+1)<<2)) return -1; 00286 for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) { 00287 c1 = ((((unsigned char)*((unsigned char *)&input[i])))); 00288 c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0; 00289 c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0; 00290 00291 c = ((c1 & 0xFC) >> 2); 00292 output[j+0] = base64[c]; 00293 c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4); 00294 output[j+1] = base64[c]; 00295 c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6); 00296 output[j+2] = (length>i+1)?base64[c]:'='; 00297 c = (c3 & 0x3F); 00298 output[j+3] = (length>i+2)?base64[c]:'='; 00299 } 00300 output[(((length-1)/3)+1)<<2] = '\0'; 00301 return 0; 00302 } 00303 00304 /* urlencode code from 00305 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00306 */ 00307 int GSwifi::urlencode (char *str, char *buf, int len) { 00308 // char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf; 00309 char *pstr = str, *pbuf = buf; 00310 00311 if (len < (strlen(str) * 3 + 1)) return -1; 00312 while (*pstr) { 00313 if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 00314 *pbuf++ = *pstr; 00315 else if (*pstr == ' ') 00316 *pbuf++ = '+'; 00317 else 00318 *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); 00319 pstr++; 00320 } 00321 *pbuf = '\0'; 00322 return 0; 00323 } 00324 00325 /* urldecode code from 00326 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00327 */ 00328 int GSwifi::urldecode (char *str, char *buf, int len) { 00329 // char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf; 00330 char *pstr = str, *pbuf = buf; 00331 00332 if (len < (strlen(str) / 3 - 1)) return -1; 00333 while (*pstr) { 00334 if (*pstr == '%') { 00335 if (pstr[1] && pstr[2]) { 00336 *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); 00337 pstr += 2; 00338 } 00339 } else if (*pstr == '+') { 00340 *pbuf++ = ' '; 00341 } else { 00342 *pbuf++ = *pstr; 00343 } 00344 pstr++; 00345 } 00346 *pbuf = '\0'; 00347 return 0; 00348 } 00349 00350 #endif
Generated on Tue Jul 12 2022 22:02:57 by 1.7.2