00001 #include "SerialPort.h"
00002 #include <iostream>
00003 #include <sys/ioctl.h>
00004
00005 using namespace std ;
00006 using namespace SerialPorts ;
00007
00008 int SerialPort::open(char * devicename) {
00009
00010 this->fd = ::open(devicename, O_RDWR | O_NOCTTY | O_NDELAY);
00011
00012 if (this->fd == -1) {
00013
00014
00015
00016
00017 this->state = -1;
00018 } else {
00019
00020
00021
00022 struct termios options;
00023
00024
00025 if ( tcgetattr(this->fd, &options) != 0 ){
00026 this->state = -1;
00027 return this->state;
00028 }
00029 options.c_cflag |= (CLOCAL | CREAD);
00030 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
00031 if ( tcsetattr(this->fd, TCSANOW, &options) != 0 ) {
00032 this->state = -1;
00033 return this->state;
00034 }
00035 fcntl(fd, F_SETFL, 0);
00036 this->state = 1;
00037 }
00038 return this->state;
00039 }
00040
00041 int SerialPort::close(void) {
00042 this->state = -1;
00043 return ::close(this->fd);
00044 }
00045
00046 int SerialPort::status() {
00047 return this->state;
00048 }
00049
00050 int SerialPort::write(char * data, int lenght) {
00051
00052
00053
00054 return ::write(this->fd, data, lenght);
00055 }
00056 char SerialPort::readChar() {
00057 char character = '\0';
00058 char * character_ptr;
00059 int bytesRecv;
00060
00061 character_ptr = &character;
00062 bytesRecv = read(this->fd, character_ptr, sizeof(character));
00063 if ( bytesRecv == sizeof(character) ){
00064 return character;
00065 }
00066 return 0;
00067 }
00068
00069 char * SerialPort::readBytes(int bytes) {
00070 char * buffer = (char *) malloc(bytes);
00071 int bytesRead;
00072 bytesRead = ::read(this->fd, buffer, bytes);
00073 if ( bytesRead != bytes ) {
00074 cout << "OOPS bytes <> bytes_wait" << endl;
00075 }
00076 return buffer;
00077 }
00078
00079 int SerialPort::dataWaiting() {
00080 int bytes;
00081
00082 ioctl(this->fd, FIONREAD, &bytes);
00083 return bytes;
00084 }
00085
00086 enum BaudRateEnum SerialPort::setBaudRate( enum BaudRateEnum baud) {
00087 if ( ! this->state ) {
00088 this->baud = BAUD_ERR;
00089 return this->baud;
00090 }
00091
00092 switch ( baud ) {
00093 case BAUD_50:
00094 case BAUD_75:
00095 case BAUD_110:
00096 case BAUD_134:
00097 case BAUD_150:
00098 case BAUD_200:
00099 case BAUD_300:
00100 case BAUD_600:
00101 case BAUD_1200:
00102 case BAUD_1800:
00103 case BAUD_2400:
00104 case BAUD_4800:
00105 case BAUD_9600:
00106 case BAUD_19200:
00107 case BAUD_38400:
00108 case BAUD_57600:
00109 case BAUD_115200:
00110
00111 struct termios options;
00112
00113
00114 if ( tcgetattr(this->fd, &options) != 0 ){
00115 this->state = -1;
00116 }
00117
00118
00119 if ( cfsetispeed(&options, baud) != 0 ){
00120 this->state = -1;
00121 }
00122 if ( cfsetospeed(&options, baud) != 0 ){
00123 this->state = -1;
00124 }
00125 if ( this->state == -1 ) {
00126 this->baud = BAUD_ERR;
00127 } else {
00128 this->baud = baud;
00129 }
00130 return this->baud;
00131 break ;
00132
00133 default:
00134 this->baud = BAUD_ERR;
00135 return this->baud;
00136 break;
00137 };
00138 }
00139
00140 enum CharSizeEnum SerialPort::setCharSize( enum CharSizeEnum charsize) {
00141 if ( ! this->state ) {
00142 this->charsize = CHAR_SIZE_ERR;
00143 return this->charsize;
00144 }
00145
00146 struct termios options;
00147 if ( tcgetattr(this->fd, &options) != 0 ) {
00148 this->state = -1;
00149 this->charsize = CHAR_SIZE_ERR;
00150 return this->charsize;
00151 }
00152
00153 switch ( charsize ) {
00154 case CHAR_SIZE_5:
00155 case CHAR_SIZE_6:
00156 case CHAR_SIZE_7:
00157 case CHAR_SIZE_8:
00158
00159 if( charsize == CHAR_SIZE_8 ) {
00160 options.c_iflag &= ~ISTRIP ;
00161 } else {
00162 options.c_iflag |= ISTRIP ;
00163 }
00164 options.c_cflag &= ~CSIZE;
00165 options.c_cflag |= charsize;
00166
00167 if ( tcsetattr(this->fd, TCSANOW, &options) != 0 ){
00168 this->state = -1;
00169 this->charsize = CHAR_SIZE_ERR;
00170 } else {
00171 this->charsize = charsize;
00172 }
00173 return this->charsize;
00174 break ;
00175
00176 default:
00177 this->charsize = CHAR_SIZE_ERR;
00178 return this->charsize;
00179 break;
00180 }
00181 }
00182
00183 enum ParityEnum SerialPort::setParity( enum ParityEnum parity) {
00184 if ( ! this->state ) {
00185 this->parity = PARITY_ERR;
00186 return this->parity;
00187 }
00188
00189 struct termios options ;
00190 if ( tcgetattr(this->fd, &options) != 0 ) {
00191 this->state = -1;
00192 this->parity = PARITY_ERR;
00193 return this->parity;
00194 }
00195
00196 switch ( parity ) {
00197 case PARITY_EVEN:
00198 options.c_cflag |= PARENB ;
00199 options.c_cflag &= ~PARODD ;
00200 break ;
00201 case PARITY_ODD:
00202 options.c_cflag |= PARENB ;
00203 options.c_cflag |= PARODD ;
00204 break ;
00205 case PARITY_NONE:
00206 options.c_cflag &= ~PARENB ;
00207 break ;
00208 default:
00209 this->parity = PARITY_ERR;
00210 return this->parity;
00211 }
00212
00213 if ( tcsetattr(this->fd, TCSANOW, &options) != 0 ){
00214 this->state = -1;
00215 this->parity = PARITY_ERR;
00216 } else {
00217 this->parity = parity;
00218 }
00219 return this->parity;
00220 }
00221
00222 int SerialPort::setStopBits(int stopbits) {
00223 if ( ! this->state ) {
00224 this->stopbits = -1;
00225 return this->parity;
00226 }
00227
00228 struct termios options ;
00229 if ( tcgetattr(this->fd, &options) != 0 ) {
00230 this->state = -1;
00231 this->stopbits = -1;
00232 return this->parity;
00233 }
00234 switch ( stopbits ) {
00235 case 1:
00236 options.c_cflag &= ~CSTOPB ;
00237 break;
00238 case 2:
00239 options.c_cflag |= CSTOPB ;
00240 break;
00241 default:
00242 this->stopbits = -1;
00243 return this->stopbits;
00244 break;
00245 }
00246
00247 if ( tcsetattr(this->fd, TCSANOW, &options) != 0 ){
00248 this->state = -1;
00249 this->stopbits = -1;
00250 return this->stopbits;
00251 }
00252 this->stopbits = stopbits;
00253 return this->stopbits;
00254 }
00255
00256 enum FlowControlEnum SerialPort::setFlowControl( enum FlowControlEnum flowctrl) {
00257 if ( ! this->state ) {
00258 this->flowctrl = FLOW_CONTROL_ERR;
00259 return this->flowctrl;
00260 }
00261
00262 struct termios options ;
00263 if ( tcgetattr(this->fd, &options) != 0 ) {
00264 this->state = -1;
00265 this->flowctrl = FLOW_CONTROL_ERR;
00266 return this->flowctrl;
00267 }
00268
00269 switch ( flowctrl ) {
00270 case FLOW_CONTROL_HARD:
00271 options.c_iflag &= ~ (IXON|IXOFF);
00272 options.c_cflag |= CRTSCTS;
00273 options.c_cc[VSTART] = _POSIX_VDISABLE;
00274 options.c_cc[VSTOP] = _POSIX_VDISABLE;
00275 break;
00276 case FLOW_CONTROL_SOFT:
00277 options.c_iflag |= IXON|IXOFF;
00278 options.c_cflag &= ~CRTSCTS;
00279 options.c_cc[VSTART] = CTRL_Q ;
00280 options.c_cc[VSTOP] = CTRL_S ;
00281 break;
00282 case FLOW_CONTROL_NONE:
00283 options.c_iflag &= ~(IXON|IXOFF);
00284 options.c_cflag &= ~CRTSCTS;
00285 break;
00286 default:
00287 this->flowctrl = FLOW_CONTROL_ERR;
00288 return this->flowctrl;
00289 break;
00290 }
00291
00292 if ( tcsetattr(this->fd, TCSANOW, &options) != 0 ){
00293 this->state = -1;
00294 this->flowctrl = FLOW_CONTROL_ERR;
00295 return this->flowctrl;
00296 }
00297 this->flowctrl = flowctrl;
00298 return this->flowctrl;
00299 }