Exemplo n.º 1
0
void rtm_get_ff(struct fins_module *module) {
	struct rtm_data *md = (struct rtm_data *) module->data;
	struct finsFrame *ff;

	do {
		secure_sem_wait(module->event_sem);
		secure_sem_wait(module->input_sem);
		ff = read_queue(module->input_queue);
		sem_post(module->input_sem);
	} while (module->state == FMS_RUNNING && ff == NULL && !md->interrupt_flag); //TODO change logic here, combine with switch_to_rtm?

	if (module->state != FMS_RUNNING) {
		if (ff != NULL) {
			freeFinsFrame(ff);
		}
		return;
	}

	if (ff != NULL) {
		if (ff->metaData == NULL) {
			PRINT_ERROR("Error fcf.metadata==NULL");
			exit(-1);
		}

		if (ff->dataOrCtrl == FF_CONTROL) {
			rtm_fcf(module, ff);
			PRINT_DEBUG("");
		} else if (ff->dataOrCtrl == FF_DATA) {
			if (ff->dataFrame.directionFlag == DIR_UP) {
				//rtm_in_fdf(module, ff);
				PRINT_WARN("todo error");
				freeFinsFrame(ff);
			} else if (ff->dataFrame.directionFlag == DIR_DOWN) {
				//rtm_out_fdf(module, ff);
				PRINT_WARN("todo error");
				freeFinsFrame(ff);
			} else {
				PRINT_ERROR("todo error");
				exit(-1);
			}
		} else {
			PRINT_ERROR("todo error");
			exit(-1);
		}
	} else if (md->interrupt_flag) {
		md->interrupt_flag = 0;

		rtm_interrupt(module); //TODO unused, implement or remove
	} else {
		PRINT_ERROR("todo error: dataOrCtrl=%u", ff->dataOrCtrl);
		exit(-1);
	}
}
Exemplo n.º 2
0
void rtm_set_param_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	secure_sem_wait(&md->shared_sem);
	struct rtm_command *cmd = (struct rtm_command *) list_find1(md->cmd_list, rtm_cmd_serial_test, &ff->ctrlFrame.serial_num);
	if (cmd != NULL) {
		list_remove(md->cmd_list, cmd);

		struct rtm_console *console = (struct rtm_console *) list_find1(md->console_list, rtm_console_id_test, &cmd->console_id);
		if (console != NULL) {
			//TODO extract answer
			if (ff->ctrlFrame.ret_val) {
				//send '' ?
				rtm_send_text(console->fd, "successful");
			} else {
				//send error
				rtm_send_text(console->fd, "unsuccessful");
			}
		} else {
			PRINT_ERROR("todo error");
		}
		sem_post(&md->shared_sem);

		free(cmd);
	} else {
		sem_post(&md->shared_sem);
		PRINT_ERROR("todo error");
		//TODO error, drop
		freeFinsFrame(ff);
	}
}
Exemplo n.º 3
0
void rtm_set_param_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	secure_sem_wait(&md->shared_sem);
	struct rtm_command *cmd = (struct rtm_command *) list_find1(md->cmd_list, rtm_cmd_serial_test, &ff->ctrlFrame.serial_num);
	if (cmd != NULL) {
		list_remove(md->cmd_list, cmd);

		struct rtm_console *console = (struct rtm_console *) list_find1(md->console_list, rtm_console_id_test, &cmd->console_id);
		if (console != NULL) {
			if (ff->ctrlFrame.ret_val == FCF_TRUE) {
				rtm_send_text(console->fd, "successful");
			} else {
				//send error
				uint32_t ret_msg;
				secure_metadata_readFromElement(ff->metaData, "ret_msg", &ret_msg);

				char temp[100];
				sprintf(temp, "unsuccessful, returned error=%u", ret_msg);
				rtm_send_text(console->fd, temp);
			}
		} else {
			PRINT_WARN("todo error");
		}
		sem_post(&md->shared_sem);

		free(cmd);
	} else {
		sem_post(&md->shared_sem);
		PRINT_WARN("todo error");
		//TODO error, drop
		freeFinsFrame(ff);
	}
}
Exemplo n.º 4
0
void *controller_thread(void *local) {
	struct pool_controller *controller = (struct pool_controller *) local;
	PRINT_DEBUG("Entered: id=%u, fd=%d", controller->id, controller->fd);

	int ret;
	uint64_t exp;

	//check worker num, inactive num, & queue len periodically, optimize values
	while (1) {
		ret = read(controller->fd, &exp, sizeof(uint64_t)); //blocking read
		if (!controller->running) {
			break;
		}

		if (ret != sizeof(uint64_t)) {
			//read error
			PRINT_ERROR("Read error: id=%d, fd=%d", controller->id, controller->fd);
			continue;
		}

		secure_sem_wait(&controller->pool->inactive_sem);
		if (list_is_empty(controller->pool->queue)) {
			//check if should reduce workers
			if (controller->pool->inactive_num) {
				double threads = floor(controller->pool->inactive_num / 2.0);
				//PRINT_DEBUG("workers=%u, inact=%u, queue=%u, space=%u, threads=%f", controller->pool->workers->len, controller->pool->inactive_num, controller->pool->queue->len, space, threads);
				if (threads > 0) {
					//pool_start(controller->pool, (uint32_t) threads);
				}
			} else {
				//do nothing
			}
		} else {
			if (controller->pool->queue->len > controller->pool->inactive_num) {
				uint32_t space = list_space(controller->pool->workers);
				double threads = ceil((controller->pool->queue->len - controller->pool->inactive_num) / 2.0);
				PRINT_DEBUG("workers=%u, inact=%u, queue=%u, space=%u, threads=%f",
						controller->pool->workers->len, controller->pool->inactive_num, controller->pool->queue->len, space, threads);
				if (space > 0) {
					if (threads < space) {
						pool_start(controller->pool, (uint32_t) threads);
					} else {
						pool_start(controller->pool, space);
					}
				}
			} else {
				//queue smaller than inactive, should be able to handle, increase timer rate?
				controller->period /= 2;
			}
		}

		//start_timer(controller->fd, controller->period); //TODO uncomment/fix this by using alert timers
		sem_post(&controller->pool->inactive_sem);
	}

	PRINT_DEBUG("Exited: id=%u", controller->id);
	return NULL;
}
Exemplo n.º 5
0
void ipv4_get_ff(struct fins_module *module) {
	struct finsFrame *ff;
	do {
		secure_sem_wait(module->event_sem);
		secure_sem_wait(module->input_sem);
		ff = read_queue(module->input_queue);
		sem_post(module->input_sem);
	} while (module->state == FMS_RUNNING && ff == NULL); //TODO change logic here, combine with switch_to_ipv4?

	if (module->state != FMS_RUNNING) {
		if (ff != NULL) {
			freeFinsFrame(ff);
		}
		return;
	}

	if (ff->metaData == NULL) {
		PRINT_ERROR("Error fcf.metadata==NULL");
		exit(-1);
	}

	if (ff->dataOrCtrl == FF_CONTROL) {
		ipv4_fcf(module, ff);
		PRINT_DEBUG("");
	} else if (ff->dataOrCtrl == FF_DATA) {
		if (ff->dataFrame.directionFlag == DIR_UP) {
			ipv4_in_fdf(module, ff);
			PRINT_DEBUG("");
		} else if (ff->dataFrame.directionFlag == DIR_DOWN) {
			ipv4_out_fdf(module, ff);
			PRINT_DEBUG("");
		} else {
			PRINT_ERROR("Error: Wrong value of fdf.directionFlag");
			exit(-1);
		}
	} else {
		PRINT_ERROR("Error: Wrong ff->dataOrCtrl value");
		exit(-1);
	}

}
Exemplo n.º 6
0
void *worker_thread(void *local) {
	struct pool_worker *worker = (struct pool_worker *) local;
	PRINT_DEBUG("Entered: id=%u", worker->id);

	while (1) {
		secure_sem_wait(worker->inactive_sem);
		PRINT_DEBUG("queue=%p", worker->queue);
		if (list_is_empty(worker->queue)) {
			*worker->inactive_num += 1;
			worker->inactive = 1;
			PRINT_DEBUG("inactive: worker=%p, inactive_num=%u", worker, *worker->inactive_num);
			sem_post(worker->inactive_sem);

			secure_sem_wait(&worker->activate_sem);
			if (!worker->running) {
				break;
			}
		} else {
			if (worker->running) {
				struct pool_request *request = (struct pool_request *) list_remove_front(worker->queue);
				worker->work = request->work;
				worker->local = request->local;

				PRINT_DEBUG("Freeing: request=%p", request);
				free(request);
				sem_post(worker->inactive_sem);
			} else {
				sem_post(worker->inactive_sem);
				break;
			}
		}

		worker->work(worker->local);
	}

	PRINT_DEBUG("Exited: id=%u", worker->id);
	return NULL;
}
Exemplo n.º 7
0
struct thread_pool *pool_create(uint32_t initial, uint32_t max, uint32_t limit) {
	PRINT_DEBUG("Entered: initial=%u, max=%u, limit=%u", initial, max, limit);

	struct thread_pool *pool = (struct thread_pool *) secure_malloc(sizeof(struct thread_pool));
	pool->workers = list_create(max);
	pool->queue = list_create(limit);
	sem_init(&pool->inactive_sem, 0, 1);
	pool->inactive_num = 0;
	pool->worker_count = 0;

	//pool->controller = controller_create(pool);

	secure_sem_wait(&pool->inactive_sem);
	pool_start(pool, initial);
	sem_post(&pool->inactive_sem);

	PRINT_DEBUG("Exited: initial=%u, max=%u, pool=%p", initial, max, pool);
	return pool;
}
Exemplo n.º 8
0
//Code to receive a finsFrame from the Switch
void rtm_get_ff(void) {
    int numBytes = 0;

    struct finsFrame *ff;
    do {
        secure_sem_wait(&Switch_to_RTM_Qsem);
        ff = read_queue(Switch_to_RTM_Queue);
        sem_post(&Switch_to_RTM_Qsem);
    } while (ff == NULL);

    if (ff->dataOrCtrl == CONTROL) { //CONTROL FF
        // send to something to deal with FCF
        //format: || Data/Control | Destination_IDs_List | SenderID | Write_parameter_Confirmation_Code | Serial_Number ||

        PRINT_DEBUG("send to CONTROL HANDLER !");
        PRINT_DEBUG("dataOrCtrl parameter has been set to %d", (int)(ff->dataOrCtrl));
        PRINT_DEBUG("destinationID parameter has been set to %d", (int)(ff->destinationID.id));
        PRINT_DEBUG("opcode parameter has been set to %d", ff->ctrlFrame.opcode);
        PRINT_DEBUG("senderID parameter has been set to %d", (int)(ff->ctrlFrame.senderID));

        //PRINT_DEBUG("serial_num parameter has been set to %d",ff->ctrlFrame.serial_num);

        //Currently it serializes and sends any Control Frame it receives over the rtm_out pipe
        rtm_out_fd = open(RTM_PIPE_OUT, O_RDWR); //should not be O_RDWR, should be WRITE ONLY

        //FOWARD CONFIRMATION FRAME TO CLICOMM
        //|| Data/Control | Destination_IDs_List | SenderID | Write_parameter_Confirmation_Code | Serial_Number ||
        // reimplement with the new serialize function
        numBytes = 0;
        numBytes += write(rtm_out_fd, &ff->dataOrCtrl, sizeof(unsigned char));
        numBytes += write(rtm_out_fd, &ff->destinationID.id, sizeof(unsigned char));
        numBytes += write(rtm_out_fd, &ff->ctrlFrame.senderID, sizeof(unsigned char));
        numBytes += write(rtm_out_fd, &ff->ctrlFrame.opcode, sizeof(unsigned short int));
        numBytes += write(rtm_out_fd, &ff->ctrlFrame.serial_num, sizeof(unsigned int));
        PRINT_DEBUG ("serial_num %d", ff->ctrlFrame.serial_num);

    } else //DATA FF
    {
        PRINT_DEBUG("Find out what to do with data frames");
    }

}
Exemplo n.º 9
0
//TODO remove? deprecated
int switch_register_module(struct fins_module *module, struct fins_module *new_mod) {
	PRINT_DEBUG("Entered: module=%p, new_mod=%p, id=%d, name='%s'", module, new_mod, new_mod->id, new_mod->name);
	struct switch_data *md = (struct switch_data *) module->data;

	if (new_mod->index >= MAX_MODULES) {
		PRINT_WARN("todo error");
		return -1;
	}

	secure_sem_wait(module->input_sem);
	if (md->overall->modules[new_mod->index] != NULL) {
		PRINT_IMPORTANT("Replacing: mod=%p, id=%d, name='%s'",
				md->overall->modules[new_mod->index], md->overall->modules[new_mod->index]->id, md->overall->modules[new_mod->index]->name);
	}
	PRINT_IMPORTANT("Registered: new_mod=%p, id=%d, name='%s'", new_mod, new_mod->id, new_mod->name);
	md->overall->modules[new_mod->index] = new_mod;
	sem_post(module->input_sem);

	PRINT_DEBUG("Exited: module=%p, new_mod=%p, id=%d, name='%s'", module, new_mod, new_mod->id, new_mod->name);
	return 0;
}
Exemplo n.º 10
0
void rtm_alert(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	//Get from fcf: module index, opcode==CTRL_ALERT, param_id

	secure_sem_wait(&md->shared_sem);
	//search for consoles with type==listener/dual, & registered for module index / param_id
	struct linked_list *listening_list = list_find_all2(md->console_list, rtm_console_listening_test, &ff->ctrlFrame.sender_id, &ff->ctrlFrame.param_id);

	//for each console push the traffic
	struct rtm_console *console;
	while (!list_is_empty(listening_list)) {
		console = (struct rtm_console *) list_remove_front(listening_list);
		rtm_send_fd(console->fd, ff->ctrlFrame.data_len, ff->ctrlFrame.data);
	}
	sem_post(&md->shared_sem);
	free(listening_list);

	freeFinsFrame(ff);
}
Exemplo n.º 11
0
//TODO remove? deprecated
int switch_unregister_module(struct fins_module *module, int index) {
	PRINT_DEBUG("Entered: module=%p, index=%d", module, index);
	struct switch_data *md = (struct switch_data *) module->data;

	if (index < 0 || index > MAX_MODULES) {
		PRINT_WARN("todo error");
		return 0;
	}

	secure_sem_wait(module->input_sem);
	if (md->overall->modules[index] != NULL) {
		PRINT_IMPORTANT("Unregistering: mod=%p, id=%d, name='%s'",
				md->overall->modules[index], md->overall->modules[index]->id, md->overall->modules[index]->name);
		md->overall->modules[index] = NULL;
	} else {
		PRINT_IMPORTANT("No module to unregister: index=%d", index);
	}
	sem_post(module->input_sem);

	return 1;
}
Exemplo n.º 12
0
void *accept_console(void *local) {
	struct fins_module *module = (struct fins_module *) local;
	PRINT_DEBUG("Entered: module=%p", module);
	PRINT_IMPORTANT("Thread started: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	struct rtm_data *md = (struct rtm_data *) module->data;

	int32_t addr_size = sizeof(struct sockaddr_un);
	struct sockaddr_un *addr;
	int console_fd;
	struct rtm_console *console;
	int i;

	secure_sem_wait(&md->shared_sem);
	while (module->state == FMS_RUNNING) {
		if (list_has_space(md->console_list)) {
			sem_post(&md->shared_sem);

			addr = (struct sockaddr_un *) secure_malloc(addr_size);
			while (module->state == FMS_RUNNING) {
				sleep(1);
				console_fd = accept(md->server_fd, (struct sockaddr *) addr, (socklen_t *) &addr_size);
				if (console_fd > 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
					break;
				}
			}
			if (module->state != FMS_RUNNING) {
				free(addr);

				secure_sem_wait(&md->shared_sem);
				break;
			}

			if (console_fd < 0) {
				PRINT_ERROR("accept error: server_fd=%d, console_fd=%d, errno=%u, str='%s'", md->server_fd, console_fd, errno, strerror(errno));
				free(addr);

				secure_sem_wait(&md->shared_sem);
				continue;
			}

			secure_sem_wait(&md->shared_sem);
			console = (struct rtm_console *) secure_malloc(sizeof(struct rtm_console));
			console->id = md->console_counter++;
			console->fd = console_fd;
			console->addr = addr;
			console->type = RTM_TYPE_DEFAULT;
			console->listeners = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(console->listeners);

			PRINT_IMPORTANT("Console created: id=%u, fd=%d, addr='%s', type=%u", console->id, console->fd, console->addr->sun_path, console->type);
			list_append(md->console_list, console);

			for (i = 0; i < MAX_CONSOLES; i++) {
				if (md->console_fds[i] == 0) {
					md->console_fds[i] = console_fd;
					break;
				}
			}
		} else {
			sem_post(&md->shared_sem);
			sleep(5);
			secure_sem_wait(&md->shared_sem);
		}
	}
	sem_post(&md->shared_sem);

	PRINT_IMPORTANT("Thread exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	PRINT_DEBUG("Exited: module=%p", module);
	return NULL;
}
Exemplo n.º 13
0
void *switch_loop(void *local) {
	struct fins_module *module = (struct fins_module *) local;
	PRINT_DEBUG("Entered: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	struct switch_data *md = (struct switch_data *) module->data;

	uint32_t i;
	int ret;
	//int32_t val;
	struct finsFrame *ff;
	//uint8_t index;

	int counter = 0;

	while (module->state == FMS_RUNNING) {
		secure_sem_wait(module->event_sem); //TODO uncomment, for testing
		//secure_sem_wait(module->input_sem);
		secure_sem_wait(&md->overall->sem);
		for (i = 0; i < MAX_MODULES; i++) {
			if (md->overall->modules[i] != NULL) {
				//helgrind says is race condition, though there will always be FF when post to event_sem
				if (!IsEmpty(md->overall->modules[i]->output_queue)) { //added as optimization
					/*
					 //can possibly cause switch to be "behind"
					 ret = sem_getvalue(md->overall->modules[i]->output_sem, &val);
					 if (ret) {
					 PRINT_ERROR("sem get value prob: src module_index=%u, ret=%d", i, ret);
					 exit(-1);
					 } //*/

					//if (val != 0) {
					while ((ret = sem_wait(md->overall->modules[i]->output_sem)) && errno == EINTR)
						;
					if (ret != 0) {
						PRINT_ERROR("sem wait prob: src module_index=%u, ret=%d", i, ret);
						exit(-1);
					}
					ff = read_queue(md->overall->modules[i]->output_queue);
					sem_post(md->overall->modules[i]->output_sem);

					//if (ff != NULL) { //shouldn't occur
					counter++;

					//index = ff->destinationID;
					if (ff->destinationID < 0 || ff->destinationID > MAX_MODULES) {
						PRINT_ERROR("dropping ff: illegal destination: src module_index=%u, dst module_index=%u, ff=%p, meta=%p",
								i, ff->destinationID, ff, ff->metaData);
						//TODO if FCF set ret_val=0 & return? or free or just exit(-1)?
						freeFinsFrame(ff);
					} else { //if (i != id) //TODO add this?
						if (md->overall->modules[ff->destinationID] != NULL) {
							PRINT_DEBUG("Counter=%d, from='%s', to='%s', ff=%p, meta=%p",
									counter, md->overall->modules[i]->name, md->overall->modules[ff->destinationID]->name, ff, ff->metaData);
							//TODO decide if should drop all traffic to switch input queues, or use that as linking table requests
							if (ff->destinationID == module->index) {
								switch_process_ff(module, ff);
							} else {
								while ((ret = sem_wait(md->overall->modules[ff->destinationID]->input_sem)) && errno == EINTR)
									;
								if (ret != 0) {
									PRINT_ERROR("sem wait prob: dst index=%u, ff=%p, meta=%p, ret=%d", ff->destinationID, ff, ff->metaData, ret);
									exit(-1);
								}
								if (write_queue(ff, md->overall->modules[ff->destinationID]->input_queue)) {
									sem_post(md->overall->modules[ff->destinationID]->event_sem);
									sem_post(md->overall->modules[ff->destinationID]->input_sem);
								} else {
									sem_post(md->overall->modules[ff->destinationID]->input_sem);
									PRINT_ERROR("Write queue error: dst index=%u, ff=%p, meta=%p", ff->destinationID, ff, ff->metaData);
									freeFinsFrame(ff);
								}
							}
						} else {
							PRINT_ERROR("dropping ff: destination not registered: src index=%u, dst index=%u, ff=%p, meta=%p",
									i, ff->destinationID, ff, ff->metaData);
							print_finsFrame(ff);
							//TODO if FCF set ret_val=0 & return? or free or just exit(-1)?
							freeFinsFrame(ff);
						}
						//}
						//}
					}
				}
			}
		}
		//sem_post(module->input_sem);
		sem_post(&md->overall->sem);
	}

	PRINT_DEBUG("Exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	return NULL;
}
Exemplo n.º 14
0
void rtm_read_param_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	secure_sem_wait(&md->shared_sem);
	struct rtm_command *cmd = (struct rtm_command *) list_find1(md->cmd_list, rtm_cmd_serial_test, &ff->ctrlFrame.serial_num);
	if (cmd != NULL) {
		list_remove(md->cmd_list, cmd);

		struct rtm_console *console = (struct rtm_console *) list_find1(md->console_list, rtm_console_id_test, &cmd->console_id);
		if (console != NULL) {
			//TODO extract answer
			if (ff->ctrlFrame.ret_val == FCF_TRUE) {
				char temp[100];

				int32_t val_int32;
				int64_t val_int64;
				float val_float;
				char *val_str;

				switch (cmd->param_type) {
				case META_TYPE_INT32:
					secure_metadata_readFromElement(ff->metaData, "value", &val_int32);
					sprintf(temp, "'%s'=%d", cmd->param_str, val_int32);
					break;
				case META_TYPE_INT64:
					secure_metadata_readFromElement(ff->metaData, "value", &val_int64);
					sprintf(temp, "'%s'=%lld", cmd->param_str, val_int64);
					break;
				case META_TYPE_FLOAT:
					secure_metadata_readFromElement(ff->metaData, "value", &val_float);
					sprintf(temp, "'%s'=%f", cmd->param_str, val_float);
					break;
				case META_TYPE_STRING:
					secure_metadata_readFromElement(ff->metaData, "value", &val_str);
					sprintf(temp, "'%s'='%s'", cmd->param_str, val_str);
					break;
				default:
					PRINT_ERROR("todo error");
					exit(-1);
				}

				rtm_send_text(console->fd, temp);
			} else {
				//send error
				uint32_t ret_msg;
				secure_metadata_readFromElement(ff->metaData, "ret_msg", &ret_msg);

				char temp[100];
				sprintf(temp, "unsuccessful, returned error=%u", ret_msg);
				rtm_send_text(console->fd, temp);
			}
		} else {
			PRINT_WARN("todo error");
		}
		sem_post(&md->shared_sem);

		free(cmd);
	} else {
		sem_post(&md->shared_sem);
		PRINT_WARN("todo error");
		//TODO error, drop
		freeFinsFrame(ff);
	}
}
Exemplo n.º 15
0
void *console_to_rtm(void *local) {
	struct fins_module *module = (struct fins_module *) local;
	PRINT_DEBUG("Entered: module=%p", module);
	PRINT_IMPORTANT("Thread started: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	struct rtm_data *md = (struct rtm_data *) module->data;

	int poll_num;
	struct pollfd poll_fds[MAX_CONSOLES];
	int time = 1;
	int ret;
	struct rtm_console *console;

	int i;
	for (i = 0; i < MAX_CONSOLES; i++) {
		poll_fds[i].events = POLLIN | POLLPRI | POLLRDNORM;
		//poll_fds[1].events = POLLIN | POLLPRI | POLLOUT | POLLERR | POLLHUP | POLLNVAL | POLLRDNORM | POLLRDBAND | POLLWRNORM | POLLWRBAND;
	}
	PRINT_DEBUG("events=0x%x", poll_fds[0].events);

	uint32_t cmd_len;
	uint8_t cmd_buf[MAX_CMD_LEN + 1];

	secure_sem_wait(&md->shared_sem);
	while (module->state == FMS_RUNNING) {
		poll_num = md->console_list->len;
		if (poll_num > 0) {
			for (i = 0; i < MAX_CONSOLES; i++) {
				if (md->console_fds[i] == 0) {
					poll_fds[i].fd = -1;
				} else {
					poll_fds[i].fd = md->console_fds[i];
				}
			}
			sem_post(&md->shared_sem);
			ret = poll(poll_fds, poll_num, time);
			secure_sem_wait(&md->shared_sem);
			if (ret < 0) {
				PRINT_ERROR("ret=%d, errno=%u, str='%s'", ret, errno, strerror(errno));
				break;
			} else if (ret > 0) {
				PRINT_DEBUG("poll: ret=%d", ret);

				for (i = 0; i < MAX_CONSOLES; i++) {
					if (poll_fds[i].fd > 0 && poll_fds[i].revents > 0) {
						if (1) {
							PRINT_DEBUG(
									"POLLIN=%d POLLPRI=%d POLLOUT=%d POLLERR=%d POLLHUP=%d POLLNVAL=%d POLLRDNORM=%d POLLRDBAND=%d POLLWRNORM=%d POLLWRBAND=%d",
									(poll_fds[i].revents & POLLIN) > 0, (poll_fds[i].revents & POLLPRI) > 0, (poll_fds[i].revents & POLLOUT) > 0, (poll_fds[i].revents & POLLERR) > 0, (poll_fds[i].revents & POLLHUP) > 0, (poll_fds[i].revents & POLLNVAL) > 0, (poll_fds[i].revents & POLLRDNORM) > 0, (poll_fds[i].revents & POLLRDBAND) > 0, (poll_fds[i].revents & POLLWRNORM) > 0, (poll_fds[i].revents & POLLWRBAND) > 0);
						}

						console = (struct rtm_console *) list_find1(md->console_list, rtm_console_fd_test, &poll_fds[i].fd);
						if (console != NULL) {
							if (poll_fds[i].revents & (POLLERR | POLLNVAL)) {
								//TODO ??
								PRINT_ERROR("todo: kinda error case that needs to be handled");
								list_remove(md->console_list, console);
								console_free(console);

								md->console_fds[i] = 0;
							} else if (poll_fds[i].revents & (POLLHUP)) {
								PRINT_IMPORTANT("Console closed: console=%p, id=%u", console, console->id);
								list_remove(md->console_list, console);
								console_free(console);

								md->console_fds[i] = 0;
							} else if (poll_fds[i].revents & (POLLIN | POLLRDNORM | POLLPRI | POLLRDBAND)) {
								cmd_len = (uint32_t) rtm_recv_fd(console->fd, MAX_CMD_LEN, cmd_buf);
								if (cmd_len != (uint32_t) -1) {
									cmd_buf[cmd_len] = '\0';
									rtm_process_cmd(module, console, cmd_len, cmd_buf);
								} else {
									PRINT_WARN("todo error");
								}
							}
						} else {
							PRINT_WARN("todo error");
							//console removed after poll started, before it returned, remove?
						}
					}
				}
			}
		} else {
			sem_post(&md->shared_sem);
			sleep(time);
			secure_sem_wait(&md->shared_sem);
		}
	}
	sem_post(&md->shared_sem);

	PRINT_IMPORTANT("Thread exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	PRINT_DEBUG("Exited: module=%p", module);
	return NULL;
}
Exemplo n.º 16
0
//RTM's main function
//Gets information from RTM_IN pipe
//Is started as a thread in core.c
void rtm_init(pthread_attr_t *fins_pthread_attr) {

    PRINT_IMPORTANT("RTM has started");

    /*
     //added to include code from fins_daemon.sh -- mrd015 !!!!! //TODO move this to RTM module
     if (mkfifo(RTM_PIPE_IN, 0777) != 0) {
     if (errno == EEXIST) {
     PRINT_DEBUG("mkfifo(" RTM_PIPE_IN ", 0777) already exists.");
     } else {
     PRINT_ERROR("mkfifo(" RTM_PIPE_IN ", 0777) failed.");
     exit(-1);
     }
     }
     if (mkfifo(RTM_PIPE_OUT, 0777) != 0) {
     if (errno == EEXIST) {
     PRINT_DEBUG("mkfifo(" RTM_PIPE_OUT ", 0777) already exists.");
     } else {
     PRINT_ERROR("mkfifo(" RTM_PIPE_OUT ", 0777) failed.");
     exit(-1);
     }
     }
     */

    //int datalen;
    int numBytes;
    //int val_len;
    int temp_serial_cntr = 0;
    unsigned char* serialized_FCF = NULL;
    int length_serialized_FCF;

    //create a finsframe to be sent tover the queue
    struct finsFrame *fins_frame = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));
    fins_frame->dataOrCtrl = CONTROL;

    //opens the pipe from clicomm (or wherever)
    rtm_in_fd = open(RTM_PIPE_IN, O_RDWR);

    if (rtm_in_fd == -1) {
        PRINT_DEBUG("rtm_in_fd Pipe failure ");
        exit(EXIT_FAILURE);
    }

    fflush(stdout);

    while (1) {
        temp_serial_cntr++; //used as a temporary serial_number generator

        //READ FROM PIPE RTM_IN
        numBytes = 0;
        numBytes += read(rtm_in_fd, &length_serialized_FCF, sizeof(int)); //length of incoming serialized FCF
        numBytes += read(rtm_in_fd, serialized_FCF, length_serialized_FCF); //incoming serialized FCF

        fins_frame = unserializeCtrlFrame(serialized_FCF, length_serialized_FCF);

        //value, Assumption was made, notice the size
        PRINT_DEBUG("received data");
        numBytes = 0;

        //ERROR Message
        fflush(stdout);
        if (numBytes >= 0) {
            PRINT_DEBUG("numBytes written %d", numBytes);
        }

        //CHANGE SenderID and SerialNum
        fins_frame->ctrlFrame.senderID = RTM_ID;
        fins_frame->ctrlFrame.serial_num = temp_serial_cntr;

        //SEND TO QUEUE
        secure_sem_wait(&RTM_to_Switch_Qsem);
        write_queue(fins_frame, RTM_to_Switch_Queue);
        sem_post(&RTM_to_Switch_Qsem);
        PRINT_DEBUG("sent data ");

        //READ FROM QUEUE
        rtm_get_ff();
    }
}
Exemplo n.º 17
0
int pool_execute(struct thread_pool *pool, void *(*work)(void *local), void *local) {
	PRINT_DEBUG("Entered: pool=%p, work=%p, local=%p", pool, work, local);

	secure_sem_wait(&pool->inactive_sem);
	PRINT_DEBUG("inactive_num=%u", pool->inactive_num);
	if (pool->inactive_num) {
		struct pool_worker *worker = (struct pool_worker *) list_find(pool->workers, worker_inactive_test);
		PRINT_DEBUG("found worker=%p", worker);
		if (worker != NULL) {
			pool->inactive_num--;

			worker->inactive = 0;
			worker->work = work;
			worker->local = local;
			PRINT_DEBUG("activating: worker=%p, inactive_num=%u", worker, *worker->inactive_num);
			sem_post(&worker->activate_sem);
			sem_post(&pool->inactive_sem);

			return 1;
		} else {
			PRINT_WARN("todo error");
			sem_post(&pool->inactive_sem);
			//TODO shouldn't be possible

			return 0;
		}
	} else {
		//TODO change to simply queue it, have controller optimize pool size
		//TODO have execute change queue size?
		if (list_has_space(pool->queue)) {
			struct pool_request *request = (struct pool_request *) secure_malloc(sizeof(struct pool_request));
			request->work = work;
			request->local = local;

			list_append(pool->queue, request);
			sem_post(&pool->inactive_sem);

			return 1;
		} else {
			sem_post(&pool->inactive_sem);

			return 0;
		}

		if (0) {
			if (list_has_space(pool->workers)) {
				PRINT_DEBUG("Starting new worker");
				struct pool_worker *worker = worker_create(&pool->inactive_sem, &pool->inactive_num, pool->queue, pool->worker_count++);
				list_append(pool->workers, worker);

				worker->work = work;
				worker->local = local;
				PRINT_DEBUG("activating: worker=%p, inactive_num=%u", worker, *worker->inactive_num);
				sem_post(&worker->activate_sem);
				sem_post(&pool->inactive_sem);

				//TODO wait? or do the find function again? etc preload it.

				return 1;
			} else {
				sem_post(&pool->inactive_sem);

				//TODO queue it? have finishing threads check queue?
				return 0;
			}
		}
	}
}