dn_com.c
Go to the documentation of this file.
00001 
00025 #include "stdint.h"
00026 #include <stdio.h>
00027 #include <string.h>
00028 
00029 #if defined(_USE_WIN_API)
00030 #include <windows.h>
00031 #elif defined(_USE_LINUX_API)
00032 #include <errno.h>
00033 #include <fcntl.h>
00034 #include <sys/ioctl.h>
00035 #include <termios.h>
00036 #include <unistd.h>
00037 #define _BAUD_MAX    (15)
00038 #define _BAUD_PAIR(val)   {val, B ## val}
00039 static const unsigned int BAUD_RATE[_BAUD_MAX][2] =
00040   { _BAUD_PAIR(50), _BAUD_PAIR(75), _BAUD_PAIR(110), _BAUD_PAIR(134), _BAUD_PAIR(150),
00041     _BAUD_PAIR(200), _BAUD_PAIR(300), _BAUD_PAIR(600), _BAUD_PAIR(1200), _BAUD_PAIR(1800),
00042     _BAUD_PAIR(2400), _BAUD_PAIR(4800), _BAUD_PAIR(9600), _BAUD_PAIR(19200), _BAUD_PAIR(38400)};
00043 #else
00044 #include "dn_additional.h"
00045 #endif
00046 
00047 #include "dn_common.h"
00048 #include "dn_device.h"
00049 #include "dn_com.h"
00050 
00051 #define _COM_PORT_MAX (256)
00052 
00053 #define _FLOW_XINOUT   (1)
00054 #define _FLOW_HARDWARE (2)
00055 
00056 #if defined(_USE_WIN_API)
00057 static HRESULT _com_open(const struct CONN_PARAM_COM *com_param, int *sock)
00058 {
00059   char szName[16];
00060   COM_STATE state;
00061   HRESULT hr;
00062 
00063   sprintf(szName, "//./COM%d", com_param->port);
00064   *sock = (int)CreateFileA(szName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00065 
00066   if(*sock < 0) {
00067     *sock = 0;
00068     hr = DNGetLastError();
00069     return OSERR2HRESULT(hr);
00070   }
00071 
00072   /* Clears the rest buffers */
00073   com_clear(*sock, 0);
00074 
00075   hr = com_get_state(*sock, &state);
00076   if(SUCCEEDED(hr)) {
00077     state.BaudRate = com_param->baud_rate;
00078     state.ByteSize = com_param->data_bits;
00079     state.Parity = com_param->parity;
00080     state.StopBits = com_param->stop_bits;
00081 
00082     if(com_param->flow & _FLOW_XINOUT) {
00083       state.fOutX = 1;
00084       state.fInX = 1;
00085     } else {
00086       state.fOutX = 0;
00087       state.fInX = 0;
00088     }
00089 
00090     if(com_param->flow & _FLOW_HARDWARE) {
00091       state.fOutxCtsFlow = 1;
00092       state.fRtsControl = RTS_CONTROL_HANDSHAKE;
00093     } else {
00094       state.fOutxCtsFlow = 0;
00095       state.fRtsControl = RTS_CONTROL_ENABLE;
00096     }
00097     state.fOutxDsrFlow = 0;
00098     state.fDtrControl = DTR_CONTROL_ENABLE;
00099     state.fDsrSensitivity = 0;
00100 
00101     hr = com_set_state(*sock, &state);
00102   }
00103 
00104   return hr;
00105 }
00106 
00107 static int _com_close(int sock)
00108 {
00109   return CloseHandle((HANDLE)sock);
00110 }
00111 
00112 static int _com_send(int sock, const char *buf, uint32_t len_send, uint32_t *len_sended, void *arg)
00113 {
00114   return WriteFile((HANDLE)sock, buf, len_send, (LPDWORD)len_sended, NULL);
00115 }
00116 
00117 static int _com_recv(int sock, char *buf, uint32_t len_recv, uint32_t *len_recved, uint32_t timeout, void *arg)
00118 {
00119   int ret;
00120 
00121   *len_recved = 0;
00122   ret = ReadFile((HANDLE)sock, buf, len_recv, (LPDWORD)len_recved, NULL);
00123 
00124   return ret;
00125 }
00126 
00127 static HRESULT _com_set_timeout(int sock, uint32_t timeout)
00128 {
00129   int ret;
00130   COMMTIMEOUTS stTimeOut;
00131   HRESULT hr = S_OK;
00132 
00133   stTimeOut.ReadIntervalTimeout = MAXDWORD;
00134   stTimeOut.ReadTotalTimeoutMultiplier = MAXDWORD;
00135   stTimeOut.ReadTotalTimeoutConstant = timeout;
00136   stTimeOut.WriteTotalTimeoutMultiplier = 1;
00137   stTimeOut.WriteTotalTimeoutConstant = timeout;
00138   ret = SetCommTimeouts((HANDLE)sock, &stTimeOut);
00139   if(OSFAILED(ret)) {
00140     ret = DNGetLastError();
00141     hr = OSERR2HRESULT(ret);
00142   }
00143 
00144   return hr;
00145 }
00146 
00147 static HRESULT _com_clear(int sock, uint32_t timeout)
00148 {
00149   int ret;
00150   DWORD err;
00151   HRESULT hr = S_OK;
00152 
00153   ret = ClearCommError((HANDLE)sock, &err, NULL);
00154   if(OSSUCCEEDED(ret)) {
00155     ret = PurgeComm((HANDLE)sock, (PURGE_TXABORT | PURGE_RXABORT| PURGE_TXCLEAR | PURGE_RXCLEAR));
00156   }
00157   if(OSFAILED(ret)) {
00158     ret = DNGetLastError();
00159     hr = OSERR2HRESULT(ret);
00160   }
00161 
00162   return hr;
00163 }
00164 
00165 static int _com_get_state(int sock, COM_STATE *state)
00166 {
00167   return GetCommState((HANDLE)sock, state);
00168 }
00169 
00170 static int _com_set_state(int sock, COM_STATE *state)
00171 {
00172   return SetCommState((HANDLE)sock, state);
00173 }
00174 
00175 static int _com_get_modem_state(int sock, uint32_t *state)
00176 {
00177   return GetCommModemStatus((HANDLE)sock, (DWORD *)state);
00178 }
00179 #elif defined(_USE_LINUX_API)
00180 static HRESULT _com_open(const struct CONN_PARAM_COM *com_param, int *sock)
00181 {
00182   int i;
00183   char szName[16];
00184   COM_STATE state;
00185   HRESULT hr;
00186 
00187   sprintf(szName, "/dev/ttyS%d", com_param->port);
00188   *sock = open(szName, O_RDWR | O_NOCTTY | O_NONBLOCK);
00189 
00190   if(*sock < 0) {
00191     *sock = 0;
00192     hr = DNGetLastError();
00193     return OSERR2HRESULT(hr);
00194   }
00195 
00196   /* Clears the rest buffers */
00197   com_clear(*sock, 0);
00198 
00199   memset(&state, 0, sizeof(COM_STATE));
00200 
00201   state.c_cflag = (CLOCAL | CREAD);
00202 
00203   for(i = 0; i < _BAUD_MAX; i++) {
00204     if(com_param->baud_rate == BAUD_RATE[i][0]) {
00205       state.c_cflag |= BAUD_RATE[i][1];
00206       break;
00207     }
00208   }
00209 
00210   switch(com_param->data_bits) {
00211     case 5:
00212       state.c_cflag |= CS5;
00213       break;
00214     case 6:
00215       state.c_cflag |= CS6;
00216       break;
00217     case 7:
00218       state.c_cflag |= CS7;
00219       break;
00220     case 8:
00221       state.c_cflag |= CS8;
00222       break;
00223     default:
00224       break;
00225   }
00226 
00227   switch(com_param->parity) {
00228     case NOPARITY:
00229       state.c_cflag &= ~PARENB;
00230       break;
00231     case ODDPARITY:
00232       state.c_cflag |= PARENB;
00233       state.c_cflag |= PARODD;
00234       break;
00235     case EVENPARITY:
00236       state.c_cflag |= PARENB;
00237       state.c_cflag &= ~PARODD;
00238       break;
00239     default:
00240       break;
00241   }
00242 
00243   switch(com_param->stop_bits) {
00244     case ONESTOPBIT:
00245       state.c_cflag &= ~CSTOPB;
00246       break;
00247     case TWOSTOPBITS:
00248       state.c_cflag |= CSTOPB;
00249       break;
00250     default:
00251       break;
00252   }
00253 
00254   if(com_param->flow & _FLOW_XINOUT) {
00255     state.c_iflag |= IXON;
00256     state.c_iflag |= IXOFF;
00257   } else {
00258     state.c_iflag &= ~IXON;
00259     state.c_iflag &= ~IXOFF;
00260   }
00261 
00262   if(com_param->flow & _FLOW_HARDWARE) {
00263     state.c_cflag |= CRTSCTS;
00264   } else {
00265     state.c_cflag &= ~CRTSCTS;
00266   }
00267 
00268   hr = com_set_state(*sock, &state);
00269 
00270   return hr;
00271 }
00272 
00273 static int _com_close(int sock)
00274 {
00275   return close(sock);
00276 }
00277 
00278 static int _com_send(int sock, const char *buf, uint32_t len_send, uint32_t *len_sended, void *arg)
00279 {
00280   int ret;
00281   ret = write(sock, buf, len_send);
00282   *len_sended = ret;
00283   return ret;
00284 }
00285 
00286 static int _com_recv(int sock, char *buf, uint32_t len_recv, uint32_t *len_recved, uint32_t timeout, void *arg)
00287 {
00288   int ret = 0;
00289   HRESULT hr;
00290 
00291   *len_recved = 0;
00292   hr = check_timeout(sock, timeout);
00293   if(SUCCEEDED(hr)) {
00294     ret = read(sock, buf, len_recv);
00295     *len_recved = ret;
00296   }
00297 
00298   return ret;
00299 }
00300 
00301 static HRESULT _com_set_timeout(int sock, uint32_t timeout)
00302 {
00303   COM_STATE state;
00304   HRESULT hr;
00305 
00306   hr = com_get_state(sock, &state);
00307   if(SUCCEEDED(hr)) {
00308     state.c_cc[VMIN] = 0;
00309     state.c_cc[VTIME] = timeout * 10 / 1000;
00310 
00311     hr = com_set_state(sock, &state);
00312   }
00313 
00314   return hr;
00315 }
00316 
00317 static HRESULT _com_clear(int sock, uint32_t timeout)
00318 {
00319   int ret;
00320   HRESULT hr = S_OK;
00321 
00322   ret = tcflush(sock, TCIFLUSH);
00323   if(OSFAILED(ret)) {
00324     ret = DNGetLastError();
00325     return OSERR2HRESULT(ret);
00326   }
00327 
00328   ret = tcflush(sock, TCOFLUSH);
00329   if(OSFAILED(ret)) {
00330     ret = DNGetLastError();
00331     return OSERR2HRESULT(ret);
00332   }
00333 
00334   return hr;
00335 }
00336 
00337 static int _com_get_state(int sock, COM_STATE *state)
00338 {
00339   return tcgetattr(sock, state);
00340 }
00341 
00342 static int _com_set_state(int sock, COM_STATE *state)
00343 {
00344   return tcsetattr(sock, TCSAFLUSH, state);
00345 }
00346 
00347 static int _com_get_modem_state(int sock, uint32_t *state)
00348 {
00349   return ioctl(sock, TIOCMGET, (int *)state);
00350 }
00351 #endif
00352 
00359 HRESULT
00360 com_open(void *param, int *sock)
00361 {
00362   int port;
00363   HRESULT hr;
00364   const struct CONN_PARAM_COM *com_param = (const struct CONN_PARAM_COM *) param;
00365 
00366   if (param == NULL || sock == NULL)
00367     return E_INVALIDARG;
00368 
00369   /* Checks port range */
00370   port = com_param->port;
00371   if (port < 0 || _COM_PORT_MAX < port)
00372     return E_INVALIDARG;
00373 
00374   hr = _com_open(com_param, sock);
00375 
00376   return hr;
00377 }
00378 
00384 HRESULT
00385 com_close(int *sock)
00386 {
00387   int ret;
00388 
00389   if (sock == NULL || *sock <= 0)
00390     return E_HANDLE;
00391 
00392   ret = _com_close(*sock);
00393   if (OSFAILED(ret)) {
00394     ret = DNGetLastError();
00395     return OSERR2HRESULT(ret);
00396   }
00397 
00398   *sock = 0;
00399 
00400   return S_OK;
00401 }
00402 
00411 HRESULT
00412 com_send(int sock, const char *buf, uint32_t len_buf, void *arg)
00413 {
00414   int ret;
00415   uint32_t len_send, len_sended;
00416 
00417   if (sock <= 0)
00418     return E_HANDLE;
00419   if (buf == NULL || strlen(buf) == 0)
00420     return E_INVALIDARG;
00421 
00422   len_send = (len_buf != 0) ? len_buf : strlen(buf);
00423   ret = _com_send(sock, buf, len_send, &len_sended, arg);
00424 
00425   if (OSFAILED(ret)) {
00426     ret = DNGetLastError();
00427 #if defined(_USE_WIN_API)
00428     {
00429       DWORD err_flag;
00430       ClearCommError((HANDLE)sock, &err_flag, NULL);
00431     }
00432 #endif
00433     return OSERR2HRESULT(ret);
00434   }
00435 
00436   if (len_send > len_sended) {
00437     return E_TIMEOUT;
00438   }
00439 
00440   return S_OK;
00441 }
00442 
00452 HRESULT
00453 com_recv(int sock, char *buf, uint32_t len_buf, uint32_t *len_recved,
00454     uint32_t timeout, void *arg)
00455 {
00456   int ret;
00457 
00458   if (sock <= 0)
00459     return E_HANDLE;
00460   if (buf == NULL || len_recved == NULL)
00461     return E_INVALIDARG;
00462 
00463   ret = _com_recv(sock, buf, len_buf, len_recved, timeout, arg);
00464 
00465   if (OSFAILED(ret)) {
00466     ret = DNGetLastError();
00467 #if defined(_USE_WIN_API)
00468     {
00469       DWORD err_flag;
00470       ClearCommError((HANDLE)sock, &err_flag, NULL);
00471     }
00472 #endif
00473     return OSERR2HRESULT(ret);
00474   }
00475 
00476   if (*len_recved == 0)
00477     return E_TIMEOUT;
00478 
00479   return S_OK;
00480 }
00481 
00488 HRESULT
00489 com_set_timeout(int sock, uint32_t timeout)
00490 {
00491   HRESULT hr = S_OK;
00492 
00493   if (sock <= 0)
00494     return E_HANDLE;
00495 
00496   hr = _com_set_timeout(sock, timeout);
00497 
00498   return hr;
00499 }
00500 
00507 HRESULT
00508 com_clear(int sock, uint32_t timeout)
00509 {
00510   HRESULT hr = S_OK;
00511 
00512   if (sock <= 0)
00513     return E_HANDLE;
00514 
00515   hr = _com_clear(sock, timeout);
00516 
00517   return hr;
00518 }
00519 
00526 HRESULT
00527 com_get_state(int sock, COM_STATE *state)
00528 {
00529   int ret;
00530   HRESULT hr = S_OK;
00531 
00532   if (sock <= 0)
00533     return E_HANDLE;
00534   if (state == NULL)
00535     return E_INVALIDARG;
00536 
00537   ret = _com_get_state(sock, state);
00538 
00539   if (OSFAILED(ret)) {
00540     ret = DNGetLastError();
00541     hr = OSERR2HRESULT(ret);
00542   }
00543 
00544   return hr;
00545 }
00546 
00553 HRESULT
00554 com_set_state(int sock, COM_STATE *state)
00555 {
00556   int ret;
00557   HRESULT hr = S_OK;
00558 
00559   if (sock <= 0)
00560     return E_HANDLE;
00561   if (state == NULL)
00562     return E_INVALIDARG;
00563 
00564   ret = _com_set_state(sock, state);
00565 
00566   if (OSFAILED(ret)) {
00567     ret = DNGetLastError();
00568     hr = OSERR2HRESULT(ret);
00569   }
00570 
00571   return hr;
00572 }
00573 
00580 HRESULT
00581 com_get_modem_state(int sock, uint32_t *state)
00582 {
00583   int ret;
00584   HRESULT hr = S_OK;
00585 
00586   if (sock <= 0)
00587     return E_HANDLE;
00588   if (state == NULL)
00589     return E_INVALIDARG;
00590 
00591   ret = _com_get_modem_state(sock, state);
00592 
00593   if (OSFAILED(ret)) {
00594     ret = DNGetLastError();
00595     hr = OSERR2HRESULT(ret);
00596   }
00597 
00598   return hr;
00599 }


bcap_core
Author(s): DENSO WAVE INCORPORATED
autogenerated on Thu Jun 6 2019 21:00:02