#include <avr/io.h>
#include <string.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>

#include "common.h"
#include "wizfi.h"


bool_t setupBase(int8_t cid, char* data)
{
	//DP: toto vs html setup
		
	if (strncmp_P(data, fmt_RST, 3) == 0)
	{
		wzf_send_P(cid, rep_OK);
		wzf_reset();
		disp_off(FALSE);
		SW_RESET();
		// zde se návrat neuvažuje
	}
		
	if (strncmp_P(data, fmt_ID, 2) == 0)
	{
		if (data[2] == '?')
		{
			wzf_sendOpen(cid);
			wzf_sendPushText_P(fmt_ID, 2);
			wzf_sendPushText_P(PSTR("MDISP1"), 6);
			wzf_sendPushText_EE((char *)&id_EE.text, eeprom_read_byte(&id_EE.length));
			wzf_sendDo();
			
			//wzf_send_P(cid,rep_INFO);
			return TRUE;
		}


		char *p0 = strchr(data, CHR_BRK);
		uint8_t len = p0 - data - 3;
		if (len > 16)
		{
			wzf_send_P(cid, rep_ARG);
			return TRUE;
		}
		eeprom_update_byte(&id_EE.length, len);
		eeprom_update_block(data+3, &id_EE.text, len);
		wzf_send_P(cid, rep_OK);
		return TRUE;
	}
	
	//---------------------------------------------------------
	// povel NET (ip adresa, maska, brána)
	//---------------------------------------------------------
	
	// NET selfIp mask gateIp
	// NET 192.168.1.21 ...
	if (strncmp_P(data, fmt_NET, 3) == 0)
	{		
		if (data[3] == '?')
		{
			// NET? - dotaz na nastavení sítě
			wzf_sendOpen(cid);
			wzf_sendPushText_P(fmt_NET, 3);
			wzf_sendPushIp_EE(&moduleIp_EE);
			wzf_sendPushIp_EE(&maskIp_EE);
			wzf_sendPushIp_EE(&gateIp_EE);
			wzf_sendDo();
			return TRUE;
		}
		
		uint8_t argModuleIp[4];
		uint8_t argMask[4];
		uint8_t argGateIp[4];
		
		if (sscanf_P(data, fmt_NET,
		&argModuleIp[3], &argModuleIp[2], &argModuleIp[1], &argModuleIp[0],
		&argMask[3], &argMask[2], &argMask[1], &argMask[0],
		&argGateIp[3], &argGateIp[2], &argGateIp[1], &argGateIp[0]) == 12)
		{
			eeprom_update_block(&argModuleIp, &moduleIp_EE, 4);
			eeprom_update_block(&argMask, &maskIp_EE, 4);
			eeprom_update_block(&argGateIp, &gateIp_EE, 4);
			wzf_send_P(cid, rep_OK);
		}
		else
			wzf_send_P(cid, rep_ARG);
		return TRUE;
	}
	
	//---------------------------------------------------------
	// povel WLAN (vysílací výkon, zabezpečení)
	//---------------------------------------------------------
	// response:	WLAN pwr ssid auth
	// resp-none:	WLAN 1 ABCD 0
	// resp-WPA2:	WLAN 1 ABCD 2
	
	// setup-none:	WLAN pwr ssid
	// setup-WPA2:	WLAN pwr ssid psk
	
	if (strncmp_P(data, fmt_WLAN, 4) == 0)
	{
		if (data[4] == '?')
		{
			// WLAN? - dotaz na nastavení připojení k AP
			// z bezp. důvodů nevrací klíč
			wzf_sendOpen(cid);
			wzf_sendPushText_P(fmt_WLAN, 4);
			wzf_sendPushUInt(eeprom_read_byte(&txPower_EE));
			wzf_sendPushText_EE((char *)&ssid_EE.text, eeprom_read_byte(&ssid_EE.length));
			wzf_sendPushUInt( eeprom_read_byte(&psk_EE.length) ? AUTH_WPA : AUTH_NONE);
			wzf_sendDo();
			ledBlink(BLINK_500ms);
			return TRUE;
		}
		
		uint8_t txPower;
		char *p0, *p1, *p2;
		
		if (sscanf_P(data, fmt_WLAN, &txPower) == 1)
		{
			p0 = strchr(data+5, CHR_SPACE);
			p1 = strchr(p0+1, CHR_SPACE);
			p2 = strchr(p1+1, CHR_BRK);
			//DP: ohledně délky a znaků možno citovat IEEE Std 802.11™-2 2 012
			
			uint8_t lenSsid = p1 - p0 - 1;
			uint8_t lenKey = p2 - p1 - 1;
			
			if ((txPower & ~7) || !lenSsid || (lenSsid > 32) || (lenKey > 64))
			{
				wzf_send_P(cid, rep_ARG);
				return TRUE;
			}
			eeprom_update_byte(&txPower_EE, txPower);
			
			eeprom_update_byte(&ssid_EE.length, lenSsid);
			eeprom_update_block(p0+1, &ssid_EE.text, lenSsid);
			
			eeprom_update_byte(&psk_EE.length,lenKey);
			if (lenKey)
				eeprom_update_block(p1+1, &psk_EE.text, lenKey);
			
			wzf_send_P(cid, rep_OK);
			ledBlink(BLINK_500ms);
		}
		else
			wzf_send_P(cid, rep_ARG);

		return TRUE;
	}

	return FALSE;
}


void fsSetup()
{
		FS_SETUP:
		
		disp_err(1);
		LED_OFF();
		wzf_wait(50);
		LED_ON();
		wzf_wait(25);
		LED_OFF();
		wzf_wait(25);
		LED_ON();
		
		if (wzf_setup(
		(const ipAdd_t *)&fs_setupIp_EE,
		(const ipAdd_t *)&fs_maskIp_EE,
		(const ipAdd_t *)&fs_setupIp_EE,
		WZF_DHCP_DISABLE,
		&fs_ssid_EE,
		&fs_psk_EE,
		WZF_AP,
		MIN_PWR) != WZF_OK)
		{
			wzf_reset();
			goto FS_SETUP;
		}
		
		disp_err(2);
		if (wzf_associate() != WZF_OK)
		goto FS_SETUP;
		
		if (wzf_openTCPServer(
		SETUP_PORT,
		&setupExecute,
		&tcpSetupServerCID) != WZF_OK)
		{
			goto FS_SETUP;
		}
		
		LED_OFF();
		//disp_print((uint8_t[3]){SYMBOL_S, SYMBOL_E, SYMBOL_t});
		disp_print((uint8_t[3]){0xFF, 0xFF, 0xFF});
		
		for (;;)
		{
			wzf_exec();
		}	
}