00001
00013 #include "serial_errno.h"
00014 #include "ring_buffer.h"
00015 #include <unistd.h>
00016 #include <stdio.h>
00017 #include <fcntl.h>
00018 #include <errno.h>
00019 #include <string.h>
00020
00021
00022
00023 enum {
00024 False = 0,
00025 True,
00026 };
00027
00028
00029 enum {
00030 InvalidFd = -1,
00031 };
00032
00033
00034 void serial_initialize(serial_t *serial)
00035 {
00036 serial->fd_ = InvalidFd;
00037 serial->errno_ = SerialNoError;
00038 serial->has_last_ch_ = False;
00039
00040 ring_initialize(&serial->ring_, serial->buffer_, RingBufferSizeShift);
00041 }
00042
00043
00044
00045 int serial_connect(serial_t *serial, const char *device, long baudrate)
00046 {
00047 int flags = 0;
00048 int ret = 0;
00049
00050 serial_initialize(serial);
00051
00052 #ifndef MAC_OS
00053 enum { O_EXLOCK = 0x0 };
00054 #endif
00055 serial->fd_ = open(device, O_RDWR | O_EXLOCK | O_NONBLOCK | O_NOCTTY);
00056 if (serial->fd_ < 0) {
00057
00058 strerror_r(errno, serial->error_string_, SerialErrorStringSize);
00059 return SerialConnectionFail;
00060 }
00061
00062 flags = fcntl(serial->fd_, F_GETFL, 0);
00063 fcntl(serial->fd_, F_SETFL, flags & ~O_NONBLOCK);
00064
00065
00066 tcgetattr(serial->fd_, &serial->sio_);
00067 serial->sio_.c_iflag = 0;
00068 serial->sio_.c_oflag = 0;
00069 serial->sio_.c_cflag &= ~(CSIZE | PARENB | CSTOPB);
00070 serial->sio_.c_cflag |= CS8 | CREAD | CLOCAL;
00071 serial->sio_.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN);
00072
00073 serial->sio_.c_cc[VMIN] = 0;
00074 serial->sio_.c_cc[VTIME] = 0;
00075
00076
00077 ret = serial_setBaudrate(serial, baudrate);
00078 if (ret < 0) {
00079 return ret;
00080 }
00081
00082
00083 serial->has_last_ch_ = False;
00084
00085 return 0;
00086 }
00087
00088
00089
00090 void serial_disconnect(serial_t *serial)
00091 {
00092 if (serial->fd_ >= 0) {
00093 close(serial->fd_);
00094 serial->fd_ = InvalidFd;
00095 }
00096 }
00097
00098
00099 int serial_isConnected(const serial_t *serial)
00100 {
00101 return ((serial == NULL) || (serial->fd_ == InvalidFd)) ? 0 : 1;
00102 }
00103
00104
00105
00106 int serial_setBaudrate(serial_t *serial, long baudrate)
00107 {
00108 long baudrate_value = -1;
00109
00110 switch (baudrate) {
00111 case 4800:
00112 baudrate_value = B4800;
00113 break;
00114
00115 case 9600:
00116 baudrate_value = B9600;
00117 break;
00118
00119 case 19200:
00120 baudrate_value = B19200;
00121 break;
00122
00123 case 38400:
00124 baudrate_value = B38400;
00125 break;
00126
00127 case 57600:
00128 baudrate_value = B57600;
00129 break;
00130
00131 case 115200:
00132 baudrate_value = B115200;
00133 break;
00134
00135 default:
00136 return SerialSetBaudrateFail;
00137 }
00138
00139
00140 cfsetospeed(&serial->sio_, baudrate_value);
00141 cfsetispeed(&serial->sio_, baudrate_value);
00142 tcsetattr(serial->fd_, TCSADRAIN, &serial->sio_);
00143 serial_clear(serial);
00144
00145 return 0;
00146 }
00147
00148
00149
00150 int serial_send(serial_t *serial, const char *data, int data_size)
00151 {
00152 if (! serial_isConnected(serial)) {
00153 return SerialConnectionFail;
00154 }
00155 return write(serial->fd_, data, data_size);
00156 }
00157
00158
00159 static int waitReceive(serial_t* serial, int timeout)
00160 {
00161 fd_set rfds;
00162 struct timeval tv;
00163
00164
00165 FD_ZERO(&rfds);
00166 FD_SET(serial->fd_, &rfds);
00167
00168 tv.tv_sec = timeout / 1000;
00169 tv.tv_usec = (timeout % 1000) * 1000;
00170
00171 if (select(serial->fd_ + 1, &rfds, NULL, NULL,
00172 (timeout < 0) ? NULL : &tv) <= 0) {
00173
00174 return 0;
00175 }
00176 return 1;
00177 }
00178
00179
00180 static int internal_receive(char data[], int data_size_max,
00181 serial_t* serial, int timeout)
00182 {
00183 int filled = 0;
00184
00185 if (data_size_max <= 0) {
00186 return 0;
00187 }
00188
00189 while (filled < data_size_max) {
00190 int require_n;
00191 int read_n;
00192
00193 if (! waitReceive(serial, timeout)) {
00194 break;
00195 }
00196
00197 require_n = data_size_max - filled;
00198 read_n = read(serial->fd_, &data[filled], require_n);
00199 if (read_n <= 0) {
00200
00201 break;
00202 }
00203 filled += read_n;
00204 }
00205 return filled;
00206 }
00207
00208
00209
00210 int serial_recv(serial_t *serial, char* data, int data_size_max, int timeout)
00211 {
00212 int filled;
00213 int read_n;
00214 int buffer_size;
00215
00216 if (data_size_max <= 0) {
00217 return 0;
00218 }
00219
00220
00221 filled = 0;
00222 if (serial->has_last_ch_ != False) {
00223 data[0] = serial->last_ch_;
00224 serial->has_last_ch_ = False;
00225 ++filled;
00226 }
00227
00228 if (! serial_isConnected(serial)) {
00229 if (filled > 0) {
00230 return filled;
00231 }
00232 return SerialConnectionFail;
00233 }
00234
00235 buffer_size = ring_size(&serial->ring_);
00236 read_n = data_size_max - filled;
00237 if (buffer_size < read_n) {
00238
00239 char buffer[RingBufferSize];
00240 int n = internal_receive(buffer,
00241 ring_capacity(&serial->ring_) - buffer_size,
00242 serial, 0);
00243 ring_write(&serial->ring_, buffer, n);
00244 }
00245 buffer_size = ring_size(&serial->ring_);
00246
00247
00248 if (read_n > buffer_size) {
00249 read_n = buffer_size;
00250 }
00251 if (read_n > 0) {
00252 ring_read(&serial->ring_, &data[filled], read_n);
00253 filled += read_n;
00254 }
00255
00256
00257 filled += internal_receive(&data[filled],
00258 data_size_max - filled, serial, timeout);
00259 return filled;
00260 }
00261
00262
00263
00264 void serial_ungetc(serial_t *serial, char ch)
00265 {
00266 serial->has_last_ch_ = True;
00267 serial->last_ch_ = ch;
00268 }
00269
00270
00271 void serial_clear(serial_t* serial)
00272 {
00273 tcdrain(serial->fd_);
00274 tcflush(serial->fd_, TCIOFLUSH);
00275 ring_clear(&serial->ring_);
00276 serial->has_last_ch_ = False;
00277 }