Commit bc7721e3 authored by Philip Levis's avatar Philip Levis
Browse files

Restructure the code so it's compiled and linked properly:

remove the networking directory.
parent 57954e91
......@@ -2,13 +2,23 @@ PROGRAMS = data_processor
all:: $(PROGRAMS)
CC = g++
CFLAGS = -I/usr/include/python3.6 -lpython3.6m -lpthread
CC = gcc
CPP = g++
CPPFLAGS = -I/usr/include/python3.6
LIBS = -lpython3.6m -lpthread
$(PROGRAMS): %:%.cc
$(CC) $@.cc $(CFLAGS) -o $@
$(PROGRAMS): fsimulator
fsimulator: fsimulator.o flight_server.o
$(CPP) -o $@ $^ $(LIBS) $(LIBS)
%.o: %.cc
$(CPP) $(CPPFLAGS) -c $< -o $@
%.o: %.c
$(CC) -c $< -o $@
clean::
rm -f $(PROGRAMS) *.o
rm -f $(PROGRAMS) *.o *~
.PHONY: clean all
// Server side C/C++ program from geeksforgeeks.org
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <poll.h>
#include <stdbool.h>
#include <mutex>
#include "flight_server.h"
#define PORT 4040
#define NUM_FLYERS 76
#define BODYLED 1
#define WINGLED 2
#define WINGANGLE 3
#define LEFT 1
#define RIGHT 0
struct flight_flyer flyerStates[NUM_FLYERS];
std::mutex flyerLock;
int flight_server_num_flyers() {
return NUM_FLYERS;
}
struct flight_flyer* flight_server_get_flyer(int which) {
if (which < 0 || which >= NUM_FLYERS) {
return NULL;
} else {
return &(flyerStates[which]);
}
}
int flight_server_start(){
int server_fd, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
//create 64 threads to listen to each FF
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
//pollfd contains one extra fd for the server to listen to new connections
struct pollfd fds[NUM_FLYERS+1];
for(int i = 0; i < NUM_FLYERS; i++){
int tempfd;
if ((tempfd = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
int id;
char message_recieved[1024] = {0};
//reads in message to id the connected FF
valread = read(tempfd, message_recieved, 1024);
sscanf(message_recieved,"%d",&id);
fds[id].fd = tempfd;
fds[i].events = POLLIN;
}
fds[NUM_FLYERS].fd = server_fd;
fds[NUM_FLYERS].events = POLLIN;
int total = NUM_FLYERS;
flyerLock.lock();
while(total != 0){
bool change = false;
flyerLock.unlock();
int num = poll(fds,NUM_FLYERS+1,-1);
flyerLock.lock();
if(num == -1)
perror("poll");
else if(num == 0)
perror("timeout");
//loop over all FF + listen of connections
for(int i = 0; i < NUM_FLYERS+1; i++){
if (fds[i].revents & POLLIN) {
if(i == NUM_FLYERS){
int tempfd;
if ((tempfd = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
int id;
char message_recieved[1024] = {0};
//reads in message to id the connected FF
valread = read(tempfd, message_recieved, 1024);
sscanf(message_recieved,"%d",&id);
//temperary code where simulator can request the flyer state
if(id == -1){
for(int j = 0; j < NUM_FLYERS; j++){
char output[1024] = {0};
sprintf(output,"\nFlyer:%d:%d\nBody:(%d,%d,%d)\nLeftWing:(%d,%d,%d):"
"(%d,%d,%d):(%d,%d,%d):Angle:%lf\nRightWing:(%d,%d,%d):"
"(%d,%d,%d):(%d,%d,%d):Angle:%lf\n\n",i,flyerStates[j].number,
flyerStates[j].body.red,flyerStates[j].body.green,
flyerStates[j].body.blue,flyerStates[j].leftWing.node1.red,
flyerStates[j].leftWing.node1.green,flyerStates[j].leftWing.node1.blue,
flyerStates[j].leftWing.node2.red,flyerStates[j].leftWing.node2.green,
flyerStates[j].leftWing.node2.blue,flyerStates[j].leftWing.node3.red,
flyerStates[j].leftWing.node3.green,flyerStates[j].leftWing.node3.blue,
flyerStates[j].leftWing.angle,flyerStates[j].rightWing.node1.red,
flyerStates[j].rightWing.node1.green,flyerStates[j].rightWing.node1.blue,
flyerStates[j].rightWing.node2.red,flyerStates[j].rightWing.node2.green,
flyerStates[j].rightWing.node2.blue,flyerStates[j].rightWing.node3.red,
flyerStates[j].rightWing.node3.green,flyerStates[j].rightWing.node3.blue,
flyerStates[j].rightWing.angle);
send(tempfd , output , strlen(output) , 0 );
}
send(tempfd, "EOF",strlen("EOF"),0);
close(tempfd);
}else{
fds[id].fd = tempfd;
//replaces old FF connection with new
printf("Opened FF %d\n",id);
}
break;
}
char message_recieved[1024] = {0};
const char *message_send = "Hello from server!!";
//close directory when you cant read anything
valread = read( fds[i].fd , message_recieved, 1024);
if(valread <= 0){
fds[i].fd = -1;
printf("Closed FF %d\n",i);
continue;
}
int temploc;
int tempCommand;
char tempRest[100];
sscanf(message_recieved,"%d:%d:%s",&temploc,&tempCommand,tempRest);
flyerStates[temploc].number = temploc;
change = true;
if(tempCommand == BODYLED){
struct flight_rgb rgbTemp;
sscanf(tempRest,"%d,%d,%d",&rgbTemp.red,&rgbTemp.green,&rgbTemp.blue);
flyerStates[temploc].body = rgbTemp;
}
else if(tempCommand == WINGLED){
struct flight_rgb rgbNode1Temp;
struct flight_rgb rgbNode2Temp;
struct flight_rgb rgbNode3Temp;
bool direction;
sscanf(tempRest,"%d:%d,%d,%d:%d,%d,%d:%d,%d,%d",
(int*)&direction,&rgbNode1Temp.red,&rgbNode1Temp.green,
&rgbNode1Temp.blue,&rgbNode2Temp.red,&rgbNode2Temp.green,
&rgbNode2Temp.blue,&rgbNode3Temp.red,&rgbNode3Temp.green,
&rgbNode3Temp.blue);
if (direction == LEFT){
flyerStates[temploc].leftWing.node1 = rgbNode1Temp;
flyerStates[temploc].leftWing.node2 = rgbNode2Temp;
flyerStates[temploc].leftWing.node3 = rgbNode3Temp;
}else{
flyerStates[temploc].rightWing.node1 = rgbNode1Temp;
flyerStates[temploc].rightWing.node2 = rgbNode2Temp;
flyerStates[temploc].rightWing.node3 = rgbNode3Temp;
}
}else if(tempCommand == WINGANGLE){
bool direction;
double angle;
sscanf(tempRest,"%d:%lf",(int*)&direction,&angle);
if(direction == LEFT){
flyerStates[temploc].leftWing.angle = angle;
}else{
flyerStates[temploc].rightWing.angle = angle;
}
}
//printf("Recieved message Len: %d\n",valread);
printf("Message Recieved: %s\n",message_recieved);
// send(fds[i].fd , message_send , strlen(message_send) , 0 );
// //printf("Sent message Len: %lu\n",strlen(message_send));
//printf("Message sent: %s\n",message_send);
}
}
if(change){
for(int i = 0; i < NUM_FLYERS; i++){
printf("\nFlyer:%d:%d\nBody:(%d,%d,%d)\nLeftWing:(%d,%d,%d):"
"(%d,%d,%d):(%d,%d,%d):Angle:%lf\nRightWing:(%d,%d,%d):"
"(%d,%d,%d):(%d,%d,%d):Angle:%lf\n\n",i,flyerStates[i].number,
flyerStates[i].body.red,flyerStates[i].body.green,
flyerStates[i].body.blue,flyerStates[i].leftWing.node1.red,
flyerStates[i].leftWing.node1.green,flyerStates[i].leftWing.node1.blue,
flyerStates[i].leftWing.node2.red,flyerStates[i].leftWing.node2.green,
flyerStates[i].leftWing.node2.blue,flyerStates[i].leftWing.node3.red,
flyerStates[i].leftWing.node3.green,flyerStates[i].leftWing.node3.blue,
flyerStates[i].leftWing.angle,flyerStates[i].rightWing.node1.red,
flyerStates[i].rightWing.node1.green,flyerStates[i].rightWing.node1.blue,
flyerStates[i].rightWing.node2.red,flyerStates[i].rightWing.node2.green,
flyerStates[i].rightWing.node2.blue,flyerStates[i].rightWing.node3.red,
flyerStates[i].rightWing.node3.green,flyerStates[i].rightWing.node3.blue,
flyerStates[i].rightWing.angle);
}
}
}
return 0;
}
#ifndef FLIGHT_SERVER_H
#define FLIGHT_SERVER_H
struct flight_rgb {
int red;
int green;
int blue;
};
struct flight_wing {
struct flight_rgb node1;
struct flight_rgb node2;
struct flight_rgb node3;
double angle;
};
struct flight_flyer {
int number;
struct flight_rgb body;
struct flight_wing leftWing;
struct flight_wing rightWing;
};
/*
* Starts the network server, which listens to commands from all
* of the Flyer Python interpreter processes and incorporates them
* into the current state of FLIGHT.
*/
int flight_server_start();
/* Returns the number of Fractal Flyers in the simulation. */
int flight_server_num_flyers();
/* Returns the state of a particular Fractal Flyer. Returns NULL if
* which is not a valid Fractal Flyer. */
struct flight_flyer* flight_server_get_flyer(int which);
#endif
......@@ -25,35 +25,33 @@
#include <sys/wait.h>
#include <mutex>
#include <sys/prctl.h>
#include "./../networking/server.c"
#include <thread>
#include "flight_server.h"
using namespace std;
#define NUM_FF NUM_FLYERS //Change to 76.
#define BUF_LENGTH 1000
/* https://stackoverflow.com/questions/23498654/read-from-a-named-pipe TODO(SD): For testing named pipe.
* and https://docs.python.org/2/extending/embedding.html for embedding python interpreter. */
struct flier {
struct flyer {
pid_t pid; //Pid associated with the flier's process.
};
char* directory = "/tmp/fractal_flyers";
static const char* directory = "/tmp/fractal_flyers";
flier fliers[NUM_FF];
pid_t server;
static int num_flyers;
static struct flyer* flyers;
static pid_t server;
/* Signal Handler run by server to shutdown any
* open FIFOS if not shutdown by parent on death
* of server
*/
static void end_process(int signo){
for (int i =0 ; i < NUM_FF; i++) {
static void end_process(int signo) {
for (int i =0 ; i < num_flyers; i++) {
char temparray[100];
sprintf(temparray,"%s/flyer%d",directory,i);
snprintf(temparray, 99, "%s/flyer%d",directory,i);
remove(temparray);
}
remove(directory);
......@@ -63,8 +61,7 @@ static void end_process(int signo){
/* Spawns each interpreter and runs code to
* define library functions in a local frame
*/
void spawn_process (int flier_num)
{
void spawn_process (int flier_num) {
prctl(PR_SET_PDEATHSIG, SIGKILL);
char initcode[256];
sprintf(initcode, "import simLib\n"
......@@ -96,9 +93,10 @@ void spawn_process (int flier_num)
}
/* Sets up a specific flier struct with its own named pipe. */
void create_fifo (int argc, char *argv[], int flier_num, struct flier &new_flier)
{
if(stat(directory, NULL)){
void create_fifo (int argc, char *argv[], int flier_num, struct flyer &new_flier)
{
struct stat statbuf;
if (stat(directory, &statbuf)) {
int temp = mkdir(directory,0777);
}
char temparray[100];
......@@ -106,14 +104,14 @@ void create_fifo (int argc, char *argv[], int flier_num, struct flier &new_flier
int fifo_ret = mkfifo(temparray, 0666);
}
struct flier spawn_new_flier(int argc, char *argv[], int flier_num)
struct flyer spawn_new_flier(int argc, char *argv[], int flyer_num)
{
struct flier new_flier;
create_fifo (argc, argv, flier_num, new_flier);
new_flier.pid = fork();
if(new_flier.pid == 0)
spawn_process (flier_num);
return new_flier;
struct flyer new_flyer;
create_fifo (argc, argv, flyer_num, new_flyer);
new_flyer.pid = fork();
if(new_flyer.pid == 0)
spawn_process (flyer_num);
return new_flyer;
}
/* Runs server to handle all the flyer requests
......@@ -121,9 +119,9 @@ struct flier spawn_new_flier(int argc, char *argv[], int flier_num)
pid_t spawn_server(){
pid_t pid = fork();
if(pid == 0){
signal(SIGTERM,end_process);
signal(SIGTERM, end_process);
prctl(PR_SET_PDEATHSIG, SIGTERM); //runs signal on death of parent
std::thread server (serverCode);
std::thread server (flight_server_start);
//supposed to call the simulator which has shared access to
//flyerStates and flyerLock
//std::thread sim (simCode);
......@@ -137,23 +135,23 @@ pid_t spawn_server(){
void create_data_pipeline(int argc, char *argv[])
{
server = spawn_server();
for (int i =0 ; i < NUM_FF; i++) {
fliers[i] = spawn_new_flier(argc, argv, i);
for (int i =0 ; i < num_flyers; i++) {
flyers[i] = spawn_new_flier(argc, argv, i);
}
}
/* Signal handler for main thread to kill all
* children and close the open FIFOs
*/
static void kill_all_processes(int signo){
for (int i =0 ; i < NUM_FF; i++) {
kill(fliers[i].pid,SIGKILL);
waitpid(fliers[i].pid,NULL,0);
for (int i =0 ; i < num_flyers; i++) {
kill(flyers[i].pid, SIGKILL);
waitpid(flyers[i].pid, NULL, 0);
char temparray[100];
sprintf(temparray,"%s/flyer%d",directory,i);
sprintf(temparray,"%s/flyer%d", directory, i);
remove(temparray);
}
kill(server,SIGKILL);
waitpid(server,NULL,0);
kill(server, SIGKILL);
waitpid(server, NULL, 0);
remove(directory);
exit(0);
}
......@@ -166,6 +164,9 @@ static void kill_all_processes(int signo){
//TODO(SD): Eventually define an init directory to pass into the process.
int main(int argc, char *argv[])
{
num_flyers = flight_server_num_flyers();
flyers = (struct flyer*)malloc(sizeof(struct flyer) * num_flyers);
create_data_pipeline(argc, argv);
signal(SIGINT,kill_all_processes);
signal(SIGTERM,kill_all_processes);
......@@ -179,22 +180,22 @@ int main(int argc, char *argv[])
cout << "k \tkills all processes" << endl
<< "r id \trestart fractal flyer with id" << endl
<< "h \thelp" << endl;
while(1){
while (1) {
scanf("%c",&command);
if(command == 'k'){
if (command == 'k') {
kill_all_processes(-1);
}else if(command == 'r'){
} else if(command == 'r') {
scanf(" %d",&flyer);
if(flyer >= NUM_FF){
if (flyer >= num_flyers || flyer < 0) {
printf("Invalid FF id\n");
continue;
}
kill(fliers[flyer].pid,SIGKILL);
fliers[flyer].pid = fork();
if(fliers[flyer].pid == 0){
kill(flyers[flyer].pid,SIGKILL);
flyers[flyer].pid = fork();
if (flyers[flyer].pid == 0) {
spawn_process(flyer);
}
}else if(command == 'h'){
} else if(command == 'h') {
cout << "k \tkills all processes" << endl;
cout << "r id \trestart fractal flyer with id" << endl;
cout << "h \thelp" << endl;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment