embedded_linux_comms.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #ifndef ROS_EMBEDDED_LINUX_COMMS_H
19 #define ROS_EMBEDDED_LINUX_COMMS_H
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <termios.h>
27 #include <string.h>
28 #include <time.h>
29 #include <stdint.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <netinet/tcp.h>
34 #include <netdb.h>
35 #include <assert.h>
36 
37 #define DEFAULT_PORTNUM 11411
38 
39 void error(const char *msg)
40 {
41  perror(msg);
42  exit(0);
43 }
44 
45 void set_nonblock(int socket)
46 {
47  int flags;
48  flags = fcntl(socket, F_GETFL, 0);
49  assert(flags != -1);
50  fcntl(socket, F_SETFL, flags | O_NONBLOCK);
51 }
52 
53 int elCommInit(const char *portName, int baud)
54 {
55  struct termios options;
56  int fd;
57  int sockfd;
58  struct sockaddr_in serv_addr;
59  struct hostent *server;
60  int rv;
61 
62  if (*portName == '/') // linux serial port names always begin with /dev
63  {
64  printf("Opening serial port %s\n", portName);
65 
66  fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);
67 
68  if (fd == -1)
69  {
70  // Could not open the port.
71  perror("init(): Unable to open serial port - ");
72  }
73  else
74  {
75  // Sets the read() function to return NOW and not wait for data to enter
76  // buffer if there isn't anything there.
77  fcntl(fd, F_SETFL, FNDELAY);
78 
79  // Configure port for 8N1 transmission, 57600 baud, SW flow control.
80  tcgetattr(fd, &options);
81  cfsetispeed(&options, B57600);
82  cfsetospeed(&options, B57600);
83  options.c_cflag |= (CLOCAL | CREAD);
84  options.c_cflag &= ~PARENB;
85  options.c_cflag &= ~CSTOPB;
86  options.c_cflag &= ~CSIZE;
87  options.c_cflag |= CS8;
88  options.c_cflag &= ~CRTSCTS;
89  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
90  options.c_iflag &= ~(IXON | IXOFF | IXANY);
91  options.c_oflag &= ~OPOST;
92 
93  // Set the new options for the port "NOW"
94  tcsetattr(fd, TCSANOW, &options);
95  }
96  return fd;
97  }
98  else
99  {
100  // Split connection string into IP address and port.
101  const char* tcpPortNumString = strchr(portName, ':');
102  long int tcpPortNum;
103  char ip[16];
104  if (!tcpPortNumString)
105  {
106  tcpPortNum = DEFAULT_PORTNUM;
107  strncpy(ip, portName, 16);
108  }
109  else
110  {
111  tcpPortNum = strtol(tcpPortNumString + 1, NULL, 10);
112  strncpy(ip, portName, tcpPortNumString - portName);
113  }
114 
115  printf("Connecting to TCP server at %s:%ld....\n", ip, tcpPortNum);
116 
117  // Create the socket.
118  sockfd = socket(AF_INET, SOCK_STREAM, 0);
119  if (sockfd < 0)
120  {
121  error("ERROR opening socket");
122  exit(-1);
123  }
124 
125  // Disable the Nagle (TCP No Delay) algorithm.
126  int flag = 1;
127  rv = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
128  if (rv == -1)
129  {
130  printf("Couldn't setsockopt(TCP_NODELAY)\n");
131  exit(-1);
132  }
133 
134  // Connect to the server
135  server = gethostbyname(ip);
136  if (server == NULL)
137  {
138  fprintf(stderr, "ERROR, no such host\n");
139  exit(0);
140  }
141  bzero((char *) &serv_addr, sizeof(serv_addr));
142  serv_addr.sin_family = AF_INET;
143  bcopy((char *)server->h_addr,
144  (char *)&serv_addr.sin_addr.s_addr,
145  server->h_length);
146  serv_addr.sin_port = htons(tcpPortNum);
147  if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
148  error("ERROR connecting");
149  set_nonblock(sockfd);
150  printf("connected to server\n");
151  return sockfd;
152  }
153  return -1;
154 }
155 
156 int elCommRead(int fd)
157 {
158  unsigned char c;
159  unsigned int i;
160  int rv;
161  rv = read(fd, &c, 1); // read one byte
162  i = c; // convert byte to an int for return
163  if (rv > 0)
164  return i; // return the character read
165  if (rv < 0)
166  {
167  if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
168  perror("elCommRead() error:");
169  }
170 
171  // return -1 or 0 either if we read nothing, or if read returned negative
172  return rv;
173 }
174 
175 int elCommWrite(int fd, uint8_t* data, int len)
176 {
177  int rv;
178  int length = len;
179  int totalsent = 0;
180  while (totalsent < length)
181  {
182  rv = write(fd, data + totalsent, length);
183  if (rv < 0)
184  perror("write(): error writing - trying again - ");
185  else
186  totalsent += rv;
187  }
188  return rv;
189 }
190 
191 #endif
#define DEFAULT_PORTNUM
void error(const char *msg)
server
void set_nonblock(int socket)
int elCommWrite(int fd, uint8_t *data, int len)
int elCommRead(int fd)
int elCommInit(const char *portName, int baud)


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Tue Oct 20 2020 03:35:57