embedded_linux_comms.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016  
00017 
00018 #ifndef ROS_EMBEDDED_LINUX_COMMS_H
00019 #define ROS_EMBEDDED_LINUX_COMMS_H
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <fcntl.h>
00025 #include <errno.h>
00026 #include <termios.h>
00027 #include <string.h>
00028 #include <time.h>
00029 #include <stdint.h>
00030 #include <sys/types.h>
00031 #include <sys/socket.h>
00032 #include <netinet/in.h>
00033 #include <netinet/tcp.h>
00034 #include <netdb.h>
00035 #include <assert.h>
00036 
00037 #define DEFAULT_PORTNUM 11411
00038 
00039 void error(const char *msg)
00040 {
00041   perror(msg);
00042   exit(0);
00043 }
00044 
00045 void set_nonblock(int socket)
00046 {
00047   int flags;
00048   flags = fcntl(socket, F_GETFL, 0);
00049   assert(flags != -1);
00050   fcntl(socket, F_SETFL, flags | O_NONBLOCK);
00051 }
00052 
00053 int elCommInit(const char *portName, int baud)
00054 {
00055   struct termios options;
00056   int fd;
00057   int sockfd;
00058   struct sockaddr_in serv_addr;
00059   struct hostent *server;
00060   int rv;
00061 
00062   if (*portName == '/')       // linux serial port names always begin with /dev
00063   {
00064     printf("Opening serial port %s\n", portName);
00065 
00066     fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);
00067 
00068     if (fd == -1)
00069     {
00070       // Could not open the port.
00071       perror("init(): Unable to open serial port - ");
00072     }
00073     else
00074     {
00075       // Sets the read() function to return NOW and not wait for data to enter
00076       // buffer if there isn't anything there.
00077       fcntl(fd, F_SETFL, FNDELAY);
00078 
00079       // Configure port for 8N1 transmission, 57600 baud, SW flow control.
00080       tcgetattr(fd, &options);
00081       cfsetispeed(&options, B57600);
00082       cfsetospeed(&options, B57600);
00083       options.c_cflag |= (CLOCAL | CREAD);
00084       options.c_cflag &= ~PARENB;
00085       options.c_cflag &= ~CSTOPB;
00086       options.c_cflag &= ~CSIZE;
00087       options.c_cflag |= CS8;
00088       options.c_cflag &= ~CRTSCTS;
00089       options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
00090       options.c_iflag &= ~(IXON | IXOFF | IXANY);
00091       options.c_oflag &= ~OPOST;
00092 
00093       // Set the new options for the port "NOW"
00094       tcsetattr(fd, TCSANOW, &options);
00095     }
00096     return fd;
00097   }
00098   else
00099   {
00100     // Split connection string into IP address and port.
00101     const char* tcpPortNumString = strchr(portName, ':');
00102     long int tcpPortNum;
00103     char ip[16];
00104     if (!tcpPortNumString)
00105     {
00106       tcpPortNum = DEFAULT_PORTNUM;
00107       strncpy(ip, portName, 16);
00108     }
00109     else
00110     {
00111       tcpPortNum = strtol(tcpPortNumString + 1, NULL, 10);
00112       strncpy(ip, portName, tcpPortNumString - portName);
00113     }
00114 
00115     printf("Connecting to TCP server at %s:%ld....\n", ip, tcpPortNum);
00116 
00117     // Create the socket.
00118     sockfd = socket(AF_INET, SOCK_STREAM, 0);
00119     if (sockfd < 0)
00120     {
00121       error("ERROR opening socket");
00122       exit(-1);
00123     }
00124 
00125     // Disable the Nagle (TCP No Delay) algorithm.
00126     int flag = 1;
00127     rv = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
00128     if (rv == -1)
00129     {
00130       printf("Couldn't setsockopt(TCP_NODELAY)\n");
00131       exit(-1);
00132     }
00133 
00134     // Connect to the server
00135     server = gethostbyname(ip);
00136     if (server == NULL)
00137     {
00138       fprintf(stderr, "ERROR, no such host\n");
00139       exit(0);
00140     }
00141     bzero((char *) &serv_addr, sizeof(serv_addr));
00142     serv_addr.sin_family = AF_INET;
00143     bcopy((char *)server->h_addr,
00144           (char *)&serv_addr.sin_addr.s_addr,
00145           server->h_length);
00146     serv_addr.sin_port = htons(tcpPortNum);
00147     if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
00148       error("ERROR connecting");
00149     set_nonblock(sockfd);
00150     printf("connected to server\n");
00151     return sockfd;
00152   }
00153   return -1;
00154 }
00155 
00156 int elCommRead(int fd)
00157 {
00158   unsigned char c;
00159   unsigned int i;
00160   int rv;
00161   rv = read(fd, &c, 1); // read one byte
00162   i = c;          // convert byte to an int for return
00163   if (rv > 0)
00164     return i;     // return the character read
00165   if (rv < 0)
00166   {
00167     if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
00168       perror("elCommRead() error:");
00169   }
00170 
00171   // return -1 or 0 either if we read nothing, or if read returned negative
00172   return rv;
00173 }
00174 
00175 int elCommWrite(int fd, uint8_t* data, int len)
00176 {
00177   int rv;
00178   int length = len;
00179   int totalsent = 0;
00180   while (totalsent < length)
00181   {
00182     rv = write(fd, data + totalsent, length);
00183     if (rv < 0)
00184       perror("write(): error writing - trying again - ");
00185     else
00186       totalsent += rv;
00187   }
00188   return rv;
00189 }
00190 
00191 #endif


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:57