dn_com.c
Go to the documentation of this file.
1 
25 #include "stdint.h"
26 #include <stdio.h>
27 #include <string.h>
28 
29 #if defined(_USE_WIN_API)
30 #include <windows.h>
31 #elif defined(_USE_LINUX_API)
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <sys/ioctl.h>
35 #include <termios.h>
36 #include <unistd.h>
37 #define _BAUD_MAX (15)
38 #define _BAUD_PAIR(val) {val, B ## val}
39 static const unsigned int BAUD_RATE[_BAUD_MAX][2] =
40  { _BAUD_PAIR(50), _BAUD_PAIR(75), _BAUD_PAIR(110), _BAUD_PAIR(134), _BAUD_PAIR(150),
41  _BAUD_PAIR(200), _BAUD_PAIR(300), _BAUD_PAIR(600), _BAUD_PAIR(1200), _BAUD_PAIR(1800),
42  _BAUD_PAIR(2400), _BAUD_PAIR(4800), _BAUD_PAIR(9600), _BAUD_PAIR(19200), _BAUD_PAIR(38400)};
43 #else
44 #include "dn_additional.h"
45 #endif
46 
47 #include "dn_common.h"
48 #include "dn_device.h"
49 #include "dn_com.h"
50 
51 #define _COM_PORT_MAX (256)
52 
53 #define _FLOW_XINOUT (1)
54 #define _FLOW_HARDWARE (2)
55 
56 #if defined(_USE_WIN_API)
57 static HRESULT _com_open(const struct CONN_PARAM_COM *com_param, int *sock)
58 {
59  char szName[16];
60  COM_STATE state;
61  HRESULT hr;
62 
63  sprintf(szName, "//./COM%d", com_param->port);
64  *sock = (int)CreateFileA(szName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
65 
66  if(*sock < 0) {
67  *sock = 0;
68  hr = DNGetLastError();
69  return OSERR2HRESULT(hr);
70  }
71 
72  /* Clears the rest buffers */
73  com_clear(*sock, 0);
74 
75  hr = com_get_state(*sock, &state);
76  if(SUCCEEDED(hr)) {
77  state.BaudRate = com_param->baud_rate;
78  state.ByteSize = com_param->data_bits;
79  state.Parity = com_param->parity;
80  state.StopBits = com_param->stop_bits;
81 
82  if(com_param->flow & _FLOW_XINOUT) {
83  state.fOutX = 1;
84  state.fInX = 1;
85  } else {
86  state.fOutX = 0;
87  state.fInX = 0;
88  }
89 
90  if(com_param->flow & _FLOW_HARDWARE) {
91  state.fOutxCtsFlow = 1;
92  state.fRtsControl = RTS_CONTROL_HANDSHAKE;
93  } else {
94  state.fOutxCtsFlow = 0;
95  state.fRtsControl = RTS_CONTROL_ENABLE;
96  }
97  state.fOutxDsrFlow = 0;
98  state.fDtrControl = DTR_CONTROL_ENABLE;
99  state.fDsrSensitivity = 0;
100 
101  hr = com_set_state(*sock, &state);
102  }
103 
104  return hr;
105 }
106 
107 static int _com_close(int sock)
108 {
109  return CloseHandle((HANDLE)sock);
110 }
111 
112 static int _com_send(int sock, const char *buf, uint32_t len_send, uint32_t *len_sended, void *arg)
113 {
114  return WriteFile((HANDLE)sock, buf, len_send, (LPDWORD)len_sended, NULL);
115 }
116 
117 static int _com_recv(int sock, char *buf, uint32_t len_recv, uint32_t *len_recved, uint32_t timeout, void *arg)
118 {
119  int ret;
120 
121  *len_recved = 0;
122  ret = ReadFile((HANDLE)sock, buf, len_recv, (LPDWORD)len_recved, NULL);
123 
124  return ret;
125 }
126 
127 static HRESULT _com_set_timeout(int sock, uint32_t timeout)
128 {
129  int ret;
130  COMMTIMEOUTS stTimeOut;
131  HRESULT hr = S_OK;
132 
133  stTimeOut.ReadIntervalTimeout = MAXDWORD;
134  stTimeOut.ReadTotalTimeoutMultiplier = MAXDWORD;
135  stTimeOut.ReadTotalTimeoutConstant = timeout;
136  stTimeOut.WriteTotalTimeoutMultiplier = 1;
137  stTimeOut.WriteTotalTimeoutConstant = timeout;
138  ret = SetCommTimeouts((HANDLE)sock, &stTimeOut);
139  if(OSFAILED(ret)) {
140  ret = DNGetLastError();
141  hr = OSERR2HRESULT(ret);
142  }
143 
144  return hr;
145 }
146 
147 static HRESULT _com_clear(int sock, uint32_t timeout)
148 {
149  int ret;
150  DWORD err;
151  HRESULT hr = S_OK;
152 
153  ret = ClearCommError((HANDLE)sock, &err, NULL);
154  if(OSSUCCEEDED(ret)) {
155  ret = PurgeComm((HANDLE)sock, (PURGE_TXABORT | PURGE_RXABORT| PURGE_TXCLEAR | PURGE_RXCLEAR));
156  }
157  if(OSFAILED(ret)) {
158  ret = DNGetLastError();
159  hr = OSERR2HRESULT(ret);
160  }
161 
162  return hr;
163 }
164 
165 static int _com_get_state(int sock, COM_STATE *state)
166 {
167  return GetCommState((HANDLE)sock, state);
168 }
169 
170 static int _com_set_state(int sock, COM_STATE *state)
171 {
172  return SetCommState((HANDLE)sock, state);
173 }
174 
175 static int _com_get_modem_state(int sock, uint32_t *state)
176 {
177  return GetCommModemStatus((HANDLE)sock, (DWORD *)state);
178 }
179 #elif defined(_USE_LINUX_API)
180 static HRESULT _com_open(const struct CONN_PARAM_COM *com_param, int *sock)
181 {
182  int i;
183  char szName[16];
184  COM_STATE state;
185  HRESULT hr;
186 
187  sprintf(szName, "/dev/ttyS%d", com_param->port);
188  *sock = open(szName, O_RDWR | O_NOCTTY | O_NONBLOCK);
189 
190  if(*sock < 0) {
191  *sock = 0;
192  hr = DNGetLastError();
193  return OSERR2HRESULT(hr);
194  }
195 
196  /* Clears the rest buffers */
197  com_clear(*sock, 0);
198 
199  memset(&state, 0, sizeof(COM_STATE));
200 
201  state.c_cflag = (CLOCAL | CREAD);
202 
203  for(i = 0; i < _BAUD_MAX; i++) {
204  if(com_param->baud_rate == BAUD_RATE[i][0]) {
205  state.c_cflag |= BAUD_RATE[i][1];
206  break;
207  }
208  }
209 
210  switch(com_param->data_bits) {
211  case 5:
212  state.c_cflag |= CS5;
213  break;
214  case 6:
215  state.c_cflag |= CS6;
216  break;
217  case 7:
218  state.c_cflag |= CS7;
219  break;
220  case 8:
221  state.c_cflag |= CS8;
222  break;
223  default:
224  break;
225  }
226 
227  switch(com_param->parity) {
228  case NOPARITY:
229  state.c_cflag &= ~PARENB;
230  break;
231  case ODDPARITY:
232  state.c_cflag |= PARENB;
233  state.c_cflag |= PARODD;
234  break;
235  case EVENPARITY:
236  state.c_cflag |= PARENB;
237  state.c_cflag &= ~PARODD;
238  break;
239  default:
240  break;
241  }
242 
243  switch(com_param->stop_bits) {
244  case ONESTOPBIT:
245  state.c_cflag &= ~CSTOPB;
246  break;
247  case TWOSTOPBITS:
248  state.c_cflag |= CSTOPB;
249  break;
250  default:
251  break;
252  }
253 
254  if(com_param->flow & _FLOW_XINOUT) {
255  state.c_iflag |= IXON;
256  state.c_iflag |= IXOFF;
257  } else {
258  state.c_iflag &= ~IXON;
259  state.c_iflag &= ~IXOFF;
260  }
261 
262  if(com_param->flow & _FLOW_HARDWARE) {
263  state.c_cflag |= CRTSCTS;
264  } else {
265  state.c_cflag &= ~CRTSCTS;
266  }
267 
268  hr = com_set_state(*sock, &state);
269 
270  return hr;
271 }
272 
273 static int _com_close(int sock)
274 {
275  return close(sock);
276 }
277 
278 static int _com_send(int sock, const char *buf, uint32_t len_send, uint32_t *len_sended, void *arg)
279 {
280  int ret;
281  ret = write(sock, buf, len_send);
282  *len_sended = ret;
283  return ret;
284 }
285 
286 static int _com_recv(int sock, char *buf, uint32_t len_recv, uint32_t *len_recved, uint32_t timeout, void *arg)
287 {
288  int ret = 0;
289  HRESULT hr;
290 
291  *len_recved = 0;
292  hr = check_timeout(sock, timeout);
293  if(SUCCEEDED(hr)) {
294  ret = read(sock, buf, len_recv);
295  *len_recved = ret;
296  }
297 
298  return ret;
299 }
300 
301 static HRESULT _com_set_timeout(int sock, uint32_t timeout)
302 {
303  COM_STATE state;
304  HRESULT hr;
305 
306  hr = com_get_state(sock, &state);
307  if(SUCCEEDED(hr)) {
308  state.c_cc[VMIN] = 0;
309  state.c_cc[VTIME] = timeout * 10 / 1000;
310 
311  hr = com_set_state(sock, &state);
312  }
313 
314  return hr;
315 }
316 
317 static HRESULT _com_clear(int sock, uint32_t timeout)
318 {
319  int ret;
320  HRESULT hr = S_OK;
321 
322  ret = tcflush(sock, TCIFLUSH);
323  if(OSFAILED(ret)) {
324  ret = DNGetLastError();
325  return OSERR2HRESULT(ret);
326  }
327 
328  ret = tcflush(sock, TCOFLUSH);
329  if(OSFAILED(ret)) {
330  ret = DNGetLastError();
331  return OSERR2HRESULT(ret);
332  }
333 
334  return hr;
335 }
336 
337 static int _com_get_state(int sock, COM_STATE *state)
338 {
339  return tcgetattr(sock, state);
340 }
341 
342 static int _com_set_state(int sock, COM_STATE *state)
343 {
344  return tcsetattr(sock, TCSAFLUSH, state);
345 }
346 
347 static int _com_get_modem_state(int sock, uint32_t *state)
348 {
349  return ioctl(sock, TIOCMGET, (int *)state);
350 }
351 #endif
352 
359 HRESULT
360 com_open(void *param, int *sock)
361 {
362  int port;
363  HRESULT hr;
364  const struct CONN_PARAM_COM *com_param = (const struct CONN_PARAM_COM *) param;
365 
366  if (param == NULL || sock == NULL)
367  return E_INVALIDARG;
368 
369  /* Checks port range */
370  port = com_param->port;
371  if (port < 0 || _COM_PORT_MAX < port)
372  return E_INVALIDARG;
373 
374  hr = _com_open(com_param, sock);
375 
376  return hr;
377 }
378 
384 HRESULT
385 com_close(int *sock)
386 {
387  int ret;
388 
389  if (sock == NULL || *sock <= 0)
390  return E_HANDLE;
391 
392  ret = _com_close(*sock);
393  if (OSFAILED(ret)) {
394  ret = DNGetLastError();
395  return OSERR2HRESULT(ret);
396  }
397 
398  *sock = 0;
399 
400  return S_OK;
401 }
402 
411 HRESULT
412 com_send(int sock, const char *buf, uint32_t len_buf, void *arg)
413 {
414  int ret;
415  uint32_t len_send, len_sended;
416 
417  if (sock <= 0)
418  return E_HANDLE;
419  if (buf == NULL || strlen(buf) == 0)
420  return E_INVALIDARG;
421 
422  len_send = (len_buf != 0) ? len_buf : strlen(buf);
423  ret = _com_send(sock, buf, len_send, &len_sended, arg);
424 
425  if (OSFAILED(ret)) {
426  ret = DNGetLastError();
427 #if defined(_USE_WIN_API)
428  {
429  DWORD err_flag;
430  ClearCommError((HANDLE)sock, &err_flag, NULL);
431  }
432 #endif
433  return OSERR2HRESULT(ret);
434  }
435 
436  if (len_send > len_sended) {
437  return E_TIMEOUT;
438  }
439 
440  return S_OK;
441 }
442 
452 HRESULT
453 com_recv(int sock, char *buf, uint32_t len_buf, uint32_t *len_recved,
454  uint32_t timeout, void *arg)
455 {
456  int ret;
457 
458  if (sock <= 0)
459  return E_HANDLE;
460  if (buf == NULL || len_recved == NULL)
461  return E_INVALIDARG;
462 
463  ret = _com_recv(sock, buf, len_buf, len_recved, timeout, arg);
464 
465  if (OSFAILED(ret)) {
466  ret = DNGetLastError();
467 #if defined(_USE_WIN_API)
468  {
469  DWORD err_flag;
470  ClearCommError((HANDLE)sock, &err_flag, NULL);
471  }
472 #endif
473  return OSERR2HRESULT(ret);
474  }
475 
476  if (*len_recved == 0)
477  return E_TIMEOUT;
478 
479  return S_OK;
480 }
481 
488 HRESULT
489 com_set_timeout(int sock, uint32_t timeout)
490 {
491  HRESULT hr = S_OK;
492 
493  if (sock <= 0)
494  return E_HANDLE;
495 
496  hr = _com_set_timeout(sock, timeout);
497 
498  return hr;
499 }
500 
507 HRESULT
508 com_clear(int sock, uint32_t timeout)
509 {
510  HRESULT hr = S_OK;
511 
512  if (sock <= 0)
513  return E_HANDLE;
514 
515  hr = _com_clear(sock, timeout);
516 
517  return hr;
518 }
519 
526 HRESULT
527 com_get_state(int sock, COM_STATE *state)
528 {
529  int ret;
530  HRESULT hr = S_OK;
531 
532  if (sock <= 0)
533  return E_HANDLE;
534  if (state == NULL)
535  return E_INVALIDARG;
536 
537  ret = _com_get_state(sock, state);
538 
539  if (OSFAILED(ret)) {
540  ret = DNGetLastError();
541  hr = OSERR2HRESULT(ret);
542  }
543 
544  return hr;
545 }
546 
553 HRESULT
554 com_set_state(int sock, COM_STATE *state)
555 {
556  int ret;
557  HRESULT hr = S_OK;
558 
559  if (sock <= 0)
560  return E_HANDLE;
561  if (state == NULL)
562  return E_INVALIDARG;
563 
564  ret = _com_set_state(sock, state);
565 
566  if (OSFAILED(ret)) {
567  ret = DNGetLastError();
568  hr = OSERR2HRESULT(ret);
569  }
570 
571  return hr;
572 }
573 
580 HRESULT
581 com_get_modem_state(int sock, uint32_t *state)
582 {
583  int ret;
584  HRESULT hr = S_OK;
585 
586  if (sock <= 0)
587  return E_HANDLE;
588  if (state == NULL)
589  return E_INVALIDARG;
590 
591  ret = _com_get_modem_state(sock, state);
592 
593  if (OSFAILED(ret)) {
594  ret = DNGetLastError();
595  hr = OSERR2HRESULT(ret);
596  }
597 
598  return hr;
599 }
static int _com_set_state(int sock, COM_STATE *state)
unsigned uint32_t
Definition: stdint.h:43
static int32_t _com_clear(int sock, uint32_t timeout)
#define _FLOW_HARDWARE
Definition: dn_com.c:54
#define ODDPARITY
A definition for serial communication setting.
Definition: dn_device.h:75
static int _com_get_state(int sock, COM_STATE *state)
HRESULT com_clear(int sock, uint32_t timeout)
Clears the received buffer.
Definition: dn_com.c:508
HRESULT com_set_timeout(int sock, uint32_t timeout)
Sets timeout value to the serial socket.
Definition: dn_com.c:489
#define _FLOW_XINOUT
Definition: dn_com.c:53
#define S_OK
Succeeded.
Definition: dn_common.h:89
static int _com_send(int sock, const char *buf, uint32_t len_send, uint32_t *len_sended, void *arg)
static int32_t _com_set_timeout(int sock, uint32_t timeout)
#define EVENPARITY
A definition for serial communication setting.
Definition: dn_device.h:81
#define E_HANDLE
Failed because the handle is invalid.
Definition: dn_common.h:119
static int _com_recv(int sock, char *buf, uint32_t len_recv, uint32_t *len_recved, uint32_t timeout, void *arg)
HRESULT com_open(void *param, int *sock)
Opens serial port.
Definition: dn_com.c:360
#define E_INVALIDARG
Failed because some arguments are invalid.
Definition: dn_common.h:131
int32_t HRESULT
Definition: dn_common.h:61
#define DNGetLastError()
A macro that gets last OS error.
HRESULT com_get_state(int sock, COM_STATE *state)
Gets the serial socket parameters.
Definition: dn_com.c:527
HRESULT com_set_state(int sock, COM_STATE *state)
Puts the serial socket parameters.
Definition: dn_com.c:554
int COM_STATE
#define NOPARITY
A definition for serial communication setting.
Definition: dn_device.h:69
#define SUCCEEDED(hr)
A macro that returns TRUE/FALSE. If hr is zero or more, then returns TRUE.
Definition: dn_common.h:71
static int32_t _com_open(const void *com_param, int *sock)
Common device API file.
#define ONESTOPBIT
A definition for serial communication setting.
Definition: dn_device.h:87
Common API file.
#define O_NONBLOCK
Definition: dn_additional.h:83
HRESULT com_send(int sock, const char *buf, uint32_t len_buf, void *arg)
Sends serial packet.
Definition: dn_com.c:412
#define OSFAILED(ret)
A macro that returns TRUE/FALSE. If ret is OS failed, then returns TRUE.
static int _com_close(int sock)
HRESULT com_recv(int sock, char *buf, uint32_t len_buf, uint32_t *len_recved, uint32_t timeout, void *arg)
Receives serial packet.
Definition: dn_com.c:453
User own API file.
uint32_t baud_rate
Definition: dn_device.h:159
static int _com_get_modem_state(int sock, uint32_t *state)
HRESULT com_close(int *sock)
Closes the socket.
Definition: dn_com.c:385
A type definition for serial connection parameters.
Definition: dn_device.h:156
_DN_EXP_DEVICE HRESULT check_timeout(int sock, uint32_t timeout)
Checks the communication timeout.
Definition: dn_device.c:385
#define OSSUCCEEDED(ret)
A macro that returns TRUE/FALSE. If ret is OS succeeded, then returns TRUE.
Serial API file.
HRESULT com_get_modem_state(int sock, uint32_t *state)
Gets the serial port pin status.
Definition: dn_com.c:581
#define _COM_PORT_MAX
Definition: dn_com.c:51
#define E_TIMEOUT
Failed because the communication timed out.
Definition: dn_common.h:169
#define OSERR2HRESULT(err)
A macro that returns HREUSLT(0x8091) which means OS error.
Definition: dn_common.h:205
#define TWOSTOPBITS
A definition for serial communication setting.
Definition: dn_device.h:93


bcap_core
Author(s): DENSO WAVE INCORPORATED
autogenerated on Mon Jun 10 2019 13:12:20