All Classes Namespaces Files Functions Variables Enumerations Enumerator
libs/connection/SerialDevice_win.cpp
Go to the documentation of this file.
00001 
00010 #include "DetectOS.h"
00011 #include <windows.h>
00012 #include <setupapi.h>
00013 #include <string>
00014 #include <cstdio>
00015 
00016 #ifdef MSC
00017 #define snprintf _snprintf
00018 #endif
00019 
00020 using namespace std;
00021 
00022 #undef min
00023 #undef max
00024 
00025 
00026 class RawSerialDevice
00027 {
00028     string error_message_;
00029     HANDLE hCom_;
00030     int current_timeout_;
00031     string com_name_;
00032 
00033 
00034 public:
00035     RawSerialDevice(void)
00036         : error_message_("no error."), hCom_(INVALID_HANDLE_VALUE),
00037           current_timeout_(0)
00038     {
00039     }
00040 
00041 
00042     const char* what(void)
00043     {
00044         return error_message_.c_str();
00045     }
00046 
00047 
00048     bool connect(const char* device, long baudrate)
00049     {
00050         /* COM ポートを開く */
00051         enum { NameLength = 11 };
00052         char adjusted_device[NameLength];
00053         snprintf(adjusted_device, NameLength, "\\\\.\\%s", device);
00054         hCom_ = CreateFileA(adjusted_device, GENERIC_READ | GENERIC_WRITE, 0,
00055                             NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00056 
00057         if (hCom_ == INVALID_HANDLE_VALUE) {
00058             error_message_ = string("open failed: ") + device;
00059             return false;
00060         }
00061         com_name_ = device;
00062 
00063         // 通信サイズの更新
00064         SetupComm(hCom_, 4096 * 8, 4096);
00065 
00066         // タイムアウト設定
00067         setTimeout(current_timeout_);
00068 
00069         // ボーレートの変更
00070         bool ret = setBaudrate(baudrate);
00071         if (! ret) {
00072             error_message_ = "fail SerialDevice::setBaudrate()";
00073         }
00074 
00075         return true;
00076     }
00077 
00078 
00079     void setTimeout(int timeout)
00080     {
00081         COMMTIMEOUTS timeouts;
00082         GetCommTimeouts(hCom_, &timeouts);
00083 
00084         timeouts.ReadIntervalTimeout = (timeout == 0) ? MAXDWORD : 0;
00085         timeouts.ReadTotalTimeoutConstant = timeout;
00086         timeouts.ReadTotalTimeoutMultiplier = 0;
00087 
00088         SetCommTimeouts(hCom_, &timeouts);
00089     }
00090 
00091 
00092 
00093     void disconnect(void)
00094     {
00095         if (hCom_ != INVALID_HANDLE_VALUE) {
00096             CloseHandle(hCom_);
00097             hCom_ = INVALID_HANDLE_VALUE;
00098         }
00099     }
00100 
00101 
00102     bool isConnected(void)
00103     {
00104         return (hCom_ == INVALID_HANDLE_VALUE) ? false : true;
00105     }
00106 
00107 
00108     bool setBaudrate(long baudrate)
00109     {
00110         long baudrate_value;
00111         switch (baudrate) {
00112 
00113         case 4800:
00114             baudrate_value = CBR_4800;
00115             break;
00116 
00117         case 9600:
00118             baudrate_value = CBR_9600;
00119             break;
00120 
00121         case 19200:
00122             baudrate_value = CBR_19200;
00123             break;
00124 
00125         case 38400:
00126             baudrate_value = CBR_38400;
00127             break;
00128 
00129         case 57600:
00130             baudrate_value = CBR_57600;
00131             break;
00132 
00133         case 115200:
00134             baudrate_value = CBR_115200;
00135             break;
00136 
00137         default:
00138             baudrate_value = baudrate;
00139         }
00140 
00141         DCB dcb;
00142         GetCommState(hCom_, &dcb);
00143         dcb.BaudRate = baudrate_value;
00144         dcb.ByteSize = 8;
00145         dcb.Parity = NOPARITY;
00146         dcb.fParity = FALSE;
00147         dcb.StopBits = ONESTOPBIT;
00148         if (SetCommState(hCom_, &dcb) == 0) {
00149             flush();
00150             return false;
00151         } else {
00152             return true;
00153         }
00154     }
00155 
00156 
00157     int send(const char* data, size_t count)
00158     {
00159         if (count <= 0) {
00160             return 0;
00161         }
00162 
00163         DWORD n;
00164         WriteFile(hCom_, data, (DWORD)count, &n, NULL);
00165         return n;
00166     }
00167 
00168 
00169     int receive(char data[], int count, int timeout)
00170     {
00171         if (count <= 0) {
00172             return 0;
00173         }
00174 
00175         if (timeout != current_timeout_) {
00176             setTimeout(timeout);
00177             current_timeout_ = timeout;
00178         }
00179 
00180         DWORD n;
00181         ReadFile(hCom_, data, count, &n, NULL);
00182 
00183         return n;
00184     }
00185 
00186 
00187     void flush(void)
00188     {
00189         PurgeComm(hCom_,
00190                   PURGE_RXABORT | PURGE_TXABORT |
00191                   PURGE_RXCLEAR | PURGE_TXCLEAR);
00192     }
00193 };