diff options
Diffstat (limited to 'src/ghdlserver/ghdlserver.c')
-rw-r--r-- | src/ghdlserver/ghdlserver.c | 666 |
1 files changed, 666 insertions, 0 deletions
diff --git a/src/ghdlserver/ghdlserver.c b/src/ghdlserver/ghdlserver.c new file mode 100644 index 0000000..0e5c887 --- /dev/null +++ b/src/ghdlserver/ghdlserver.c @@ -0,0 +1,666 @@ +#include <string.h> +#include "ghdlserver.h" +#include "uthash.h" +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <limits.h> +#include <time.h> + +#define _XOPEN_SOURCE 500 +#define MAX_NUMBER_PORT 100 +//#define LOG_FILE "vhpi.log" +//FILE *log_file = NULL; +//FILE *log_sock_id = NULL; +FILE *log_server = NULL; +#define z32__ "00000000000000000000000000000000" + +char* Out_Port_Array[MAX_NUMBER_PORT]; +int out_port_num=0; + +int vhpi_cycle_count =0; +//server socket +int server_socket_id=-1; +struct my_struct { + char val[1024]; + char key[1024]; //Key + UT_hash_handle hh; /* makes this structure hashable */ +}; + + +struct my_struct *s, *users ,*tmp = NULL; + +void parse_buffer(int sock_id,char* receive_buffer) +{ + /*Taking time information for log*/ + + //time_t systime; + //systime = time(NULL); + log_server=fopen("server.log","a"); + //fprintf(log_server,"Buffer came at %s \n",ctime(&systime)); + + fprintf(log_server,"Server-The recieved buffer is : %s \n",receive_buffer); + fprintf(log_server,"Server-The socket id is : %d \n",sock_id); + + /*Parsing buffer to store in hash table */ + char *rest; + char *token; + char *ptr1=receive_buffer; + + char *var; + char *value; + + + fprintf(stderr,"Server-The recieved buffer is : %s \n",receive_buffer); + fprintf(stderr,"Server-The socket id is : %d \n",sock_id); + while(token = strtok_r(ptr1,",",&rest)) + { + ptr1 = rest; // rest contains the left over part..assign it to ptr...and start tokenizing again. + + //Processing token again; + + while(var=strtok_r(token,":",&value)) + { + + s = (struct my_struct*)malloc(sizeof(struct my_struct)); + printf("Server-Variable is %s \n",var); + printf("Server-Value is %s \n",value); + + strncpy(s->key, var,10); + strncpy(s->val,value,10); + HASH_ADD_STR( users, key, s ); + break; + } + } + + s = (struct my_struct*)malloc(sizeof(struct my_struct)); + strncpy(s->key,"sock_id",10); + snprintf(s->val,10,"%d",sock_id); + HASH_ADD_STR(users,key,s); + fflush(log_server); + fclose(log_server); +} + + +void Vhpi_Set_Port_Value(char *port_name,char *port_value,int port_width) +{ + //char *lb; // you need to know maximum size of lb. + //int I; + //snprintf(lb,sizeof(char),"%s", port_value); + + printf("Server-Vhpi_Set_Port_value \n"); + printf("Server-The port name is %s \n",port_name); + + + //printf("Port valu is %s",port_value); + + s = (struct my_struct*)malloc(sizeof(struct my_struct)); + strncpy(s->key, port_name,10); + strncpy(s->val,port_value,10); + HASH_ADD_STR( users, key, s ); + + + printf("Server-The out port value is %s \n ",port_value); + + log_server=fopen("server.log","a"); + fprintf(log_server,"Set Port Details \n"); + fprintf(log_server,"Port Name - %s And Port Value - %s \n",port_name,port_value); + fflush(log_server); + fclose(log_server); + + +} + +void Vhpi_Get_Port_Value(char* port_name,char* port_value,int port_width) + +{ + + printf("Server-Vhpi_Get_Port_Value \n"); + //int I; + //snprintf(port_value,1024,"1"); + + log_server=fopen("server.log","a"); + fprintf(log_server,"Get Port Details \n"); + + HASH_FIND_STR(users,port_name,s); + if(s) + { + printf("Server-The key is %s and value is %s \n",s->key,s->val); + + snprintf(port_value,sizeof(port_value),"%s",s->val); + fprintf(log_server,"Port Name - %s And Port Value - %s \n",port_name,port_value); + HASH_DEL(users, s); + free(s); + } + else + { + printf("Server-Port %s Not found \n",port_name); + fprintf(log_server,"Port : %s not found \n",port_name); + } + + fflush(log_server); + fclose(log_server); +} +/* +int Copy_Value(char* dest, char* src, int width) +{ + int ret_val = 0; + char src_buf[4096]; + int src_width = 0; + + // skip spaces + while(*src == ' ') + src++; + while(1) + { + if(src[src_width] == '1' || src[src_width] == '0') + { + src_buf[src_width] = src[src_width]; + src_width++; + } + else + break; + } + src_buf[src_width] = 0; // null-terminate + ret_val = src_width - width; + dest[width] = 0; + int i; + for(i = 1; i <= width; i++) + { + if(i <= src_width) + dest[width-i] = src[src_width-i]; + else + dest[width-i] = '0'; // pad with 0. + } + + return(ret_val); +} + +*/ +/* +int extract_payload(char* receive_buffer,char* payload, int max_n) +{ + int hash_pos = 0; + int ret_val = 0; + while(receive_buffer[hash_pos] != '#') + { + printf("Buffer is %c \n",receive_buffer[hash_pos]); + if(receive_buffer[hash_pos] == 0) // end of string + { + hash_pos = -1; + break; + } + hash_pos++; + } + + if(hash_pos >= 0) + { + receive_buffer[hash_pos] = 0; + ret_val = max_n - (hash_pos+1); + bcopy(receive_buffer+(hash_pos+1),payload,ret_val); + } + + return(ret_val); +} +*/ + + +// +//Create Server to listen for message +// + +int create_server(int port_number,int max_connections) +{ + + + int sockfd; + struct sockaddr_in serv_addr; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + fprintf(stderr, "Server- Info: opening socket for server on port %d with socket id %d \n",port_number,sockfd); + if (sockfd < 0) + fprintf(stderr, "Server- Error: in opening socket on port %d\n", port_number); + + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(port_number); + + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + { + fprintf(stderr,"Server- Error: could not bind socket to port %d\n",port_number); + close(sockfd); + sockfd= -1; + } + else + fprintf(stderr,"Server- Info: finished binding socket to port %d\n",port_number); + // start listening on the server. + listen(sockfd,max_connections); + return sockfd; + +} + + +// +// ask the server to wait for a client connection +// and accept one connection if possible +// +// uses select to make this non-blocking. +// +// + +int connect_to_client(int server_fd) +{ + int ret_val = 1; + int newsockfd = -1; + socklen_t clilen; + struct sockaddr_in cli_addr; + fd_set c_set; + struct timeval time_limit; + time_limit.tv_sec = 0; + time_limit.tv_usec = 1000; + + clilen = sizeof(cli_addr); + FD_ZERO(&c_set); + FD_SET(server_fd,&c_set); + select(server_fd+1, &c_set,NULL,NULL,&time_limit); + if(FD_ISSET(server_fd,&c_set)) + { + newsockfd = accept(server_fd,(struct sockaddr *) &cli_addr,&clilen); + if (newsockfd >= 0) + { + fprintf(stderr,"Server- Info: new client connection %d \n",newsockfd); + } + else + { + fprintf(stderr,"Server- Info: failed in accept()\n"); + } + } + //else + //{ + // fprintf(stderr,"Server- failed to connect to client \n"); + //} + + return(newsockfd); +} + + +// +//use select to check if we can write to +// the socket.. +// + +int can_read_from_socket(int socket_id) +{ + struct timeval time_limit; + time_limit.tv_sec = 0; + time_limit.tv_usec = 1000; + + fd_set c_set; + FD_ZERO(&c_set); + FD_SET(socket_id,&c_set); + + int npending = select(socket_id + 1, &c_set, NULL,NULL,&time_limit); + + return(FD_ISSET(socket_id,&c_set)); +} + + +// +// use select to check if we can write to +// the socket.. +// + +int can_write_to_socket(int socket_id) +{ + struct timeval time_limit; + time_limit.tv_sec = 0; + time_limit.tv_usec = 1000; + + fd_set c_set; + FD_ZERO(&c_set); + FD_SET(socket_id,&c_set); + int npending = select(socket_id + 1, NULL, &c_set,NULL,&time_limit); + + return(FD_ISSET(socket_id,&c_set)); +} + + +//receive string from socket and put it inside buffer. + +int receive_string(int sock_id, char* buffer) +{ + int nbytes = 0; + + while(1) + { + if(can_read_from_socket(sock_id)) + break; + else + usleep(1000); + } + + nbytes = recv(sock_id,buffer,MAX_BUF_SIZE,0); + return(nbytes); +} + +// +// will establish a connection, send the +// packet and block till a response is obtained. +// socket will be closed after the response +// is obtained.. +// the buffer is used for the sent as well +// as the received data. +// + + +void set_non_blocking(int sock_id) +{ + int x; + x=fcntl(sock_id,F_GETFL,0); + fcntl(sock_id,F_SETFL,x | O_NONBLOCK); + fprintf(stderr,"Server- Setting server to non blocking state"); +} + + +void Vhpi_Initialize() +{ + + /*Taking time info for log*/ + time_t systime; + systime = time(NULL); + + log_server=fopen("server.log","a"); + //log_file=fopen("vhpi.log","a"); + + signal(SIGINT,Vhpi_Close); + signal(SIGTERM,Vhpi_Close); + + int try_limit = 100; + + while(try_limit > 0) + { + server_socket_id = create_server(DEFAULT_SERVER_PORT,DEFAULT_MAX_CONNECTIONS); + + if(server_socket_id > 0) + { + fprintf(stderr,"Server- Info:Success: Started the server on port %d\n",DEFAULT_SERVER_PORT); + fprintf(log_server,"Server -Started the server at port %d \n",DEFAULT_SERVER_PORT); + set_non_blocking(server_socket_id); + break; + + } + else + fprintf(stderr,"Server- Info:Could not start server on port %d,will try again\n",DEFAULT_SERVER_PORT); + + usleep(1000); + try_limit--; + + if(try_limit==0) + { + fprintf(stderr,"Server- Error:Tried to start server on port %d, failed..giving up \n",DEFAULT_SERVER_PORT); + exit(1); + } + + } + + //fprintf(log_server,"Setup completed on server side at %s ",ctime(&systime)); + fflush(log_server); + fclose(log_server); + + // + //Reading Output Port name and storing in Out_Port_Array; + // + char *line = NULL; + size_t len = 0; + ssize_t read; + char *token; + FILE *fp; + fp=fopen("connection_info.txt","r"); + + while ((read = getline(&line, &len, fp)) != -1) + { + if (strstr(line,"OUT") != NULL || strstr(line,"out") != NULL ) + { + strtok_r(line, " ",&token); + Out_Port_Array[out_port_num] = line; + out_port_num++; + } + line = (char *)malloc(sizeof(char)); + } + + + fprintf(stderr,"\n Server- Vhpi_Initialize finished \n"); + sleep(2); + fclose(fp); +} + +void Vhpi_Listen() +{ + char payload[4096]; + int payload_length; + vhpi_cycle_count++; + //#ifdef DEBUG + //fprintf(log_file,"Server- Info: listening in cycle %d\n", vhpi_cycle_count); + //fflush(log_file); + //#endif + int new_sock; + while(1) + { + if((new_sock = connect_to_client(server_socket_id)) > 0) + { + char receive_buffer[MAX_BUF_SIZE]; + fprintf(stderr,"Server- Info : waiting for client message \n"); + + //if the client has connected "just now" + // it must send something! + //#ifdef DEBUG + //fprintf(log_file,"Server- Info: waiting for message from client %d\n", new_sock); + //fflush(log_file); + //#endif + int n = receive_string(new_sock,receive_buffer); + + + if(n > 0) + { + + //payload_length = extract_payload(receive_buffer,payload,n); + //#ifdef DEBUG + //fprintf(log_file,"Info: received message from client %d: %s (payload-length=%d)\n",new_sock, receive_buffer,payload_length); + //fprintf(log_file,"Server- Info: received message from client %d : %s \n",new_sock,receive_buffer); + //fflush(log_file); + //#endif + + + if(strcmp(receive_buffer,"END")==0) + { + + log_server=fopen("server.log","a"); + fprintf(log_server,"Accept Server closing request \n"); + printf("Accept server closing request \n"); + fflush(log_server); + fclose(log_server); + Vhpi_Close(); + exit(0); + sleep(1); + //close(server_socket_id); + } + + else + { + parse_buffer(new_sock,receive_buffer); + + } + + //parse_buffer(new_sock,receive_buffer); + break; + } + + } + else + { + break; + } + } + //#ifdef DEBUG + //fprintf(log_file,"Server- Info: finished listening in cycle %d\n", vhpi_cycle_count); + //fflush(log_file); + //#endif +} + +// go down the list of finished jobs and send +// out the resulting port values.. +void Vhpi_Send() +{ + int sockid; + char* out; + //#ifdef DEBUG + //fprintf(log_file,"Server- Info: sending in cycle %d\n", vhpi_cycle_count); + //fflush(log_file); + //#endif + + log_server=fopen("server.log","a"); + + fprintf(stderr,"Server- Sending data to client \n"); + fprintf(log_server,"Sending data from server to client \n"); + HASH_FIND_STR(users,"sock_id",s); + if(s) + { + printf("Server- The key is %s and value is %s \n",s->key,s->val); + sockid=atoi(s->val); + //strncpy(sockid,10,atoi(s->val)); + //HASH_DEL(users, s); + //free(s); + } + else + { + printf("Server- The socket id not found in table \n"); + fprintf(log_server,"The socket id is not present in table \n"); + } + + //snprintf(sockid,sizeof(sockid),"%d",s->val); + + int i=0; + for (i=0;i<out_port_num;i++) + { + printf("The array out is %s \n",Out_Port_Array[i]); + fprintf(log_server,"The data is sending for output %s \n",Out_Port_Array[i]); + Data_Send(sockid,Out_Port_Array[i]); + } + + /* + HASH_FIND_STR(users,"o",s); + if(s) + { + printf("Server- The key is %s and value is %s \n",s->key,s->val); + printf("Server- s-val %s \n",s->val); + + //Count Digits in number + while(cpy>0) + { + rem[count_digits]=cpy%10; + count_digits++; + cpy=cpy/10; + } + + int c=0; + + //adds the difference of length as 0's + for(i=0;i<2-count_digits;i++) + new_str[c++]='0'; + + //appends rest of the string + for(i=count_digits-1;i>=0;i--) + new_str[c++]=rem[i]+48; + new_str[c++]='\0'; + + out=(char *)malloc(sizeof(char)); + snprintf(out,sizeof(out),"%s",s->val); + //HASH_DEL(users, s); + //free(s); + + while(1) + { + if(can_write_to_socket(sockid)) + break; + usleep(1000); + + } + + if ((send(sockid,out,sizeof(out),0))== -1) + { + perror("Server- Failure Sending Message\n"); + //exit(1); + } + + } + else + { + printf("Server- The key %s Not found \n",s->key); + } + + */ + + + //#ifdef DEBUG + //fprintf(log_file,"Server- Info: trying to send message %s in %d\n", send_buffer, vhpi_cycle_count); + //fflush(log_file); + //#endif + + fflush(log_server); + fclose(log_server); + +} + +void Data_Send(int sockid,char* out_port) +{ + char* out; + HASH_FIND_STR(users,out_port,s); + if(s) + { + printf("Server-Sending data has key:%s and value:%s \n",s->key,s->val); + fprintf(log_server,"Sending data has key:%s and value:%s \n",s->key,s->val); + out=(char *)malloc(sizeof(char)); + snprintf(out,sizeof(out),"%s",s->val); + //HASH_DEL(users, s); + //free(s); + while(1) + { + if(can_write_to_socket(sockid)) + break; + usleep(1000); + } + + if ((send(sockid,out,sizeof(out),0))== -1) + { + perror("Server- Failure Sending Message\n"); + exit(1); + } + } + else + { + printf("Server- The output port's %s value Not found \n",out_port); + fprintf(log_server,"The %s's value not found in the table \n",out_port); + } +} + +void Vhpi_Close() +{ + fprintf(stderr,"Server- Info: closing VHPI link\n"); + //fclose(log_file); + close(server_socket_id); + +} + +static void Vhpi_Exit(int sig) +{ + fprintf(stderr, "Server- *** Break! ***\n"); + fprintf(stderr,"Server- Info: Stopping the simulation \n"); + Vhpi_Close(); + exit(0); +} |