text: 
  #include <sys/lpc.h>
  #include <netserv.h>
  #include <errno.h>
  #include <lwip/sockets.h>
  
  static bool remote_socket(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int domain, type, protocol;
      lpc_parcel_read_int(data, (uint32_t *)&domain);
      lpc_parcel_read_int(data, (uint32_t *)&type);
      lpc_parcel_read_int(data, (uint32_t *)&protocol);
      int socket_id = lwip_socket(domain, type, protocol);
      if (socket_id < 0) {
          lpc_parcel_write_int(reply, -EPERM);
          return false;    
      }
      lpc_parcel_write_int(reply, socket_id);
      return true;    
  }
  
  static bool remote_bind(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      struct sockaddr my_addr;
      int addrlen;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      lpc_parcel_read_sequence(data, (void *)&my_addr, (size_t *)&addrlen);
      int retval = lwip_bind(sock, (const struct sockaddr *)&my_addr, addrlen);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      return true;    
  }
  
  static bool remote_connect(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      struct sockaddr serv_addr;
      int addrlen;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence(data, (void *)&serv_addr, (size_t *)&addrlen);
      int retval = lwip_connect(sock, (const struct sockaddr *)&serv_addr, addrlen);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      return true;    
  }
  
  static bool remote_listen(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      int backlog;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_int(data, (uint32_t *)&backlog);
  
      int retval = lwip_listen(sock, backlog);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;
      }
      lpc_parcel_write_int(reply, retval);
      return true;    
  }
  
  static bool remote_accept(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      struct sockaddr addr;
      socklen_t addrlen;
      int newsock = lwip_accept(sock, &addr, &addrlen);
      if (newsock < 0) {
          lpc_parcel_write_int(reply, newsock);
          return false;
      }
      lpc_parcel_write_int(reply, newsock);
      lpc_parcel_write_sequence(reply, &addr, addrlen);
      return true;    
  }
  
  static bool remote_send(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      void *buf;
      int len;
      int flags;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence_buf(data, (void **)&buf, (size_t *)&len);
      lpc_parcel_read_int(data, (uint32_t *)&flags);
      
      int sndbytes = lwip_send(sock, buf, len, flags);
      if (sndbytes < 0) {
          lpc_parcel_write_int(reply, sndbytes);
          return false;
      }
      lpc_parcel_write_int(reply, sndbytes);
      return true;    
  }
  
  static bool remote_recv(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      void *buf;
      int len;
      int flags;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence_buf(data, (void **)&buf, (size_t *)&len);
      lpc_parcel_read_int(data, (uint32_t *)&flags);
      int recvbytes = lwip_recv(sock, buf, len, flags);
      if (recvbytes < 0) {
          lpc_parcel_write_int(reply, recvbytes);
          return false;
      }
      lpc_parcel_write_int(reply, recvbytes);
      lpc_parcel_write_sequence(reply, buf, recvbytes);
      return true;    
  }
  
  static bool remote_sendto(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      void *buf;
      int len;
      int flags;
      struct sockaddr to;
      socklen_t tolen;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence_buf(data, (void **)&buf, (size_t *)&len);
      lpc_parcel_read_int(data, (uint32_t *)&flags);
      lpc_parcel_read_sequence(data, (void *)&to, (size_t *)&tolen);
      int sndbytes = lwip_sendto(sock, buf, len, flags, (const struct sockaddr *)&to, tolen);
      if (sndbytes < 0) {
          lpc_parcel_write_int(reply, sndbytes);
          return false;
      }
      lpc_parcel_write_int(reply, sndbytes);
      return true;    
  }
  
  static bool remote_recvfrom(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      void *buf;
      int len;
      int flags;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence_buf(data, (void **)&buf, (size_t *)&len);
      lpc_parcel_read_int(data, (uint32_t *)&flags);
      struct sockaddr from;
      socklen_t fromlen;
      int recvbytes = lwip_recvfrom(sock, buf, len, flags, &from, &fromlen);
      if (recvbytes < 0) {
          lpc_parcel_write_int(reply, recvbytes);
          return false;
      }
      lpc_parcel_write_int(reply, recvbytes);
      lpc_parcel_write_sequence(reply, buf, recvbytes);
      lpc_parcel_write_sequence(reply, &from, fromlen);
      
      return true;    
  }
  
  static bool remote_close(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      int retval = lwip_close(sock);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      return true;    
  }
  
  static bool remote_ioctl(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      int request;
      void *arg;
      size_t size;
      lpc_parcel_read_int(data, (uint32_t *)&request);
      lpc_parcel_read_sequence_buf(data, (void **)&arg, &size);
      int retval = lwip_ioctl(sock, request, arg);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      lpc_parcel_write_sequence(reply, arg, size);
      return true;    
  }
  
  static bool remote_shutdown(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      int how; lpc_parcel_read_int(data, (uint32_t *)&how);
      int retval = lwip_shutdown(sock, how);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      return true;    
  }
  
  static bool remote_getpeername(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      struct sockaddr serv_addr;
      socklen_t addrlen;
      int retval = lwip_getpeername(sock, &serv_addr, &addrlen);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      lpc_parcel_write_sequence(reply, (void *)&serv_addr, addrlen);
      return true;    
  }
  
  static bool remote_getsockname(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      struct sockaddr serv_addr;
      socklen_t addrlen;
      int retval = lwip_getsockname(sock, &serv_addr, &addrlen);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      lpc_parcel_write_sequence(reply, (void *)&serv_addr, addrlen);
      return true;    
  }
  
  static bool remote_getsockopt(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      int level; lpc_parcel_read_int(data, (uint32_t *)&level);
      int optname; lpc_parcel_read_int(data, (uint32_t *)&optname);
      unsigned long optval;
      socklen_t optlen;
      int retval = lwip_getsockopt(sock, level, optname, (void *)&optval, &optlen);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      lpc_parcel_write_sequence(reply, (void *)&optval, optlen);
      return true;
  }
  
  static bool remote_setsockopt(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      int level; lpc_parcel_read_int(data, (uint32_t *)&level);
      int optname; lpc_parcel_read_int(data, (uint32_t *)&optname);
      void *optval;
      socklen_t optlen;
      lpc_parcel_read_sequence_buf(data, (void **)&optval, (size_t *)&optlen);
      int retval = lwip_setsockopt(sock, level, optname, optval, optlen);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      return true;
  }
  
  static bool remote_write(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      void *buf;
      size_t len;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence_buf(data, (void **)&buf, (size_t *)&len);
      
      int sndbytes = lwip_write(sock, (const void *)buf, len);
      if (sndbytes < 0) {
          lpc_parcel_write_int(reply, sndbytes);
          return false;
      }
      lpc_parcel_write_int(reply, sndbytes);
      return true;    
  }
  
  static bool remote_read(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock;
      void *buf;
      size_t len;
      lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0) {
          lpc_parcel_write_int(reply, -1);
          return false;    
      }
      lpc_parcel_read_sequence_buf(data, (void **)&buf, (size_t *)&len);
      int recvbytes = lwip_read(sock, buf, len);
      if (recvbytes < 0) {
          lpc_parcel_write_int(reply, recvbytes);
          return false;
      }
      lpc_parcel_write_int(reply, recvbytes);
      lpc_parcel_write_sequence(reply, buf, recvbytes);
      return true;    
  }
  
  static bool remote_fcntl(lpc_parcel_t data, lpc_parcel_t reply)
  {
      int sock; lpc_parcel_read_int(data, (uint32_t *)&sock);
      if (sock < 0)
          return false;
      int cmd;
      int val;
      lpc_parcel_read_int(data, (uint32_t *)&cmd);
      lpc_parcel_read_int(data, (uint32_t *)&val);
      
      int retval = lwip_fcntl(sock, cmd, val);
      if (retval < 0) {
          lpc_parcel_write_int(reply, retval);
          return false;    
      }
      lpc_parcel_write_int(reply, retval);
      return true;    
  }
  
  static lpc_remote_handler_t net_remote_table[] = {
      remote_socket,
      remote_bind,
      remote_connect,
      remote_listen,
      remote_accept,
      remote_send,
      remote_recv,
      remote_close,
      remote_sendto,
      remote_recvfrom,
      remote_ioctl,
      remote_shutdown,
      remote_getpeername,
      remote_getsockname,
      remote_getsockopt,
      remote_setsockopt,
      remote_read,
      remote_write,
      remote_fcntl,
  };
  
  bool netserv_echo_main(uint32_t code, lpc_parcel_t data, lpc_parcel_t reply)
  {
      //printf("netserv tid=%d do echo\n", pthread_self()); // 查看是哪个线程在处理
      if (code >= FIRST_CALL_CODE && code < NETCALL_LAST_CALL)
          return net_remote_table[code - 1](data, reply);
      return false;
  }
  