00001 #include "LCDConnection.h"
00002 #include "LCDException.h"
00003 #include "string.h"
00004 #include <string.h>
00005 #include <errno.h>
00006 #include <fcntl.h>
00007 #include <iostream>
00008
00009 using namespace std;
00010
00011 LCDConnection::LCDConnection()
00012 {
00013 _isConnected = false;
00014 memset(&_addr, 0, sizeof (_addr));
00015 _sock = socket (AF_INET, SOCK_STREAM, 0 );
00016
00017 if (!isValid())
00018 {
00019 throw LCDException(LCD_SOCKET_CREATION_ERROR);
00020 }
00021
00022 int on = 1;
00023 if (setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof (on)) == -1)
00024 {
00025 throw LCDException(LCD_SOCKET_CREATION_ERROR);
00026 }
00027 }
00028
00029 LCDConnection::LCDConnection(const string &host, const int port)
00030 {
00031 LCDConnection();
00032 connect(host, port);
00033 }
00034
00035 LCDConnection::LCDConnection(const LCDConnection &source)
00036 {
00037 _sock = source._sock;
00038 _isConnected = source._isConnected;
00039 }
00040
00041 LCDConnection::~LCDConnection()
00042 {
00043 disconnect();
00044 }
00045
00046 bool LCDConnection::isValid() const
00047 {
00048 return _sock != -1;
00049 }
00050
00051 void LCDConnection::connect(const string &host, const int port)
00052 {
00053 if (!isValid())
00054 {
00055 throw LCDException(LCD_SOCKET_CREATION_ERROR);
00056 }
00057
00058 _addr.sin_family = AF_INET;
00059 _addr.sin_port = htons(port);
00060
00061 int status = inet_pton(AF_INET, host.c_str(), &_addr.sin_addr);
00062
00063 if (errno == EAFNOSUPPORT)
00064 {
00065 throw LCDException(LCD_SOCKET_NOT_SUPPORTED);
00066 }
00067
00068 status = ::connect(_sock, (sockaddr *)&_addr, sizeof(_addr) );
00069
00070 if (status != 0)
00071 {
00072 throw LCDException(LCD_SOCKET_CONNECTION_ERROR);
00073 }
00074
00075 _isConnected = true;
00076 }
00077
00078 void LCDConnection::disconnect()
00079 {
00080 if (isValid())
00081 {
00082 ::close(_sock);
00083 }
00084 }
00085
00086 void LCDConnection::send(const string &toSend)
00087 {
00088 string s = toSend + "\r\n";
00089
00090 cerr << "Sending : " << s << endl;
00091
00092 if (!_isConnected)
00093 {
00094 throw LCDException(LCD_SOCKET_NOT_CONNECTED);
00095 }
00096
00097 int total = s.size();
00098 int offset = 0;
00099 int sent;
00100
00101 while (offset != total)
00102 {
00103 sent = ::send(_sock, s.c_str() + offset, s.size() - offset, 0);
00104 if ( ((sent == -1) && (errno != EAGAIN)) || (sent == 0) )
00105 {
00106 throw LCDException(LCD_SOCKET_SEND_ERROR);
00107 }
00108 else
00109 {
00110 offset += sent;
00111 }
00112 }
00113 }
00114
00115 string LCDConnection::recv()
00116 {
00117 if (!_isConnected)
00118 {
00119 throw LCDException(LCD_SOCKET_NOT_CONNECTED);
00120 }
00121
00122 char buf[LCD_MAXRECV + 1];
00123 memset (buf, 0, LCD_MAXRECV + 1);
00124 char *current = buf - 1;
00125 int status;
00126
00127 do
00128 {
00129 current++;
00130 status = ::recv(_sock, current, 1, 0);
00131 if (status == -1)
00132 {
00133 throw LCDException(LCD_SOCKET_RECV_ERROR);
00134 }
00135 } while ( (*current != '\0' ) && (*current != '\r' ) && (*current != '\n' ) && ((current - buf) < LCD_MAXRECV) );
00136
00137 *current = '\0';
00138
00139 string result(buf);
00140
00141 cerr << "Receiving : " << result << endl;
00142
00143 return result;
00144 }
00145
00146 LCDConnection & LCDConnection::operator = (const LCDConnection ©)
00147 {
00148 disconnect();
00149
00150 _sock = copy._sock;
00151 _isConnected = copy._isConnected;
00152 }
00153
00154 const LCDConnection& LCDConnection::operator << (const string &s)
00155 {
00156 send(s);
00157 return *this;
00158 }
00159
00160 const LCDConnection& LCDConnection::operator >> (string &s)
00161 {
00162 s = recv();
00163 return *this;
00164 }
00165