//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)
{
}
}
-
-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;
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;
}
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;
}
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);
static void mf624_register_device(void)
{
- printf("MF624 Loaded.\n");
pci_qdev_register(&mf624_info);
}