//
// Copyright (C) 1999-2002 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

//#include <X11/Xlib.h>
#define _ANSI_SOURCE
#include <basic.h>
#include <btron/event.h>
#include <WScom.h>
//#include <x11/WSDxappDev.h>
#include <btron/WSDbtronSocket.h>
#include <btron/bsocket.h>
#ifdef TE
#include <btron/errcode.h>
#include <btron/message.h>
#else
#include <errcode.h>
#endif
#include <btron/proctask.h>
#include <btron/taskcomm.h>
#include <btron/hmi.h>

//#include <unistd.h>
//#include <netdb.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include <pthread.h>
//#include <fcntl.h>
//#include <errno.h>
//#include <sys/file.h>
#include <string.h>

#define SOCKLEN_T  W

WSMFclassInit(WSDbtronSocket,WSDbtronSocket);

WSDsocket* _btronSocket_create_handler(){
  WSDbtronSocket* sock = new WSDbtronSocket();
//printf("WSDbtronSocket created..0x%x\n",sock);
  return sock;
};


class  _btronSocket_init {
  public:
  _btronSocket_init(){
    WSDsocket::setCreateHandler(_btronSocket_create_handler);
//printf("WSDbtronSocket init\n");
  };
};
_btronSocket_init   WSGIappXsocketInit;

WSDbtronSocket::WSDbtronSocket(){
  _socket = -1; 
  _listened = False;
  _sem = NULL;
  _no_delay = False;
}

WSDbtronSocket::~WSDbtronSocket(){
  if (_sem != NULL){
//    pthread_sem_unlock_np((pthread_sem_t*)_sem);
    sig_sem((ID)_sem);
    _sem = NULL;
  }
  destroy();
}

long WSDbtronSocket::destroy(){
  if (_socket != -1){
    so_close(_socket);
    seterr();
    _socket = -1;
  }
  _listened = False;
  _started_accept = False;
  return WSDsocket::destroy();
}

long WSDbtronSocket::connect(){
//printf("WSDbtronSocket::connect here1\n");
  if (_socket == -1){
    initialize();
    if (_socket == -1){
fprintf(stderr,"WSDbtronSocket::connect socket not created.\n");
      return WS_ERR;
    }
  }
  if (_udp != False){
fprintf(stderr,"WSDbtronSocket::connect socket is udp.\n");
    return WS_ERR;
  }
  struct sockaddr_in server;
  struct hostent  hptmp;
  struct hostent  *hp = &hptmp;
  ERR ret;
//printf("WSDbtron::connect begin gethostbyname dest_naddr=#%s#\n",(char*)_dest_naddr);
  if (!strcmp(_dest_naddr,"")){
    B tmpbuf[HBUFLEN];
    ret = so_gethostbyname("localhost",hp,tmpbuf);
  }else{
    B tmpbuf[HBUFLEN];
    ret = so_gethostbyname((char*)_dest_naddr,hp,tmpbuf);
  }
  server.sin_family = AF_INET;
  if (ret < 0){
    server.sin_addr.s_addr = (unsigned long)inet_addr((char*)_dest_naddr);
    if ( server.sin_addr.s_addr == (unsigned long)-1 ) {
fprintf(stderr,"WSDbtronSocket::connect invarid addr=%s\n",(char*)_dest_naddr);
      return WS_ERR;
    }
  }else{
    server.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
  }
  server.sin_port = htons( _dest_port );
//printf("WSDbtron::connect begin connect\n");
  ret = so_connect(_socket, (struct sockaddr *)&server,sizeof server);
//printf("WSDbtron::connect begin connect done\n");
  if( ret < 0 ){
    seterr();
    close();
fprintf(stderr,"WSDbtronSocket::connect failed addr=%s port=%d err=%d\n",(char*)_dest_naddr,_dest_port,ret>>16);
    return WS_ERR;
  }
//printf("WSDbtronSocket::connect connected addr=%s port=%d\n",(char*)_dest_naddr,_dest_port);
  return WS_NO_ERR;
}

long WSDbtronSocket::listen(){
  if (_socket == -1){
    initialize();
    if (_socket == -1){
      return WS_NO_ERR;
    }
  }
  if (_udp != False){
    return WS_ERR;
  }
  struct sockaddr_in server;

  server.sin_family = AF_INET;
  if (!strcmp((char*)_naddr,"")){
    server.sin_addr.s_addr = INADDR_ANY;
  }else{
    server.sin_addr.s_addr = (unsigned long)inet_addr((char*)_naddr);
//printf("WSDbtronSocket::listen addr=%s %x\n",(char*)_naddr, server.sin_addr.s_addr);
  }  
  server.sin_port = htons( _port );
  int val;
  val = 1;
  so_setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof val);

  if( so_bind(_socket, (struct sockaddr *)&server, sizeof server) < 0){
//printf("WSDbtronSocket::listen addr=%s %x port=%d bind err..\n",(char*)_naddr, server.sin_addr.s_addr,_port);
    seterr();
    return WS_ERR;
  }
  if ( so_listen(_socket, 5) != 0){
//printf("WSDbtronSocket::listen addr=%s %x listen err..\n",(char*)_naddr, server.sin_addr.s_addr);
    seterr();
    return WS_ERR;
  }
//printf("WSDbtronSocket::listen addr=%s %x listen..\n",(char*)_naddr, server.sin_addr.s_addr);
  _listened = True;
  seterr();
  return WS_NO_ERR;
}
void* WSDbtronSocket::accept(){
  if (_socket == -1){
    initialize();
    if (_socket == -1){
      return NULL;
    }
  }
  if (_udp != False){
    return 0;
  }
  if (_listened == False){
    if (listen() != WS_NO_ERR){
      return NULL;
    }
  }
  struct sockaddr_in sock_addr;
  SOCKLEN_T hlen = sizeof(sock_addr);

  int sock = so_accept(_socket,(sockaddr*)&sock_addr,&hlen);
  if (sock < 0){
    seterr();
    return NULL;
  }
  _set_dest_addr_(htonl(sock_addr.sin_addr.s_addr));
  return (void*)sock;
}

struct tmp_data{
  WSDbtronSocket* obj;
  void(*hd)(WSDsocket*,void*,WSCulong);
};

void WSDbtronSocket::_accept_thread_(W ptr){
  tmp_data* dt = (tmp_data*)ptr;
  WSDbtronSocket* _this = dt->obj;
  void(*hd)(WSDsocket*,void*,WSCulong) = dt->hd;
  delete dt;

//  Display* disp = XOpenDisplay((char*)NULL);
//  if (disp == NULL){
//printf("return1\n");
//    return 0;
//  }
  while(1){
    struct sockaddr_in sock_addr;
    SOCKLEN_T hlen = sizeof(sock_addr);
//printf("accept start...\n");
    int sock = so_accept(_this->_socket,(sockaddr*)&sock_addr,&hlen);
//printf("accept done...\n");

    if (_this->_stop_accept != False){
      _this->_stop_accept = False;
      ext_tsk();
      return;
    }
    _accept_send_type* data = (_accept_send_type*)malloc(sizeof(_accept_send_type));
    data->sock = _this;
    data->socket = sock;
    data->addr = htonl(sock_addr.sin_addr.s_addr);
    data->hd = hd;


    MESSAGE* msg;
    char buffer[128];
    msg = (MESSAGE*)buffer;
    msg->msg_type = MS_TYPE1;
    msg->msg_size = sizeof(data);
    memcpy(msg->msg_body.ANYMSG.msg_str,&data,sizeof(data));

//printf("WSDbtronSocket::_accept_thread data=0x%x\n",data);
//    put_evt(&ev,EP_NONE);
//    wugt_evt((WEVENT*)&ev);
//    wsnd_evt((WEVENT*)&ev);
//fprintf(stderr,"WSDbtronSocket::_accept_thread data=0x%x pid=0x%x\n",data,prc_sts(0,NULL,NULL));


    W ret = snd_msg(0,msg,WAIT);
//fprintf(stderr,"WSDbtronSocket::_accept_thread data=0x%x ret=%d\n",data,ret>>16);
  }
}
long WSDbtronSocket::_continue_udp_read_accept(){
//printf("WSDbtronSocket::_continue_udp_read_accept.. _sem=0x%x\n",_sem);
  if (_sem != NULL){
//printf("WSDbtronSocket::_continue_udp_read_accept unlock\n");
//    pthread_sem_unlock_np((pthread_sem_t*)_sem);
    sig_sem((ID)_sem);
    _sem = NULL;
    return WS_NO_ERR;
  }
  return WS_ERR;
}
void WSDbtronSocket::_udp_read_thread_(W ptr){
  tmp_data* dt = (tmp_data*)ptr;
  WSDbtronSocket* _this = dt->obj;
  void(*hd)(WSDsocket*,void*,WSCulong) = dt->hd;
  delete dt;

  if (_this->_udp_binded == False){
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    if (!strcmp((char*)_this->_naddr,"")){
      server.sin_addr.s_addr = INADDR_ANY;
//printf("WSDbtronSocket::_udp_read_thread addr=INADDR_ANY %x\n",(char*)_this->_naddr, server.sin_addr.s_addr);
    }else{
      server.sin_addr.s_addr = (unsigned long)inet_addr((char*)_this->_naddr);
//printf("WSDbtronSocket::_udp_read_thread2 addr=%s %x\n",(char*)_this->_naddr, server.sin_addr.s_addr);
    }  
    server.sin_port = htons( _this->_port );
//printf("WSDbtronSocket::_udp_read_thread bind\n");
    if( so_bind(_this->_socket, (struct sockaddr *)&server, sizeof(server)) < 0){
      ext_tsk();
      return;
    }
    _this->_udp_binded = True;
  }
//printf("WSDbtronSocket::_udp_read_thread...\n");
  while(1){
    WSCulong timeout = 0xffffffff;
    struct timeval tm;
    tm.tv_sec = 0xffff;
    tm.tv_usec = 0;
    fd_set read_fds;
    FD_ZERO(&read_fds);
    FD_SET(_this->_socket,&read_fds);
//printf("WSDbtronSocket::_udp_read_thread before select\n");
    long ret = so_select(FD_SETSIZE,&read_fds,NULL,NULL,&tm);
//printf("WSDbtronSocket::_udp_read_thread after select\n");
    if (ret < 0){
      continue;
    }
    if (ret == 0){
      continue;
    }
    if (1){
      if (_this->_stop_accept != False){
//        XCloseDisplay(disp);
        _this->_stop_accept = False;
        ext_tsk();
        return;
      }
      _accept_send_type* data = (_accept_send_type*)malloc(sizeof(_accept_send_type));
      data->sock = _this;
      data->socket = _this->_socket;
      data->addr = 0;
      data->hd = hd;

//printf("WSDbtronSocket::_accept_thread data=0x%x\n",data);
 

      MESSAGE* msg;
      char buffer[128];
      msg = (MESSAGE*)buffer;
      msg->msg_type = MS_TYPE1;
      msg->msg_size = sizeof(data);
      memcpy(msg->msg_body.ANYMSG.msg_str,&data,sizeof(data));
//printf("WSDbtronSocket::_udp_read_thread...data=0x%x\n",data);

 
      WERR sem = cre_sem(0,SEM_SYNC|DELEXIT );
      if (sem < 0){
        ext_tsk();
        return;
      }
      _this->_sem = (void*)sem;
      snd_msg(0,msg,WAIT);
 
//printf("WSDbtronSocket::_udp_read_thread wait..\n");
      wai_sem(sem,T_FOREVER); 
//printf("WSDbtronSocket::_udp_read_thread unlocked...\n");
      sig_sem(sem); 
      del_sem(sem);
    }else{
      break;
    }
  }
  ext_tsk();
  return;
}

long WSDbtronSocket::acceptEx(void(*hd)(WSDsocket*,void*,WSCulong)){
  if (_started_accept != False){
    return WS_ERR;
  }
  if (hd == NULL){
    return WS_ERR;
  }
  if (_socket == -1){
    initialize();
    if (_socket == -1){
      return WS_ERR;
    }
  }
  if (_udp != False){
//    pthread_t thr;
    tmp_data* dt = new tmp_data;
    dt->obj = this;
    dt->hd = hd;

//    int ret = pthread_create(&thr,NULL,_udp_read_thread_,dt);
    int ret = cre_tsk(_udp_read_thread_,-1,(int)dt);
    if (ret < 0){
      return WS_ERR;
    }
    _started_accept = True;
//    pthread_detach(thr);
    return WS_NO_ERR;
  }
  if (_listened == False){
    if (listen() != WS_NO_ERR){
      return WS_ERR;
    }
  }
//  pthread_t thr;
  tmp_data* dt = new tmp_data;
  dt->obj = this;
  dt->hd = hd;

//  int ret = pthread_create(&thr,NULL,_accept_thread_,dt);
  int ret = cre_tsk(_accept_thread_,-1,(int)dt);
  if (ret < 0){
    return WS_ERR;
  }
  _started_accept = True;
//  pthread_detach(thr);
  return WS_NO_ERR;
}


long WSDbtronSocket::close(void* sock){
  if (sock != 0){
    so_close((int)sock);
    seterr();
    return WS_NO_ERR;
  }else{
    destroy();
    return WS_ERR;
  }
}
long WSDbtronSocket::initialize(){
//printf("WSDbtronSocket::initialize .. _udp=%d\n",_udp);
  if (_socket == -1){
    if (_udp == False){
      _socket = so_socket(AF_INET,SOCK_STREAM,0);
    }else{
      _socket = so_socket(AF_INET,SOCK_DGRAM,0);
//printf("WSDbtronSocket::initialize .. fd=%d\n",_socket);
      _udp_binded = False;
    }
  }
//printf("WSDbtronSocket::initialize .. fd=%d\n",_socket);
  if (_socket < 0){
fprintf(stderr,"WSDbtronSocket::initialize socket not created. err=%d\n",_socket>>16);
    _socket = -1;
    seterr();
    return WS_ERR;
  }
  return WSDsocket::initialize();
}
long WSDbtronSocket::read(void* handle,WSCuchar* buf,long size){
//printf("WSDbtronSocket::read this=0x%x here0\n",this);
  if (_udp != False){
    if (_udp_binded == False){
      struct sockaddr_in server;
      server.sin_family = AF_INET;
      if (!strcmp((char*)_naddr,"")){
        server.sin_addr.s_addr = INADDR_ANY;
      }else{
        server.sin_addr.s_addr = (unsigned long)inet_addr((char*)_naddr);
//printf("WSDbtronSocket::read addr=%s %x\n",(char*)_naddr, server.sin_addr.s_addr);
      }  
      server.sin_port = htons( _port );
      if( so_bind(_socket, (struct sockaddr *)&server, sizeof server) < 0){
        seterr();
//printf("WSDbtronSocket::read 0\n");
        return WS_ERR;
      }
      _udp_binded = True;
    }
  }
  WSCulong timeout = 0;
  if (_socket == (int)handle){
    timeout = _timeout *1000;
  }else{
    timeout = _cl_timeout *1000;
  }
  if (timeout > 0){
    if (_no_delay == False){
      int fl = so_fcntl((int)handle,F_GETFL,0);
      if (fl == -1){
        seterr();
        return 0;
      }
      int ret = so_fcntl((int)handle,F_SETFL,fl | FNDELAY);
      if (ret == -1){
        seterr();
        return 0;
      }
      _no_delay = True;
    }
  }else{
    if (_no_delay != False){
      int fl = so_fcntl((int)handle,F_GETFL,0);
      if (fl == -1){
        seterr();
        return 0;
      }
      int ret = so_fcntl((int)handle,F_SETFL,fl & ~FNDELAY);
      if (ret == -1){
        seterr();
        return 0;
      }
      _no_delay = False;
    }
  }

  long read_len = 0;
  long len_to_read = size; 
  long read_first = True;
  while(1){
    long ret = 0;
    if (_udp == False){
      ret = so_recv((int)handle,(char*)&buf[read_len],len_to_read,0);
//printf("WSDbtronSocket::read ret=%d len=%d buf=0x%x handle=0x%x ret=%d\n",ret,len_to_read,buf,handle,ret>>16);
    }else{
      struct sockaddr_in fromaddr;
      fromaddr.sin_family = AF_INET;
      fromaddr.sin_port = 0;
      fromaddr.sin_addr.s_addr = 0;
      SOCKLEN_T len = sizeof(fromaddr);
      ret = so_recvfrom((int)handle,(char*)&buf[read_len],len_to_read,0,(sockaddr*)&fromaddr,&len);
      _set_dest_addr_(htonl(fromaddr.sin_addr.s_addr));
      _dest_port = htons(fromaddr.sin_port);
    }
//printf("timeout=%d\n",timeout);
    if (timeout > 0){
      struct timeval tm;
      tm.tv_sec = timeout;
      tm.tv_usec = 0;
      fd_set read_fds;
      FD_ZERO(&read_fds);
      FD_SET((int)handle,&read_fds);
//printf("WSDbtronSocket::read... ret=0x%x 0x%x\n",ret,EX_WOULDBLOCK);
      if (ret > 0){
        read_len +=  ret;
        len_to_read -= ret;
        if (len_to_read == 0){
//printf("WSDbtronSocket::read... here7\n");
//printf("WSDbtronSocket::read... here7 read_len=%d\n",read_len);
          seterr();
          return read_len;
        }
      }else if (ret == 0){        
        if (read_first == False){
//printf("WSDbtronSocket::read... here6 read_len=%d\n",read_len);
          seterr();
          return read_len;
        }
      }else if (ret < 0){        
//printf("WSDbtronSocket::read... here5\n");
        if (ret != EX_WOULDBLOCK){
          seterr();
          return read_len;
        }
      }

      read_first = False;
      ret = so_select( FD_SETSIZE,&read_fds,NULL,NULL,&tm );
      long err = ret;
      if (ret < 0 && err != EX_ALREADY){
//printf("WSDbtronSocket::read... ret=%d\n",ret>>16);
        seterr();
        return read_len;
      }
      if (ret == 0){
//printf("WSDbtronSocket::read... ret=%d\n",ret>>16);
        seterr(EX_TIMEDOUT);
        return read_len;
      }
      continue;
//printf("WSDbtronSocket::read... select ret=0x%x\n",ret);
    }
//printf("WSDbtronSocket::read... here3 ret=%d\n",ret);
    seterr();
    return ret;
  }
//printf("WSDbtronSocket::read... here4 ret=%d\n",read_len);
  seterr();
  return read_len;
}

long WSDbtronSocket::read(WSCuchar* buf,long size){
  if (_socket == -1 && _udp != False){
    initialize();
    if (_socket == -1){
      return -1;
    }
  }
  if (_socket != -1){
    long ret = read((void*)_socket,buf,size);
//printf("WSDbtronSocket::read ret=%d size=%d\n",ret,size);
    return ret;
  }
  return -1;
}
long WSDbtronSocket::write(void* handle,WSCuchar* buf,long size){
//printf("WSDbtronSocket::write this=0x%x _udp=%d size=%d\n",this,_udp,size);
  if (_udp != False){
    int val;
    val = 1;
    int ret = so_setsockopt((int)handle, SOL_SOCKET, SO_BROADCAST,
                         (char *)&val, sizeof(val));
    if (ret < 0){
      seterr();
      return 0;
    }
//printf("WSDbtronSocket::write setsockopt... _socket=%d handle=%d ret=%d\n",_socket,handle,ret);
  }
  WSCulong timeout = 0;
  if (_socket == (int)handle){
    timeout = _timeout *1000;
  }else{
    timeout = _cl_timeout *1000;
  }

  if (timeout > 0){
    if (_no_delay == False){
      int fl = so_fcntl((int)handle,F_GETFL,0);
      if (fl == -1){
        seterr();
        return 0;
      }
      int ret = so_fcntl((int)handle,F_SETFL,fl | FNDELAY);
      if (ret == -1){
        seterr();
        return 0;
      }
      _no_delay = True;
    }
  }else{
    if (_no_delay != False){
      int fl = so_fcntl((int)handle,F_GETFL,0);
      if (fl == -1){
        seterr();
        return 0;
      }
      int ret = so_fcntl((int)handle,F_SETFL,fl & ~FNDELAY);
      if (ret == -1){
        seterr();
        return 0;
      }
      _no_delay = False;
    }
  }

  long write_len = 0;
  long len_to_write = size; 
  long write_first = True;
  while(1){
    long ret = 0;
    if (_udp == False){
      ret = so_send((int)handle,(char*)&buf[write_len],len_to_write,0);
//printf("WSDbtronSocket::write done ret=%d len_to_write=%d\n",ret,len_to_write);
    }else if (_udp_binded == False){
      struct sockaddr_in toaddr;
      toaddr.sin_family = AF_INET;
      toaddr.sin_port = htons( _dest_port );
//printf("WSDbtronSocket::write port=%d\n",_dest_port);
      if (!strcmp(_dest_naddr,"")){
        toaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
//printf("here..... addr=0x%x port=0x%x\n",toaddr.sin_addr.s_addr,toaddr.sin_port);
      }else{
        toaddr.sin_addr.s_addr =(unsigned long)inet_addr((char*)_dest_naddr);
//printf("here2..... addr=0x%x port=0x%x\n",toaddr.sin_addr.s_addr,toaddr.sin_port);
      }

      ret = so_sendto((int)handle,(char*)&buf[write_len],len_to_write,0,
                   (sockaddr*)&toaddr,sizeof(toaddr));
//printf("sendto.. size=%d\n",sizeof(toaddr));
//printf("sendto.. handle=%d ret=%d errno=%d\n",handle,ret,ret >> 16);
    }
    if (_timeout > 0){
      struct timeval tm;
      tm.tv_sec = _timeout;
      tm.tv_usec = 0;
      fd_set write_fds;
      FD_ZERO(&write_fds);
      FD_SET((int)handle,&write_fds);
      if (ret > 0){
        write_len +=  ret;
        len_to_write -= ret;
        if (_udp != False && size == write_len){
          return write_len;
        } 
      }else if (ret == 0){        
        if (write_first == False){
          seterr();
          return write_len;
        }
      }else if (ret < 0){        
        seterr();
        return write_len;
      }
      if (timeout < 1){
        return write_len;
      }
      write_first = False;
//printf("before select\n",write_len);
      ret = so_select(FD_SETSIZE,NULL,&write_fds,NULL,&tm);
//printf("after select\n",write_len);
      long err = ret;
      if (ret < 0 && err != EX_ALREADY){
        seterr();
        return write_len;
      }
      if (write_len == size){
        seterr(0);
        return write_len;
      }
      continue;
    }
//printf("return write_len=%d\n",write_len);
    seterr();
    return write_len;
  }
  seterr();
  return write_len;
}
long WSDbtronSocket::write(WSCuchar* buf,long size){
  if (_socket == -1 && _udp != False){
    initialize();
    if (_socket == -1){
      return -1;
    }
  }
//printf("WSDbtronSocket::write.. _socket=0x%x\n",_socket);
  if (_socket != -1){
//printf("WSDbtronSocket::write.. call\n");
    long ret = write((void*)_socket,buf,size);
//printf("WSDbtronSocket::write done ret=%d size=%d\n",ret,size);
    return ret;
  }
  return -1;
}

void WSDbtronSocket::seterr(int err){
  if (err < 0){
    _error_str = "";
    _error_str << "SOCKET ERR=" << err;
  }else if (err ==0){
    _error_str = "";
  }else{
    _error_str = "";
    _error_str << "SOCKET ERR=" << err;
//    _error_str = strerror(err);
  }
}

WSCstring WSDbtronSocket::getLastError(){
  return _error_str;
}

