int main(int argc, char* argv[]){
	Cola<MensajeGenerico>* colaMaestra = new Cola<MensajeGenerico>(COLA_MAESTRA,0);
	MensajeGenerico msg;
	while(1){
		// RECIBO PEDIDO DE BROADCAST
		colaMaestra->leer(BROKER_BROADCAST_ID, &msg);
		std::cout << "RECIBI UN PEDIDO DE BROADCAST DE: " << msg.id << std::endl;
		
		// MANDO EL BROADCAST
		// ABRO ARCHIVO DE PROCESOS
		int fd = open(BROKER_PIDS_FILE, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
		// TOMO LOCK
		struct flock fl;
		fl.l_type=F_RDLCK;
    		fl.l_whence=SEEK_SET;
    		fl.l_start=0;
    		fl.l_len=0;
		fcntl(fd,F_SETLKW,&fl);

		Proceso p;
		while(read(fd,&p,sizeof(p)) > 0){
			if(!p.borrado && p.tipo == PUERTA){
				long id = p.id;
				msg.mtype = id;
				colaMaestra->escribir(msg);
				std::cout << "MANDO MENSAJE DE BROADCAST A: " << msg.mtype << std::endl;
			}
		}
		// DEVUELVO LOCK
		fl.l_type=F_UNLCK;
    		fcntl(fd,F_SETLK,&fl);
	}

	return 0;
}
int main (int argc, char** argv) try
{
	std::cout << "Iniciando componente..." << std::endl;

	int err;
	Cola<IPersonaMsg> mqComp (calcularRutaMQ (argv[0]), 1);
	long mtype = getpid ();

	IPersonaMsg msg;
	IPersonaMsg res;

	// Bloqueo en la cola hasta que haya una solicitud de operación
	err = mqComp.leer (mtype, &msg);
	System::check (err);

	std::cout << "[COMPONENTE] Se obtuvo solicitud: op "
			<< msg.op << std::endl;

	// Acá el componente lee de la red una petición a esta puerta
	// Simulamos que una persona quiere entrar
	// Enviamos la operación de solicitud de entrada
	res.mtype = msg.msg.spo.rtype;
	res.op = OP_SOLIC_ENTRAR_MUSEO_PERSONA;
	// Id de la persona que quiere entrar como se recibió de la red
	res.msg.osemp.idOrigen = 12345;
	err = mqComp.escribir (res);
	System::check (err);

	// Luego esperamos que responda la interfaz
	err = mqComp.leer (mtype, &msg);
	System::check (err);

	if (msg.op != NOTIF_ENTRADA_PERSONA) {
		std::cerr << "[COMPONENTE] Interfaz respondio con"
				" operación incorrecta " << msg.op
				<< std::endl;
		goto out;
	}

	std::cout << "[COMPONENTE] La interfaz respondio: op "
				<< msg.op << std::endl;
	std::cout << "[COMPONENTE] La interfaz respondio: res "
					<< msg.msg.nep.res << std::endl;

	// Acá el componente debería responder por la red al origen
	System::millisleep (2000);

	// Y despues volver al inicio
	// Aquí simulamos que la persona quiere salir

	// Espera por la próxima solicitud de la interfaz
	err = mqComp.leer (mtype, &msg);
	System::check (err);

	// Simulamos que una persona quiere salir

	// Enviamos la operación de solicitud de salida
	res.mtype = msg.msg.spo.rtype;
	res.op = OP_SOLIC_SALIR_MUSEO_PERSONA;
	// Id de la persona que quiere salir como se recibió de la red
	res.msg.ossmp.idOrigen = 12345;
	err = mqComp.escribir (res);
	System::check (err);

	// Luego esperamos que responda la interfaz
	err = mqComp.leer (mtype, &msg);
	System::check (err);

	if (msg.op != NOTIF_SALIDA_PERSONA) {
		std::cerr << "[COMPONENTE] Interfaz respondio con"
				" operación incorrecta " << msg.op
				<< std::endl;
		goto out;
	}

	std::cout << "[COMPONENTE] La interfaz respondio: op "
				<< msg.op << std::endl;
	std::cout << "[COMPONENTE] La interfaz respondio: res "
					<< msg.msg.nsp.res << std::endl;

	// Acá el componente debería responder por la red al origen
	System::millisleep (2000);

	// Fin de la simulación
	// Enviamos el cierre para que el test de la interfaz
	// termine.

out:
	// Envía notificación de cierre
	err = mqComp.leer (mtype, &msg);
	System::check (err);

	res.mtype = msg.msg.spo.rtype;
	res.op = OP_NOTIFICAR_CIERRE_MUSEO;
	err = mqComp.escribir (res);
	System::check (err);
	return 0;
} catch (...) {
	// try-catch para que se corran los destructores
	std::cerr << "[COMPONENTE] Error al correr la simulación."
			<< std::endl;
}
int main (int argc, char** argv)
{
	std::cout << "Iniciando componente..." << std::endl;

	Cola<IPuertaMsg> mqComp (calcularRutaMQ (argv[0]), 'A');
	long mtype = getpid ();
	IPuertaMsg msg = {};
	IPuertaMsg res = {};
	int err;

	std::cout << "Aceptando mensajes..." << std::endl;

	while (true) {
		err = mqComp.leer (mtype, &msg);
		System::check (err);

		switch (msg.op) {
		case OP_SOLIC_ENTRAR_MUSEO_PERSONA:
			// Este componente siempre deja entrar las personas
			std::cout << "Persona entrando por puerta "
				<< msg.msg.semp.idPuerta << std::endl;
			res.mtype = msg.msg.semp.rtype;
			res.op = NOTIF_ENTRADA_PERSONA;
			res.msg.nep.res = ENTRO;
			err = mqComp.escribir (res);
			System::check (err);
			break;
		case OP_SOLIC_ENTRAR_MUSEO_INVESTIGADOR:
			// Este componente guarda las pertenencias en el numero
			// de locker.
			std::cout << "Investigador entrando por puerta "
					<< msg.msg.semi.idPuerta
					<< " con pertenencias "
					<< msg.msg.semi.pertenencias << std::endl;
			res.mtype = msg.msg.semi.rtype;
			res.op = NOTIF_ENTRADA_INVESTIGADOR;
			res.msg.nei.res = ENTRO;
			res.msg.nei.numeroLocker = msg.msg.semi.pertenencias;
			err = mqComp.escribir (res);
			System::check (err);
			break;
		case OP_SOLIC_SALIR_MUSEO_PERSONA:
			// Responde que salió
			std::cout << "Persona saliendo por puerta "
					<< msg.msg.ssmp.idPuerta << std::endl;
			res.mtype = msg.msg.ssmp.rtype;
			res.op = NOTIF_SALIDA_PERSONA;
			res.msg.nsp.res = SALIO;
			err = mqComp.escribir (res);
			System::check (err);
			break;
		case OP_SOLIC_SALIR_MUSEO_INVESTIGADOR:
			// Devuelve las pertenencias que guardo en el
			// numero de locker.
			// No checkea puerta correcta
			std::cout << "Investigador saliendo por puerta "
					<< msg.msg.ssmi.idPuerta
					<< " con numero de locker "
					<< msg.msg.ssmi.numeroLocker << std::endl;
			res.mtype = msg.msg.ssmi.rtype;
			res.op = NOTIF_SALIDA_INVESTIGADOR;
			res.msg.nsi.res = SALIO;
			res.msg.nsi.pertenencias = msg.msg.ssmi.numeroLocker;
			err = mqComp.escribir (res);
			System::check (err);
			break;
		default:
			std::cerr << "Componente recibio mensaje inválido: "
				<< msg.op << std::endl;
		}
	}

	/* not reached */
	return 0;
}