Update of /cvsroot/playerstage/code/player/server/drivers/shell
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25787/server/drivers/shell

Modified Files:
      Tag: b_thjc_dynamic_arrays
        passthrough.cc .cvsignore kartowriter.cc Makefile.am 
Log Message:
Merged some changes from head a while back

Work on updating drivers, A-J done,  laser is next

Index: .cvsignore
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/shell/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.1.20.1
diff -C2 -d -r1.1 -r1.1.20.1
*** .cvsignore  5 Feb 2003 22:33:57 -0000       1.1
--- .cvsignore  10 Oct 2007 09:26:04 -0000      1.1.20.1
***************
*** 1,2 ****
--- 1,7 ----
  Makefile
  Makefile.in
+ .deps
+ *.la
+ *.a
+ *.lo
+ *.libs

Index: kartowriter.cc
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/shell/kartowriter.cc,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -C2 -d -r1.5 -r1.5.2.1
*** kartowriter.cc      23 Aug 2007 19:58:48 -0000      1.5
--- kartowriter.cc      10 Oct 2007 09:26:04 -0000      1.5.2.1
***************
*** 222,231 ****
                this->device_addr))
        {
-               if(hdr->size != sizeof(player_log_set_write_state_t))
-               {
-                       PLAYER_ERROR2("request is wrong length (%d != %d); 
ignoring",
-                               hdr->size, 
sizeof(player_log_set_write_state_t));
-                       return(-1);
-               }
                player_log_set_write_state_t* sreq = 
(player_log_set_write_state_t*)data;
  
--- 222,225 ----
***************
*** 250,260 ****
                PLAYER_LOG_REQ_GET_STATE, this->device_addr))
        {
-               if(hdr->size != 0)
-               {
-                       PLAYER_ERROR2("request is wrong length (%d != %d); 
ignoring",
-                               hdr->size, 0);
-                       return(-1);
-               }
- 
                player_log_get_state_t greq;
  
--- 244,247 ----

Index: Makefile.am
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/shell/Makefile.am,v
retrieving revision 1.17
retrieving revision 1.17.2.1
diff -C2 -d -r1.17 -r1.17.2.1
*** Makefile.am 2 May 2007 22:09:00 -0000       1.17
--- Makefile.am 10 Oct 2007 09:26:04 -0000      1.17.2.1
***************
*** 14,21 ****
  endif
  
  AM_CPPFLAGS = -g3 -Wall -I$(top_srcdir)
  
  libdummy_la_SOURCES = dummy.cc
! #libpassthrough_a_SOURCES = passthrough.cc 
  liblogfile_la_SOURCES = writelog.cc encode.h encode.cc \
                          readlog_time.h readlog_time.cc readlog.cc 
--- 14,25 ----
  endif
  
+ if INCLUDE_PASSTHROUGH
+ noinst_LTLIBRARIES += libpassthrough.la
+ endif
+ 
  AM_CPPFLAGS = -g3 -Wall -I$(top_srcdir)
  
  libdummy_la_SOURCES = dummy.cc
! libpassthrough_la_SOURCES = passthrough.cc 
  liblogfile_la_SOURCES = writelog.cc encode.h encode.cc \
                          readlog_time.h readlog_time.cc readlog.cc 

Index: passthrough.cc
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/shell/passthrough.cc,v
retrieving revision 1.20
retrieving revision 1.20.4.1
diff -C2 -d -r1.20 -r1.20.4.1
*** passthrough.cc      23 Feb 2006 18:54:55 -0000      1.20
--- passthrough.cc      10 Oct 2007 09:26:04 -0000      1.20.4.1
***************
*** 1,6 ****
  /*
   *  Player - One Hell of a Robot Server
!  *  Copyright (C) 2000  Brian Gerkey   &  Kasper Stoy
!  *                      [EMAIL PROTECTED]    [EMAIL PROTECTED]
   *
   *  This program is free software; you can redistribute it and/or modify
--- 1,6 ----
  /*
   *  Player - One Hell of a Robot Server
!  *  Copyright (C) 2007 Alexis Maldonado Herrera
!  *                     maldonad \/at/\ cs.tum.edu
   *
   *  This program is free software; you can redistribute it and/or modify
***************
*** 21,54 ****
  
  /*
!  * $Id$
!  */
  
  /** @ingroup drivers */
  /** @{ */
! /** @defgroup driver_passthrough passthrough (deprecated)
   * @brief General-purpose proxy driver
  
!  @deprecated This driver is probably no longer needed, since a driver can now
!  require a remote driver directly in the configuration file.
  
! The @p passthrough driver acts as a @e client to another Player server;
! it returns data generated by the remote server to client programs, and
! send commands from the client programs to the remote server.  In this
! way, one Player server can pretend to have devices that are actually
! located at some other location in the network (i.e., owned by some
! other Player server).  Thus, the @p passthrough driver makes possible
! three important capabilities:
!   - Data from multiple robots can be aggregated in a single Player
!     server; client programs can then talk to more than one robot through
!     a single connection.
!   - Computationally intensive drivers can be moved off the robot and
!     onto a workstation.  Client programs connect to the workstation rather
!     that the robot, but are otherwise unchanged.
!   - When working with Stage 1.3.x, you can use sophisticated drivers,
!     like @ref driver_amcl and @ref driver_vfh by instantiating
!     them in a second copy of Player, and passing through data and commands
!     for the simulated devices.
! See the below for some examples of the @p passthrough driver in
! action.
  
  @par Compile-time dependencies
--- 21,51 ----
  
  /*
!  This is the new passthrough driver for Player 2.
!  It does the following:
!        - From the configuration file, reads requires ["SRC interface"], and 
provides ["DST interface"]
!        - When a client connects to our DST interface, it subscribes to the 
SRC interface, and forwards all packets to the DST interface.
!        - If the client sends a command to the DST, it gets forwarded to the 
SRC interfaces, and the ACK, NACK, or SYNCH answers get sent back to the DST 
interface
!        - When the client disconnects from our DST interface, we unsubscribe 
from the SRC interface.
!        - When forwarding packets, the header gets changed accordingly, 
specifically: devaddr (host, robot, interface, index)
! */
! 
! //Doxygen documentation taken partly from the old Player 1.x passthrough 
driver, and modified to fit the new one
  
  /** @ingroup drivers */
  /** @{ */
! /** @defgroup driver_passthrough passthrough
   * @brief General-purpose proxy driver
  
! The @p passthrough driver relays packets between two player interfaces.
! It connects as a @e client to an interface, and offers the same interface
! to other clients. All communication packets are forwarded between the two.
  
! This is specially useful to aggregate many player devices in a single Player
! Server, and control them using only one connection. Probably the most
! useful usage is to have a Player Server offering a stable set of interfaces,
! that get forwarded to the appropriate Player Servers connected to the 
hardware.
! If a device is moved around to a different computer, the clients don't have to
! be reconfigured, since the change is done only in the server running the 
passthrough
! driver.
  
  @par Compile-time dependencies
***************
*** 59,63 ****
  
  - The @p passthrough driver will support any of Player's interfaces,
! and can connect to any Player device.
  
  @par Requires
--- 56,60 ----
  
  - The @p passthrough driver will support any of Player's interfaces,
!   and can connect to any Player device.
  
  @par Requires
***************
*** 71,558 ****
  @par Configuration file options
  
! The @p passthrough driver needs the full address of the remote device
! which is a tuple host:port:interface:index.  The interface is determined
! with the normal "provides" syntax.  Specify the remaining parts in the
! configuration file:
! 
! - remote_host (string)
!   - Default: "localhost"
!   - Hostname of the remote device
! - remote_port (integer)
!   - Default: the port being used by this instance of Player
!   - TCP port of the remote device
! - remote_index (integer)
!   - Default: the index of the passthrough device
!   - Index of the remote device
! - access (string)
!   - Default: "a"
!   - The access to be acquired ("r", "w", or "a")
! 
! @par Example: Controlling multiple robots through a single connection
! 
! The @p passthrough driver can be used to aggregate devices from multiple
! robots into a single server.  The following example illustrates the
! general method for doing this.
  
! - Imagine that we have two laser-equipped Pioneer robots named @p bee
! and @p bug.  On each robot, start a Player server with the following
! configuration file:
! @verbatim
! driver
! (
!   name "p2os"
!   provides ["odometry::position:0"]
! )
! driver
! (
!   name "sicklms200"
!   provides ["laser:0"]
! )
! @endverbatim
! - Now imagine that we have a workstation named @p orac.  On this
! workstation, start another instance of Player with the following
! configuration file:
  @verbatim
  driver
  (
!   name "passthrough"
!   provides ["position:0"]
!   remote_host "bee"
!   remote_port 6665
!   remote_index 0
!   access "a"
! )
! driver
! (
!   name "passthrough"
!   provides ["laser:0"]
!   remote_host "bee"
!   remote_port 6665
!   remote_index 0
!   access "r"
! )
! driver
! (
!   name "passthrough"
!   provides ["position:1"]
!   remote_host "bug"
!   remote_port 6665
!   remote_index 0
!   access "a"
! )
! driver
! (
!   name "passthrough"
!   provides ["laser:1"]
!   remote_host "bug"
!   remote_port 6665
!   remote_index 0
!   access "r"
  )
  @endverbatim
- A client connecting to @p orac will see four devices: two @ref
- interface_position2d devices and two @ref interface_laser
- devices.  Both robots can now be controlled through a single connection
- to @p orac.
- 
- @par Example: Shifting computation
- 
- Computationally expensive drivers (such as @ref driver_amcl)
- can be shifted off the robot and onto a workstation.  The basic method
- is a straight-forward variant of the example given above.
  
! - Imagine that we have a robot named @p bee.  On @p bee, run the Player
! server with this configuration file:
  @verbatim
  driver
  (
!   name "p2os"
!   provides ["odometry::position:0"]
! )
! driver
! (
!   name "sicklms200"
!   provides ["laser:0"]
  )
  @endverbatim
- The robot is assumed to be a Pioneer with a SICK laser range-finder.
  
! - Now imagine that we have a workstation named @p orac.  On
! this workstation, start another instance of Player with the
! following configuration file:
! @verbatim
! driver
! (
!   name "passthrough"
!   provides ["position:0"]
!   remote_host "bee"
!   remote_port 6665
!   remote_index 0
!   access "a"
! )
! driver
! (
!   name "passthrough"
!   provides ["laser:0"]
!   remote_host "bee"
!   remote_port 6665
!   remote_index 0
!   access "r"
! )
! driver
! (
!   name "amcl"
!   provides ["localize:0"]
!   requires ["position:0" "laser:0"]
!   ....
! )
! @endverbatim
! (See the documentation for the @ref driver_amcl driver for a
! detailed description of the additional setings for that driver.)
! Clients connecting to this server will see a robot with @ref
! interface_position2d, @ref interface_laser and @ref
! interface_localize devices, but all of the heavy computation will
! be done on the workstation.
  
- @par Example: Using the amcl driver with Stage 1.3.x
  
! Some newer drivers, such as the @ref driver_amcl and @ref
! driver_vfh driver, are not supported natively in Stage.  For these
! drivers users must employ a second Player server configured to use the
! @p passthrough driver.  The basic procedure is as follows.
  
- - Start Stage with a world file something like this:
- @verbatim
- ...
- position (port 6665 laser ())
- ...
- @endverbatim
- Stage will create one robot (position device) with a laser, and
- will start a Player server that listens on port 6665.
- - Start another Player server using the command
- @verbatim
-   player -p 7000 amcl.cfg
- @endverbatim
- where the configuration file @p amcl.cfg looks like this (see the
- documentation for the @ref driver_amcl driver for a detailed
- description of the additional setings for that driver):
- @verbatim
- driver
- (
-   name "passthrough"
-   provides ["position:0"]
-   remote_host "localhost"
-   remote_port 6665
-   remote_index 0
-   access "a"
- )
- driver
- (
-   name "passthrough"
-   provides ["laser:0"]
-   remote_host "localhost"
-   remote_port 6665
-   remote_index 0
-   access "r"
- )
- driver
- (
-   name "mapfile"
-   provides ["map:0"]
-   filename "cave.pnm"
-   resolution 0.03
-   negate 1
- )
- driver
- (
-   name "amcl"
-   provides ["localize:0"]
-   requires ["odometry::position:0" "laser:0" "laser::map:0"]
- )
- @endverbatim
- The second Player server will start up and listen on port 7000;
- clients connecting to this server will see a robot with @ref
- interface_position2d, @ref interface_laser, and @ref
- interface_localize devices.
  
- @author Brian Gerkey, Andrew Howard
  
- */
- /** @} */
  
! #include <stdlib.h>
! #include <sys/time.h>
  #include <string.h>
  
- // we'll use the C client facilities to connect to the remote server
  #include <libplayercore/playercore.h>
- #include <playercclient.h>
  
! extern int global_playerport;
  
! class PassThrough:public Driver
! {
!   private:
!   // info for our local device
!   player_device_id_t local_id;
  
!   // info for the server/device to which we will connect
!   const char* remote_hostname;
!   player_device_id_t remote_id;
!   unsigned char remote_access;
!   char remote_drivername[PLAYER_MAX_DEVICE_STRING_LEN];
  
!   // bookkeeping for the client connection
!   player_connection_t conn;
!   char* remote_data;
!   char* remote_command;
!   char* remote_config;
!   char* remote_reply;
  
!   // MessageHandler
!   int ProcessMessage(ClientData * client, player_msghdr * hdr, uint8_t * 
data, uint8_t * resp_data, int * resp_len);
  
!   // this function will be run in a separate thread
!   virtual void Main();
  
!   // close and cleanup
!   void CloseConnection();
  
-   public:
-   PassThrough(ConfigFile* cf, int section);
-   ~PassThrough();
-   virtual int Setup();
-   virtual int Shutdown();
  };
  
- // initialization function
  Driver*
! PassThrough_Init( ConfigFile* cf, int section)
! {
!   return((Driver*)(new PassThrough(cf, section)));
  }
  
! // a driver registration function
! void
! PassThrough_Register(DriverTable* table)
! {
!   table->AddDriver("passthrough",  PassThrough_Init);
  }
  
  PassThrough::PassThrough(ConfigFile* cf, int section)
!  : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, -1, 
PLAYER_ALL_MODE)
! {
!   this->local_id = this->device_id;
!   // Figure out remote device location
!   this->remote_hostname = cf->ReadString(section, "remote_host", "localhost");
  
!   // Figure out remote device id
!   this->remote_id.code = this->local_id.code;
!   this->remote_id.index = cf->ReadInt(section, "remote_index", 
this->local_id.index);
!   this->remote_id.port = cf->ReadInt(section, "remote_port", 
this->local_id.port);
  
!   // See if we are connected to ourself
!   if(!strcmp(this->remote_hostname,"localhost") && (this->remote_id.port == 
this->local_id.port))
!   {
!     PLAYER_ERROR("passthrough connected to itself; you should specify\n the 
hostname and/or port of the remote server in the configuration file");
!     this->SetError(-1);
!     return;
!   }
  
-   this->remote_access = (unsigned char)cf->ReadString(section, "access", 
"a")[0];
-   this->conn.protocol = PLAYER_TRANSPORT_TCP;
  
!   assert(this->remote_data = (char*)calloc(PLAYER_MAX_PAYLOAD_SIZE,1));
!   assert(this->remote_command = (char*)calloc(PLAYER_MAX_PAYLOAD_SIZE,1));
!   assert(this->remote_config = (char*)calloc(PLAYER_MAX_PAYLOAD_SIZE,1));
!   assert(this->remote_reply = (char*)calloc(PLAYER_MAX_PAYLOAD_SIZE,1));
  }
  
! void
! PassThrough::CloseConnection()
! {
!   if(this->conn.sock >=0)
!     player_disconnect(&this->conn);
!   //PutData(NULL,0,NULL);
! }
  
! PassThrough::~PassThrough()
! {
!   //CloseConnection();
!   free(this->remote_data);
!   free(this->remote_command);
!   free(this->remote_config);
!   free(this->remote_reply);
! }
  
- int
- PassThrough::Setup()
- {
-   unsigned char grant_access;
-   Device* devp;
-   player_msghdr_t hdr;
  
!   // zero out the buffers
!   //PutData(NULL,0,0,0);
!   //PutCommand(this->device_id,NULL,0,NULL);
  
!   printf("Passthrough connecting to server at %s:%d...", 
this->remote_hostname,
!          this->remote_id.port);
!   // connect to the server
!   if(player_connect(&this->conn,this->remote_hostname,this->remote_id.port) < 
0)
!   {
!     PLAYER_ERROR1("couldn't connect to remote host \"%s\"",
!                   this->remote_hostname);
!     return(-1);
!   }
  
-   puts("Done");
  
!   printf("Passthrough opening device %d:%d:%d...",
!          this->remote_id.port,
!          this->remote_id.code,
!          this->remote_id.index);
!   // open the device
!   if((player_request_device_access(&this->conn,
!                                    this->remote_id.code,
!                                    this->remote_id.index,
!                                    this->remote_access,
!                                    &grant_access,
!                                    this->remote_drivername,
!                                    sizeof(this->remote_drivername)) < 0) ||
!      (grant_access != this->remote_access))
!   {
!     PLAYER_ERROR("couldn't get requested access to remote device");
!     CloseConnection();
!     return(-1);
!   }
!   puts("Done");
  
!   // set the driver name in the devicetable
!   if(!(devp = deviceTable->GetDevice(this->device_id)))
!   {
!     PLAYER_ERROR("couldn't find my own entry in the deviceTable");
!     CloseConnection();
!     return(-1);
!   }
!   
strncpy(devp->drivername,this->remote_drivername,PLAYER_MAX_DEVICE_STRING_LEN);
  
-   for(;;)
-   {
-     // wait for one data packet from the remote server, to avoid sending
-     // zero length packets to our clients
-     
if(player_read(&this->conn,&hdr,this->remote_data,PLAYER_MAX_PAYLOAD_SIZE))
-     {
-       PLAYER_ERROR("got error while reading data; bailing");
-       CloseConnection();
-       return(-1);
-     }
  
!     if((hdr.type == PLAYER_MSGTYPE_DATA) &&
!        (hdr.device == this->remote_id.code) &&
!        (hdr.device_index == this->remote_id.index))
!     {
!       struct timeval ts;
!       ts.tv_sec = hdr.timestamp_sec;
!       ts.tv_usec = hdr.timestamp_usec;
!       PutMsg(remote_id,NULL,PLAYER_MSGTYPE_DATA,0,this->remote_data,hdr.size, 
&ts);
!       break;
!     }
!   }
  
-   StartThread();
  
!   return(0);
! }
  
! int
! PassThrough::Shutdown()
! {
!   StopThread();
!   CloseConnection();
!   return(0);
  }
  
! /*int player_request(player_connection_t* conn, uint8_t reqtype,
!                    uint16_t device, uint16_t device_index,
!                    const char* payload, size_t payloadlen,
!                    player_msghdr_t* replyhdr, char* reply, size_t replylen);*/
  
- int PassThrough::ProcessMessage(ClientData * client, player_msghdr * hdr, 
uint8_t * data, uint8_t * resp_data, int * resp_len)
- {
-   assert(hdr);
-   assert(data);
-   assert(resp_data);
-   assert(resp_len);
  
!   player_msghdr_t replyhdr;
  
!     if (hdr->type == PLAYER_MSGTYPE_REQ)
!     {
!       // send it
!       if(player_request(&this->conn,hdr->subtype,this->remote_id.code,
!                         this->remote_id.index,
!                         (const char*)data,hdr->size,&replyhdr,
!                         this->remote_reply,PLAYER_MAX_PAYLOAD_SIZE) < 0)
!       {
!         PLAYER_ERROR("got error while sending request; bailing");
!         CloseConnection();
!         pthread_exit(NULL);
!       }
!       *resp_len = replyhdr.size;
!       memcpy(resp_data,remote_reply,*resp_len);
!       return replyhdr.type;
      }
  
!     if (hdr->type == PLAYER_MSGTYPE_CMD)
!     {
!       if(player_write(&this->conn,this->remote_id.code,
!                       this->remote_id.index,
!                         (const char *)data,hdr->size) < 0)
!       {
!         PLAYER_ERROR("got error while writing command; bailing");
!         CloseConnection();
!         pthread_exit(NULL);
!       }
      }
  
!   *resp_len = 0;
!   return -1;
! }
  
- void
- PassThrough::Main()
- {
- //  size_t len_command;
- //  size_t len_config;
-   player_msghdr_t hdr;
- //  void* client;
- //  player_msghdr_t replyhdr;
- //  struct timeval ts;
  
!   for(;;)
!   {
  
  
  
!     // get new data from the remote server
!     
if(player_read(&this->conn,&hdr,this->remote_data,PLAYER_MAX_PAYLOAD_SIZE))
!     {
!       PLAYER_ERROR("got error while reading data; bailing");
!       CloseConnection();
!       pthread_exit(NULL);
!     }
  
!     if((hdr.type == PLAYER_MSGTYPE_DATA) &&
!        //(hdr.robot == this->remote_id.robot) &&
!        (hdr.device == this->remote_id.code) &&
!        (hdr.device_index == this->remote_id.index))
!     {
!       struct timeval ts;
!       ts.tv_sec = hdr.timestamp_sec;
!       ts.tv_usec = hdr.timestamp_usec;
!       PutMsg(this->local_id, NULL, 
PLAYER_MSGTYPE_DATA,0,this->remote_data,hdr.size,&ts);
      }
-   }
  }
  
--- 68,269 ----
  @par Configuration file options
  
! The @p passthrough driver can be used with local or remote interfaces using 
the
! requires section in the configuration file.
  
! For local interfaces, the format is:
  @verbatim
  driver
  (
!    name "passthrough"
!    requires ["interface:index"]  // example: ["dio:0"]
!    provides ["interface:anotherindex"] // example: ["dio:25"]
  )
  @endverbatim
  
! To connect to an interface running on another server, the format is:
  @verbatim
  driver
  (
!    name "passthrough"
!    requires [":hostname:port:interface:index"]   // example: 
[":someserver:6665:dio:0"]
!    provides ["interface:someindex"] //example: [dio:0]
  )
  @endverbatim
  
! Note that the in the case of connecting to remote interfaces, the provided 
interface can have
! any index number. The driver changes the header accordingly.
  
  
! @author Alexis Maldonado
! */
! /** @} */
  
  
  
  
! #include <unistd.h>
  #include <string.h>
  
  #include <libplayercore/playercore.h>
  
! class PassThrough : public Driver {
! public:
  
!     PassThrough(ConfigFile* cf, int section);
  
!     virtual int Setup();
!     virtual int Shutdown();
  
!     virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr * hdr, 
void * data);
  
! private:
  
!     virtual void Main();
  
!     //Devices used to compare the header, and forward packets accordingly
!     player_devaddr_t dstAddr;
!     player_devaddr_t srcAddr;
!     //the device that this server connects to to get data
!     Device *srcDevice;
  
  };
  
  Driver*
! PassThrough_Init(ConfigFile* cf, int section) {
!     return((Driver*)(new PassThrough(cf, section)));
  }
  
! 
! void PassThrough_Register(DriverTable* table) {
!     table->AddDriver("passthrough", PassThrough_Init);
  }
  
+ 
  PassThrough::PassThrough(ConfigFile* cf, int section)
!         : Driver(cf, section) {
!     memset(&srcAddr, 0, sizeof(player_devaddr_t));
!     memset(&dstAddr, 0, sizeof(player_devaddr_t));
  
!     //let's create our DST interface
!     if (cf->ReadDeviceAddr(&dstAddr, section, "provides",
!                            -1, 0, NULL) == 0) {
!         if (AddInterface(dstAddr) != 0) {
!             SetError(-1);
!             return;
!         }
!     } else {
!         PLAYER_ERROR("PassThrough: Missing 'provides' section, aborting.");
!         SetError(-1);
!         return;
!     }
  
!     //Find our SRC inteface
!     if (cf->ReadDeviceAddr(&srcAddr, section, "requires", -1, 0, NULL) != 0) {
!         PLAYER_ERROR("PassThrough: Missing 'requires' section, aborting.");
!         this->SetError(-1);
!         return;
!     }
  
  
!     return;
  }
  
! 
////////////////////////////////////////////////////////////////////////////////
! // Set up the device.  Return 0 if things go well, and -1 otherwise.
! int PassThrough::Setup() {
!     PLAYER_MSG0(1,"PassThrough driver initialising");
  
!     PLAYER_MSG0(1,"PassThrough driver ready");
  
  
!     srcDevice=deviceTable->GetDevice(srcAddr);
  
!     if (!srcDevice) {
!         PLAYER_ERROR3("Could not locate device [%d:%s:%d] for forwarding",
!                       srcDevice->addr.robot,::lookup_interface_name(0, 
srcDevice->addr.interf),
!                       srcDevice->addr.index);
!         return -1;
!     }
!     if (srcDevice->Subscribe(this->InQueue) != 0) {
!         PLAYER_ERROR("unable to subscribe to device");
!         return -1;
!     }
  
  
!     StartThread();
  
!     return(0);
! }
  
  
! int PassThrough::Shutdown() {
!     PLAYER_MSG0(1,"Shutting PassThrough driver down");
  
  
!     StopThread();
  
!     //Our clients disconnected, so let's disconnect from our SRC interface
!     srcDevice->Unsubscribe(this->InQueue);
! 
!     PLAYER_MSG0(1,"PassThrough driver has been shutdown");
! 
!     return(0);
  }
  
! int PassThrough::ProcessMessage(QueuePointer & resp_queue,
!                                 player_msghdr * hdr,
!                                 void * data) {
  
  
!     bool inspected(false);
  
!     PLAYER_MSG0(9,"PassThrough::ProcessMessage: Received a packet!");
! 
!     if ( Device::MatchDeviceAddress(hdr->addr,srcAddr) && ( (hdr->type == 
PLAYER_MSGTYPE_DATA) || (hdr->type == PLAYER_MSGTYPE_RESP_ACK) || (hdr->type == 
PLAYER_MSGTYPE_SYNCH)  || (hdr->type == PLAYER_MSGTYPE_RESP_NACK)   ) )  {
!         PLAYER_MSG7(3,"PassThrough: Forwarding SRC->DST Interface code=%d  
%d:%d:%d -> %d:%d:%d",hdr->addr.interf, hdr->addr.host,hdr->addr.robot, 
hdr->addr.index, dstAddr.host, dstAddr.robot, dstAddr.index);
! 
!         hdr->addr=dstAddr; //will send to my clients, making it seem like it 
comes from my DST interface
! 
!         this->Publish (hdr,data);  //publish to all clients that subscribed 
to my DST interface. *data remains unchanged
!         inspected=true;
      }
  
!     if ( Device::MatchDeviceAddress(hdr->addr,dstAddr) && ( (hdr->type == 
PLAYER_MSGTYPE_CMD) || (hdr->type == PLAYER_MSGTYPE_REQ) ) )  {
!         PLAYER_MSG7(3,"PassThrough: Forwarding DST->SRC Interface code=%d  
%d:%d:%d -> %d:%d:%d",hdr->addr.interf, hdr->addr.host,hdr->addr.robot, 
hdr->addr.index, srcAddr.host, srcAddr.robot, srcAddr.index);
! 
! 
!         hdr->addr=srcAddr;  //send to the device to which I subscribed, 
making it seem like it comes from my original interface
! 
!         srcDevice->PutMsg(this->InQueue,hdr,data);  //putMsg is the correct 
way to talk to this subscribed device, any answer comes to the queue of this 
driver
!         inspected=true;
      }
  
!     //Check if a packet went thorugh, without being forwarded
!     if (!inspected) {
!         static bool reported(false);
!         if (!reported) {
!             PLAYER_WARN("PassThrough: A packet did not get forwarded.\nThis 
warning is only shown once.\nRun player -d 2 or -d 3 for more information.");
!             reported=true;
!         }
!         PLAYER_MSG0(2,"PassThrough: Something did not get forwarded. Check 
the header:");
!         PLAYER_MSG4(2,"host: %d  robot: %d  interf: %d  index: 
%d",hdr->addr.host,hdr->addr.robot,hdr->addr.interf,hdr->addr.index);
!         PLAYER_MSG2(2,"type: %d  subtype: %d",hdr->type,hdr->subtype);
!     }
  
  
!     return(0);
! }
  
  
  
! void PassThrough::Main() {
!     //The forwarding is done in the ProcessMessage method. Called once per 
each message by ProcessMessages()
!     while (true) {
!         pthread_testcancel();
  
!         ProcessMessages();
! 
!         usleep(100);
      }
  }
  


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to