Index: trunk/FACT++/src/Connection.cc
===================================================================
--- trunk/FACT++/src/Connection.cc	(revision 10278)
+++ trunk/FACT++/src/Connection.cc	(revision 10284)
@@ -31,5 +31,5 @@
 }
 
-void Connection::AsyncRead(ba::mutable_buffers_1 buffers, int type)
+void Connection::AsyncRead(const ba::mutable_buffers_1 buffers, int type)
 {
     ba::async_read(*this, buffers,
@@ -38,5 +38,5 @@
 }
 
-void Connection::AsyncWrite(ba::mutable_buffers_1 buffers)
+void Connection::AsyncWrite(const ba::const_buffers_1 &buffers)
 {
     ba::async_write(*this, buffers,
@@ -63,7 +63,4 @@
 void Connection::AsyncConnect(tcp::resolver::iterator iterator)
 {
-    //cout << "Start async connect(...)" << endl;
-    fConnectionStatus = 1;
-
     tcp::endpoint endpoint = *iterator;
 
@@ -72,5 +69,5 @@
                   boost::bind(&Connection::ConnectImp,
                               this, ba::placeholders::error,
-                              ++iterator));
+                              iterator));
 
     // We will get a "Connection timeout anyway"
@@ -85,5 +82,5 @@
     {
         stringstream str;
-        str << "Connection closed to " << URL() << ".";// << endl;
+        str << "Connection closed to " << URL() << ".";
         Message(str);
     }
@@ -96,5 +93,5 @@
 
     // Reset the connection status
-    fConnectionStatus = 0;
+    fConnectionStatus = kDisconnected;
 
     // Stop deadline counters
@@ -102,4 +99,7 @@
     fOutTimeout.cancel();
 
+    // Empty output queue
+    fOutQueue.clear();
+
     if (!restart || IsConnecting())
         return;
@@ -111,4 +111,5 @@
     // Start trying to reconnect
     fMsgConnect = "";
+    fErrConnect = "";
     StartConnect();
 }
@@ -122,10 +123,13 @@
 void Connection::HandleWriteTimeout(const bs::error_code &error)
 {
-    // 125: Operation canceled
-    if (error && error!=bs::error_code(125, bs::system_category))
+    // 125: Operation canceled (bs::error_code(125, bs::system_category))
+    if (error && error!=ba::error::basic_errors::operation_aborted)
     {
         stringstream str;
         str << "Write timeout of " << URL() << ": " << error.message() << " (" << error << ")";// << endl;
         Error(str);
+
+        CloseImp();
+        return;
     }
 
@@ -149,5 +153,5 @@
 }
 
-void Connection::HandleSentData(const bs::error_code& error, size_t)
+void Connection::HandleSentData(const bs::error_code& error, size_t n)
 {
     if (error)
@@ -161,5 +165,7 @@
     }
 
-    Message("Data successfully sent to "+URL());
+    stringstream msg;
+    msg << n << " bytes successfully sent to " << URL();
+    Message(msg);
 
     // This is "thread" safe because SendMessage and HandleSentMessage
@@ -177,9 +183,11 @@
 
     // AsyncWrite + Deadline
-    AsyncWrite(ba::buffer(fOutQueue.front())/*, &Connection::HandleSentData*/);
+    AsyncWrite(ba::const_buffers_1(&fOutQueue.front()[0],fOutQueue.front().size())/*, &Connection::HandleSentData*/);
     AsyncWait(fOutTimeout, 5000, &Connection::HandleWriteTimeout);
 }
 
-void Connection::SendMessageImp(const vector<char> &msg)
+// It is important that when SendMessageImp is called, or to be more
+// precise boost::bind is called, teh data is copied!
+void Connection::SendMessageImp(const vector<char> msg)
 {
     /*
@@ -202,24 +210,6 @@
 
     // AsyncWrite + Deadline
-    AsyncWrite(ba::buffer(fOutQueue.front())/*, &Connection::HandleSentData*/);
+    AsyncWrite(ba::const_buffers_1(&fOutQueue.front()[0],fOutQueue.front().size())/*, &Connection::HandleSentData*/);
     AsyncWait(fOutTimeout, 5000, &Connection::HandleWriteTimeout);
-}
-
-void Connection::PostMessage(vector<uint16_t> inp)
-{
-    // Convert to network byte order
-    for_each(inp.begin(), inp.end(), htons);
-
-    // FIXME FIXME
-
-    PostMessage((char*)&inp.front(), sizeof(uint16_t)*inp.size());
-
-//    const vector<char> msg((char*)&inp.front(), (char*)&inp.last()+1);
-//    get_io_service().post(boost::bind(&Connection::SendMessageImp, this, msg));
-}
-
-void Connection::PostMessage(const vector<char> &msg)
-{
-    get_io_service().post(boost::bind(&Connection::SendMessageImp, this, msg));
 }
 
@@ -239,11 +229,7 @@
     vector <char>msg(max);
 
-    for (unsigned int i=0; i<max; i++)
-        msg[i] = 0;
-
-    for (unsigned int i=0; i<min(cmd.length()+1, max); i++)
-        msg[i] = cmd[i];
-
-    get_io_service().post(boost::bind(&Connection::SendMessageImp, this, msg));
+    copy(cmd.begin(), cmd.begin()+min(cmd.length()+1, max), msg.begin());
+
+    PostMessage(msg);
 }
 
@@ -251,5 +237,5 @@
 {
     // 125: Operation canceled
-    if (error && error!=bs::error_code(125, bs::system_category))
+    if (error && error!=ba::error::basic_errors::operation_aborted)
     {
         stringstream str;
@@ -274,28 +260,17 @@
 
 void Connection::ConnectImp(const bs::error_code& error,
-                            tcp::resolver::iterator endpoint_iterator)
-{
+                            tcp::resolver::iterator iterator)
+{
+    tcp::endpoint endpoint = *iterator;
+
+    const string host = endpoint.port()==0 ? "" :
+        endpoint.address().to_string()+":"+lexical_cast<string>(endpoint.port());
+
     // Connection established
     if (!error)
     {
-        Message("Connection established to "+URL()+"...");
-
-        // Initialize hardware...
-        // Set state to : connected/undefined until we get the first message
-        //                (send request for configuration) ?
-        //                (send configuration?)
-        fMsgConnect = "";
-        fErrConnect = "";
-
-        fConnectionStatus = 2;
-        //StartAsyncRead();
-
-        // We can create the buffer here and delete it in
-        // Handle Read. However, the read buffer is not filled again
-        // before it was not read within HandleReceivedData -- so a single
-        // buffer should be good enough. Before HandleReceivedData
-        // returns the data must be copied to a "safe" place.
-
-        // fSocket.get_io_service()/*fEventQueue*/.stop();
+        Message("Connection established to "+host+"...");
+
+        fConnectionStatus = kConnected;
 
         ConnectionEstablished();
@@ -309,25 +284,21 @@
     // the endpoint again.
     CloseImp(false);
-    //fSocket.close();
-
-    // 111: Connection refused
-    if (1/*error!=bs::error_code(111, bs::system_category)*/)
-    {
-        stringstream msg;
-        if (URL()!=":")
-            msg << "Connecting to " << URL() << ": " << error.message() << " (" << error << ")";
-
-        if (fErrConnect!=msg.str())
-        {
+
+    stringstream msg;
+    if (!host.empty())
+        msg << "Connecting to " << host << ": " << error.message() << " (" << error << ")";
+
+    if (fErrConnect!=msg.str())
+    {
+        if (error!=ba::error::basic_errors::connection_refused)
             fMsgConnect = "";
-            fErrConnect = msg.str();
-            Warn(fErrConnect);
-        }
+        fErrConnect = msg.str();
+        Warn(fErrConnect);
     }
 
     // Go on with the next
-    if (endpoint_iterator != tcp::resolver::iterator())
-    {
-        AsyncConnect(endpoint_iterator);
+    if (++iterator != tcp::resolver::iterator())
+    {
+        AsyncConnect(iterator);
         return;
     }
@@ -346,5 +317,5 @@
 void Connection::StartConnect()
 {
-    fConnectionStatus = 1;
+    fConnectionStatus = kConnecting;
 
     tcp::resolver resolver(get_io_service());
@@ -401,5 +372,5 @@
     if (p0==string::npos || p0!=p1)
     {
-        Error("Connection::SetEndPoint - Wrong format of argument.");
+        Error("Connection::SetEndPoint - Wrong format of argument ('host:port' expected)");
         return;
     }
@@ -411,24 +382,7 @@
 
 Connection::Connection(ba::io_service& ioservice, ostream &out) :
-MessageImp(out), tcp::socket(ioservice),
-fLog(0), //fAddress("localhost"), fPort("5000"),
+MessageImp(out), tcp::socket(ioservice), fLog(0),
 fInTimeout(ioservice), fOutTimeout(ioservice), fConnectionTimer(ioservice),
-fConnectionStatus(0)
-{
-}
-/*
-Connection::Connection(ba::io_service& ioservice, const string &addr, int port) :
-tcp::socket(ioservice),
-fLog(0), fAddress(addr), fPort(lexical_cast<string>(port)),
-fInTimeout(ioservice), fOutTimeout(ioservice), fConnectionTimer(ioservice),
-fConnectionStatus(0)
-{
-}
-
-Connection::Connection(ba::io_service& ioservice, const string &addr, const string &port) :
-tcp::socket(ioservice), fLog(0), fAddress(addr), fPort(port),
-fInTimeout(ioservice), fOutTimeout(ioservice), fConnectionTimer(ioservice),
-fConnectionStatus(0)
-{
-}
-*/
+fConnectionStatus(kDisconnected)
+{
+}
Index: trunk/FACT++/src/Connection.h
===================================================================
--- trunk/FACT++/src/Connection.h	(revision 10278)
+++ trunk/FACT++/src/Connection.h	(revision 10284)
@@ -17,4 +17,12 @@
     std::string fAddress;
     std::string fPort;
+
+    enum ConnectionStatus_t
+    {
+        kDisconnected = 0,
+        kConnecting   = 1,
+        kConnected    = 2,
+    };
+
 protected:
     boost::asio::deadline_timer   fInTimeout;
@@ -23,29 +31,24 @@
     boost::asio::deadline_timer   fOutTimeout;
     boost::asio::deadline_timer   fConnectionTimer;
-    std::deque<std::vector<char>> fOutQueue; // Shell we directly put ba:buffers into the queue?
+    std::deque<std::vector<char>> fOutQueue;
 
-    int fConnectionStatus;   // 0=offline, 1=connecting, 2=connected
+    ConnectionStatus_t fConnectionStatus;
 
     std::string fErrConnect;
     std::string fMsgConnect;
 
-protected:
-    char fReadBuffer[1000];
-
-
 public:
     void SetLogStream(MessageImp *log) { fLog = log; }
+    std::ostream &Out() { return fLog ? fLog->Out() : Out(); }
 
     // -------- Abbreviations for starting async tasks ---------
 
-    int Write(const Time &t, const char *txt, int qos=kInfo);
-
-    void AsyncRead(boost::asio::mutable_buffers_1 buffers, int type=0);
-    void AsyncWrite(boost::asio::mutable_buffers_1 buffers);
+    void AsyncRead(const boost::asio::mutable_buffers_1 buffers, int type=0);
+    void AsyncWrite(const boost::asio::const_buffers_1 &buffers);
     void AsyncWait(boost::asio::deadline_timer &timer, int millisec,
                    void (Connection::*handler)(const boost::system::error_code&));
+
+private:
     void AsyncConnect(boost::asio::ip::tcp::resolver::iterator iterator);
-
-    std::string URL() const { return fAddress + ":" + fPort; }
 
     void CloseImp(bool restart=true);
@@ -54,41 +57,42 @@
                     boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
 
-public:
-
-    // ------------------------ close --------------------------
-    // close from another thread
-    void PostClose(bool restart=true);
-
-    // ------------------------ write --------------------------
     void HandleConnectionTimer(const boost::system::error_code &error);
     void HandleWriteTimeout(const boost::system::error_code &error);
     void HandleSentData(const boost::system::error_code& error, size_t);
-    void SendMessageImp(const std::vector<char> &msg);
-    void PostMessage(std::vector<uint16_t> msg);
-    void PostMessage(const std::vector<char> &msg);
-    void PostMessage(const void *msg, size_t s=0);
-    void PostMessage(const std::string &cmd, size_t s=-1);
 
-    template<std::size_t N>
-        void PostMessage(boost::array<uint16_t, N> arr)
-    {
-        // Convert to network byte order
-        for_each(arr.begin(), arr.end(), htons);
-        PostMessage(std::vector<uint16_t>(arr.begin(), arr.end()));
-    }
-
-    // ------------------------ connect --------------------------
+    int Write(const Time &t, const char *txt, int qos=kInfo);
 
     virtual void ConnectionEstablished() { }
 
-    void StartConnect();
+public:
+    Connection(boost::asio::io_service& io_service, std::ostream &out);
 
-    Connection(boost::asio::io_service& io_service, std::ostream &out);
-//    Connection(boost::asio::io_service& io_service, const std::string &addr="localhost", int port=5000);
-//    Connection(boost::asio::io_service& io_service, const std::string &addr, const std::string &port);
+    // ------------------------ connect --------------------------
 
     void SetEndpoint(const std::string &addr, int port);
     void SetEndpoint(const std::string &addr, const std::string &port);
     void SetEndpoint(const std::string &addr);
+
+    void StartConnect();
+
+    // ------------------------ close --------------------------
+    void PostClose(bool restart=true);
+
+    // ------------------------ write --------------------------
+    void SendMessageImp(const std::vector<char> msg);
+    void PostMessage(const void *msg, size_t s=0);
+    void PostMessage(const std::string &cmd, size_t s=-1);
+
+    template<typename T, size_t N>
+        void PostMessage(const boost::array<T, N> &msg)
+    {
+        PostMessage(msg.begin(), msg.size()*sizeof(T));
+    }
+
+    template<typename T>
+        void PostMessage(const std::vector<T> &msg)
+    {
+        PostMessage(&msg[0], msg.size()*sizeof(T));
+    }
 
     // ------------------------ others --------------------------
@@ -99,6 +103,8 @@
     int IsClosed() const { return !is_open(); }
 
-    bool IsConnected()  const { return fConnectionStatus==2; }
-    bool IsConnecting() const { return fConnectionStatus==1; }
+    bool IsConnected()  const { return fConnectionStatus==kConnected;  }
+    bool IsConnecting() const { return fConnectionStatus==kConnecting; }
+
+    std::string URL() const { return fAddress + ":" + fPort; }
 };
 
