// Useage. Circuit, IP, Port, Input file, builder flag
int main(int argc, char *argv[])
{
	srand(time(NULL));

	// elgamal_commit_main();
	// testHKE(argv[1], argv[2], argv[3], argv[4], atoi(argv[5]));
	runProtocol(argv[1], argv[2], argv[3], argv[4], atoi(argv[5]), atoi(argv[6]));
	// testCircuitComp(argv[1]);
	// test_local_OT_NP(atoi(argv[5]));
	// testVSS();
	// test_ZKPoK_ECC();
	// test_ZKPoK_ECC_1Of2();
	// testRawCheckCircuits();

	return 0;
}
void main()
{
	// Placa Generica - Implementacion del protocolo
	init();

	// Init del protocol
	initProtocol();

	// FOREVER
	while(true)
	{
		// Hace sus funciones...

		// Protocolo
		runProtocol(&command);
	}

	return;
}
void main()
{
	// Placa Generica - Implementacion del protocolo
	init();

	// Init del protocol
	initProtocol();

	// FOREVER
	while(true)
	{

		// Ejecucion de la maquina de estados
		switch (state)
		{
			case STATE_FREE:
				/*
				* Analiza los paquetes y retransmite o lanza el pedido de lectura
				*/
				
#if TRIGGER_TYPE == SWITCH_SENSOR
				// Enviar alarma de trigger
				if (triggerAlarm == 1)
					sendAlarm();
#endif

				// Protocolo
				runProtocol(&command);

				if (readSensor != 0x00)
				{
					// Almacena el pedido sobre los sensores
					actualReadSensor = readSensor;
					readSensor = 0x00;
					actalTO = requestFrom;
					actalCmd = requestCmd;
					// Cambio de estado
					state = STATE_START_READING;
				}	
				break;
			case STATE_START_READING:
				/*
				* Genera un pedido de lectura a los sensores que lo necesiten
				* y setea los TIMERs para contabilizar los tiempos
				*/
				
				// Limpio la variable
				bufferedReadSensor = 0x00;

				// Inhabilita los sensores enmascarados
				actualReadSensor &= sensorMask;
				
				// Pedido de -START-
				startReading(actualReadSensor);
				
				// Flag de interrupcion
				intTMR = 0;
				
				// Seteo de TIMERs
				set_timer1(SENSORS_WAITING_TIME);
				enable_interrupts(INT_TIMER1);
				
				// Cambio de estado
				state = STATE_WAIT_TO_READ;
				
				break;
			case STATE_WAIT_TO_READ:
				/*
				* Espera el tiempo necesario para tomar las muestras en los sensores
				* Recibe nuevos pedidos y los agraga para una proxima lectura
				*/

#if TRIGGER_TYPE == SWITCH_SENSOR
				// Enviar alarma de trigger
				if (triggerAlarm == 1)
					sendAlarm();
#endif

				// Protocolo
				runProtocol(&command);
				
				// Almacena el pedido sobre los sensores si no hay otro ya
				if ((readSensor != 0x00) && (bufferedReadSensor == 0x00))
				{
					bufferedReadSensor = readSensor;
					bufferedFrom = requestFrom;
					bufferedCmd = requestCmd;
					readSensor = 0x00;
				}
				
				// Cambio de estado?
				if (intTMR == 1)
				{
					// El TIMER1 hizo timeout -> leer sensores
					state = STATE_READ_VALUES;
				}	
				
				break;
			case STATE_READ_VALUES:
				/*
				* Toma las muestras en los sensores y envia el paquete de respuesta
				*/
				
				// Toma las muestras de los sensores
				readSensors(actualReadSensor);
				
				// Mandar paquete de respuesta
				sendValues(actalTO, actalCMD, values, actualReadSensor);
				
				// Flag de interrupcion
				intTMR = 0;
				
				// Setea el tiempo de espera y pasa al estado de espera
				set_timer1(WAITING_TIME);
				enable_interrupts(INT_TIMER1);
				
				state = STATE_WAITING;
				
				break;
			case STATE_WAITING:
				/*
				* Espera a que pase el tiempo de espera entre lecturas para evitar rebotes
				* Recibe nuevos pedidos y los agraga para una proxima lectura
				*/
				
#if TRIGGER_TYPE == SWITCH_SENSOR
				// Enviar alarma de trigger
				if (triggerAlarm == 1)
					sendAlarm();
#endif

				// Protocolo
				runProtocol(&command);
				
				// Almacena el pedido sobre los sensores si no hay otro ya
				if ((readSensor != 0x00) && (bufferedReadSensor == 0x00))
				{
					bufferedReadSensor = readSensor;
					bufferedFrom = requestFrom;
					bufferedCmd = requestCmd;
					readSensor = 0x00;
				}
				
				// Cambio de estado?
				if (intTMR == 1)
				{
					// El TIMER1 hizo timeout
					if (bufferedReadSensor != 0x00)
					{
						// Hay un pedido pendiente y lo carga
						actualReadSensor = bufferedReadSensor;
						bufferedReadSensor = 0x00;
						actalTO = bufferedFrom;
						actalCmd = bufferedCmd;
						// Cambio de estado 
						state = STATE_START_READING;
					} else {
						state = STATE_FREE;
					}	
				}

				break;
			default:
				init();
				break;
		}
	}

	return;
}