int deserializar_imprimir_valor(void * buffer) {
	int valor = 0;

	t_header * head = deserializar_header(buffer);
	valor = head->tamanio;
	free(head);

	return valor;
}
예제 #2
0
파일: nivel.c 프로젝트: ignaciohugog/SISOP
void baja_de_personaje(char id_pj,t_nivel* nivel,ITEM_NIVEL** listaItems){
    log_info(logger, "Ejecutando [baja_de_personaje]...");
	t_list* recursos_a_orquestador = list_create();
    log_info(logger, "[baja_de_personaje] Cargando recursos a orquestador...");
	cargarRecursosAOrquestador(recursos_a_orquestador,id_pj,nivel->personajes_deadlock);

	//int* socket = socket_create_sin_puerto();
	int* socket = socket_create(15000, logger);
	log_trace(logger, "Procesando [conectarse_a_orquestador]...");

	 if (socket_connect_with_retry(socket, nivel->ip, nivel->puerto, logger) < 0) {
		log_error(logger, "[baja_de_personaje] No pudo conectar");
		exit(EXIT_FAILURE);
	}
	log_trace(logger, "Saliendo [baja_de_personaje]...");


	int id_nivel = parsear_nivel(nivel->nombre);
	t_stream* stream=lista_liberados_serialize(recursos_a_orquestador,id_nivel);
	log_info(logger, "[baja_de_personaje] Sending bytes...");
	sendBytes(socket,stream->data,stream->size, logger);

	log_info(logger, "[baja_de_personaje] Borrando item para id_pj=[%c]...", id_pj);
	BorrarItem(&nivel->lista_items,id_pj);

	liberarPersonaje(nivel->personajes_deadlock,id_pj);
	log_info(logger, "[baja_de_personaje] recibiendo del orquestador posibles personajes desbloqueados...");
	char* data=receiveBytes(socket,sizeof(int)*2, logger);
	if(data!=NULL){
	    log_info(logger, "[baja_de_personaje] Deserializando data...");
		t_header* header=(t_header*)deserializar_header(data);
		switch (header->tipo){
			case NO_LIBERE:
			{
			    log_info(logger, "[baja_de_personaje] Agregando a disponibles...");
				agregarDisponibles(listaItems,recursos_a_orquestador);
				break;
			}
			case LIBERADOS:
			{
			    log_info(logger, "[baja_de_personaje] Liberados -> Recibiendo del orquestador Personajes Desbloqueados...");
				data = receiveBytes(socket,header->tamanio, logger);
				char* personajes = deserializar_liberados(data);

				actualizarPersonajesYActualizarDisponibles(personajes,nivel->personajes_deadlock,recursos_a_orquestador,listaItems);
				break;
			}
		}
	}

	log_info(logger, "[baja_de_personaje] cerrando socket=[%d]...", *socket);
	socket_close(socket, logger);
	log_info(logger, "Saliendo [baja_de_personaje]...");
}
int deserializar_cambio_proceso(void * buffer) {
	t_header * head = deserializar_header(buffer);

	if (head->identificador != (uint8_t) 18) {
		puts("Error en el header **cambio_proceso_activo**");
		return -1;
	}
	int response = head->tamanio;

	free(head);
	return response;
}
int deserializar_fin_prog(void * buffer) {
	t_header * head = deserializar_header(buffer);

	if (head->identificador != (uint8_t) 13) {
		puts("Error en el header **fin_programa**");
		return -1;
	}
	int response = head->tamanio;

	free(head);
	return response;
}
int deserializar_tamanio_pagina(void * buffer) {
	t_header * head = deserializar_header(buffer);

	if (head->identificador != (uint8_t) 19) {
		puts("Error en el header **tamaño_pagina**");
		return -1;
	}

	int response = head->tamanio;

	free(head);
	return response;
}
t_header * recibir_header(int socket) {
	void * buffer = malloc(5);

	int result = recv(socket, buffer, 5, 0);

	if (result <= 0) {
		//puts("Error en el recv del header");
		return NULL;
	}

	t_header * header = deserializar_header(buffer);

	return header;
}
int recibir_handshake(int socket) {
	void * buffer = malloc(5);
	int handshake_id = 0;

	int result = recv(socket, buffer, 5, 0);

	if (result == -1) {
		puts("Error en el recv del handshake");
		return result;
	}
	if (result <= 0)
		return -1;

	t_header * header = deserializar_header(buffer);

	handshake_id = (int) header->identificador;
	free(header);

	return handshake_id;
}
예제 #8
0
void recibir_mensaje(t_th_parametros_receive *parametros) {
	t_th_parametros_receive *parametros_receive = parametros;
	int bytes_recibidos_header;
	int bytes_recibidos_payload;
	char buffer_header[sizeof(t_header)];
	int estoy_conectado = TRUE;

	while (estoy_conectado) {
		buffer_header[0] = '\0';

		// Recibo header
		if ((bytes_recibidos_header = recv(parametros_receive->socket_cliente,
				buffer_header, sizeof(t_header), 0)) == -1) {
			estoy_conectado = FALSE;
			perror("recv header");
			free(parametros);
			break;
		}

		// Verifico que el cliente no haya cerrado la conexion
		if (bytes_recibidos_header == 0) {
			perror("el socket cliente cerro la conexion\n");
			estoy_conectado = FALSE;
			break;
		} else {
			t_paquete *paquete = malloc(sizeof(t_paquete));

			paquete->header = malloc(sizeof(t_header));
			deserializar_header(buffer_header, paquete->header);

			if (paquete->header->longitud_mensaje > 0) {

				paquete->payload = malloc(paquete->header->longitud_mensaje);
				// Recibo payload
				if ((bytes_recibidos_payload = recv(
						parametros_receive->socket_cliente, paquete->payload,
						paquete->header->longitud_mensaje, 0)) == -1) {
					estoy_conectado = FALSE;
					perror("recv payload");
					break;
				}
			} else {
				//printf("\n payload vacio\n");
			}

			void (*fn)() = parametros_receive->funcion;

			//ACA PREGUNTO SI LOS PARAMETROS SON NULL

			if (parametros_receive->parametros_funcion != NULL) {

				fn(paquete, parametros_receive->socket_cliente,
						parametros_receive->parametros_funcion);

			} else {
				fn(paquete, parametros_receive->socket_cliente);
			}

			if (paquete->header->longitud_mensaje > 0) {
				free(paquete->payload);
			}
			free(paquete->header);
			free(paquete);
		}

	}

}
/*
 * La cola RR solo la agregamos por compatibilidad,
 * siempre va a ser un puntero a NULL.
 */
uint32_t atender_peticion_orquestador(uint32_t cliente, t_stream *pedido, t_queue_rr *cola_rr){

	/*t_stream *pedido;
	recibir(cliente, (void*)&pedido);
*/
	t_header header;
	deserializar_header(pedido, &header);
	int32_t pos_payload = sizeof(t_header);
	//char personajeElegido;
	switch (header.type){

	case HANDSHAKE_NUEVO_NIVEL:{

		uint32_t nro_nivel;
		uint32_t puerto;
		t_stream *payload = get_payload(pedido);
		memcpy(&nro_nivel,&payload[0],4);
		memcpy(&puerto,&payload[4],4);

		t_planificador *nodo_planificador;
		nodo_planificador = get_nodo_nivel(nro_nivel);
		//log_debug(logger_orq, "Hand_nuevo_nivel: dir nodo_planificador = %d", nodo_planificador);
		if(nodo_planificador == NULL){
			nodo_planificador = malloc(sizeof(t_planificador));
			nodo_planificador->tid=malloc(sizeof(pthread_t));
			nodo_planificador->nivel.direccion = malloc(sizeof(struct sockaddr_in));

			log_info(logger_orq, "Handshake_nuevo_nivel: Nueva conexión, nivel %d.", nro_nivel);
			completar_datos_nivel(nro_nivel, cliente, nodo_planificador);

			nodo_planificador->planificador.descriptor = 0;
			(nodo_planificador->nivel.direccion)->sin_port=htons(puerto);
			list_mutex_add(planificadores, (void*) nodo_planificador);
			sem_post(&semaforo_nodos_nuevos);
			free(pedido);
			return EXIT_SUCCESS;
		}
		log_info(logger_orq, "Se reconecta en nivel %d.", nro_nivel);
		completar_datos_nivel(nro_nivel, cliente, nodo_planificador);
		(nodo_planificador->nivel.direccion)->sin_port=htons(puerto);
		free(pedido);
		return EXIT_SUCCESS;
		}

	case HANDSHAKE_NUEVO_PJ:{

		int8_t simbolo_pj;
		t_stream *payload =get_payload(pedido);
		simbolo_pj = (int8_t)payload[0];
		log_info(logger_orq, "Handshake_nuevo_pj: Nueva conexión, pj %c", simbolo_pj);
		t_personaje_finalizado *pj;
		int pos_pj;
		pos_pj = get_pos_pj_finalizado(simbolo_pj);

		//Si todavía no está en la lista lo metemos.
		if(pos_pj == -1){
			log_debug(logger_orq, "Handshake_nuevo_pj: El pj no existía así que lo guardo en listo personajes_finalizados.");
			pj = malloc(sizeof(t_personaje_finalizado));
			pj->simbolo_pj = simbolo_pj;
			pj->termino_plan_de_niveles = false;
			log_debug(logger_orq, "Handshake_nuevo_pj: Guardo: Simbolo = %c  bool_fin = %d", pj->simbolo_pj, pj->termino_plan_de_niveles);
			list_mutex_add(personajes_finalizados, (void*)pj);
			t_personaje_finalizado *test_pj = list_mutex_get(personajes_finalizados, 0);
			log_debug(logger_orq,"Handshake_nuevo_pj: Guardé simbolo = %c, bool_fin = %d ", test_pj->simbolo_pj, test_pj->termino_plan_de_niveles);
		}
		else{
			pthread_mutex_lock(&personajes_finalizados->mutex);
			pj = list_get(personajes_finalizados->list, pos_pj);
			pj->termino_plan_de_niveles = false;
			pthread_mutex_unlock(&personajes_finalizados->mutex);
		}
		t_stream *stream_senial_ok;
		stream_senial_ok  = serializar_senial(OK);
		log_debug(logger_orq, "Handshake_nuevo_pj: Envío OK al pj recién conectado");
		enviar(cliente, stream_senial_ok);
		free(stream_senial_ok);
		free(pedido);
		return EXIT_SUCCESS;


	}

	case SOLICITUD_DATOS_NIVEL:{

		t_stream *payload = get_payload(pedido);
		int8_t simbolo_pj = payload[0];
		int8_t nro_nivel = payload[1];
	    t_datos_nivel datos_nivel;
	    datos_nivel.direccion_nivel[0] = '\0';
	    datos_nivel.direccion_planificador[0]='\0';
	    int resultado = get_datos_nivel(nro_nivel, &datos_nivel);

	    //Si el nivel no existe o si todavía no se lanzó su planificador asociado.
	    if(resultado == EXIT_FAILURE){
	    	char cadena_vacia = 'a';
	        t_stream *stream_nivel_no_existe = serializar_solicitud(NO_EXISTE_EL_NIVEL, sizeof(cadena_vacia), (t_stream*)&cadena_vacia);
	        log_info(logger_orq, "Sol_datos_nivel: El pj %c solicitó los datos del nivel %d pero el nivel aún no fue cargado.", simbolo_pj, nro_nivel);
	        enviar(cliente, (void*) stream_nivel_no_existe);
	        free(pedido);
	        free(stream_nivel_no_existe);
	        return EXIT_SUCCESS;
	    }
	   t_stream *stream_datos_nivel;
	   //En esta linea tira
	   stream_datos_nivel = serializar_datos_nivel(&datos_nivel);

	   log_debug(logger_orq,"Sol_datos_nivel: Datos del nivel solicitado: %s",datos_nivel.direccion_nivel);
	   log_debug(logger_orq, "Sol_datos_nivel: Datos del planificador solicitado: %s",datos_nivel.direccion_planificador);

	   log_info(logger_orq, "Sol_datos_nivel: El pj %c solicitó los datos del nivel %d. Se responde con los datos solicitados.", simbolo_pj, nro_nivel);
	   enviar(cliente, stream_datos_nivel);
	    free(stream_datos_nivel);
	    free(pedido);

	    return EXIT_SUCCESS;
	}

	case RECURSOS_LIBERADOS:{
			//Los recursos vienen en un string con formato HHHHFFFFMMMM,
			char *recursos = (char*) &pedido[pos_payload];
			uint32_t nro_nivel = get_nro_nivel(cliente);
			log_debug(logger_orq,"Recursos_liberados: Obteniendo socket_pair del planificador.");
			int32_t socket_pair_planificador = get_socket_pair_planificador(nro_nivel);
			log_debug(logger_orq,"Recursos_liberados: El socket pair es: %d", socket_pair_planificador);
			int32_t indice_recurso = 0;
			int8_t personaje_recurso[2];
			int8_t personaje_nro_nivel[2];
			log_info(logger_orq, "Recursos_liberados: El nivel %d liberó los recursos: %s ", nro_nivel, recursos);
			while(recursos[indice_recurso] != '\0'){
				//La función pasa a un pj de bloqueados a personajes_listos.
				int8_t simbolo_pj_desbloqueado = desbloquear_personaje(recursos[indice_recurso], nro_nivel);
				if (simbolo_pj_desbloqueado>0)
					log_info(logger_orq,"Recursos_liberados: PJ elegido para desbloquear: %c, recurso: %c", simbolo_pj_desbloqueado, recursos[indice_recurso]);
				else
					log_info(logger_orq,"Recursos_liberados: Ningún pj esperaba el recurso %c", recursos[indice_recurso]);

				//Si no hay un pj que necesite ese recurso, en lugar del símbolo del pj envía -1.
				personaje_recurso[0] = simbolo_pj_desbloqueado;
				personaje_recurso[1] = recursos[indice_recurso];
				t_stream *stream_pj_recurso = serializar_solicitud(DESBLOQUEAR_PERSONAJE, 2*sizeof(int8_t), (t_stream*) personaje_recurso);

				//Aviso al planificador para que lo saque de personajes_listo y lo ponga en cola_rr
				if(simbolo_pj_desbloqueado != -1){
					personaje_nro_nivel[0] = simbolo_pj_desbloqueado;
					personaje_nro_nivel[1] = (int8_t) nro_nivel;
					log_debug(logger_orq,"Recursos_liberados: Envio al planificador pj: %c, nro_nivel: %d", personaje_nro_nivel[0], personaje_nro_nivel[1]);
					t_stream *stream_pj_nro_nivel = serializar_solicitud(DESBLOQUEAR_PERSONAJE, 2*sizeof(int8_t), (t_stream*) personaje_nro_nivel);
					int test_result_sock_pair = enviar(socket_pair_planificador, (void*) stream_pj_nro_nivel);
					if(test_result_sock_pair == EXIT_FAILURE)
						log_error(logger_orq,"Recursos_liberados: Error al enviar mensaje al socket_pair (nro %d)del planificador ", socket_pair_planificador);
					else
						log_debug(logger_orq,"Recursos_liberados: Se envió el msj al socket_pair nro %d", socket_pair_planificador);

					free(stream_pj_nro_nivel);
				}

				log_debug(logger_orq,"Recursos_liberados: Envio al nivel pj: %c, recurso: %c  ", personaje_recurso[0], personaje_recurso[1]);
				enviar(cliente, (void*)stream_pj_recurso);
				free(stream_pj_recurso);
				//simbolo_pj_desbloqueado = desbloquear_personaje(recursos[indice_recurso], nro_nivel);
				indice_recurso++;

			}

			free(pedido);
			return EXIT_SUCCESS;
		}

	case FIN_PLAN_NIVELES:{
		t_stream *payload = get_payload(pedido);
		int8_t simbolo_pj = payload[0];
		log_info(logger_orq,"Fin_plan_niveles: El pj %c terminó su plan de niveles ", simbolo_pj);
		int pos_pj = get_pos_pj_finalizado(simbolo_pj);
		log_debug(logger_orq,"Fin_plan_niveles: Pos del pj finalizado = %d", pos_pj);
		t_personaje_finalizado *pj_finalizado = list_mutex_get(personajes_finalizados, pos_pj);
		pj_finalizado->termino_plan_de_niveles = true;
		if(todos_los_pj_terminaron()){

			log_info(logger_orq,"Fin_plan_niveles: Todos los pj finalizaron su plan de niveles.");

			solicitar_fin_ejecucion_planificadores();

			//Variable global que está en el while principal de todos los hilos.
			keep_running = false;
			estado_plataforma = false;
			sem_post(&semaforo_nodos_nuevos);
		}
		log_debug(logger_orq, "Fin_plan_niveles: FIN_PLAN_DE_NIVELES,case: retorno EXIT_SUCCESS;");
		free(pedido);
		return EXIT_SUCCESS;
	}
	case RECOVERY:{
		log_info(logger_orq, "Llegó pedido de recovery.");
		int8_t * personajesEnDeadlock = (int8_t*) &pedido[pos_payload];
		printf("Llegó string: %s \n", personajesEnDeadlock);
		log_info(logger_orq, "Los PJs involucrados en el interbloqueo son %s", personajesEnDeadlock);
		t_personaje_listo *personajeElegido;
		int index_pj = 0;

		//Este while es solo por contención, se supone el pj[0] siempre va a estar bloqueado.
		while(personajesEnDeadlock[index_pj] != '\0'){
			int8_t simbolo_pj = personajesEnDeadlock[index_pj];
			personajeElegido= list_remove_personaje(personajes_bloqueados, simbolo_pj);

			if(personajeElegido != NULL){
				log_info(logger_orq, "Recovery: Se da muerte al pj %c y se notifica al nivel.", personajeElegido->simbolo_pj);
				notificarPersonajeAsesinado(cliente, personajeElegido);
					if(index_pj != 0)
						log_info(logger_orq, "El pj asesinado estaba en la posición %d", index_pj);
				free(pedido);
				return EXIT_SUCCESS;
			}
			index_pj++;

		}
		log_error(logger_orq, "No se encontró ningún personaje para asesinar.");
		free(pedido);
		return EXIT_SUCCESS;


	}
	case HUBO_UNA_DESCONEXION:{
		log_info(logger_orq, "Hubo una desconexión.");
		free(pedido);
		return EXIT_SUCCESS;
	}


		log_warning(logger_orq, "Hubo_desconexión: Recibo petición de tipo desconocida");

		return EXIT_SUCCESS;

	}



/*
	case RECOVERY:{//todo: agregar al serializador
		//todo: matar_personaje, func q devuelve el nombre de pj asesinado.
		//char *nombre_personaje = matar_personaje();
		notificacion_pj_asesinado(cliente, nombre_personaje);
		free(nombre_personaje);
		free(pedido); //todo: poner free pedido fuera de atender_peticion()?
		return EXIT_SUCCESS;

	}*/



	return EXIT_SUCCESS;
}