// This cgi uses the routines above to connect to a specific access point with the // given ESSID using the given password. int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) { int mode = wifi_get_opmode(); if(mode == 2){ jsonHeader(connData, 400); httpdSend(connData, "Can't associate to an AP en SoftAP mode", -1); return HTTPD_CGI_DONE; } char essid[128]; char passwd[128]; if (connData->conn==NULL) return HTTPD_CGI_DONE; int el = httpdFindArg(connData->getArgs, "essid", essid, sizeof(essid)); int pl = httpdFindArg(connData->getArgs, "passwd", passwd, sizeof(passwd)); if (el > 0 && pl >= 0) { //Set to 0 if you want to disable the actual reconnecting bit os_strncpy((char*)stconf.ssid, essid, 32); os_strncpy((char*)stconf.password, passwd, 64); DBG("Wifi try to connect to AP %s pw %s\n", essid, passwd); //Schedule disconnect/connect os_timer_disarm(&reassTimer); os_timer_setfn(&reassTimer, reassTimerCb, NULL); os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it jsonHeader(connData, 200); } else { jsonHeader(connData, 400); httpdSend(connData, "Cannot parse ssid or password", -1); } return HTTPD_CGI_DONE; }
int cmd_systime_get(HttpdConnData *conn) { uint8_t i; for (i = 0; i < 4; i++) { os_printf("\r\nsystime_get\r\n"); bool res = get_answer(200); if (res == true) { uint8_t seconds = integer_from_string(ans_buf, 0); uint8_t minutes = integer_from_string(ans_buf, 1); uint8_t hours = integer_from_string(ans_buf, 2); uint8_t date = integer_from_string(ans_buf, 3); uint8_t month = integer_from_string(ans_buf, 4); uint8_t year = integer_from_string(ans_buf, 5); uint8_t dow = integer_from_string(ans_buf, 6); char dow_readable[30]; if (dow == 255) continue; else if (dow == 1) os_strcpy(dow_readable, "Montag"); else if (dow == 2) os_strcpy(dow_readable, "Dienstag"); else if (dow == 3) os_strcpy(dow_readable, "Mittwoch"); else if (dow == 4) os_strcpy(dow_readable, "Donnerstag"); else if (dow == 5) os_strcpy(dow_readable, "Freitag"); else if (dow == 6) os_strcpy(dow_readable, "Samstag"); else if (dow == 7) os_strcpy(dow_readable, "Sonntag"); else if (dow == 0) os_strcpy(dow_readable, "Ungültige Systemzeit"); char resbuf[80]; os_sprintf(resbuf, "%s, %d.%d.%d %d:%d:%d Uhr", dow_readable, date, month, year, hours, minutes, seconds); httpdSend(conn, resbuf, -1); return HTTPD_CGI_DONE; } } httpdSend(conn, "Keine Antwort vom AVR-Controller", -1); return HTTPD_CGI_DONE; }
int cmd_opentime_set(HttpdConnData *conn) { // Parse command from GET parameters char hours_str[5]; char minutes_str[5]; httpdFindArg(conn->getArgs, "hours", hours_str, sizeof(hours_str)); httpdFindArg(conn->getArgs, "minutes", minutes_str, sizeof(minutes_str)); char command[30]; os_sprintf(command, "\r\nopentime_set %s %s\r\n", hours_str, minutes_str); // Send command / wait for answer uint8_t i; for (i = 0; i < 4; i++) { os_printf(command); bool res = get_answer(200); if (res == true && os_strcmp("ots_ok", ans_buf) == 0) { httpdSend(conn, "ok", -1); return HTTPD_CGI_DONE; } } httpdSend(conn, "Keine Antwort vom AVR-Controller", -1); return HTTPD_CGI_DONE; }
int ICACHE_FLASH_ATTR cgiPWM(HttpdConnData *connData) { int len; char buff[128]; if (connData->conn==NULL) { //Connection aborted. Clean up. return HTTPD_CGI_DONE; } httpdStartResponse(connData, 200); httpdHeader(connData, "Content-Type", "text/json"); httpdEndHeaders(connData); len=httpdFindArg(connData->getArgs, "duty", buff, sizeof(buff)); if (len>0) { pwm_set_duty(atoi(buff), 0); pwm_start(); len=os_sprintf(buff, "OK"); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; } else { //with no parameters returns JSON with state len=os_sprintf(buff, "{\"pwm\": %d\n}\n", pwm_get_duty(0) ); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; } }
//This CGI is called from the bit of AJAX-code in wifi.tpl. It will initiate a //scan for access points and if available will return the result of an earlier scan. //The result is embedded in a bit of JSON parsed by the javascript in wifi.tpl. int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) { int len; int i; char buff[1024]; httpdStartResponse(connData, 200); httpdHeader(connData, "Content-Type", "text/json"); httpdEndHeaders(connData); if (cgiWifiAps.scanInProgress==1) { //We're still scanning. Tell Javascript code that. len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n"); httpdSend(connData, buff, len); } else { //We have a scan result. Pass it on. len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n"); httpdSend(connData, buff, len); if (cgiWifiAps.apData==NULL) cgiWifiAps.noAps=0; for (i=0; i<cgiWifiAps.noAps; i++) { //Fill in json code for an access point len=os_sprintf(buff, "{\"essid\": \"%s\", \"rssi\": \"%d\", \"enc\": \"%d\"}%s\n", cgiWifiAps.apData[i]->ssid, cgiWifiAps.apData[i]->rssi, cgiWifiAps.apData[i]->enc, (i==cgiWifiAps.noAps-1)?"":","); httpdSend(connData, buff, len); } len=os_sprintf(buff, "]\n}\n}\n"); httpdSend(connData, buff, len); //Also start a new scan. wifiStartScan(); } return HTTPD_CGI_DONE; }
// Change special settings int ICACHE_FLASH_ATTR cgiRadioSpecial(HttpdConnData *connData) { char dhcp[8]; char hostname[32]; char staticip[20]; char netmask[20]; char gateway[20]; if (connData->conn==NULL) return HTTPD_CGI_DONE; // get args and their string lengths int dl = httpdFindArg(connData->getArgs, "dhcp", dhcp, sizeof(dhcp)); int hl = httpdFindArg(connData->getArgs, "hostname", hostname, sizeof(hostname)); int sl = httpdFindArg(connData->getArgs, "staticip", staticip, sizeof(staticip)); int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask)); int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway)); if (!(dl > 0 && hl >= 0 && sl >= 0 && nl >= 0 && gl >= 0)) { jsonHeader(connData, 400); httpdSend(connData, "Request is missing fields", -1); return HTTPD_CGI_DONE; } char url[64]; // redirect URL jsonHeader(connData, 200); httpdSend(connData, url, -1); return HTTPD_CGI_DONE; }
// Change special settings int ICACHE_FLASH_ATTR cgiWiFiSpecial(HttpdConnData *connData) { char dhcp[8]; char staticip[20]; char netmask[20]; char gateway[20]; if (connData->conn==NULL) return HTTPD_CGI_DONE; // get args and their string lengths int dl = httpdFindArg(connData->getArgs, "dhcp", dhcp, sizeof(dhcp)); int sl = httpdFindArg(connData->getArgs, "staticip", staticip, sizeof(staticip)); int nl = httpdFindArg(connData->getArgs, "netmask", netmask, sizeof(netmask)); int gl = httpdFindArg(connData->getArgs, "gateway", gateway, sizeof(gateway)); if (!(dl > 0 && sl >= 0 && nl >= 0 && gl >= 0)) { jsonHeader(connData, 400); httpdSend(connData, "Request is missing fields", -1); return HTTPD_CGI_DONE; } char url[64]; // redirect URL if (os_strcmp(dhcp, "off") == 0) { // parse static IP params struct ip_info ipi; bool ok = parse_ip(staticip, &ipi.ip); if (nl > 0) ok = ok && parse_ip(netmask, &ipi.netmask); else IP4_ADDR(&ipi.netmask, 255, 255, 255, 0); if (gl > 0) ok = ok && parse_ip(gateway, &ipi.gw); else ipi.gw.addr = 0; if (!ok) { jsonHeader(connData, 400); httpdSend(connData, "Cannot parse static IP config", -1); return HTTPD_CGI_DONE; } // save the params in flash flashConfig.staticip = ipi.ip.addr; flashConfig.netmask = ipi.netmask.addr; flashConfig.gateway = ipi.gw.addr; // construct redirect URL os_sprintf(url, "{\"url\": \"http://%d.%d.%d.%d\"}", IP2STR(&ipi.ip)); } else { // dynamic IP flashConfig.staticip = 0; os_sprintf(url, "{\"url\": \"http://%s\"}", flashConfig.hostname); } configSave(); // ignore error... // schedule change-over os_timer_disarm(&reassTimer); os_timer_setfn(&reassTimer, configWifiIP, NULL); os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it // return redirect info jsonHeader(connData, 200); httpdSend(connData, url, -1); return HTTPD_CGI_DONE; }
int cmd_slider_down(HttpdConnData *conn) { uint8_t i; for (i = 0; i < 4; i++) { os_printf("\r\nslider_down\r\n"); bool res = get_answer(200); if (res == true && os_strcmp("sld_ok", ans_buf) == 0) { httpdSend(conn, "ok", -1); return HTTPD_CGI_DONE; } } httpdSend(conn, "Keine Antwort vom AVR-Controller", -1); return HTTPD_CGI_DONE; }
int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) { char buff[1024]; int len; if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. jsonHeader(connData, 200); len = os_sprintf(buff, "{"); len += printWifiInfo(buff+len); len += os_sprintf(buff+len, ", "); if (wifiReason != 0) { len += os_sprintf(buff+len, "\"reason\": \"%s\", ", wifiGetReason()); } #if 0 // commented out 'cause often the client that requested the change can't get a request in to // find out that it succeeded. Better to just wait the std 15 seconds... int st=wifi_station_get_connect_status(); if (st == STATION_GOT_IP) { if (wifi_get_opmode() != 1) { // Reset into AP-only mode sooner. os_timer_disarm(&resetTimer); os_timer_setfn(&resetTimer, resetTimerCb, NULL); os_timer_arm(&resetTimer, 1000, 0); } } #endif len += os_sprintf(buff+len, "\"x\":0}\n"); //DBG(" -> %s\n", buff); httpdSend(connData, buff, len); return HTTPD_CGI_DONE; }
int ICACHE_FLASH_ATTR nixieTplWlan(HttpdConnData *connData, char *token, void **arg) { char buff[1024]; int x; static struct station_config stconf; if (token==NULL) return HTTPD_CGI_DONE; wifi_station_get_config(&stconf); os_strcpy(buff, "Unknown"); if (os_strcmp(token, "WiFiMode")==0) { x=wifi_get_opmode(); if (x==1) os_strcpy(buff, "Client"); if (x==2) os_strcpy(buff, "SoftAP"); if (x==3) os_strcpy(buff, "Client+AP"); } else if (os_strcmp(token, "currSsid")==0) { os_strcpy(buff, (char*)stconf.ssid); } else if (os_strcmp(token, "WiFiPasswd")==0) { os_strcpy(buff, (char*)stconf.password); } else if (os_strcmp(token, "DeviceID")==0) { uint8_t client_id[16]; os_sprintf(client_id, "%08X", system_get_chip_id()); os_strcpy(buff, (char*)client_id); } else if (os_strcmp(token, "WiFiapwarn")==0) { x=wifi_get_opmode(); if (x==2) { os_strcpy(buff, "<b>Can't scan in this mode.</b><a href=\"setmode.cgi?mode=3\">Go to STA+AP mode.</a>"); } else if(x==1) { os_strcpy(buff, "<a href=\"setmode.cgi?mode=3\">Go back to Client+AP mode.</a>"); } else { os_strcpy(buff, "<a href=\"setmode.cgi?mode=1\">Go to Client Only Mode</a><br /> To reset hold Button for 5 sec and release"); } } httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; }
int ICACHE_FLASH_ATTR settingsCGI(HttpdConnData *connData) { char buff[256]; float * r = readDHT(); float lastTemp = r[0]; float lastHum = r[1]; os_sprintf(buff, "{\"power\":\"%s\",\"mode\":\"%s\",\"temp\":\"%d\",\"fan\":\"%s\",\"swing\":\"%s\",\"dht_temp\":\"%d\",\"dht_humid\":\"%d\"}", sysCfg.power, sysCfg.mode, sysCfg.temp, sysCfg.fan, sysCfg.swing, (int)(lastTemp * 100), (int)(lastHum * 100) ); httpdStartResponse(connData, 200); httpdHeader(connData, "Content-Type", "text/html"); httpdEndHeaders(connData); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; }
/************************************************ * name: httpdProcessRequest * parameters: ptConnection - connection data * return value: none * purpose: called when headers have been received and * the connection is ready to send the result headers and data ************************************************/ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnection * ptConnection) { /* initialization */ int iCgiResult = HTTPD_CGI_FAILED; /* execute cgi */ iCgiResult = ptConnection->pfnCgi(ptConnection); if (HTTPD_CGI_NOTFOUND != iCgiResult) { if (HTTPD_CGI_DONE == iCgiResult) { /* cgi finishes immediately then mark ptConnection for destruction */ ptConnection->pfnCgi = NULL; } xmitSendBuff(ptConnection); } else { /* didn't find */ #ifdef HTTPD_DEBUG os_printf(HTTPD_HEADER_404_ERROR_STRING, ptConnection->pszUrl); #endif httpdSend(ptConnection, HTTPD_HEADER_NOT_FOUND_STRING, -1); xmitSendBuff(ptConnection); /* mark for destruction */ ptConnection->pfnCgi = NULL; } }
/* cgiGetAppVer */ int ICACHE_FLASH_ATTR cgiGetAppVer(HttpdConnection * ptConnection) { /* initialization */ int iRet = 0; if (NULL == ptConnection->ptEspConnection) { /* connection aborted - clean up */ iRet = HTTPD_CGI_DONE; goto lblCleanup; } char bVersion[1] = { 0 }; /* set and send app version */ os_sprintf(bVersion, "%d", system_upgrade_userbin_check() + 1); httpdStartResponse(ptConnection, 200); httpdHeader(ptConnection, CONTENT_LENGTH_STRING, "1"); httpdEndHeaders(ptConnection); httpdSend(ptConnection, bVersion, 1); iRet = HTTPD_CGI_DONE; lblCleanup: return iRet; }
//Start the response headers. void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) { char buff[128]; int l; char *status = code < 400 ? "OK" : "ERROR"; l = os_sprintf(buff, "HTTP/1.0 %d %s\r\nServer: esp-link\r\nConnection: close\r\n", code, status); httpdSend(conn, buff, l); }
int ICACHE_FLASH_ATTR ajaxConsoleFormat(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. char buff[16]; int len, status = 400; len = httpdFindArg(connData->getArgs, "fmt", buff, sizeof(buff)); if (len >= 3) { int c = buff[0]; if (c >= '5' && c <= '8') flashConfig.data_bits = c - '5' + FIVE_BITS; if (buff[1] == 'N') flashConfig.parity = NONE_BITS; if (buff[1] == 'E') flashConfig.parity = EVEN_BITS; if (buff[1] == 'O') flashConfig.parity = ODD_BITS; if (buff[2] == '1') flashConfig.stop_bits = ONE_STOP_BIT; if (buff[2] == '2') flashConfig.stop_bits = TWO_STOP_BIT; uart0_config(flashConfig.data_bits, flashConfig.parity, flashConfig.stop_bits); status = configSave() ? 200 : 400; } else if (connData->requestType == HTTPD_METHOD_GET) { status = 200; } jsonHeader(connData, status); os_sprintf(buff, "{\"fmt\": \"%c%c%c\"}", flashConfig.data_bits + '5', flashConfig.parity ? 'E' : 'N', flashConfig.stop_bits ? '2': '1'); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; }
// This cgi uses the routines above to connect to a specific access point with the // given ESSID using the given password. int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) { char essid[128]; char passwd[128]; if (connData->conn==NULL) { //Connection aborted. Clean up. return HTTPD_CGI_DONE; } int el = httpdFindArg(connData->getArgs, "essid", essid, sizeof(essid)); int pl = httpdFindArg(connData->getArgs, "passwd", passwd, sizeof(passwd)); if (el > 0 && pl >= 0) { //Set to 0 if you want to disable the actual reconnecting bit #ifndef DEMO_MODE os_strncpy((char*)stconf.ssid, essid, 32); os_strncpy((char*)stconf.password, passwd, 64); os_printf("Wifi try to connect to AP %s pw %s\n", essid, passwd); //Schedule disconnect/connect os_timer_disarm(&reassTimer); os_timer_setfn(&reassTimer, reassTimerCb, NULL); os_timer_arm(&reassTimer, 1000, 0); #endif jsonHeader(connData, 200); } else { jsonHeader(connData, 400); httpdSend(connData, "Cannot parse ssid or password", -1); } return HTTPD_CGI_DONE; }
//Cgi that allows the ESPFS image to be replaced via http POST int ICACHE_FLASH_ATTR cgiUploadRaw(HttpdConnData *connData) { if (connData->conn==NULL) { //Connection aborted. Clean up. return HTTPD_CGI_DONE; } int part = get_updatable_partition(); if (connData->post->processed == 0 && connData->getArgs!=0){ // First run, init the partition and prep if necessary part = connData->getArgs[0] - '0'; // Turn for arg (should be partition ID) into partition index os_printf("\nFlashing partition: %d\n", part); } SpiFlashOpResult ret; // The source should be 4byte aligned, so go ahead an flash whatever we have ret=flash_binary(connData->post->buff, connData->post->buffLen, part); if (ret != connData->post->buffLen){ os_printf("Error writing to the flash\n"); return HTTPD_CGI_DONE; } // Count bytes for data connData->post->processed += ret; os_printf("Wrote %d bytes (%dB of %d)\n", connData->post->buffSize, connData->post->processed, connData->post->len);//&connData->postBuff)); if (connData->post->processed == connData->post->len){ httpdSend(connData, "Finished uploading", -1); reset_flash(); return HTTPD_CGI_DONE; } else { return HTTPD_CGI_MORE; } }
int cmd_systime_set(HttpdConnData *conn) { // Parse command from GET parameters char seconds_str[3]; char minutes_str[3]; char hours_str[3]; char date_str[3]; char month_str[3]; char year_str[3]; char dow_str[2]; httpdFindArg(conn->getArgs, "seconds", seconds_str, sizeof(seconds_str)); httpdFindArg(conn->getArgs, "minutes", minutes_str, sizeof(minutes_str)); httpdFindArg(conn->getArgs, "hours", hours_str, sizeof(hours_str)); httpdFindArg(conn->getArgs, "date", date_str, sizeof(date_str)); httpdFindArg(conn->getArgs, "month", month_str, sizeof(month_str)); httpdFindArg(conn->getArgs, "year", year_str, sizeof(year_str)); httpdFindArg(conn->getArgs, "dow", dow_str, sizeof(dow_str)); time.seconds = atoi(seconds_str); time.minutes = atoi(minutes_str); time.hours = atoi(hours_str); time.date = atoi(date_str); time.month = atoi(month_str); time.year = atoi(year_str); time.dow = atoi(dow_str); time_valid = true; httpdSend(conn, "ok", -1); return HTTPD_CGI_DONE; }
/** * HTTP commands * They forward the corresponding command to the AVR controller and decode the * answer. The may then forward that answer to the HTTP client in a human-readable * format. */ int cmd_slider_up(HttpdConnData *conn) { uint8_t i; for (i = 0; i < 4; i++) { os_printf("\r\nslider_up\r\n"); bool res = get_answer(200); if (res == true && os_strcmp("slu_ok", ans_buf) == 0) { os_printf("Leaving with success state\r\n"); httpdSend(conn, "ok", -1); return HTTPD_CGI_DONE; } } os_printf("Leaving with error state, buffer is %s\r\n", ans_buf); httpdSend(conn, "Keine Antwort vom AVR-Controller", -1); return HTTPD_CGI_DONE; }
//Template code for the led page. void ICACHE_FLASH_ATTR tplGPIO(HttpdConnData *connData, char *token, void **arg) { char buff[128]; if (token==NULL) return; os_strcpy(buff, "Unknown"); if (os_strcmp(token, "relay1name")==0) { os_strcpy(buff, (char *)sysCfg.relay1name); } if (os_strcmp(token, "relay1")==0) { if (currGPIO12State) { os_strcpy(buff, "on"); } else { os_strcpy(buff, "off"); } os_printf("Relay 1 is now "); os_printf(buff); os_printf("\n "); } httpdSend(connData, buff, -1); }
// Get current Soft-AP settings int ICACHE_FLASH_ATTR cgiApSettingsInfo(HttpdConnData *connData) { char buff[1024]; if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. os_sprintf(buff, "{ " "\"ap_ssid\": \"%s\", " "\"ap_password\": \"%s\", " "\"ap_authmode\": %d, " "\"ap_maxconn\": %d, " "\"ap_beacon\": %d, " "\"ap_hidden\": \"%s\" " " }", apconf.ssid, apconf.password, apconf.authmode, apconf.max_connection, apconf.beacon_interval, apconf.ssid_hidden ? "enabled" : "disabled" ); jsonHeader(connData, 200); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; }
int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. char buff[1024]; // don't use jsonHeader so the response does get cached httpdStartResponse(connData, 200); httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate"); httpdHeader(connData, "Content-Type", "application/json"); httpdEndHeaders(connData); // limit hostname to 12 chars char name[13]; os_strncpy(name, flashConfig.hostname, 12); name[12] = 0; // construct json response os_sprintf(buff, "{ " "\"menu\": [ " "\"Overview\", \"/home.html\", " "\"WiFi Console\", \"/console.html\", " "\"WiFi\", \"/wifi/wifi.html\", " #ifdef MQTT "\"Connectivity\", \"/mqtt.html\", " #endif "\"Debug log\", \"/log.html\"" " ], " "\"version\": \"%s\", " "\"name\": \"%s\"" " }", esp_link_version, name); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; }
//Template code for the WLAN page. void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) { char buff[1024]; int x; static struct station_config stconf; if (token==NULL) return; wifi_station_get_config(&stconf); os_strcpy(buff, "Unknown"); if (os_strcmp(token, "WiFiMode")==0) { x=wifi_get_opmode(); if (x==1) os_strcpy(buff, "Client"); if (x==2) os_strcpy(buff, "SoftAP"); if (x==3) os_strcpy(buff, "STA+AP"); } else if (os_strcmp(token, "currSsid")==0) { os_strcpy(buff, (char*)stconf.ssid); } else if (os_strcmp(token, "WiFiPasswd")==0) { os_strcpy(buff, (char*)stconf.password); } else if (os_strcmp(token, "WiFiapwarn")==0) { x=wifi_get_opmode(); if (x==2) { os_strcpy(buff, "<b>Can't scan in this mode.</b> Click <a href=\"setmode.cgi?mode=3\">here</a> to go to STA+AP mode."); } else { os_strcpy(buff, "Click <a href=\"setmode.cgi?mode=2\">here</a> to go to standalone AP mode."); } } httpdSend(connData, buff, -1); }
int ICACHE_FLASH_ATTR ajaxLogDbg(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. char buff[512]; int len, status = 400; len = httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff)); if (len > 0) { int8_t mode = -1; if (os_strcmp(buff, "auto") == 0) mode = LOG_MODE_AUTO; if (os_strcmp(buff, "off") == 0) mode = LOG_MODE_OFF; if (os_strcmp(buff, "on0") == 0) mode = LOG_MODE_ON0; if (os_strcmp(buff, "on1") == 0) mode = LOG_MODE_ON1; if (mode >= 0) { flashConfig.log_mode = mode; if (mode != LOG_MODE_AUTO) log_uart(mode >= LOG_MODE_ON0); status = configSave() ? 200 : 400; } } else if (connData->requestType == HTTPD_METHOD_GET) { status = 200; } jsonHeader(connData, status); os_sprintf(buff, "{\"mode\": \"%s\"}", dbg_mode[flashConfig.log_mode]); httpdSend(connData, buff, -1); return HTTPD_CGI_DONE; }
//This is called when the headers have been received and the connection is ready to send //the result headers and data. static void ICACHE_FLASH_ATTR httpdSendResp(HttpdConnData *conn) { int i=0; int r; //See if the url is somewhere in our internal url table. while (builtInUrls[i].url!=NULL && conn->url!=NULL) { int match=0; // os_printf("%s == %s?\n", builtInUrls[i].url, conn->url); if (os_strcmp(builtInUrls[i].url, conn->url)==0) match=1; if (builtInUrls[i].url[os_strlen(builtInUrls[i].url)-1]=='*' && os_strncmp(builtInUrls[i].url, conn->url, os_strlen(builtInUrls[i].url)-1)==0) match=1; if (match) { os_printf("Is url index %d\n", i); conn->cgiData=NULL; conn->cgi=builtInUrls[i].cgiCb; conn->cgiArg=builtInUrls[i].cgiArg; r=conn->cgi(conn); if (r!=HTTPD_CGI_NOTFOUND) { if (r==HTTPD_CGI_DONE) conn->cgi=NULL; //If cgi finishes immediately: mark conn for destruction. return; } } i++; } //Can't find :/ os_printf("%s not found. 404!\n", conn->url); httpdSend(conn, httpNotFoundHeader, -1); conn->cgi=NULL; //mark for destruction }
//Send a http header. void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const char *val) { char buff[256]; int l; l=os_sprintf(buff, "%s: %s\r\n", field, val); httpdSend(conn, buff, l); }
//ToDo: sprintf->snprintf everywhere... esp doesn't have snprintf tho' :/ //Redirect to the given URL. void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) { char buff[1024]; int l; conn->priv->code = 302; l = os_sprintf(buff, "HTTP/1.0 302 Found\r\nServer: esp8266-link\r\nConnection: close\r\n" "Location: %s\r\n\r\nRedirecting to %s\r\n", newUrl, newUrl); httpdSend(conn, buff, l); }
static int ICACHE_FLASH_ATTR cgiWiFiGetScan(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. char buff[1460]; const int chunk = 1460/64; // ssid is up to 32 chars int len = 0; os_printf("GET scan: cgiData=%d noAps=%d\n", (int)connData->cgiData, cgiWifiAps.noAps); // handle continuation call, connData->cgiData-1 is the position in the scan results where we // we need to continue sending from (using -1 'cause 0 means it's the first call) if (connData->cgiData) { int next = (int)connData->cgiData-1; int pos = next; while (pos < cgiWifiAps.noAps && pos < next+chunk) { len += os_sprintf(buff+len, "{\"essid\": \"%s\", \"rssi\": %d, \"enc\": \"%d\"}%c\n", cgiWifiAps.apData[pos]->ssid, cgiWifiAps.apData[pos]->rssi, cgiWifiAps.apData[pos]->enc, (pos+1 == cgiWifiAps.noAps) ? ' ' : ','); pos++; } // done or more? if (pos == cgiWifiAps.noAps) { len += os_sprintf(buff+len, "]}}\n"); httpdSend(connData, buff, len); return HTTPD_CGI_DONE; } else { connData->cgiData = (void*)(pos+1); httpdSend(connData, buff, len); return HTTPD_CGI_MORE; } } jsonHeader(connData, 200); if (cgiWifiAps.scanInProgress==1) { //We're still scanning. Tell Javascript code that. len = os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n"); httpdSend(connData, buff, len); return HTTPD_CGI_DONE; } len = os_sprintf(buff, "{\"result\": {\"inProgress\": \"0\", \"APs\": [\n"); connData->cgiData = (void *)1; // start with first result next time we're called httpdSend(connData, buff, len); return HTTPD_CGI_MORE; }
void ICACHE_FLASH_ATTR errorResponse(HttpdConnData *connData, int code, char *message) { noCacheHeaders(connData, code); httpdEndHeaders(connData); httpdSend(connData, message, -1); #ifdef CGI_DBG os_printf("HTTP %d error response: \"%s\"\n", code, message); #endif }
//This CGI is called from the bit of AJAX-code in wifi.tpl. It will initiate a //scan for access points and if available will return the result of an earlier scan. //The result is embedded in a bit of JSON parsed by the javascript in wifi.tpl. int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) { int pos=(int)connData->cgiData; int len; char buff[1024]; if (!cgiWifiAps.scanInProgress && pos!=0) { //Fill in json code for an access point if (pos-1<cgiWifiAps.noAps) { len=os_sprintf(buff, "{\"essid\": \"%s\", \"rssi\": \"%d\", \"enc\": \"%d\"}%s\n", cgiWifiAps.apData[pos-1]->ssid, cgiWifiAps.apData[pos-1]->rssi, cgiWifiAps.apData[pos-1]->enc, (pos-1==cgiWifiAps.noAps-1)?"":","); httpdSend(connData, buff, len); } pos++; if ((pos-1)>=cgiWifiAps.noAps) { len=os_sprintf(buff, "]\n}\n}\n"); httpdSend(connData, buff, len); //Also start a new scan. wifiStartScan(); return HTTPD_CGI_DONE; } else { connData->cgiData=(void*)pos; return HTTPD_CGI_MORE; } } httpdStartResponse(connData, 200); httpdHeader(connData, "Content-Type", "text/json"); httpdEndHeaders(connData); if (cgiWifiAps.scanInProgress==1) { //We're still scanning. Tell Javascript code that. len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n"); httpdSend(connData, buff, len); return HTTPD_CGI_DONE; } else { //We have a scan result. Pass it on. len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n"); httpdSend(connData, buff, len); if (cgiWifiAps.apData==NULL) cgiWifiAps.noAps=0; connData->cgiData=(void *)1; return HTTPD_CGI_MORE; } }