| @@ -0,0 +1,335 @@ | ||
| #include "Network.h" | ||
| #include "elev.h" | ||
|
|
||
| void *listen_for_and_maintain_incomming_connections(void* net_status) | ||
| { | ||
| Network_status *my_net_status = (Network_status *) net_status; | ||
| struct sockaddr_in address; | ||
| int max_sd, sd, i, activity; | ||
| int new_socket; | ||
| int valread; | ||
| fd_set readfds; | ||
| int addrlen = sizeof address; | ||
|
|
||
| char buffer[sizeof(Network_status)]; | ||
|
|
||
| if(listen(my_net_status->master_socket, MAX_NUMBER_OF_ELEVS) < 0) { | ||
| perror("listen"); | ||
| exit(1); | ||
| } | ||
|
|
||
| while(1) { | ||
| FD_ZERO(&readfds); | ||
|
|
||
| FD_SET(my_net_status->master_socket, &readfds); | ||
| max_sd = my_net_status->master_socket; | ||
|
|
||
| for(i = 0; i < MAX_NUMBER_OF_ELEVS; i++) { | ||
| sd = my_net_status->client_sockets[i]; | ||
|
|
||
| if(sd > 0) { | ||
| FD_SET(sd, &readfds); | ||
| } | ||
|
|
||
| if( sd > max_sd) { | ||
| max_sd = sd; | ||
| } | ||
| } | ||
|
|
||
| activity = select(max_sd +1, &readfds, NULL, NULL, NULL); | ||
|
|
||
| if(FD_ISSET(my_net_status->master_socket, &readfds)) { | ||
| if((new_socket = accept(my_net_status->master_socket, (struct sockaddr *) &address, (socklen_t *)&addrlen)) <0) { | ||
| perror("accept"); | ||
| break; | ||
| } | ||
| printf("New elevator connected, socket fd is %d, ip is : %s, port %d\n", new_socket, inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); | ||
|
|
||
| for (i = 0; i < MAX_NUMBER_OF_ELEVS; i++) { | ||
| if( my_net_status->client_sockets[i] == 0 ) { | ||
| my_net_status->client_sockets[i] = new_socket; | ||
| my_net_status->active_connections += 1; | ||
| printf("Adding to list of sockets as %d\n" , i); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| for(i = 0; i < MAX_NUMBER_OF_ELEVS; i++) { | ||
| sd = my_net_status->client_sockets[i]; | ||
|
|
||
| if(FD_ISSET(sd, &readfds)) { | ||
| if((valread = read(sd, &buffer, 1024)) == 0) { | ||
| getpeername(sd , (struct sockaddr*)&address , (socklen_t*)&addrlen); | ||
| printf("Client disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); | ||
|
|
||
| //Close the socket and mark as 0 in list for reuse | ||
| close(sd); | ||
| my_net_status->client_sockets[i] = 0; | ||
| my_net_status->active_connections -= 1; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| int main_server() { | ||
| Network_status *net_status = malloc(sizeof(Network_status)); | ||
| pthread_t listen_for_clients; | ||
|
|
||
| net_status->master_socket = initialize_server_socket(); | ||
| pthread_mutex_init(&net_stat_lock, NULL); | ||
|
|
||
| pthread_create(&listen_for_clients, NULL, listen_for_and_maintain_incomming_connections, (void *) net_status); | ||
|
|
||
| pthread_join(listen_for_clients, NULL); | ||
|
|
||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| int main_client(char const *server_ip) { | ||
|
|
||
| int server_socket; | ||
| Elev_info *this_elevator = malloc(sizeof(Elev_info)); | ||
|
|
||
| pthread_mutex_init(&elev_info_lock, NULL); | ||
|
|
||
| elev_init(); | ||
| elev_set_motor_direction(DIRN_STOP); | ||
|
|
||
| this_elevator->current_floor = elev_get_floor_sensor_signal(); | ||
|
|
||
| this_elevator->is_busy = 0; | ||
| this_elevator->is_connected_to_network = 0; | ||
|
|
||
|
|
||
| while(1) { | ||
|
|
||
| if ((this_elevator->is_connected_to_network) == 0) { | ||
| printf("No network connection could be established\n"); | ||
| printf("Currently Running in single elevator mode\n"); | ||
| single_elevator_mode(this_elevator, &server_socket, server_ip); | ||
| this_elevator->is_connected_to_network = 1; | ||
| printf("Network connection established\n"); | ||
| printf("Switching to network mode\n"); | ||
| } | ||
|
|
||
| if (this_elevator->is_connected_to_network == 1) | ||
| { | ||
| printf("Elevator is now i network mode"); | ||
| //Hvis får ordre sender til server | ||
| //Mottar ordre | ||
| //Utfører Oppgave | ||
| //Oppgave utført | ||
| } | ||
| } | ||
|
|
||
| } | ||
|
|
||
| int wait_for_orders_from_server(int server_socket) { | ||
| return 0; | ||
|
|
||
| } | ||
|
|
||
|
|
||
|
|
||
| void *thread_recieve_orders_from_elevators(void *net_status) { | ||
| Network_status *my_net_status = (Network_status *) net_status; | ||
|
|
||
| int bytes_received, i; | ||
| int max_data_size = sizeof(Elev_info); | ||
| char buf[max_data_size]; | ||
|
|
||
| while(1){ | ||
| for(i = 0; i = (my_net_status->active_connections -1); i++) { | ||
| bytes_received = recv(my_net_status->client_sockets[i], buf, max_data_size -1, 0); | ||
| printf("%c\n", buf); | ||
| memset(&buf, 0, sizeof(buf)); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| } | ||
|
|
||
| int update_elevator_status() { | ||
| return 1; | ||
| } | ||
|
|
||
|
|
||
| int initialize_client_socket(char const* server_ip) { | ||
|
|
||
| int sockfd; | ||
| struct addrinfo hints, *servinfo, *p; | ||
| int rv; | ||
|
|
||
| memset(&hints, 0, sizeof hints); | ||
|
|
||
| hints.ai_family = AF_INET; | ||
| hints.ai_socktype = SOCK_STREAM; | ||
|
|
||
| if((rv = getaddrinfo(server_ip, PORT, &hints, &servinfo)) != 0) { | ||
| fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); | ||
| return 2; | ||
| } | ||
| for(p = servinfo; p != NULL; p = p->ai_next) { | ||
| if ((sockfd = socket(p->ai_family, p->ai_socktype, | ||
| p->ai_protocol)) == -1) { | ||
| perror("client: socket"); | ||
| continue; | ||
| } | ||
|
|
||
| if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { | ||
| freeaddrinfo(servinfo); | ||
| close(sockfd); | ||
| return 2; | ||
| } | ||
|
|
||
|
|
||
| break; | ||
| } | ||
|
|
||
| if(p == NULL) { | ||
| fprintf(stderr, "client: failed to connect\n"); | ||
| return 2; | ||
| } | ||
|
|
||
| printf("client: connecting\n"); | ||
|
|
||
| freeaddrinfo(servinfo); | ||
| return sockfd; | ||
| } | ||
|
|
||
|
|
||
| int initialize_server_socket() { | ||
|
|
||
| int rv, sockfd; | ||
| int yes = 1; | ||
| struct addrinfo hints, *servinfo, *p; | ||
|
|
||
|
|
||
| memset(&hints, 0, sizeof hints); | ||
| hints.ai_family = AF_INET; | ||
| hints.ai_socktype = SOCK_STREAM; | ||
| hints.ai_flags = AI_PASSIVE; | ||
|
|
||
| if((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { | ||
| fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); | ||
| return 1; | ||
| } | ||
|
|
||
| for(p = servinfo; p != NULL; p = p->ai_next) { | ||
| if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { | ||
| perror("server: socket"); | ||
| continue; | ||
| } | ||
|
|
||
| if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { | ||
| perror("setsockopt"); | ||
| return -1; | ||
| } | ||
|
|
||
| if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { | ||
| close(sockfd); | ||
| perror("server: bind"); | ||
| continue; | ||
| } | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| freeaddrinfo(servinfo); | ||
|
|
||
| return sockfd; | ||
| } | ||
|
|
||
| int sendall(int s, char *buf, int *len) | ||
| { | ||
| int total = 0; | ||
| int bytesleft = *len; | ||
| int n; | ||
|
|
||
| while(total < *len) { | ||
| n = send(s, buf+total, bytesleft,0); | ||
| if (n == -1) { | ||
| printf("Failed to send\n"); | ||
| break; | ||
| } | ||
| total += n; | ||
| bytesleft -=n; | ||
| } | ||
|
|
||
| *len = total; | ||
|
|
||
| return n==-1?-1:0; | ||
| } | ||
|
|
||
| /*void* listen_for_orders(void *sockfd) { | ||
| int bytes_received; | ||
| int length = 32; | ||
| char Server_reply[32]; | ||
| int MsgEl, MsgFloor; | ||
| while(1) | ||
| { | ||
| if ((bytes_received = recv(*(int*)sockfd, Server_reply, length, 0)) != 0) | ||
| { | ||
| sscanf(Server_reply, "<E%dF%d>", &MsgEl, &MsgFloor); | ||
| if (MsgEl == E.Num) | ||
| { | ||
| E.DesiredFloor = MsgFloor; | ||
| E.TaskComplete = 0; | ||
| printf("Pesant #%d, Move your ass to coal sector %d\n", MsgEl, MsgFloor); | ||
| } | ||
| else | ||
| { | ||
| printf("%d\n",bytes_received); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| * | ||
| char *get_string(int msgType) { | ||
| char *msg = (char*) malloc(10 * sizeof(int)); | ||
| if (msgType == 1){ | ||
| sprintf(msg, "<%dE%dF%d>", msgType, E.Num, E.CurrentFloor); | ||
| } | ||
| else if(msgType == 2){ | ||
| sprintf(msg, "<%dE%dF%d>", msgType, E.ButtonType, E.ButtonFloor); | ||
| sprintf(msg, "<%dE%dBT%dF%d>", msgType, E.Num, E.ButtonType, E.ButtonFloor); | ||
| } | ||
| return msg; | ||
| } | ||
| //SendMsg(int socket, int msgType), msgType 1 = job done, msgType 2 = button press. | ||
| void* send_message(void *sockfd) { | ||
| int msgType; | ||
| char *msg; | ||
| int len; | ||
| int bytes_sent; | ||
| while (1) { | ||
| if(E.TaskComplete == 1 || E.ButtonClick ==1 ){ | ||
| if (E.TaskComplete == 1) { | ||
| msgType = 1; | ||
| } | ||
| else if (E.ButtonClick == 1) { | ||
| msgType = 2; | ||
| E.ButtonClick = 0; | ||
| } | ||
| msg = get_string(msgType); | ||
| len = strlen(msg); | ||
| bytes_sent = send(*(int *)sockfd, msg, len, 0); | ||
| free(msg); | ||
| } | ||
| } | ||
| } | ||
| */ |
| @@ -0,0 +1,41 @@ | ||
|
|
||
| #include <assert.h> | ||
| #include <stdlib.h> | ||
|
|
||
| #include <stdio.h> | ||
| #include <unistd.h> | ||
| #include <pthread.h> | ||
|
|
||
| #include <sys/types.h> | ||
| #include <sys/socket.h> | ||
| #include <netdb.h> | ||
| #include <arpa/inet.h> | ||
| #include <netinet/in.h> | ||
| #include <string.h> | ||
|
|
||
| #define PORT "3492" | ||
| #define MAX_NUMBER_OF_ELEVS 3 | ||
| #define BACKLOG 10 | ||
|
|
||
| typedef struct { | ||
| int active_connections; | ||
| int client_sockets[MAX_NUMBER_OF_ELEVS]; | ||
| int master_socket; | ||
| } Network_status; | ||
|
|
||
| pthread_mutex_t net_stat_lock; | ||
|
|
||
|
|
||
| int main_server(); | ||
| int main_client(char const *server_ip); | ||
| int initialize_server_socket(); | ||
| int initialize_client_socket(char const *server_ip); | ||
| int wait_for_orders_from_server(int server_socket); | ||
| int update_elevator_status(); | ||
|
|
||
| //void* listen_for_orders(void *sockfd); | ||
| //char *get_string(int msgType); | ||
| //void Send_message(void *sockfd); | ||
| int sendall(int s, char *buf, int *len); | ||
| void *listen_for_and_maintain_incomming_connections(void* net_status); | ||
| void *thread_recieve_orders_from_elevator(void *net_status); |
| @@ -0,0 +1,64 @@ | ||
| #pragma once | ||
|
|
||
|
|
||
| //in port 4 | ||
| #define PORT_4_SUBDEVICE 3 | ||
| #define PORT_4_CHANNEL_OFFSET 16 | ||
| #define PORT_4_DIRECTION COMEDI_INPUT | ||
| #define OBSTRUCTION (0x300+23) | ||
| #define STOP (0x300+22) | ||
| #define BUTTON_COMMAND1 (0x300+21) | ||
| #define BUTTON_COMMAND2 (0x300+20) | ||
| #define BUTTON_COMMAND3 (0x300+19) | ||
| #define BUTTON_COMMAND4 (0x300+18) | ||
| #define BUTTON_UP1 (0x300+17) | ||
| #define BUTTON_UP2 (0x300+16) | ||
|
|
||
| //in port 1 | ||
| #define PORT_1_SUBDEVICE 2 | ||
| #define PORT_1_CHANNEL_OFFSET 0 | ||
| #define PORT_1_DIRECTION COMEDI_INPUT | ||
| #define BUTTON_DOWN2 (0x200+0) | ||
| #define BUTTON_UP3 (0x200+1) | ||
| #define BUTTON_DOWN3 (0x200+2) | ||
| #define BUTTON_DOWN4 (0x200+3) | ||
| #define SENSOR_FLOOR1 (0x200+4) | ||
| #define SENSOR_FLOOR2 (0x200+5) | ||
| #define SENSOR_FLOOR3 (0x200+6) | ||
| #define SENSOR_FLOOR4 (0x200+7) | ||
|
|
||
| //out port 3 | ||
| #define PORT_3_SUBDEVICE 3 | ||
| #define PORT_3_CHANNEL_OFFSET 8 | ||
| #define PORT_3_DIRECTION COMEDI_OUTPUT | ||
| #define MOTORDIR (0x300+15) | ||
| #define LIGHT_STOP (0x300+14) | ||
| #define LIGHT_COMMAND1 (0x300+13) | ||
| #define LIGHT_COMMAND2 (0x300+12) | ||
| #define LIGHT_COMMAND3 (0x300+11) | ||
| #define LIGHT_COMMAND4 (0x300+10) | ||
| #define LIGHT_UP1 (0x300+9) | ||
| #define LIGHT_UP2 (0x300+8) | ||
|
|
||
| //out port 2 | ||
| #define PORT_2_SUBDEVICE 3 | ||
| #define PORT_2_CHANNEL_OFFSET 0 | ||
| #define PORT_2_DIRECTION COMEDI_OUTPUT | ||
| #define LIGHT_DOWN2 (0x300+7) | ||
| #define LIGHT_UP3 (0x300+6) | ||
| #define LIGHT_DOWN3 (0x300+5) | ||
| #define LIGHT_DOWN4 (0x300+4) | ||
| #define LIGHT_DOOR_OPEN (0x300+3) | ||
| #define LIGHT_FLOOR_IND2 (0x300+1) | ||
| #define LIGHT_FLOOR_IND1 (0x300+0) | ||
|
|
||
| //out port 0 | ||
| #define MOTOR (0x100+0) | ||
|
|
||
| //non-existing ports (for alignment) | ||
| #define BUTTON_DOWN1 -1 | ||
| #define BUTTON_UP4 -1 | ||
| #define LIGHT_DOWN1 -1 | ||
| #define LIGHT_UP4 -1 | ||
|
|
||
|
|
| @@ -0,0 +1,157 @@ | ||
| #include "elev.h" | ||
| #include "channels.h" | ||
| #include "io.h" | ||
|
|
||
| #include <assert.h> | ||
| #include <stdlib.h> | ||
|
|
||
| #include <stdio.h> | ||
| #include <unistd.h> | ||
| #include <pthread.h> | ||
|
|
||
| #include <sys/types.h> | ||
| #include <sys/socket.h> | ||
| #include <netdb.h> | ||
|
|
||
| #include <arpa/inet.h> | ||
| #include <netinet/in.h> | ||
| #include <string.h> | ||
|
|
||
|
|
||
| #define MOTOR_SPEED 2800 | ||
|
|
||
|
|
||
| static const int lamp_channel_matrix[N_FLOORS][N_BUTTONS] = { | ||
| {LIGHT_UP1, LIGHT_DOWN1, LIGHT_COMMAND1}, | ||
| {LIGHT_UP2, LIGHT_DOWN2, LIGHT_COMMAND2}, | ||
| {LIGHT_UP3, LIGHT_DOWN3, LIGHT_COMMAND3}, | ||
| {LIGHT_UP4, LIGHT_DOWN4, LIGHT_COMMAND4}, | ||
| }; | ||
|
|
||
|
|
||
| static const int button_channel_matrix[N_FLOORS][N_BUTTONS] = { | ||
| {BUTTON_UP1, BUTTON_DOWN1, BUTTON_COMMAND1}, | ||
| {BUTTON_UP2, BUTTON_DOWN2, BUTTON_COMMAND2}, | ||
| {BUTTON_UP3, BUTTON_DOWN3, BUTTON_COMMAND3}, | ||
| {BUTTON_UP4, BUTTON_DOWN4, BUTTON_COMMAND4}, | ||
| }; | ||
|
|
||
|
|
||
| void elev_init(void) { | ||
| int init_success = io_init(); | ||
| assert(init_success && "Unable to initialize elevator hardware!" ); | ||
|
|
||
| for (int f = 0; f < N_FLOORS; f++) { | ||
| for (elev_button_type_t b = 0; b < N_BUTTONS; b++){ | ||
| elev_set_button_lamp(b, f, 0); | ||
| } | ||
| } | ||
|
|
||
| elev_set_stop_lamp(0); | ||
| elev_set_door_open_lamp(0); | ||
| elev_set_floor_indicator(0); | ||
| } | ||
|
|
||
|
|
||
| void elev_set_motor_direction(elev_motor_direction_t dirn) { | ||
| if (dirn == 0){ | ||
| io_write_analog(MOTOR, 0); | ||
| } else if (dirn > 0) { | ||
| io_clear_bit(MOTORDIR); | ||
| io_write_analog(MOTOR, MOTOR_SPEED); | ||
| } else if (dirn < 0) { | ||
| io_set_bit(MOTORDIR); | ||
| io_write_analog(MOTOR, MOTOR_SPEED); | ||
| } | ||
| } | ||
|
|
||
| void elev_set_button_lamp(elev_button_type_t button, int floor, int value) { | ||
| assert(floor >= 0); | ||
| assert(floor < N_FLOORS); | ||
| assert(button >= 0); | ||
| assert(button < N_BUTTONS); | ||
|
|
||
| if (value) { | ||
| io_set_bit(lamp_channel_matrix[floor][button]); | ||
| } else { | ||
| io_clear_bit(lamp_channel_matrix[floor][button]); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void elev_set_floor_indicator(int floor) { | ||
| //assert(floor >= 0); | ||
| //assert(floor < N_FLOORS); | ||
|
|
||
| // Binary encoding. One light must always be on. | ||
| if (floor & 0x02) { | ||
| io_set_bit(LIGHT_FLOOR_IND1); | ||
| } else { | ||
| io_clear_bit(LIGHT_FLOOR_IND1); | ||
| } | ||
|
|
||
| if (floor & 0x01) { | ||
| io_set_bit(LIGHT_FLOOR_IND2); | ||
| } else { | ||
| io_clear_bit(LIGHT_FLOOR_IND2); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void elev_set_door_open_lamp(int value) { | ||
| if (value) { | ||
| io_set_bit(LIGHT_DOOR_OPEN); | ||
| } else { | ||
| io_clear_bit(LIGHT_DOOR_OPEN); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void elev_set_stop_lamp(int value) { | ||
| if (value) { | ||
| io_set_bit(LIGHT_STOP); | ||
| } else { | ||
| io_clear_bit(LIGHT_STOP); | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| int elev_get_button_signal(elev_button_type_t button, int floor) { | ||
| assert(floor >= 0); | ||
| assert(floor < N_FLOORS); | ||
| assert(button >= 0); | ||
| assert(button < N_BUTTONS); | ||
|
|
||
|
|
||
| if (io_read_bit(button_channel_matrix[floor][button])) { | ||
| return 1; | ||
| } else { | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| int elev_get_floor_sensor_signal(void) { | ||
| if (io_read_bit(SENSOR_FLOOR1)) { | ||
| return 0; | ||
| } else if (io_read_bit(SENSOR_FLOOR2)) { | ||
| return 1; | ||
| } else if (io_read_bit(SENSOR_FLOOR3)) { | ||
| return 2; | ||
| } else if (io_read_bit(SENSOR_FLOOR4)) { | ||
| return 3; | ||
| } else { | ||
| return -1; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| int elev_get_stop_signal(void) { | ||
| return io_read_bit(STOP); | ||
| } | ||
|
|
||
|
|
||
| int elev_get_obstruction_signal(void) { | ||
| return io_read_bit(OBSTRUCTION); | ||
| } |
| @@ -0,0 +1,157 @@ | ||
| #include "elev.h" | ||
| #include "channels.h" | ||
| #include "io.h" | ||
|
|
||
| #include <assert.h> | ||
| #include <stdlib.h> | ||
|
|
||
| #include <stdio.h> | ||
| #include <unistd.h> | ||
| #include <pthread.h> | ||
|
|
||
| #include <sys/types.h> | ||
| #include <sys/socket.h> | ||
| #include <netdb.h> | ||
|
|
||
| #include <arpa/inet.h> | ||
| #include <netinet/in.h> | ||
| #include <string.h> | ||
|
|
||
|
|
||
| #define MOTOR_SPEED 2800 | ||
|
|
||
|
|
||
| static const int lamp_channel_matrix[N_FLOORS][N_BUTTONS] = { | ||
| {LIGHT_UP1, LIGHT_DOWN1, LIGHT_COMMAND1}, | ||
| {LIGHT_UP2, LIGHT_DOWN2, LIGHT_COMMAND2}, | ||
| {LIGHT_UP3, LIGHT_DOWN3, LIGHT_COMMAND3}, | ||
| {LIGHT_UP4, LIGHT_DOWN4, LIGHT_COMMAND4}, | ||
| }; | ||
|
|
||
|
|
||
| static const int button_channel_matrix[N_FLOORS][N_BUTTONS] = { | ||
| {BUTTON_UP1, BUTTON_DOWN1, BUTTON_COMMAND1}, | ||
| {BUTTON_UP2, BUTTON_DOWN2, BUTTON_COMMAND2}, | ||
| {BUTTON_UP3, BUTTON_DOWN3, BUTTON_COMMAND3}, | ||
| {BUTTON_UP4, BUTTON_DOWN4, BUTTON_COMMAND4}, | ||
| }; | ||
|
|
||
| //Basic functions below | ||
| void elev_init(void) { | ||
| int init_success = io_init(); | ||
| assert(init_success && "Unable to initialize elevator hardware!" ); | ||
|
|
||
| for (int f = 0; f < N_FLOORS; f++) { | ||
| for (elev_button_type_t b = 0; b < N_BUTTONS; b++){ | ||
| elev_set_button_lamp(b, f, 0); | ||
| } | ||
| } | ||
|
|
||
| elev_set_stop_lamp(0); | ||
| elev_set_door_open_lamp(0); | ||
| elev_set_floor_indicator(0); | ||
| } | ||
|
|
||
|
|
||
| void elev_set_motor_direction(elev_motor_direction_t dirn) { | ||
| if (dirn == 0){ | ||
| io_write_analog(MOTOR, 0); | ||
| } else if (dirn > 0) { | ||
| io_clear_bit(MOTORDIR); | ||
| io_write_analog(MOTOR, MOTOR_SPEED); | ||
| } else if (dirn < 0) { | ||
| io_set_bit(MOTORDIR); | ||
| io_write_analog(MOTOR, MOTOR_SPEED); | ||
| } | ||
| } | ||
|
|
||
| void elev_set_button_lamp(elev_button_type_t button, int floor, int value) { | ||
| assert(floor >= 0); | ||
| assert(floor < N_FLOORS); | ||
| assert(button >= 0); | ||
| assert(button < N_BUTTONS); | ||
|
|
||
| if (value) { | ||
| io_set_bit(lamp_channel_matrix[floor][button]); | ||
| } else { | ||
| io_clear_bit(lamp_channel_matrix[floor][button]); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void elev_set_floor_indicator(int floor) { | ||
| //assert(floor >= 0); | ||
| //assert(floor < N_FLOORS); | ||
|
|
||
| // Binary encoding. One light must always be on. | ||
| if (floor & 0x02) { | ||
| io_set_bit(LIGHT_FLOOR_IND1); | ||
| } else { | ||
| io_clear_bit(LIGHT_FLOOR_IND1); | ||
| } | ||
|
|
||
| if (floor & 0x01) { | ||
| io_set_bit(LIGHT_FLOOR_IND2); | ||
| } else { | ||
| io_clear_bit(LIGHT_FLOOR_IND2); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void elev_set_door_open_lamp(int value) { | ||
| if (value) { | ||
| io_set_bit(LIGHT_DOOR_OPEN); | ||
| } else { | ||
| io_clear_bit(LIGHT_DOOR_OPEN); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void elev_set_stop_lamp(int value) { | ||
| if (value) { | ||
| io_set_bit(LIGHT_STOP); | ||
| } else { | ||
| io_clear_bit(LIGHT_STOP); | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| int elev_get_button_signal(elev_button_type_t button, int floor) { | ||
| assert(floor >= 0); | ||
| assert(floor < N_FLOORS); | ||
| assert(button >= 0); | ||
| assert(button < N_BUTTONS); | ||
|
|
||
|
|
||
| if (io_read_bit(button_channel_matrix[floor][button])) { | ||
| return 1; | ||
| } else { | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| int elev_get_floor_sensor_signal(void) { | ||
| if (io_read_bit(SENSOR_FLOOR1)) { | ||
| return 0; | ||
| } else if (io_read_bit(SENSOR_FLOOR2)) { | ||
| return 1; | ||
| } else if (io_read_bit(SENSOR_FLOOR3)) { | ||
| return 2; | ||
| } else if (io_read_bit(SENSOR_FLOOR4)) { | ||
| return 3; | ||
| } else { | ||
| return -1; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| int elev_get_stop_signal(void) { | ||
| return io_read_bit(STOP); | ||
| } | ||
|
|
||
|
|
||
| int elev_get_obstruction_signal(void) { | ||
| return io_read_bit(OBSTRUCTION); | ||
| } |
| @@ -0,0 +1,65 @@ | ||
| #include <pthread.h> | ||
| // Wrapper for libComedi Elevator control. | ||
| // These functions provide an interface to the elevators in the real time lab | ||
|
|
||
|
|
||
| // Number of floors. Hardware-dependent, do not modify. | ||
| #define N_FLOORS 4 | ||
|
|
||
| // Number of buttons (and corresponding lamps) on a per-floor basis | ||
| #define N_BUTTONS 3 | ||
|
|
||
| #define DOOR_OPEN_TIME 1 | ||
|
|
||
| typedef enum tag_elev_motor_direction { | ||
| DIRN_DOWN = -1, | ||
| DIRN_STOP = 0, | ||
| DIRN_UP = 1 | ||
| } elev_motor_direction_t; | ||
|
|
||
| typedef enum tag_elev_lamp_type { | ||
| BUTTON_CALL_UP = 0, | ||
| BUTTON_CALL_DOWN = 1, | ||
| BUTTON_COMMAND = 2 | ||
| } elev_button_type_t; | ||
|
|
||
| typedef struct { | ||
| int num; | ||
| int desired_floor; | ||
| int current_floor; | ||
| int is_busy; | ||
| int button_click; | ||
| int button_floor; | ||
| int button_type; //0 = up, 1 = down, 2 = inside | ||
| int is_connected_to_network; | ||
| int server_socket; | ||
| } Elev_info; | ||
|
|
||
| pthread_mutex_t elev_info_lock; | ||
|
|
||
| int single_elevator_mode(Elev_info *this_elevator, int *server_socket, char const *server_ip); | ||
| int network_elevator_mode(Elev_info *this_elevator, int *server_socket, char const *server_ip); | ||
|
|
||
| int run_elevator(Elev_info *this_elevator); | ||
| int run_down_until_hit_floor(); | ||
| void *send_status_to_server(void* this_elevator); | ||
|
|
||
| void* listen_for_orders(void *sockfd); | ||
|
|
||
| void elev_init(void); | ||
|
|
||
| void* elev_go_to_floor(void *this_elevator); | ||
| void* listen_for_button_input(void *this_elevator); | ||
| int elev_hold_door_open(); | ||
|
|
||
| void elev_set_motor_direction(elev_motor_direction_t dirn); | ||
| void elev_set_button_lamp(elev_button_type_t button, int floor, int value); | ||
| void elev_set_floor_indicator(int floor); | ||
| void elev_set_door_open_lamp(int value); | ||
| void elev_set_stop_lamp(int value); | ||
|
|
||
|
|
||
| int elev_get_button_signal(elev_button_type_t button, int floor); | ||
| int elev_get_floor_sensor_signal(void); | ||
| int elev_get_stop_signal(void); | ||
| int elev_get_obstruction_signal(void); |
| @@ -0,0 +1,59 @@ | ||
| #include <comedilib.h> | ||
|
|
||
| #include "io.h" | ||
| #include "channels.h" | ||
|
|
||
|
|
||
| static comedi_t *it_g = NULL; | ||
|
|
||
|
|
||
| int io_init(void) { | ||
|
|
||
| it_g = comedi_open("/dev/comedi0"); | ||
|
|
||
| if (it_g == NULL) { | ||
| return 0; | ||
| } | ||
|
|
||
| int status = 0; | ||
| for (int i = 0; i < 8; i++) { | ||
| status |= comedi_dio_config(it_g, PORT_1_SUBDEVICE, i + PORT_1_CHANNEL_OFFSET, PORT_1_DIRECTION); | ||
| status |= comedi_dio_config(it_g, PORT_2_SUBDEVICE, i + PORT_2_CHANNEL_OFFSET, PORT_2_DIRECTION); | ||
| status |= comedi_dio_config(it_g, PORT_3_SUBDEVICE, i + PORT_3_CHANNEL_OFFSET, PORT_3_DIRECTION); | ||
| status |= comedi_dio_config(it_g, PORT_4_SUBDEVICE, i + PORT_4_CHANNEL_OFFSET, PORT_4_DIRECTION); | ||
| } | ||
|
|
||
| return (status == 0); | ||
| } | ||
|
|
||
|
|
||
| void io_set_bit(int channel) { | ||
| comedi_dio_write(it_g, channel >> 8, channel & 0xff, 1); | ||
| } | ||
|
|
||
|
|
||
| void io_clear_bit(int channel) { | ||
| comedi_dio_write(it_g, channel >> 8, channel & 0xff, 0); | ||
| } | ||
|
|
||
|
|
||
| void io_write_analog(int channel, int value) { | ||
| comedi_data_write(it_g, channel >> 8, channel & 0xff, 0, AREF_GROUND, value); | ||
| } | ||
|
|
||
|
|
||
| int io_read_bit(int channel) { | ||
| unsigned int data = 0; | ||
| comedi_dio_read(it_g, channel >> 8, channel & 0xff, &data); | ||
| return (int)data; | ||
| } | ||
|
|
||
|
|
||
| int io_read_analog(int channel) { | ||
| lsampl_t data = 0; | ||
| comedi_data_read(it_g, channel >> 8, channel & 0xff, 0, AREF_GROUND, &data); | ||
| return (int)data; | ||
| } | ||
|
|
||
|
|
||
|
|
| @@ -0,0 +1,13 @@ | ||
| #pragma once | ||
|
|
||
| // Returns 0 on init failure | ||
| int io_init(void); | ||
|
|
||
| void io_set_bit(int channel); | ||
| void io_clear_bit(int channel); | ||
|
|
||
| int io_read_bit(int channel); | ||
|
|
||
| int io_read_analog(int channel); | ||
| void io_write_analog(int channel, int value); | ||
|
|
| @@ -13,7 +13,6 @@ | ||
| #include <netinet/in.h> | ||
| #include <string.h> | ||
|
|
||
| #define PORT "3492" | ||
| #define MAX_NUMBER_OF_ELEVS 3 | ||
| #define BACKLOG 10 | ||
| @@ -0,0 +1 @@ | ||
| llvm-symbolizer-3.6 |