LOCAL void ICACHE_FLASH_ATTR get_devicekey_cb(const char *key) {
	if(*key)
		dhsettings_set_devicehive_devicekey(key);
	dhuart_send_str("Configuring complete, store settings...");
	if(dhsettings_commit()) {
		dhuart_send_line("OK");
		dhuart_send_line("Rebooting...");
		system_restart();
	} else {
		dhuart_send_line("ERROR. Not saved. Check debug output.");
	}
	dhterminal_set_mode(SM_NORMAL_MODE, 0, 0, 0, 0);
}
LOCAL void ICACHE_FLASH_ATTR receive_post(const char *data, unsigned short len, char * internal, unsigned int internalsize) {
	const unsigned int POST_BUF_SIZE = 2048;
	const char content_length[] = "Content-Length:";
	const char sp[] = "\r\n\r\n";
	if(mPostBuf == 0) {
		mPostBuf = (char*)os_malloc(POST_BUF_SIZE);
		if(mPostBuf == 0) {
			check_send_res(espconn_send(mCurrentPost, internal, internalsize));
			mCurrentPost = 0;
			return;
		}
	}
	if(len > POST_BUF_SIZE - mPostBufPos) {
		check_send_res(espconn_send(mCurrentPost, internal, internalsize));
		mCurrentPost = 0;
		return;
	}
	os_memcpy(&mPostBuf[mPostBufPos], data, len);
	mPostBufPos += len;
	const int to = (int)mPostBufPos - sizeof(content_length) + 1;
	int i;
	unsigned int cont_len;
	for(i = 0; i < to; i++) {
		if(os_strncmp(&mPostBuf[i], content_length, sizeof(content_length) - 1) == 0) {
			i += sizeof(content_length) - 1;
			while(mPostBuf[i] == ' ')
				i++;
			if(strToUInt(&mPostBuf[i], &cont_len)) {
				for(; i < mPostBufPos; i++) {
					if(os_strncmp(&mPostBuf[i], sp, sizeof(sp) - 1) == 0) {
						i += sizeof(sp) - 1;
						if(cont_len <= mPostBufPos - i) {
							dhdebug("POST len %u/%u", cont_len, mPostBufPos - i);
							char *res = dhap_post_parse(&mPostBuf[i], mPostBufPos - i);
							unsigned int rlen;
							if(res) {
								res = dhap_pages_error(res, &rlen);
							} else {
								if(dhsettings_commit() == 0) {
									res = internal;
									rlen = internalsize;
								} else {
									res = dhap_pages_ok(&rlen);
									if(res == 0) {
										dhdebug("Generate OK page fail");
										res = internal;
										rlen = internalsize;
									} else {
										dhdebug("Configuration was written. Will be rebooted in %d ms", RECONFIGURE_DELAY_MS);
										os_timer_disarm(&mReconfigureTimer);
										os_timer_setfn(&mReconfigureTimer, (os_timer_func_t *)system_reconfigure, NULL);
										os_timer_arm(&mReconfigureTimer, RECONFIGURE_DELAY_MS, 0);
										mConfigured = 1;
									}
								}
							}
							dhdebug("Parse post, send result %u bytes", rlen);
							check_send_res(espconn_send(mCurrentPost, res, rlen));
							mCurrentPost = 0;
						}
						return;
					}
				}
			}
			return;
		}
	}
}