Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / test / Pendulum / Serial / arduino-serial-lib.c
1 /*
2  *
3  * Copyright 2019 AT&T Intellectual Property
4  * Copyright 2019 Nokia
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 //
21 // arduino-serial-lib -- simple library for reading/writing serial ports
22 //
23 // 2006-2013, Tod E. Kurt, http://todbot.com/blog/
24 //
25
26 #include "arduino-serial-lib.h"
27
28 #include <stdio.h>    // Standard input/output definitions
29 #include <unistd.h>   // UNIX standard function definitions
30 #include <fcntl.h>    // File control definitions
31 #include <errno.h>    // Error number definitions
32 #include <termios.h>  // POSIX terminal control definitions
33 #include <string.h>   // String function definitions
34 #include <sys/ioctl.h>
35
36 // uncomment this to debug reads
37 //#define SERIALPORTDEBUG
38
39 // takes the string name of the serial port (e.g. "/dev/tty.usbserial","COM1")
40 // and a baud rate (bps) and connects to that port at that speed and 8N1.
41 // opens the port in fully raw mode so you can send binary data.
42 // returns valid fd, or -1 on error
43 int serialport_init(const char* serialport, int baud)
44 {
45     struct termios toptions;
46     int fd;
47
48     //fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);
49     fd = open(serialport, O_RDWR | O_NONBLOCK );
50
51     if (fd == -1)  {
52         perror("serialport_init: Unable to open port s");
53         return -1;
54     }
55
56     //int iflags = TIOCM_DTR;
57     //ioctl(fd, TIOCMBIS, &iflags);     // turn on DTR
58     //ioctl(fd, TIOCMBIC, &iflags);    // turn off DTR
59
60     if (tcgetattr(fd, &toptions) < 0) {
61         perror("serialport_init: Couldn't get term attributes");
62         return -1;
63     }
64     speed_t brate = baud; // let you override switch below if needed
65     switch(baud)
66     {
67         case 4800:   brate=B4800;   break;
68         case 9600:   brate=B9600;   break;
69       #ifdef B14400
70           case 14400:  brate=B14400;  break;
71       #endif
72           case 19200:  brate=B19200;  break;
73       #ifdef B28800
74           case 28800:  brate=B28800;  break;
75       #endif
76         case 38400:  brate=B38400;  break;
77         case 57600:  brate=B57600;  break;
78         case 115200: brate=B115200; break;
79     }
80     cfsetispeed(&toptions, brate);
81     cfsetospeed(&toptions, brate);
82
83     // 8N1
84     toptions.c_cflag &= ~PARENB;
85     toptions.c_cflag &= ~CSTOPB;
86     toptions.c_cflag &= ~CSIZE;
87     toptions.c_cflag |= CS8;
88     // no flow control
89     toptions.c_cflag &= ~CRTSCTS;
90
91     //toptions.c_cflag &= ~HUPCL; // disable hang-up-on-close to avoid reset
92
93     toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
94     toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
95
96     toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
97     toptions.c_oflag &= ~OPOST; // make raw
98
99     // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
100     toptions.c_cc[VMIN]  = 0;
101     toptions.c_cc[VTIME] = 0;
102     //toptions.c_cc[VTIME] = 20;
103
104     tcsetattr(fd, TCSANOW, &toptions);
105     if( tcsetattr(fd, TCSAFLUSH, &toptions) < 0) {
106         perror("init_serialport: Couldn't set term attributes");
107         return -1;
108     }
109
110     return fd;
111 }
112
113 //
114 int serialport_close( int fd )
115 {
116     return close( fd );
117 }
118
119 //
120 int serialport_writebyte( int fd, uint8_t b)
121 {
122     int n = write(fd,&b,1);
123     if( n!=1)
124         return -1;
125     return 0;
126 }
127
128 //
129 int serialport_write(int fd, const char* str)
130 {
131     int len = strlen(str);
132     int n = write(fd, str, len);
133     if( n!=len ) {
134         perror("serialport_write: couldn't write whole string\n");
135         return -1;
136     }
137     return 0;
138 }
139
140 //
141 int serialport_read_until(int fd, char* buf, char until, int buf_max, int timeout)
142 {
143     char b[1];  // read expects an array, so we give it a 1-byte array
144     int i=0;
145     do {
146         int n = read(fd, b, 1);  // read a char at a time
147         if( n==-1) return -1;    // couldn't read
148         if( n==0 ) {
149             usleep( 1 * 1000 );  // wait 1 msec try again
150             timeout--;
151             if( timeout==0 ) return -2;
152             continue;
153         }
154 #ifdef SERIALPORTDEBUG
155         fprintf(stderr, "serialport_read_until: i=%d, n=%d b='%c'\n",i,n,b[0]); // debug
156 #endif
157         buf[i] = b[0];
158         i++;
159     } while( b[0] != until && i < buf_max && timeout>0 );
160
161     buf[i] = 0;  // null terminate the string
162     return 0;
163 }
164
165 //
166 int serialport_flush(int fd)
167 {
168     sleep(2); //required to make flush work, for some reason
169     return tcflush(fd, TCIOFLUSH);
170 }