From db9cfec8ae7e781d34ea4a2a5e7b3cf55367927d Mon Sep 17 00:00:00 2001
From: Maxime Graulich <maxime.graulich@gmail.com>
Date: Fri, 12 Dec 2014 18:21:56 +0000
Subject: [PATCH] ONELAB2: use solverToRun instead of launchSolverAtStartup

---
 Common/Context.cpp                      |  1 +
 Common/Context.h                        |  2 +
 Common/Gmsh.cpp                         |  9 -----
 Common/GmshMessage.cpp                  | 21 ++++++++---
 Common/OpenFile.cpp                     |  2 +
 Common/onelabUtils.cpp                  | 30 +++++++++++++--
 Common/onelabUtils.h                    |  4 +-
 Fltk/onelab2Group.cpp                   |  5 +--
 contrib/onelab2/OnelabAttributes.h      |  6 +--
 contrib/onelab2/OnelabDatabase.cpp      |  1 -
 contrib/onelab2/OnelabDatabase.h        | 16 ++++++--
 contrib/onelab2/OnelabNetworkClient.cpp | 50 ++++++++++++++++++++++++-
 contrib/onelab2/OnelabNetworkClient.h   | 47 ++++++++++++++++-------
 contrib/onelab2/OnelabProtocol.cpp      |  8 ++--
 contrib/onelab2/OnelabServer.cpp        | 23 +++++++++---
 15 files changed, 168 insertions(+), 57 deletions(-)

diff --git a/Common/Context.cpp b/Common/Context.cpp
index 42134a4974..11a23c629b 100644
--- a/Common/Context.cpp
+++ b/Common/Context.cpp
@@ -45,6 +45,7 @@ CTX::CTX() : gamepad(0)
   bgmFileName = "";
   createAppendMeshStatReport = 0;
   launchSolverAtStartup = -1;
+  solverToRun = -1;
   lc = 1.;
   min[0] = min[1] = min[2] = max[2] = 0.;
   max[0] = max[1] = 1.; // for nice view when adding point in new model
diff --git a/Common/Context.h b/Common/Context.h
index 4da71f888a..a1ce981aa3 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -99,6 +99,8 @@ class CTX {
   int createAppendMeshStatReport;
   // should we launch a solver at startup?
   int launchSolverAtStartup ;
+  // solver to use with ONELAB2
+  int solverToRun ;
   // save session/option file on exit?
   int sessionSave, optionsSave;
   // ask confirmation when overwriting files?
diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index b75935c142..dd192bbe18 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -210,15 +210,6 @@ int GmshBatch()
 
   if(CTX::instance()->onelab.server_ip[0] != '\0' && CTX::instance()->onelab.server_port > 0) {
     OnelabDatabase::instance()->useAsNetworkClient(ip4_inet_pton(CTX::instance()->onelab.server_ip), CTX::instance()->onelab.server_port, "Gmsh");
-    OpenProject(GModel::current()->getFileName());
-    while(OnelabDatabase::instance()->wait() == 0 &&
-      !OnelabDatabase::instance()->networkClientHaveToStop()) {
-      std::cout << "ok now i " << OnelabDatabase::instance()->actionToDo() << std::endl;
-      OnelabDatabase::instance()->useAsNetworkClient(ip4_inet_pton(CTX::instance()->onelab.server_ip), CTX::instance()->onelab.server_port, "Gmsh"); // restart the listen thread
-      OnelabDatabase::instance()->run(OnelabDatabase::instance()->actionToDo(), "Gmsh");// run Gmsh
-    }
-    std::cout << "Exit had to stop ? " << OnelabDatabase::instance()->networkClientHaveToStop() << std::endl;
-    Msg::Exit(0);
   }
 #endif
 
diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 88091b54e0..6fd7a9493f 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -742,7 +742,17 @@ void Msg::SetOnelabNumber(std::string name, double val, bool visible)
 
 void Msg::SetOnelabString(std::string name, std::string val, bool visible)
 {
-#if defined(HAVE_ONELAB)
+#ifdef HAVE_ONELAB2
+    std::vector<onelab::string> strings;
+    OnelabDatabase::instance()->get(strings, name);
+    if(strings.empty()){
+      strings.resize(1);
+      strings[0].setName(name);
+    }
+    strings[0].setValue(val);
+    strings[0].setVisible(visible);
+    OnelabDatabase::instance()->set(strings[0], std::string("Gmsh"));
+#elif defined(HAVE_ONELAB)
   if(_onelabClient){
     std::vector<onelab::string> strings;
     _onelabClient->get(strings, name);
@@ -753,9 +763,6 @@ void Msg::SetOnelabString(std::string name, std::string val, bool visible)
     strings[0].setValue(val);
     strings[0].setVisible(visible);
     _onelabClient->set(strings[0]);
-#ifdef HAVE_ONELAB2
-    OnelabDatabase::instance()->set(strings[0], std::string("Gmsh"));
-#endif
   }
 #endif
 }
@@ -790,16 +797,17 @@ public:
 
 void Msg::InitializeOnelab(const std::string &name, const std::string &sockname)
 {
-#if defined(HAVE_ONELAB)
+if defined(HAVE_ONELAB)
   if(_onelabClient) delete _onelabClient;
   if(sockname.empty()){
     _onelabClient = new localGmsh();
     if(name != "Gmsh"){ // load db from file:
       FILE *fp = Fopen(name.c_str(), "rb");
       if(fp){
-        _onelabClient->fromFile(fp);
 #ifdef HAVE_ONELAB2
        OnelabDatabase::instance()->fromFile(fp); 
+#else
+        _onelabClient->fromFile(fp);
 #endif
         fclose(fp);
       }
@@ -808,6 +816,7 @@ void Msg::InitializeOnelab(const std::string &name, const std::string &sockname)
     }
   }
   else{
+    // TODO ONELAB2 client...
     onelab::remoteNetworkClient *c = new onelab::remoteNetworkClient(name, sockname);
     _onelabClient = c;
     _client = c->getGmshClient();
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index b30519ccf5..4642db2360 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -439,6 +439,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setWindowTit
     GModel::current()->setName(split[1] + ".geo");
     GModel::current()->setFileName(split[0] + split[1] + ".geo");
     CTX::instance()->launchSolverAtStartup = num;
+    CTX::instance()->solverToRun = num; // used in ONELAB2
     return 1;
   }
   else if(ext == ".py" || ext == ".PY" ||
@@ -447,6 +448,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setWindowTit
     int num = defineSolver(split[1]);
     opt_solver_executable(num, GMSH_SET, fileName);
     CTX::instance()->launchSolverAtStartup = num;
+    CTX::instance()->solverToRun = num; // used in ONELAB2
     return 1;
   }
 #endif
diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp
index aa17c56cd8..85288c7143 100644
--- a/Common/onelabUtils.cpp
+++ b/Common/onelabUtils.cpp
@@ -32,7 +32,7 @@ namespace onelabUtils {
   // get command line arguments for the client if "UseCommandLine" is set for
   // this client
 #ifdef HAVE_ONELAB2
-  std::vector<std::string> getCommandLine(const std::string client)
+  std::vector<std::string> getCommandLine(const std::string &client)
   {
     std::vector<std::string> args;
     std::vector<onelab::number> n;
@@ -76,8 +76,29 @@ namespace onelabUtils {
       o.setAttribute("Closed", "1");
       OnelabDatabase::instance()->set(o, std::string("Gmsh"));
     }
-  return name;
-}
+    return name;
+  }
+
+  void guessModelName(const std::string &client)
+  {
+    std::vector<onelab::number> n;
+    OnelabDatabase::instance()->get(n, client + "/GuessModelName");
+    if(n.size() && n[0].getValue()){
+      std::vector<onelab::string> ps;
+      OnelabDatabase::instance()->get(ps, client + "/1ModelName");
+      if(ps.empty()){
+        std::vector<std::string> split = SplitFileName(GModel::current()->getFileName());
+        std::string ext = "";
+        OnelabDatabase::instance()->get(ps, client + "/FileExtension");
+        if(ps.size()) ext = ps[0].getValue();
+        std::string name(split[0] + split[1] + ext);
+        onelab::string o(client + "/1ModelName", name, "Model name");
+        o.setKind("file");
+        OnelabDatabase::instance()->set(o, client);
+      }
+    }
+  }
+
 #else
   std::vector<std::string> getCommandLine(onelab::client *c)
   {
@@ -136,7 +157,6 @@ namespace onelabUtils {
     */
     return name;
   }
-#endif
 
   void guessModelName(onelab::client *c)
   {
@@ -158,6 +178,8 @@ namespace onelabUtils {
     }
   }
 
+#endif
+
   void initializeLoop(const std::string &level)
   {
     bool changed = false;
diff --git a/Common/onelabUtils.h b/Common/onelabUtils.h
index 246467a9b3..1cf5218464 100644
--- a/Common/onelabUtils.h
+++ b/Common/onelabUtils.h
@@ -13,9 +13,9 @@
 
 namespace onelabUtils {
 #ifdef HAVE_ONELAB2
-  std::vector<std::string> getCommandLine(const std::string client);
+  std::vector<std::string> getCommandLine(const std::string &client);
   std::string getMshFileName();
-  void guessModelName(onelab::client *c); // TODO ?
+  void guessModelName(const std::string &client);
 #else
   std::vector<std::string> getCommandLine(onelab::client *c);
   std::string getMshFileName(onelab::client *c);
diff --git a/Fltk/onelab2Group.cpp b/Fltk/onelab2Group.cpp
index 2c8a6456ef..0b1a7c9fa7 100644
--- a/Fltk/onelab2Group.cpp
+++ b/Fltk/onelab2Group.cpp
@@ -145,13 +145,12 @@ void solver_cb(Fl_Widget *w, void *data)
     std::cout << name << ' ';
     std::string exe = opt_solver_executable(num, GMSH_GET, "");
     std::string host = opt_solver_remote_login(num, GMSH_GET, "");
-    // TODO check if the client exist, if not launch it
     OnelabDatabase::instance()->run("initialize", name);
   }
   if(FlGui::instance()->onelab->isBusy())
     FlGui::instance()->onelab->show();
   else{
-    if(CTX::instance()->launchSolverAtStartup >= 0){
+    if(CTX::instance()->solverToRun >= 0){
       onelab_cb(0, (void*)"reset");
       onelabUtils::setFirstComputationFlag(true);
     }
@@ -163,8 +162,6 @@ void solver_cb(Fl_Widget *w, void *data)
     }
     FlGui::instance()->onelab->updateGearMenu();
   }
-
-  CTX::instance()->launchSolverAtStartup = -1;
 }
 void solver_batch_cb(Fl_Widget *w, void *data)
 {
diff --git a/contrib/onelab2/OnelabAttributes.h b/contrib/onelab2/OnelabAttributes.h
index 7a8b7fe6b5..a591d9d783 100644
--- a/contrib/onelab2/OnelabAttributes.h
+++ b/contrib/onelab2/OnelabAttributes.h
@@ -100,7 +100,7 @@ private:
 	
 public:
 	OnelabAttrMessage() : _message(NULL), _messageLength(0), _level(0) {}
-	OnelabAttrMessage(std::string message, const int level=OnelabAttrMessage::Debug) : _message(NULL){setMessage(message, level);}
+	OnelabAttrMessage(const std::string &message, const int level=OnelabAttrMessage::Debug) : _message(NULL){setMessage(message, level);}
 	~OnelabAttrMessage(){if(_message != NULL) free(_message);};
 	UInt8 *encodeAttribute(UInt8 *dst);
 	UInt8 *parseAttribute(UInt8 *src, UInt32 length);
@@ -110,8 +110,8 @@ public:
 	inline UInt16 getAttributeType() const {return this->attributeType();}
 	inline UInt16 getAttributeLength() const {return 1+_messageLength;}
 
-	void setMessage(std::string message, const int level=OnelabAttrMessage::Debug) {
-		_messageLength = message.size();
+	void setMessage(const std::string &message, const int level=OnelabAttrMessage::Debug) {
+		_messageLength = message.size()+1;
     if(_messageLength == 0) return;
 		_level = level;
 		if(_message != NULL) free(_message);
diff --git a/contrib/onelab2/OnelabDatabase.cpp b/contrib/onelab2/OnelabDatabase.cpp
index 1a59891028..5ff0521a51 100644
--- a/contrib/onelab2/OnelabDatabase.cpp
+++ b/contrib/onelab2/OnelabDatabase.cpp
@@ -17,7 +17,6 @@ DWORD WINAPI OnelabDatabase_listen(LPVOID arg)
     if(recvlen == 1 && buff[0] == 'S')
       break;
     msg.parseMsg(buff, recvlen);
-    msg.showMsg();
     switch(msg.msgType()) {
       case OnelabProtocol::OnelabStop:
         std::clog << "\033[0;35m" << "Client is going to stop" << "\033[0;0m" << std::endl;
diff --git a/contrib/onelab2/OnelabDatabase.h b/contrib/onelab2/OnelabDatabase.h
index 467e54e3a4..0bc64b9640 100644
--- a/contrib/onelab2/OnelabDatabase.h
+++ b/contrib/onelab2/OnelabDatabase.h
@@ -5,6 +5,8 @@
 #include <stdio.h>
 
 #include "GmshMessage.h"
+#include "Options.h"
+#include "Context.h"
 #include "onelabUtils.h"
 #include "OnelabServer.h"
 #include "VirtualClient.h"
@@ -185,16 +187,22 @@ public:
       run(action, "Gmsh");
 
       // iterate over all other clients
+      std::string solver = "";
+      if(CTX::instance()->solverToRun >= 0) solver = opt_solver_name(CTX::instance()->solverToRun, GMSH_GET, "");
       if(_client) {
         std::cout << "server is remote" << std::endl;
-        msg.attrs.push_back(new OnelabAttrAction(action, client));
-        int size = msg.encodeMsg(buff, 1024);
-        sendbytes(buff, size);
+        if(CTX::instance()->solverToRun >= 0) run(action, solver);
+        else {
+          msg.attrs.push_back(new OnelabAttrAction(action, client));
+          int size = msg.encodeMsg(buff, 1024);
+          sendbytes(buff, size);
+        }
         return true;
       }
       else {
         std::cout << "server is local" << std::endl;
-        OnelabServer::instance()->performAction(action);
+        if(CTX::instance()->solverToRun >= 0) OnelabServer::instance()->performAction(action, solver);
+        else OnelabServer::instance()->performAction(action, client);
         return true;
       }
     }
diff --git a/contrib/onelab2/OnelabNetworkClient.cpp b/contrib/onelab2/OnelabNetworkClient.cpp
index 5d1fcc5b0f..ea90b879d0 100644
--- a/contrib/onelab2/OnelabNetworkClient.cpp
+++ b/contrib/onelab2/OnelabNetworkClient.cpp
@@ -97,6 +97,44 @@ int OnelabNetworkClient::recvfrom(OnelabProtocol &msg)
   free(buff);
   return recvlen + 4;
 }
+int OnelabNetworkClient::recvfrom()
+{
+  OnelabProtocol msg(-1);
+  int totalrecv = 0;
+  int recvlen = 0;
+  do {
+    ip4_socket_timeout(_fds, 0, 1000);
+    recvlen = recvfrom(msg);
+    ip4_socket_timeout(_fds, 0);
+    if(recv > 0) totalrecv+=recvlen;
+
+    if(recv <= 0) return totalrecv;
+
+    switch(msg.msgType()) {
+      case OnelabProtocol::OnelabResponse:
+      case OnelabProtocol::OnelabUpdate:
+        for(std::vector<OnelabAttr *>::iterator it = msg.attrs.begin() ; it != msg.attrs.end(); ++it) {
+         if((*it)->getAttributeType() == OnelabAttr::Number) {
+           onelab::number *attr = (onelab::number *)*it;
+           set(*attr, false);
+         }
+         else if((*it)->getAttributeType() == OnelabAttr::String) {
+           onelab::string *attr = (onelab::string *)*it;
+           set(*attr, false);
+         }
+         else if((*it)->getAttributeType() == OnelabAttr::Region) {
+           onelab::region *attr = (onelab::region *)*it;
+           set(*attr, false);
+         }
+         else if((*it)->getAttributeType() == OnelabAttr::Function) {
+           onelab::function *attr = (onelab::function *)*it;
+           set(*attr, false);
+         }
+      }
+    }
+  } while(recvlen > 0);
+  return totalrecv;
+}
 bool OnelabNetworkClient::connect()
 {
   UInt16 bufflen = 1024;
@@ -121,14 +159,13 @@ bool OnelabNetworkClient::connect()
   udt_socket_timeout(_fdu, 3);
 #endif
   ip4_socket_timeout(_fds, 3);
-  recvlen = recvfrom(buff, bufflen);
+  recvlen = recvfrom(msg);
 
 #ifdef HAVE_UDT
   udt_socket_timeout(_fdu, -1);
 #endif
   ip4_socket_timeout(_fds, 0);
   if(recvlen <= 0) return false;
-  msg.parseMsg(buff, recvlen);
   if(recvlen > 0 && msg.msgType() == OnelabProtocol::OnelabStart) _connected = true;
   return _connected;
 }
@@ -158,3 +195,12 @@ void OnelabNetworkClient::requestParameters()
   OnelabProtocol msg(OnelabProtocol::OnelabRequest);
   this->request(msg);
 }
+
+void OnelabNetworkClient::sendMessage(const int level, const std::string &message)
+{
+  OnelabProtocol msg(OnelabProtocol::OnelabMessage);
+  UInt8 buff[1024];
+  msg.attrs.push_back(new OnelabAttrMessage(message, level));
+  int recvlen = msg.encodeMsg(buff, 1024);
+  this->sendto(buff, recvlen);
+}
diff --git a/contrib/onelab2/OnelabNetworkClient.h b/contrib/onelab2/OnelabNetworkClient.h
index b627b40f50..b9e2741e06 100644
--- a/contrib/onelab2/OnelabNetworkClient.h
+++ b/contrib/onelab2/OnelabNetworkClient.h
@@ -27,16 +27,7 @@ private:
 		OnelabProtocol msg(OnelabProtocol::OnelabRequest);
 		msg.attrs.push_back(new OnelabAttrParameterQuery(name.c_str(), T::attributeType()));
 		this->request(msg);
-		// wait for the answer
-    fd_set readfds;
-    struct timeval timeout;
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-    FD_ZERO(&readfds);
-    FD_SET(_fds, &readfds);
-    int nfds = select(_fds+1, &readfds, NULL, NULL, &timeout);
-    usleep(100000); // FIXME sleep while read the buffer
-    return nfds > 0;
+    return true;
 	}
 	void requestParameters(); // request all parameter for this client
 public:
@@ -70,14 +61,26 @@ public:
 		}
 		return false;
 	}
-	template <class T> bool get(std::vector<T> &ps, const std::string &name=""){
-		if(_parameterSpace->get(ps, name, this->_name) && ps.size() == 0)
-			if(requestParameter(ps, name))
+	template <class T> bool get(std::vector<T> &ps, const std::string &name, bool needed="false"){
+		if(_parameterSpace->get(ps, name, this->_name) && ps.size() == 0) {
+			if(requestParameter(ps, name)) {
+		    if(needed) {// wait for the answer
+          fd_set readfds;
+          struct timeval timeout;
+          timeout.tv_sec = 1;
+          timeout.tv_usec = 0;
+          FD_ZERO(&readfds);
+          FD_SET(_fds, &readfds);
+          int nfds = select(_fds+1, &readfds, NULL, NULL, &timeout); // Wait for the server to answer
+          if(nfds > 0) recvfrom();
+        }
         return _parameterSpace->get(ps, name, this->_name) && ps.size() == 0;
+      }
       else
         return false;
+    }
 		return true;
-	}
+  }
   FILE *openFile(const std::string name, const char *mode="rb")
   {
     FILE *fp = fopen(name.c_str(), mode);
@@ -137,6 +140,7 @@ public:
 	// network specific method
 	bool connect();
 	bool isConnected(){return _connected;}
+	int recvfrom(); // empty the buffer (useful when the client do not listen on another thread)
 	int recvfrom(OnelabProtocol &msg);
 	int recvfrom(UInt8 *buff, UInt16 maxlen);
 	void sendto(UInt8 *buff, UInt16 len);
@@ -145,6 +149,21 @@ public:
 	void setRemotePort(unsigned short port){if(!_connected) _ip.port=port;}
 
   void run(std::string action) {}
+
+  void sendMessage(const int level, const std::string &message);
+  void sendInfo(const std::string &msg)
+  {
+    sendMessage(OnelabAttrMessage::Info, msg);
+  }
+  void sendWarning(const std::string &msg)
+  {
+    sendMessage(OnelabAttrMessage::Warning, msg);
+  }
+  void sendError(const std::string &msg)
+  {
+    sendMessage(OnelabAttrMessage::Error, msg);
+  }
+
 };
 
 #endif
diff --git a/contrib/onelab2/OnelabProtocol.cpp b/contrib/onelab2/OnelabProtocol.cpp
index dd03b8e6b9..1fd1162942 100644
--- a/contrib/onelab2/OnelabProtocol.cpp
+++ b/contrib/onelab2/OnelabProtocol.cpp
@@ -51,6 +51,8 @@ int OnelabProtocol::parseHeader(UInt8 *buff, UInt32 len)
   ptr = parse(ptr, _type);
   ptr = parse(ptr, _size);
 
+  //std::cout << "current version is " << (int)ONELAB_VERSION << ", message version is " << (int)version << "(length is " << len << ", size is "<< _size <<" )" << std::endl;
+
   return _size;
 }
 UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len)
@@ -65,7 +67,7 @@ UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len)
 		ptr = parse(ptr, attrType);
 		ptr = parse(ptr, attrSize);
 		size -= 4;
-		std::cout << "Try to parse an attribute of type 0x" << std::hex << (UInt16)attrType << std::dec << " and size : " << attrSize << std::endl;
+		//std::cout << "Try to parse an attribute of type 0x" << std::hex << (UInt16)attrType << std::dec << " and size : " << attrSize << std::endl;
 		if(attrSize > size) throw ERROR_BUFFER_TOO_SMALL;
 		switch(attrType) {
 			case OnelabAttr::Message:
@@ -119,7 +121,7 @@ UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len)
 		size -= attrSize;
     parsed += (attrSize+4);
 	}
-  if(parsed != len) {std::cout << "parse - size left:"  << len-parsed << '-' << size << "(len is "<< len <<" and parsed is "<< parsed <<" )" << std::endl;}
+  //if(parsed != len) {std::cout << "parse - size left:"  << len-parsed << '-' << size << "(len is "<< len <<" and parsed is "<< parsed <<" )" << std::endl;}
  
   return len-parsed;
 }
@@ -133,7 +135,7 @@ UInt32 OnelabProtocol::parseMsg(UInt8 *buff, UInt32 len)
 	if(version != ONELAB_VERSION) throw ERROR_ONELAB_VERSION;
 	ptr = parse(ptr, _type);
 	ptr = parse(ptr, _size);
-  std::cout << "current version is " << (int)ONELAB_VERSION << ", message version is " << (int)version << "(length is " << len << ", size is "<< _size <<" )" << std::endl; // TODO send to gmsh ?
+  //std::cout << "current version is " << (int)ONELAB_VERSION << ", message version is " << (int)version << "(length is " << len << ", size is "<< _size <<" )" << std::endl;
 
 	UInt8 *payload = ptr;
   unsigned short parsed = 4;
diff --git a/contrib/onelab2/OnelabServer.cpp b/contrib/onelab2/OnelabServer.cpp
index 2959173e02..1b661de8dd 100644
--- a/contrib/onelab2/OnelabServer.cpp
+++ b/contrib/onelab2/OnelabServer.cpp
@@ -94,7 +94,6 @@ int OnelabServer::launchClient(const std::string &client) // FIXME OnelabDatabas
     std::string exe = opt_solver_executable(num, GMSH_GET, "");
     command.assign(exe);
   }
-  //std::string command = FixWindowsPath(_client->getExecutable()); // TODO
 
   if(command.size()){
     std::vector<std::string> args = onelabUtils::getCommandLine(client);
@@ -181,6 +180,7 @@ void OnelabServer::removeClient(OnelabLocalNetworkClient *client)
 void OnelabServer::performAction(const std::string action, const std::string client)
 {
   if(client.size()) {
+    onelabUtils::guessModelName(client);
     OnelabLocalNetworkClient *cli = getClient(client);
     OnelabLocalClient *localcli = getLocalClient(client);
     if(cli != NULL || localcli == NULL) {
@@ -254,7 +254,7 @@ void *listenOnClients(void *param)
     for(std::set<Socket>::iterator it = fdss.begin(); it != fdss.end(); ++it) {
 
       OnelabLocalNetworkClient *cli = OnelabServer::instance()->getClient(*it);
-      if(cli == NULL) { // Client is not in the list (it muste be a Start message)
+      if(cli == NULL) { // Client is not in the list (we should get a Start message)
         IPv4 ip;
         // recv the header
         recvlen = ip4_socket_recv(*it, buff, 4, ip);
@@ -274,7 +274,6 @@ void *listenOnClients(void *param)
         // then recv the message
         recvlen = ip4_socket_recv(*it, buff, msglen, ip);
         msg.parseMessage(buff, recvlen);
-        msg.showMsg();
         if(msg.msgType() == OnelabProtocol::OnelabStart && msg.attrs.size() > 0 && msg.attrs[0]->getAttributeType() == OnelabAttr::Start) {
           std::string name = std::string(((OnelabAttrStart *)msg.attrs[0])->name());
           if(OnelabServer::instance()->getClient(name) != NULL) {
@@ -348,8 +347,20 @@ void *listenOnClients(void *param)
           UDT::close(*it);
           break;
         case OnelabProtocol::OnelabMessage:
-          std::cout << "recv a message ... (TODO)" << std::endl;
-          // TODO
+          // TODO do not use Gmsh, send message to GUI
+          if(msg.attrs.size()==1 && msg.attrs[0]->getAttributeType() == OnelabAttrMessage::attributeType()) {
+            switch(((OnelabAttrMessage *)msg.attrs[0])->getLevel()) {
+              case OnelabAttrMessage::Info:
+                Msg::Direct("Info    : %s - %s", cli->getName().c_str(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage());
+                break;
+              case OnelabAttrMessage::Warning:
+                Msg::Warning("%s - %s", cli->getName().c_str(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage());
+                break;
+              case OnelabAttrMessage::Error:
+                Msg::Error("%s - %s", cli->getName().c_str(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage());
+                break;
+            }
+          }
           break;
         case OnelabProtocol::OnelabRequest:
           rep.msgType(OnelabProtocol::OnelabResponse);
@@ -489,6 +500,8 @@ void OnelabServer::sendAllParameter(OnelabLocalNetworkClient *cli)
   UInt32 bufflen = 1024, recvlen = 0;
   UInt8 buff[1024];
   _parameterSpace.getAllParameters(ps);
+  if(ps.size() == 0) return;
+  // FIXME ...
   for(std::set<onelab::parameter*, onelab::parameterLessThan>::iterator it = ps.begin(); it != ps.end(); it++)
     if((*it)->hasClient(cli->getName())) msg.attrs.push_back(*it);
   recvlen = msg.encodeMsg(buff, bufflen);
-- 
GitLab