]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Sockets fixed
authorRostislav Lisovy <lisovy@gmail.com>
Fri, 15 Apr 2011 16:09:57 +0000 (18:09 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Fri, 15 Apr 2011 16:09:57 +0000 (18:09 +0200)
src/qemu/hw/mf624.c

index b75f69c5b76cb3e201e89d9bb551d5043ae7f03b..3b4c5db9c277f8f5e57d865a021eee7330438788 100755 (executable)
@@ -124,6 +124,8 @@ typedef struct {
                                        //Which value will come next
 } mf624_state_t;
 
+int instance = 0; // Global variable shared between multiple mf624 devices
+
 
 int16_t volts_to_adinternal(double volt)
 {
@@ -181,40 +183,75 @@ void socket_write(mf624_state_t *s, const char* reg, unsigned int val)
        }
 }
 
-
-void* socket_accept(void* ptr)
+#define STRING_BUFF_SIZE       256
+void socket_read(mf624_state_t* dev)
 {
-       struct sockaddr_in addr_client;
-       mf624_state_t* dev = (mf624_state_t*) ptr;
+       // For parsing read instructions
+       char reg[STRING_BUFF_SIZE+1];
+       int val;
+       // For reading from socket
+       char read_buffer[STRING_BUFF_SIZE];
+       int received_length = 0;
+       int status;
+
 
        while(1) {
-               printf("Waiting on port %d for MF624 client to connect\n", dev->port);
-               socklen_t len_client = sizeof(addr_client);
-               dev->socket_tmp = accept(dev->socket_srv, (struct sockaddr*) &addr_client, &len_client);
-               if (dev->socket_tmp == -1) {
-                       perror("accept()");
+               memset(read_buffer, '\0', STRING_BUFF_SIZE);
+               received_length = read(dev->socket_tmp, read_buffer, STRING_BUFF_SIZE-1);
+               if (received_length < 0) {
+                       perror("read()");
+                       return;
+               }
+               
+               if (received_length == 0) {
+                       printf("Error while reading from socket. Client disconnected?\n");
+                       return;
+               }
+
+               // REG has "same size +1" as READ_BUFFER to avoid buffer overflow
+               status = sscanf(read_buffer, "%[A-Z0-9]=%d", reg, &val);
+               if (status == 2) {
+                       if(!strcmp(reg, "DIN")) {
+                               dev->BAR2.DIN = val;
+                       }
+                       else if(!strcmp(reg, "ADC0")) {
+                               dev->real_world_AD0 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC1")) {
+                               dev->real_world_AD1 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC2")) {
+                               dev->real_world_AD2 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC3")) {
+                               dev->real_world_AD3 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC4")) {
+                               dev->real_world_AD4 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC5")) {
+                               dev->real_world_AD5 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC6")) {
+                               dev->real_world_AD6 = volts_to_adinternal(val);
+                       }
+                       else if(!strcmp(reg, "ADC7")) {
+                               dev->real_world_AD7 = volts_to_adinternal(val);
+                       }
+                       else {
+                               printf("reg = %s; val = %d\n", reg, val);
+                       } 
                }
-               printf("Client connected\n");
        }
 }
 
 
 void* init_socket(void* ptr)
 {
-#define STRING_BUFF_SIZE       256
-       // Socket stuff
+       struct sockaddr_in addr_client;
        struct sockaddr_in addr_srv;
        int port;
        int yes = 1;
-       // For reading from socket
-       char read_buffer[STRING_BUFF_SIZE];
-       int received_length = 0;
-       // For parsing read instructions
-       char reg[STRING_BUFF_SIZE+1];
-       int val;
-       // ----
-       int status;
-       QemuThread socket_accept_thread;
 
        
        mf624_state_t* dev = (mf624_state_t*) ptr;
@@ -225,12 +262,12 @@ void* init_socket(void* ptr)
        dev->socket_srv = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (dev->socket_srv == -1) {
                perror("socket()");
-               goto exit;
+               return NULL;
        }
        
        if (setsockopt(dev->socket_srv, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
                perror("setsockopt()");
-               goto exit;
+               return NULL;
        }
 
 
@@ -241,77 +278,31 @@ void* init_socket(void* ptr)
        addr_srv.sin_port = htons(port);
        if(bind(dev->socket_srv, (struct sockaddr*) &addr_srv, len) == -1) {
                perror("bind()");
-               goto exit;
+               return NULL;
        }
        
        if (listen(dev->socket_srv, 5) == -1) {
                perror("listen()");
-               goto exit;
+               return NULL;
        }
 
 
-       qemu_thread_create(&socket_accept_thread, socket_accept, (void*) ptr);
-
-
-       memset(read_buffer, '\0', STRING_BUFF_SIZE);
        while(1) {
-               if (dev->socket_tmp > 0) {
-                       received_length = read(dev->socket_tmp, read_buffer, STRING_BUFF_SIZE-1);
-                       if (received_length < 0) {
-                               perror("read()");
-                               goto exit_close;
-                       }
-                       
-                       if (received_length == 0) {
-                               printf("Error while reading from socket. Client disconnected?\n");
-                               //FIXME For client it is not possible to reconnect
-                               goto exit_close;
-                       }
-
-                       // REG has "same size +1" as READ_BUFFER to avoid buffer overflow
-                       status = sscanf(read_buffer, "%[A-Z0-9]=%d", reg, &val);
-                       if (status == 2) {
-                               if(!strcmp(reg, "DIN")) {
-                                       dev->BAR2.DIN = val;
-                               }
-                               else if(!strcmp(reg, "ADC0")) {
-                                       dev->real_world_AD0 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC1")) {
-                                       dev->real_world_AD1 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC2")) {
-                                       dev->real_world_AD2 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC3")) {
-                                       dev->real_world_AD3 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC4")) {
-                                       dev->real_world_AD4 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC5")) {
-                                       dev->real_world_AD5 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC6")) {
-                                       dev->real_world_AD6 = volts_to_adinternal(val);
-                               }
-                               else if(!strcmp(reg, "ADC7")) {
-                                       dev->real_world_AD7 = volts_to_adinternal(val);
-                               }
-                               else {
-                                       printf("reg = %s; val = %d\n", reg, val);
-                               } 
-                       }
-               }
-               else {
-                       sleep(1);
+               printf("Waiting on port %d for MF624 client to connect\n", dev->port);
+               socklen_t len_client = sizeof(addr_client);
+               dev->socket_tmp = accept(dev->socket_srv, (struct sockaddr*) &addr_client, &len_client);
+               if (dev->socket_tmp == -1) {
+                       perror("accept()");
                }
-       }
 
+               printf("Client connected\n");
+       
+               socket_read(dev); // should run forever if everything is OK; 
+                               // If error occurs (client disconnected), returns here
+               
+               close(dev->socket_tmp);
+       }
 
-exit_close:
-       close(dev->socket_tmp);
-exit:
        return NULL;
 }
 
@@ -644,15 +635,11 @@ static int pci_mf624_init(PCIDevice *pci_dev)
        mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev); //alocation of mf624_state_t
        uint8_t *pci_conf;
        QemuThread socket_thread;
-       //char options_buff[8];
 
-       //Parameters from command line
-       //if (get_param_value(options_buff, sizeof(options_buff), "port", opts)) {
-       //      s->port = atoi(options_buff);
-       //}
-       //else {
-               s->port = 55555; // Default port
-       //}
+       printf("MF624 Loaded.\n");
+
+       s->port = 55555 + instance; // Default port
+       instance ++;
 
        //Set all internal registers to default values
        mf624_init_registers(s);
@@ -718,7 +705,6 @@ static PCIDeviceInfo mf624_info = {
 
 static void mf624_register_device(void)
 {
-       printf("MF624 Loaded.\n");
        pci_qdev_register(&mf624_info);
 }