serial_transport_tcp_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 #include <winsock.h>
00038 #pragma comment(lib, "Ws2_32.lib")
00039 #define snprintf sprintf_s
00040 #endif /* WIN32 */
00041 
00042 #include "tm_reader.h"
00043 
00044 __declspec(dllexport) TMR_Status
00045 tcp_open(TMR_SR_SerialTransport *this)
00046 {
00047   TMR_SR_SerialPortNativeContext *c;
00048   struct hostent *he;
00049   struct in_addr **addr_list;
00050   struct sockaddr_in server;
00051   char ip[100];
00052   char hostCopy[256];
00053   SOCKET s;
00054   WSADATA wsa;
00055   uint8_t i;
00056   int portNum = 0;
00057   const char* port;
00058   TMR_Status ret = TMR_SUCCESS;
00059 
00060   c = this->cookie;
00061   port = strchr(c->devicename, ':');
00062   strcpy(hostCopy, c->devicename + 1);
00063   portNum = atoi(port + 1);
00064   hostCopy[port - c->devicename -1 ] = '\0';
00065 
00066   /* Initialising Winsock... */
00067   if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
00068   {
00069           ret = WSAGetLastError();
00070           WSACleanup();
00071           return ret;
00072   }
00073 
00074   if ( (he = gethostbyname( hostCopy ) ) == NULL)
00075   {
00076           ret = WSAGetLastError();
00077           WSACleanup();
00078           return ret;
00079   }
00080   addr_list = (struct in_addr **) he->h_addr_list;
00081   for(i = 0; addr_list[i] != NULL; i++)
00082   {
00083           //Return the first one;
00084           strcpy(ip , inet_ntoa(*addr_list[i]) );
00085   }
00086 
00087   /* create a socket */
00088   if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
00089   {
00090           /* Could not create socket */
00091           ret = WSAGetLastError();
00092           WSACleanup();
00093           return ret;
00094   }
00095 
00096   server.sin_addr.s_addr = inet_addr(ip);
00097   server.sin_family = AF_INET;
00098   server.sin_port = htons(portNum);
00099 
00100   /* Connect the socket to the reader. This can stall. */
00101   if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
00102   {
00103           /* Connect error */
00104           closesocket(s);
00105           WSACleanup();
00106           return TMR_ERROR_INVALID;
00107   }
00108 
00109   /* Record the socket in the connection instance */
00110   c->handle = (PLATFORM_HANDLE)s;
00111   
00112   return TMR_SUCCESS;
00113 }
00114 
00115 __declspec(dllexport) TMR_Status
00116 tcp_sendBytes(TMR_SR_SerialTransport *this, uint32_t length,
00117             uint8_t* message, const uint32_t timeoutMs)
00118 {
00119   TMR_SR_SerialPortNativeContext *c;
00120   uint32_t sendLen = 0;
00121   TMR_Status ret = TMR_SUCCESS;
00122   
00123   c = this->cookie;
00124     
00125   sendLen = send( (SOCKET)c->handle, message, (int)length, 0 );
00126   if (sendLen == SOCKET_ERROR)
00127   {
00128           /* send failed */
00129           closesocket((SOCKET)c->handle);
00130           WSACleanup();
00131           return ret;
00132   }
00133   return ret;
00134 }
00135 
00136 __declspec(dllexport) TMR_Status
00137 tcp_receiveBytes(TMR_SR_SerialTransport *this, uint32_t length,
00138               uint32_t* messageLength, uint8_t* message, const uint32_t
00139 timeoutMs)
00140 {
00141  int32_t readLength;
00142  TMR_Status ret = TMR_SUCCESS;
00143  TMR_SR_SerialPortNativeContext *c;
00144  DWORD dwTime = timeoutMs;
00145 
00146  c = this->cookie;
00147  *messageLength = 0;
00148 
00149  setsockopt((SOCKET)c->handle, SOL_SOCKET, SO_RCVTIMEO, (const char*)&dwTime, sizeof(dwTime));
00150 
00151  while (length > 0)
00152  {
00153    readLength=0;
00154    readLength = recv((SOCKET)c->handle, message, length, 0);   
00155    if (readLength > 0)
00156    {
00157            /* bytes received */
00158            *messageLength += readLength;
00159    }
00160    else if(readLength == 0)
00161    {
00162            /* send failed */
00163         closesocket((SOCKET)c->handle);
00164         WSACleanup();
00165                 return TMR_ERROR_TIMEOUT;
00166    }
00167    else
00168    {
00169            ret = WSAGetLastError();
00170      if (WSAETIMEDOUT == ret)
00171      {
00172        return TMR_ERROR_TIMEOUT;
00173      }
00174            return ret;
00175    }
00176    length -= readLength;
00177    message += readLength;
00178  }
00179  return ret;
00180 }
00181 
00182 #if 0
00183 __declspec(dllexport) TMR_Status
00184 tcp_setBaudRate(TMR_SR_SerialTransport *this, uint32_t rate)
00185 {
00186   TMR_SR_SerialPortNativeContext *c;
00187   DCB   dcb;
00188 
00189   c = this->cookie;
00190 
00191   dcb.DCBlength = sizeof(DCB);
00192   GetCommState(c->handle, &dcb);
00193   dcb.BaudRate  = rate;
00194 
00195   if (0 == SetCommState(c->handle, &dcb)) /* @todo use GetLastError() */
00196   {
00197     return TMR_ERROR_INVALID;
00198   }
00199 
00200   return TMR_SUCCESS;
00201 }
00202 #endif
00203 
00204 static TMR_Status
00205 tcp_shutdown(TMR_SR_SerialTransport *this)
00206 {
00207   TMR_SR_SerialPortNativeContext *c;
00208   TMR_Status ret = TMR_SUCCESS;
00209 
00210   c = this->cookie;
00211   
00212   closesocket((SOCKET)c->handle);
00213   WSACleanup();
00214 
00215   return ret;
00216 }
00217 
00218 static TMR_Status
00219 tcp_flush(TMR_SR_SerialTransport *this)
00220 {
00221 
00222   return TMR_SUCCESS;
00223 }
00224 
00225 __declspec(dllexport)TMR_Status
00226 TMR_SR_SerialTransportTcpNativeInit(TMR_SR_SerialTransport *transport,
00227                                  TMR_SR_SerialPortNativeContext *context,
00228                                  const char *device)
00229 {
00230   if (strlen(device) + 1 > TMR_MAX_READER_NAME_LENGTH)
00231   {
00232           return TMR_ERROR_INVALID;
00233   }
00234   strcpy(context->devicename, device);
00235 
00236   transport->cookie = context;
00237   transport->open = tcp_open;
00238   transport->sendBytes = tcp_sendBytes;
00239   transport->receiveBytes = tcp_receiveBytes;
00240   transport->setBaudRate = NULL;
00241   transport->shutdown = tcp_shutdown;
00242   transport->flush = tcp_flush;
00243 
00244   return TMR_SUCCESS;
00245 }


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