/* Giacomo Ortona this program will allow the communication between a linux processor and a at90can128 through serial door (ttyS1) print the received data on the screen and send them through tcp/ip to a server -it will ask every 2 seconds (default) to the at90can128 for communicate the temperatures values of all the devices and will print the received string on the screen -if no data is received, or there were errors reading the data, a warning will appear on the screen */ /* $id$ $Source: /home/giacomo/cvsroot/hadtempsens/serial_etrax/serialtrx.c,v $ $Header: /home/giacomo/cvsroot/hadtempsens/serial_etrax/serialtrx.c,v 1.8 2006/09/22 10:40:23 giacomo Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define SLEEP_TIME 2 #define BUFFSIZE 1503 /*WARNING: buf size must be at least num_devices*25+3, 1503 is enough for 60 devices*/ /*error function*/ void Die(char *mess) { perror(mess); exit(2); } /*this functions will wait for seconds.mseconds seconds or until some data is *received it will return the value of select(fdset,null,null,time), in fact it *will return: *0 if timeout occurs (no data received) *1 if data has been received *-1 if an error has occurred in function select. see man select for more info */ int input_timeout(int filedes,int seconds,int mseconds) { fd_set set; struct timeval timeout; /* Initialize the file descriptor set. */ FD_ZERO (&set); FD_SET (filedes, &set); /* Initialize the timeout data structure. */ timeout.tv_sec = seconds; timeout.tv_usec = mseconds; /* select returns 0 if timeout, 1 if input available, -1 if error. */ return select (FD_SETSIZE,&set, NULL, NULL,&timeout); } /* *this function will read a string of data, will print it on the screen and *send it to the server */ void PrintReceivedData (int fd, int sock){ char buf[BUFFSIZE]; int res=0; long int messagelen; /*this will read from the serial port, and print a string of data of res size on buf string*/ res = read(fd,(char *)buf,BUFFSIZE); /*this will print the data on the screen*/ printf("read %d char\n", res); if(res==-1) { /*read was unsuccesfull*/ printf("read unsuccesful\n"); buf[0]='\0'; } else { /*read succesful, add an eof at the end of buffer, needed for using printf*/ buf[res]='\0'; } /*print on the screen buf*/ printf("values read(printf): %s\n",buf); /*send the data on tcp/ip*/ messagelen = strlen(buf); if (send(sock, buf, messagelen, 0) != messagelen) { Die("Mismatch in number of sent bytes"); } } /* *the main will read from the serial port the temperature data, and will send *them to the server */ int main(int argc, char *argv[]) { int i = 0; int sock; struct sockaddr_in server; /* 4 arg needed*/ if (argc != 4) { fprintf(stderr, "USAGE: serial port TCP \n"); exit(3); } printf("number of command line arguments: %d\n",argc); for ( i=0; i>%s<<\n",i,argv[i]); } /* Create the TCP socket */ sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if ( sock < 0) { /*sock is like a file handle (fd)*/ Die("Failed to create socket"); } /*establish connection*/ /* Construct the server sockaddr_in structure */ memset(&server, 0, sizeof(server)); /* Clear struct */ server.sin_family = AF_INET; /* Internet/IP */ server.sin_addr.s_addr = inet_addr(argv[2]); /* IP address */ if(inet_addr(argv[2])==-1) { Die("invalip IP address"); } /*BETTER: USE INET_ATON INSTEAD OF INET_ADDR*/ server.sin_port = htons(atoi(argv[3])); /* server port */ /* Establish connection */ if (connect(sock,(struct sockaddr *)&server, sizeof(server)) < 0) { Die("Failed to connect with server"); } /*if failed in establishing connection, connect return -1*/ /* fd The returned file handle to the open port. -1 if an error occured device The path to the serial port (i.e /dev/ttyS0) O_RDWR Opens the port for reading and writing O_NOCTTY Opens the port without assuming full control O_NDELAY Ignore the DCD signal line */ char *DEVICE = argv[1]; //open the line FILE *out; int fd = open( DEVICE, O_RDWR | O_NOCTTY | O_NDELAY); if( fd == -1 ) { printf( "failed to open port\n" ); exit(1); } struct termios oldsettings,newsettings; int selretval; tcgetattr(fd, &oldsettings);/*save current serial port settings*/ bzero(&newsettings,sizeof(newsettings));/*clear the struct*/ /* CRTSCTS : output hardware flow control (only used if the cable has all necessary lines. See sect. 7 of Serial-HOWTO) CS8 : 8n1 (8bit,no parity,1 stopbit) CLOCAL : local connection, no modem contol CREAD : enable receiving characters CBAUDEX : enable baud higher then 9600 */ newsettings.c_cflag = B38400 | CS8 | CREAD | CLOCAL; /*only standards values for baud rate allowed. see /bits/termios.h for the defines and values*/ /* IGNPAR : ignore bytes with parity errors ICRNL : map CR to NL (otherwise a CR input on the other computer will not terminate input) otherwise make device raw (no other input processing) */ newsettings.c_iflag = IGNPAR | ICRNL; /* Raw output. */ newsettings.c_oflag = 0; /* ICANON : enable canonical input disable all echo functionality, and don't send signals to calling program */ newsettings.c_lflag = ICANON; /* now clean the modem line and activate the settings for the port */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newsettings); /* terminal settings done, now handle input*/ out = fopen ("readtemp.txt","w"); /* check if output was opened! */ if (out ==0) { printf("error opening file"); exit(-1); } char command; while (1) { /* loop until we have a terminating condition */ /* read blocks program execution until a line terminating character is input, even if more than 255 chars are input. If the number of characters read is smaller than the number of chars available, subsequent reads will return the remaining chars. res will be set to the actual number of characters actually read */ // command='a'; int received=-1; if ((received = recv(sock, &command, 1, 0)) < 0) { Die("Failed to receive command"); } i=0; i = write(fd,&command,1); /*if in this form write is not working, set up a switch(command)*/ if (i == -1) { printf("unable to write on port %s\n",DEVICE); } switch(command){ case 'a'|'A':{ } break; case 'b'|'B':{ uint8_t thigh,tlow; uint8_t numdev[8]; if ((received = recv(sock, &thigh, 8, 0)) < 0) { Die("Failed to receive upper limit"); } i=0; i = write(fd,&thigh,8); if (i == -1) { printf("unable to write on port %s\n",DEVICE); } if ((received = recv(sock, &tlow, 8, 0)) < 0) { Die("Failed to receive lower limit"); } i=0; i = write(fd,&tlow,8); if (i == -1) { printf("unable to write on port %s\n",DEVICE); } int q=0; for(q=0;q<8;q++){ if ((received = recv(sock, &numdev[q], 8, 0)) < 0) { Die("Failed to receive device's ID"); } i=0; i = write(fd,&numdev[q],8); if (i == -1) { printf("unable to write on port %s\n",DEVICE); } } } break; case 'c'|'C':{ } break; case 'd'|'D':{ tcsetattr(fd,TCSANOW,&oldsettings); close(sock); printf("server has closed the connection\n"); return 1; } break; default :{ } }//end of switch /* wait 5 seconds or until data is received */ selretval = input_timeout(fd, 5,0); if (selretval == -1){ /*error happened in select function*/ perror("select()"); exit(2); } if (selretval) { printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ /*this will read from the serial port, and print a string of data of res size on buf string*/ PrintReceivedData(fd,sock); } else { char buf[45] = "No data within five seconds. try again\n"; long int messagelen = strlen(buf); if (send(sock, buf, messagelen, 0) != messagelen) { Die("Mismatch in number of sent bytes"); } printf("No data within five seconds. try again\n"); } /* wait a short time*/ sleep(SLEEP_TIME); } // never reached /*restore the old port settings IF THIS IS NOT NEEDED; ALSO OLDSETTINGS ISN'T NEEDED*/ tcsetattr(fd,TCSANOW,&oldsettings); /* wrapup, closing the socket*/ // fprintf(stdout, "\n"); close(sock); return 0; }