Exemple #1
0
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;
}
Exemple #2
0
// Cgi to query which firmware needs to be uploaded next
int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) {
    if (connData->conn==NULL) {
        //Connection aborted. Clean up.
        return HTTPD_CGI_DONE;
    }
    uint8 id = system_upgrade_userbin_check();
    httpdStartResponse(connData, 200);
    httpdHeader(connData, "Content-Type", "text/plain");
    httpdHeader(connData, "Content-Length", "9");
    httpdEndHeaders(connData);
    char *next = id == 1 ? "user1.bin" : "user2.bin";
    httpdSend(connData, next, -1);
    os_printf("Next firmware: %s (got %d)\n", next, id);
    return HTTPD_CGI_DONE;
}
Exemple #3
0
//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) {
		len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n");
		espconn_sent(connData->conn, (uint8 *)buff, len);
	} else {
		len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n");
		espconn_sent(connData->conn, (uint8 *)buff, len);
		if (cgiWifiAps.apData==NULL) cgiWifiAps.noAps=0;
		for (i=0; i<cgiWifiAps.noAps; i++) {
			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)?"":",");
			espconn_sent(connData->conn, (uint8 *)buff, len);
		}
		len=os_sprintf(buff, "]\n}\n}\n");
		espconn_sent(connData->conn, (uint8 *)buff, len);
		wifiStartScan();
	}
	return HTTPD_CGI_DONE;
}
//Sends Content-encoding header if the requested file was GZIP compressed
//If the client does not sent the Accept-encoding, send out a static html message.
const char* sendGZIPEncodingIfNeeded(HttpdConnData *connData) {
	int i=0;
	char acceptEncodingBuffer[64];
	//Go find the extension
	char *ext=connData->url+(strlen(connData->url)-1);
	while (ext!=connData->url && *ext!='.') ext--;
	if (*ext=='.') ext++;
	
	//ToDo: os_strcmp is case sensitive; we may want to do case-intensive matching here...
	while (gzippedFileTypes[i]!=NULL) {
		if (os_strcmp(ext, gzippedFileTypes[i])==0) {
			//when serving gzipped files check the browser's  "Accept-Encoding" header
			//if the client does not advertises that he accepts GZIP send a warning message (telnet users for e.g.)
			httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64);
			if (os_strstr(acceptEncodingBuffer, "gzip") == NULL) {
				//No Accept-Encoding: gzip header present
				return gzipNonSupportedMessage;
			} else {
				httpdHeader(connData, "Content-Encoding", "gzip");
				return NULL;
			}
		}
		i++;
	}
	return NULL;
}
Exemple #5
0
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;	
	}
}
Exemple #6
0
//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");
		espconn_sent(connData->conn, (uint8 *)buff, len);
	} else {
		//We have a scan result. Pass it on.
		len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n");
		espconn_sent(connData->conn, (uint8 *)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)?"":",");
			espconn_sent(connData->conn, (uint8 *)buff, len);
		}
		len=os_sprintf(buff, "]\n}\n}\n");
		espconn_sent(connData->conn, (uint8 *)buff, len);
		//Also start a new scan.
		wifiStartScan();
	}
	return HTTPD_CGI_DONE;
}
Exemple #7
0
/*	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;
}
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
//path in the filesystem and if it exists, passes the file through. This simulates what a normal
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
	EspFsFile *file=connData->cgiData;
	int len;
	char buff[1024];
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	if (file==NULL) {
		//First call to this cgi. Open the file so we can read it.
		file=espFsOpen(connData->url);
		if (file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=file;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(file, buff, 1024);
	if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len);
	if (len!=1024) {
		//We're done.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
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;
}
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
//path in the filesystem and if it exists, passes the file through. This simulates what a normal
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
	EspFsFile *file=connData->cgiData;
	int len;
	char buff[1024];
#ifdef GZIP_COMPRESSION
	const char *gzipSendResult = NULL;
#endif
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	if (file==NULL) {
		//First call to this cgi. Open the file so we can read it.
		file=espFsOpen(connData->url);
		if (file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=file;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
#ifdef GZIP_COMPRESSION
		gzipSendResult = sendGZIPEncodingIfNeeded(connData);
		if (gzipSendResult != NULL) {
			httpdEndHeaders(connData);
			httpdSend(connData, gzipSendResult, os_strlen(gzipSendResult));
			return HTTPD_CGI_DONE;
		}
#endif
		httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate");
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(file, buff, 1024);
	if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len);
	if (len!=1024) {
		//We're done.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
Exemple #11
0
int ICACHE_FLASH_ATTR cgiDHT22(HttpdConnData *connData) {
	char buff[256];
	char temp[32];
	char humi[32];

	httpdStartResponse(connData, 200);
	httpdHeader(connData, "Content-Type", "text/json");
	httpdHeader(connData, "Access-Control-Allow-Origin", "*");
	httpdEndHeaders(connData);

	dht_temp_str(temp);
	dht_humi_str(humi);
	
	os_sprintf(buff, "{ \n\"temperature\": \"%s\"\n , \n\"humidity\": \"%s\"\n}\n", temp, humi );
	
	httpdSend(connData, buff, -1);
	return HTTPD_CGI_DONE;
}
Exemple #12
0
CgiStatus ICACHE_FLASH_ATTR authBasic(HttpdConnData *connData) {
	const char *unauthorized = "401 Unauthorized.";
	int no=0;
	int r;
	char hdr[(AUTH_MAX_USER_LEN+AUTH_MAX_PASS_LEN+2)*10];
	char userpass[AUTH_MAX_USER_LEN+AUTH_MAX_PASS_LEN+2];
	char user[AUTH_MAX_USER_LEN];
	char pass[AUTH_MAX_PASS_LEN];

	if(connData->isConnectionClosed)
	{
		//Connection closed. Clean up.
		return HTTPD_CGI_DONE;
	}

	r=httpdGetHeader(connData, "Authorization", hdr, sizeof(hdr));
	if (r && strncmp(hdr, "Basic", 5)==0) {
		r=libesphttpd_base64_decode(strlen(hdr)-6, hdr+6, sizeof(userpass), (unsigned char *)userpass);
		if (r<0) r=0; //just clean out string on decode error
		userpass[r]=0; //zero-terminate user:pass string
//		printf("Auth: %s\n", userpass);
		while (((AuthGetUserPw)(connData->cgiArg))(connData, no,
				user, AUTH_MAX_USER_LEN, pass, AUTH_MAX_PASS_LEN)) {
			//Check user/pass against auth header
			if (strlen(userpass)==strlen(user)+strlen(pass)+1 &&
					strncmp(userpass, user, strlen(user))==0 &&
					userpass[strlen(user)]==':' &&
					strcmp(userpass+strlen(user)+1, pass)==0) {
				//Authenticated. Yay!
				return HTTPD_CGI_AUTHENTICATED;
			}
			no++; //Not authenticated with this user/pass. Check next user/pass combo.
		}
	}

	//Not authenticated. Go bug user with login screen.
	httpdStartResponse(connData, 401);
	httpdHeader(connData, "Content-Type", "text/plain");
	httpdHeader(connData, "WWW-Authenticate", "Basic realm=\""HTTP_AUTH_REALM"\"");
	httpdEndHeaders(connData);
	httpdSend(connData, unauthorized, -1);
	//Okay, all done.
	return HTTPD_CGI_DONE;
}
Exemple #13
0
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
  noCacheHeaders(connData, 200);
  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
  //  limit menu dependend on menu level
  if( flashConfig.menu_level > 0)
	 os_sprintf(buff,
    "{ "
      "\"menu\": [ "
        "\"goDMD\", \"/godmd/index.html\", "
        "\"Home\", \"/home.html\", "
        "\"WiFi Station\", \"/wifi/wifiSta.html\", "
        "\"WiFi Soft-AP\", \"/wifi/wifiAp.html\", "
        "\"&#xb5;C Console\", \"/console.html\", "
        "\"Services\", \"/services.html\", "
#ifdef MQTT
        "\"REST/MQTT\", \"/mqtt.html\", "
#endif
        "\"Debug log\", \"/log.html\","
        "\"Upgrade Firmware\", \"/flash.html\","
        "\"Web Server\", \"/web-server.html\""
	"%s"
      " ], "
      "\"version\": \"%s\", "
      "\"name\": \"%s\""
    " }",
	WEB_UserPages(), esp_link_version, name);
  else
	 os_sprintf(buff,
	"{ "
	  "\"menu\": [ "
		"\"goDMD\", \"/godmd/index.html\", "
		"\"Home\", \"/home.html\", "
		"\"WiFi Station\", \"/wifi/wifiSta.html\", "
		"\"WiFi Soft-AP\", \"/wifi/wifiAp.html\", "
		"\"Upgrade Firmware\", \"/flash.html\""
	"%s"
	  " ], "
	  "\"version\": \"%s\", "
	  "\"name\": \"%s\""
	" }",
	WEB_UserPages(), esp_link_version, name);


  httpdSend(connData, buff, -1);
  return HTTPD_CGI_DONE;
}
Exemple #14
0
//Cgi that turns the Relays on or off according to the 'relayX' param in the GET data
int ICACHE_FLASH_ATTR cgiGPIO(HttpdConnData *connData) {
	int len;
	char buff[128];
	int gotcmd=0;
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		return HTTPD_CGI_DONE;
	}

	len=httpdFindArg(connData->getArgs, "relay1", buff, sizeof(buff));
	if (len>0) {
		currGPIO12State=atoi(buff);
		ioGPIO(currGPIO12State,12);
		gotcmd=1;
		//Manually switching relays means switching the thermostat off
		if(sysCfg.thermostat1state!=0) {
			sysCfg.thermostat1state=0;
		}
	}
	
	if(gotcmd==1) {
		if( sysCfg.relay_latching_enable) {		
			sysCfg.relay_1_state=currGPIO12State;
			CFG_Save();
		}

		httpdRedirect(connData, "relay.tpl");
		return HTTPD_CGI_DONE;
	} else { //with no parameters returns JSON with relay state

		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", "text/json");
		httpdHeader(connData, "Access-Control-Allow-Origin", "*");
		httpdEndHeaders(connData);

		len=os_sprintf(buff, "{\"relay1\": %d\n,\"relay1name\":\"%s\"}\n",  currGPIO12State,(char *)sysCfg.relay1name );
		httpdSend(connData, buff, -1);
		return HTTPD_CGI_DONE;	
	}
}
// Send build info
int ICACHE_FLASH_ATTR cgiBuildInfo(HttpdConnData *connData)
 {
  char buff[1536];
  int len;
  // Check if connection exists
  if(connData->conn==NULL)
   {
    return HTTPD_CGI_DONE;
   }
  // HTTP Header
  httpdStartResponse(connData, 200);
  httpdHeader(connData, "Content-Type", "text/plain");
  httpdHeader(connData, "Pragma", "no-cache");
  httpdHeader(connData, "Expires", "0");
  httpdEndHeaders(connData);
  // AJAX data
  len=os_sprintf(buff, "espweather %s\nCompiled on %s, %s\n%s (GCC %s)\n", VERSTRING, __DATE__, __TIME__, HOSTSTRING, __VERSION__);
  httpdSend(connData, buff, len);
  // Return
  return HTTPD_CGI_DONE;
 }
Exemple #16
0
/*	cgiReadFlash	*/
int ICACHE_FLASH_ATTR cgiReadFlash(HttpdConnection *	ptConnection)
{
	/* initialization */
	int 	iRet 			= 0;
	int *	iFlashOffset 	= NULL;

	iFlashOffset = (int *)&ptConnection->pbCgiData;

	if (NULL == ptConnection->ptEspConnection)
	{
		/* connection aborted - clean up */
		iRet = HTTPD_CGI_DONE;
		goto lblCleanup;
	}

	if (0 == *iFlashOffset)
	{

#ifdef CGIFLASH_DEBUG
		os_printf("cgiReadFlash: begin flash download\n");
#endif

		httpdStartResponse(ptConnection, 200);
		httpdHeader(ptConnection, "Content-Type", "application/bin");
		httpdEndHeaders(ptConnection);

		/* update offset */
		*iFlashOffset = 0x40200000;

		iRet = HTTPD_CGI_MORE;
		goto lblCleanup;
	}
	
	/* send 1K of flash per call, will be called again if haven't sent 512K yet */
	espconn_sent(ptConnection->ptEspConnection, (uint8 *)(*iFlashOffset), 1024);
	*iFlashOffset += 1024;
	if (*iFlashOffset >= 0x40200000 + (512 * 1024))
	{
		iRet = HTTPD_CGI_DONE;
		goto lblCleanup;
	}
	else
	{
		iRet = HTTPD_CGI_MORE;
		goto lblCleanup;
	}

lblCleanup:
	return iRet;
}
Exemple #17
0
int ICACHE_FLASH_ATTR cgiEnv(HttpdConnData *connData) {
	char buff[2048];
	int len=0;

	httpdStartResponse(connData, 200);
	httpdHeader(connData, "Content-Type", "application/json");
	httpdHeader(connData, "Access-Control-Allow-Origin", "*");
	httpdEndHeaders(connData);

	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		return HTTPD_CGI_DONE;
	}

	//os_strcpy(buff, "Unknown");
	//os_strcpy(temp, "N/A");
	//os_strcpy(humi, "N/A");

	len=httpdFindArg(connData->getArgs, "param", buff, sizeof(buff));
	if (len>0) {
		if(os_strcmp(buff,"temp")==0) {
			len=os_sprintf(buff, "%d",tempF);
			httpdSend(connData, buff, -1);
			tempF = tempF - 2;
			hudP = hudP + 2;
			os_printf("\nTemp val = %d\n",tempF);
		}
		if(os_strcmp(buff,"hud")==0) {
			len=os_sprintf(buff, "%d",hudP);
			httpdSend(connData, buff, -1);
			hudP = hudP - 2;
			tempF = tempF + 2;
			os_printf("\nHud val = %d\n",hudP);
		}
	}
	return HTTPD_CGI_DONE;
}
Exemple #18
0
//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;
	}
}
Exemple #19
0
//Cgi that reads the SPI flash. Assumes 512KByte flash.
int ICACHE_FLASH_ATTR cgiReadFlash(HttpdConnData *connData) {
	int *pos=(int *)&connData->cgiData;
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		return HTTPD_CGI_DONE;
	}

	if (*pos==0) {
		//os_printf("Start flash download.\n");
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", "application/bin");
		httpdEndHeaders(connData);
		*pos=0x40200000;
		return HTTPD_CGI_MORE;
	}
	espconn_sent(connData->conn, (uint8 *)(*pos), 1024);
	*pos+=1024;
	if (*pos>=0x40200000+(512*1024)) return HTTPD_CGI_DONE; else return HTTPD_CGI_MORE;
}
Exemple #20
0
int ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData) {
	char buff[1024];
	int len;
	struct ip_info info;
	int st=wifi_station_get_connect_status();
	httpdStartResponse(connData, 200);
	httpdHeader(connData, "Content-Type", "text/json");
	httpdEndHeaders(connData);
	if (connTryStatus==CONNTRY_IDLE) {
		len=os_sprintf(buff, "{\n \"status\": \"idle\"\n }\n");
	} else if (connTryStatus==CONNTRY_WORKING || connTryStatus==CONNTRY_SUCCESS) {
		if (st==STATION_GOT_IP) {
			wifi_get_ip_info(0, &info);
			len=os_sprintf(buff, "{\n \"status\": \"success\",\n \"ip\": \"%d.%d.%d.%d\" }\n", 
				(info.ip.addr>>0)&0xff, (info.ip.addr>>8)&0xff, 
				(info.ip.addr>>16)&0xff, (info.ip.addr>>24)&0xff);
			//Reset into AP-only mode sooner.
			os_timer_disarm(&resetTimer);
			os_timer_setfn(&resetTimer, resetTimerCb, NULL);
			os_timer_arm(&resetTimer, 1000, 0);
		} else {
Exemple #21
0
int ICACHE_FLASH_ATTR cgiJson(HttpdConnData *connData)
{
	struct jsontree_context *json = (struct jsontree_context *)connData->cgiData;
	char buf[6];

	if (connData->conn == NULL) {
		if (json) {
			free(json);
		}
		return HTTPD_CGI_DONE;
	}

	currentConnData = connData;

	if (json == NULL) {
		json = malloc(sizeof(struct jsontree_context));
		jsontree_setup(json, (struct jsontree_value *)connData->cgiArg, httpdPutchar);

		if (httpdFindArg(connData->getArgs, "id", buf, sizeof(buf)) > 0) {
			json->index[JSONTREE_MAX_DEPTH - 1] = atoi(buf);
		}
		else {
			json->index[JSONTREE_MAX_DEPTH - 1] = 65535;
		}

		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", "application/json");
		httpdEndHeaders(connData);
		connData->cgiData = json;
	}

	while (jsontree_print_next(json) && json->path <= json->depth) {
		if (connData->priv->sendBuffLen > MAX_SENDBUFF_LEN - (MAX_SENDBUFF_LEN / 4)) {
			return HTTPD_CGI_MORE;
		}
	}

	free(json);
	return HTTPD_CGI_DONE;
}
Exemple #22
0
int ICACHE_FLASH_ATTR
cgiBms(HttpdConnData *connData)
    /* by JJC */
{
	int len_tot;
	char buff[1024];
    char single_val_buf[8];

	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		return HTTPD_CGI_DONE;
	}

    httpdStartResponse(connData, 200);
    httpdHeader(connData, "Content-Type", "text/json");
    httpdEndHeaders(connData);

    /* new JSON structure:
     * { "bms_values" : [ 5, 6, 7, 8, 999 ] }
     */
    len_tot = sprintf(buff, "{\"bms_values\":[");
    int i, numel;
    numel = bms_numel_get();
    for(i = 0; i < numel - 1; i++) {
        len_tot += sprintf(single_val_buf, "%d,", bms_value_get(i));
        strcat(buff, single_val_buf);
    }
    if(numel > 1) {
        // no comma after printed number for last element.
        len_tot += sprintf(single_val_buf, "%d", bms_value_get(numel-1));
        strcat(buff, single_val_buf);
    }
    len_tot += sprintf(single_val_buf, "]}");
    strcat(buff, single_val_buf);

    httpdSend(connData, buff, len_tot);
    return HTTPD_CGI_DONE;
}
// CGI to set settings
int ICACHE_FLASH_ATTR saveCGI(HttpdConnData *connData) {
	int len;
	char buff[10];
	//char bin[10];

	if (connData->conn == NULL) {
		//Connection aborted. Clean up.
		return HTTPD_CGI_DONE;
	}

	len = httpdFindArg(connData->getArgs, "power", buff, sizeof(buff));
	if (len != 0) ac_set_power(buff);

	len = httpdFindArg(connData->getArgs, "mode", buff, sizeof(buff));
	if (len != 0) ac_set_mode(buff);

	len = httpdFindArg(connData->getArgs, "temp", buff, sizeof(buff));
	if (len != 0) ac_set_temp(buff);

	len = httpdFindArg(connData->getArgs, "fan", buff, sizeof(buff));
	if (len != 0) ac_set_fan(buff);

	len = httpdFindArg(connData->getArgs, "swing", buff, sizeof(buff));
	if (len != 0) ac_set_swing(buff);

	ir_send();
	mqttPublishSettings(0);
	CFG_Save();

	httpdStartResponse(connData, 200);
	httpdHeader(connData, "Content-Type", "text/html");
	httpdEndHeaders(connData);

	os_strcpy(buff, "OK");
	httpdSend(connData, buff, -1);

	return HTTPD_CGI_DONE;
}
Exemple #24
0
//Cgi that turns the LED on or off according to the 'led' param in the POST data
int ICACHE_FLASH_ATTR cgiButton(HttpdConnData *connData) {
	int len;
	char buff[1024];
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		return HTTPD_CGI_DONE;
	}

	httpdStartResponse(connData, 200);
	httpdHeader(connData, "Content-Type", "application/json");
	httpdEndHeaders(connData);

	/* This will return JSON:
	 * {"button":
	 * 	{"status":"on"}
	 * }
	 */
	len = os_sprintf(buff, "{\n \"button\": { \n\"status\":\"%s\"\n}\n}\n", (GPIO_INPUT_GET(0)) ? "off" : "on");
	espconn_sent(connData->conn, (uint8 *)buff, len);

	return HTTPD_CGI_DONE;
}
Exemple #25
0
void ICACHE_FLASH_ATTR jsonHeader(HttpdConnData *connData, int code) {
  noCacheHeaders(connData, code);
  httpdHeader(connData, "Content-Type", "application/json");
  httpdEndHeaders(connData);
}
Exemple #26
0
void ICACHE_FLASH_ATTR noCacheHeaders(HttpdConnData *connData, int code) {
  httpdStartResponse(connData, code);
  httpdHeader(connData, "Cache-Control", "no-cache, no-store, must-revalidate");
  httpdHeader(connData, "Pragma", "no-cache");
  httpdHeader(connData, "Expires", "0");
}
Exemple #27
0
int ICACHE_FLASH_ATTR cgiApi(HttpdConnData *connData)
{
	struct ApiData *api = (struct ApiData *)connData->cgiPrivData;
	int nbytes, status;
	char type;

	if (connData->conn == NULL) {
		goto done;
	}

	if (connData->requestType != HTTPD_METHOD_POST) {
		httpdStartResponse(connData, 501);
		httpdHeader(connData, "Content-Type", "text/html");
		httpdEndHeaders(connData);
		return HTTPD_CGI_DONE;
	}

	if (connData->post->received <= MAX_POST) {
		api = malloc(sizeof(struct ApiData));
		jsonparse_setup(&api->state, api->buff, MAX_POST);
		api->buffLen = 0;
		api->depth = 0;
		api->status = API_OK;

		connData->cgiPrivData = api;
	}

	if (api->status < API_OK) {
		goto finish;
	}

	while (true) {
		nbytes = API_MAX_BUFF - api->buffLen - 1;
		nbytes = connData->post->buffLen < nbytes ? connData->post->buffLen : nbytes;
		memcpy(&api->buff[api->buffLen], connData->post->buff, nbytes);
		api->buffLen += nbytes;
		memmove(connData->post->buff, &connData->post->buff[nbytes], connData->post->buffLen - nbytes);
		connData->post->buffLen -= nbytes;
		if (connData->post->buffLen == 0) {
			if (connData->post->received < connData->post->len) {
				return HTTPD_CGI_MORE;
			}
			break;
		}
		while (api->state.pos < API_MIN_CHUNK) {
			type = jsonparse_next(&api->state);
			if (type == ',') {
				/* do nothing */
			} else if (type == '[') {
				api->depth = api->state.depth;
			} else {
				api->status = API_ERROR_PARSE;
				goto finish;
			}
			if ((status = api_parse(&api->state)) != API_OK) {
				api->status = status;
				if (status < API_OK) {
					goto finish;
				}
			}
			while (api->state.depth > api->depth) {
				if (!jsonparse_next(&api->state)) {
					api->status = API_ERROR_PARSE;
					goto finish;
				}
			}
		}
		memmove(api->buff, &api->buff[api->state.pos], api->buffLen - api->state.pos);
		api->buffLen -= api->state.pos;
		api->state.pos = 0;
	}

	api->buff[api->buffLen] = '\0';
	api->state.len = api->buffLen;
	while (true) {
		type = jsonparse_next(&api->state);
		if (type == ',') {
			/* do nothing */
		} else if (type == '[') {
			api->depth = api->state.depth;
		} else {
			if (api->state.error != JSON_ERROR_OK) {
				api->status = API_ERROR_PARSE;
			}
			goto finish;
		}
		if ((status = api_parse(&api->state)) != API_OK) {
			api->status = status;
			if (status < API_OK) {
				goto finish;
			}
		}
		while (api->state.depth > api->depth) {
			if (!jsonparse_next(&api->state)) {
				api->status = API_ERROR_PARSE;
				goto finish;
			}
		}
	}

finish:
	if (connData->post->received < connData->post->len) {
		return HTTPD_CGI_MORE;
	}

	if (api->status < API_OK) {
		httpdStartResponse(connData, 500);
		httpdHeader(connData, "Content-Type", "text/html");
		httpdEndHeaders(connData);
		goto done;
	}

	httpdStartResponse(connData, 200);
	httpdHeader(connData, "Content-Type", "application/json");
	httpdEndHeaders(connData);
	httpdSend(connData, api->status == API_OK ? "true" : "false", -1);

	if (api_update) {
		api_update = false;
		master_update(true);
	}

	if (status_dirty) {
		status_save();
	}

done:
	free(api);
	connData->cgiPrivData = NULL;
	return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) {
	TplData *tpd=connData->cgiData;
	int len;
	int x, sp=0;
	char *e=NULL;
	char buff[1025];

	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		os_free(tpd);
		return HTTPD_CGI_DONE;
	}

	if (tpd==NULL) {
		//First call to this cgi. Open the file so we can read it.
		tpd=(TplData *)os_malloc(sizeof(TplData));
		tpd->file=espFsOpen(connData->url);
		tpd->tplArg=NULL;
		tpd->tokenPos=-1;
		if (tpd->file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=tpd;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(tpd->file, buff, 1024);
	if (len>0) {
		sp=0;
		e=buff;
		for (x=0; x<len; x++) {
			if (tpd->tokenPos==-1) {
				//Inside ordinary text.
				if (buff[x]=='%') {
					//Send raw data up to now
					if (sp!=0) espconn_sent(connData->conn, (uint8 *)e, sp);
					sp=0;
					//Go collect token chars.
					tpd->tokenPos=0;
				} else {
					sp++;
				}
			} else {
				if (buff[x]=='%') {
					tpd->token[tpd->tokenPos++]=0; //zero-terminate token
					((TplCallback)(connData->cgiArg))(connData, tpd->token, &tpd->tplArg);
					//Go collect normal chars again.
					e=&buff[x+1];
					tpd->tokenPos=-1;
				} else {
					if (tpd->tokenPos<(sizeof(tpd->token)-1)) tpd->token[tpd->tokenPos++]=buff[x];
				}
			}
		}
	}
	//Send remaining bit.
	if (sp!=0) espconn_sent(connData->conn, (uint8 *)e, sp);
	if (len!=1024) {
		//We're done.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
//path in the filesystem and if it exists, passes the file through. This simulates what a normal
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
	EspFsFile *file=connData->cgiData;
	int len;
	char buff[1024];
	char acceptEncodingBuffer[64];
	int isGzip;
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	if (file==NULL) {
		//First call to this cgi. Open the file so we can read it.
		file=espFsOpen(connData->url);
		if (file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}

		// The gzip checking code is intentionally without #ifdefs because checking
		// for FLAG_GZIP (which indicates gzip compressed file) is very easy, doesn't
		// mean additional overhead and is actually safer to be on at all times.
		// If there are no gzipped files in the image, the code bellow will not cause any harm.

		// Check if requested file was GZIP compressed
		isGzip = espFsFlags(file) & FLAG_GZIP;
		if (isGzip) {
			// Check the browser's "Accept-Encoding" header. If the client does not
			// advertise that he accepts GZIP send a warning message (telnet users for e.g.)
			httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64);
			if (os_strstr(acceptEncodingBuffer, "gzip") == NULL) {
				//No Accept-Encoding: gzip header present
				httpdSend(connData, gzipNonSupportedMessage, -1);
				espFsClose(file);
				return HTTPD_CGI_DONE;
			}
		}

		connData->cgiData=file;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		if (isGzip) {
			httpdHeader(connData, "Content-Encoding", "gzip");
		}
		httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate");
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(file, buff, 1024);
	if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len);
	if (len!=1024) {
		//We're done.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) {
	TplData *tpd=connData->cgiData;
	int len;
	int x, sp=0;
	char *e=NULL;
	char buff[1025];

	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		os_free(tpd);
		return HTTPD_CGI_DONE;
	}

	if (tpd==NULL) {
		//First call to this cgi. Open the file so we can read it.
		tpd=(TplData *)os_malloc(sizeof(TplData));
		tpd->file=espFsOpen(connData->url);
		tpd->tplArg=NULL;
		tpd->tokenPos=-1;
		if (tpd->file==NULL) {
			espFsClose(tpd->file);
			os_free(tpd);
			return HTTPD_CGI_NOTFOUND;
		}
		if (espFsFlags(tpd->file) & FLAG_GZIP) {
			debug("cgiEspFsTemplate: Trying to use gzip-compressed file %s as template!\n", connData->url);
			espFsClose(tpd->file);
			os_free(tpd);
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=tpd;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(tpd->file, buff, 1024);
	if (len>0) {
		sp=0;
		e=buff;
		for (x=0; x<len; x++) {
			if (tpd->tokenPos==-1) {
				//Inside ordinary text.
				if (buff[x]=='%') {
					//Send raw data up to now
					if (sp!=0) httpdSend(connData, e, sp);
					sp=0;
					//Go collect token chars.
					tpd->tokenPos=0;
				} else {
					sp++;
				}
			} else {
				if (buff[x]=='%') {
					if (tpd->tokenPos==0) {
						//This is the second % of a %% escape string.
						//Send a single % and resume with the normal program flow.
						httpdSend(connData, "%", 1);
					} else {
						//This is an actual token.
						tpd->token[tpd->tokenPos++]=0; //zero-terminate token
						((TplCallback)(connData->cgiArg))(connData, tpd->token, &tpd->tplArg);
					}
					//Go collect normal chars again.
					e=&buff[x+1];
					tpd->tokenPos=-1;
				} else {
					if (tpd->tokenPos<(sizeof(tpd->token)-1)) tpd->token[tpd->tokenPos++]=buff[x];
				}
			}
		}
	}
	//Send remaining bit.
	if (sp!=0) httpdSend(connData, e, sp);
	if (len!=1024) {
		//We're done.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		os_free(tpd);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}