serial_transport_win32.c
Go to the documentation of this file.
00001 
00009 /*
00010  * Copyright (c) 2010 ThingMagic, Inc.
00011  *
00012  * Permission is hereby granted, free of charge, to any person obtaining a copy
00013  * of this software and associated documentation files (the "Software"), to deal
00014  * in the Software without restriction, including without limitation the rights
00015  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00016  * copies of the Software, and to permit persons to whom the Software is
00017  * furnished to do so, subject to the following conditions:
00018  *
00019  * The above copyright notice and this permission notice shall be included in
00020  * all copies or substantial portions of the Software.
00021  * 
00022  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00025  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00028  * THE SOFTWARE.
00029  */
00030 
00031 #include "tm_config.h"
00032 #include "tmr_status.h"
00033 
00034 #ifdef WIN32
00035 #include <windows.h>
00036 #include <stdio.h>
00037 #define snprintf sprintf_s 
00038 #endif /* WIN32 */
00039 
00040 #include "tm_reader.h"
00041 
00042 __declspec(dllexport) TMR_Status
00043 s_open(TMR_SR_SerialTransport *this)
00044 {
00045   TMR_SR_SerialPortNativeContext *c;
00046   COMMTIMEOUTS timeOuts;
00047   DCB dcb;
00048 
00049   c = this->cookie;
00050   
00051   c->handle = CreateFileA((LPCSTR)c->devicename,
00052                          GENERIC_READ | GENERIC_WRITE,
00053                          0,             /* not shared */
00054                          NULL,          /* default security */
00055                          OPEN_EXISTING, /* don't create a new file */
00056                          0,             /* flags and attributes */
00057                          NULL);         /* template file */
00058                          
00059   if (INVALID_HANDLE_VALUE == c->handle)
00060     return TMR_ERROR_INVALID; /* @todo use GetLastError() */
00061 
00062   timeOuts.ReadIntervalTimeout          = 0xFFFFFFFF;
00063   timeOuts.ReadTotalTimeoutConstant     = 0;
00064   timeOuts.ReadTotalTimeoutMultiplier   = 0;
00065   timeOuts.WriteTotalTimeoutConstant    = 5000;
00066   timeOuts.WriteTotalTimeoutMultiplier  = 0;
00067   
00068   SetCommTimeouts(c->handle, &timeOuts);
00069 
00070   dcb.DCBlength = sizeof(DCB);
00071   GetCommState(c->handle, &dcb);
00072   dcb.fOutxCtsFlow = 0;
00073   dcb.fOutxDsrFlow = 0;
00074   dcb.fDtrControl = DTR_CONTROL_DISABLE;
00075   dcb.fDsrSensitivity = 0;
00076   dcb.fOutX = 0;
00077   dcb.fInX = 0;
00078   dcb.fNull = 0;
00079   dcb.fRtsControl = RTS_CONTROL_DISABLE;
00080   dcb.ByteSize  = 8;
00081   dcb.fParity = NOPARITY;
00082   dcb.StopBits = ONESTOPBIT;
00083   if ((0 == SetCommState(c->handle, &dcb)) ||
00084       (0 == SetupComm(c->handle, 10000, 10000)))
00085   {
00086     return TMR_ERROR_INVALID;  /* @todo use GetLastError() */
00087   }
00088   
00089   return TMR_SUCCESS;
00090 }
00091 
00092 __declspec(dllexport) TMR_Status
00093 s_sendBytes(TMR_SR_SerialTransport *this, uint32_t length,
00094             uint8_t* message, const uint32_t timeoutMs)
00095 {
00096   TMR_SR_SerialPortNativeContext *c;
00097   BOOL writeStatus;
00098   COMMTIMEOUTS timeOuts;
00099 
00100   c = this->cookie;
00101   GetCommTimeouts(c->handle, &timeOuts);
00102   timeOuts.WriteTotalTimeoutConstant = timeoutMs;
00103   SetCommTimeouts(c->handle, &timeOuts);
00104   
00105   {
00106         long numberOfBytesWritten;
00107         writeStatus = WriteFile(c->handle, message, length, &numberOfBytesWritten, NULL);
00108   }
00109   if (0 == writeStatus)
00110   {
00111     return TMR_ERROR_TIMEOUT;  /* @todo use GetLastError() */
00112   }
00113   return TMR_SUCCESS;
00114 }
00115 
00116 __declspec(dllexport) TMR_Status
00117 s_receiveBytes(TMR_SR_SerialTransport *this, uint32_t length,
00118               uint32_t* messageLength, uint8_t* message, const uint32_t
00119 timeoutMs)
00120 {
00121  uint32_t readLength;
00122  DWORD errorFlags;
00123  COMSTAT comStat;
00124  TMR_SR_SerialPortNativeContext *c;
00125  BOOL    readStatus;
00126  COMMTIMEOUTS timeOuts;
00127 
00128  c = this->cookie;
00129  *messageLength=0;
00130 
00131  GetCommTimeouts(c->handle, &timeOuts);
00132  timeOuts.ReadTotalTimeoutConstant = timeoutMs;
00133  SetCommTimeouts(c->handle, &timeOuts);
00134 
00135  ClearCommError(c->handle, &errorFlags, &comStat);
00136  while (length > 0)
00137  {
00138    readLength=0;
00139    readStatus = ReadFile(c->handle, message, length, &readLength, NULL);
00140    *messageLength += readLength;
00141    if (0 == readStatus)
00142    {
00143      return TMR_ERROR_TIMEOUT;  /* @todo use GetLastError() */
00144    }
00145    if(readLength == 0)
00146    {
00147      return TMR_ERROR_TIMEOUT;
00148    }
00149    length -= readLength;
00150    message += readLength;
00151 
00152  }
00153  return TMR_SUCCESS;
00154 }
00155 
00156 
00157 __declspec(dllexport) TMR_Status
00158 s_setBaudRate(TMR_SR_SerialTransport *this, uint32_t rate)
00159 {
00160   TMR_SR_SerialPortNativeContext *c;
00161   DCB   dcb;
00162 
00163   c = this->cookie;
00164 
00165   dcb.DCBlength = sizeof(DCB);
00166   GetCommState(c->handle, &dcb);
00167   dcb.BaudRate  = rate;
00168 
00169   if (0 == SetCommState(c->handle, &dcb)) /* @todo use GetLastError() */
00170   {
00171     return TMR_ERROR_INVALID;
00172   }
00173 
00174   return TMR_SUCCESS;
00175 }
00176 
00177 static TMR_Status
00178 s_shutdown(TMR_SR_SerialTransport *this)
00179 {
00180   TMR_SR_SerialPortNativeContext *c;
00181 
00182   c = this->cookie;
00183 
00184   CloseHandle(c->handle);
00185   /* What, exactly, would be the point of checking for an error here? */
00186 
00187   return TMR_SUCCESS;
00188 }
00189 
00190 static TMR_Status
00191 s_flush(TMR_SR_SerialTransport *this)
00192 {
00193   TMR_SR_SerialPortNativeContext *c;
00194 
00195   c = this->cookie;
00196 
00197   if (PurgeComm(c->handle, PURGE_RXCLEAR) == 0)
00198   {
00199           return TMR_ERROR_COMM_ERRNO(errno);
00200   }
00201   return TMR_SUCCESS;
00202 }
00203 
00204 __declspec(dllexport)TMR_Status
00205 TMR_SR_SerialTransportNativeInit(TMR_SR_SerialTransport *transport,
00206                                  TMR_SR_SerialPortNativeContext *context,
00207                                  const char *device)
00208 {
00209   // Transform COM port name from "/COMnn" to "\\\\.\\COMnn"
00210   if (strlen(device)-1 + 4 + 1 > TMR_MAX_READER_NAME_LENGTH)
00211   {
00212     return TMR_ERROR_INVALID;
00213   }
00214   snprintf(context->devicename, sizeof(context->devicename),
00215     "\\\\.\\%s", device+1);
00216 
00217   transport->cookie = context;
00218   transport->open = s_open;
00219   transport->sendBytes = s_sendBytes;
00220   transport->receiveBytes = s_receiveBytes;
00221   transport->setBaudRate = s_setBaudRate;
00222   transport->shutdown = s_shutdown;
00223   transport->flush = s_flush;
00224 
00225   return TMR_SUCCESS;
00226 }


thingmagic_rfid
Author(s): Brian Bingham
autogenerated on Thu May 16 2019 03:01:24