/* LICENSE:
  =========================================================================
    CMPack'03 Source Code Release for OPEN-R SDK v1.0
    Copyright (C) 2003 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#ifndef INCLUDED_PetProxy_h
#define INCLUDED_PetProxy_h

// includes for OPEN-R stuff
#include <OPENR/OObject.h>
#include <OPENR/OSubject.h> 
#include <OPENR/OObserver.h>
#include <OPENR/core_macro.h>
#include "def.h"
#include "entry.h"
#include "../../../agent/headers/WaveLAN.h"

// includes for socket stuff
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/** A proxy class that listens for messages from an input
    scoket and forwards them as Open-R messages for the
    AIBOs over the wireless network.

    Basically, this lets us get network messages into
    Aperios-land and use normal TCP/IP networking for
    communication. (We don't have any results on what this
    does to latency).

    Note that despite expectations, this proxy acts as a
    CLIENT to everything it connects to and the other end
    of all the connections is the server.  This is because
    the dogs are setup to be servers (out of our control)
    and this way we can just restart the proxy instead of
    restarting the whole system when we need to restart the
    robots.
*/

class PetProxyIn : public OObject
{
public:
  static const int MaxClients = 2;

 private:
  sockaddr_in ClientAddress[MaxClients];
  int ClientSocket[MaxClients]; // tcp/ip stream connection from client program

  //int DatagramInputSocket;

 public:
  /** Create a new PetProxy that sends messages to the default client at the
     default port.  This actually creates and opens the socket, so it would
     be a good idea of the machine at client_addr was listening on
     client_port.
  */
  PetProxyIn(void);
 
  ~PetProxyIn();

  //
  //  OObserver & OSubject
  //
  OSubject*    subject[numOfSubject];
  OObserver*   observer[numOfObserver];
  
  //
  //  OPENR Method
  //
  virtual OStatus DoInit(const OSystemEvent& event);
  virtual OStatus DoStart(const OSystemEvent& event);
  virtual OStatus DoStop(const OSystemEvent& event);
  virtual OStatus DoDestroy(const OSystemEvent& event);

  void ReadyData(const OReadyEvent &event);
  
  // tcp/ip methods
  int recvData(int client_num,unsigned char *buf, int buf_size); 
  
  void processInput();

 private:
  bool connectToClient(int client_num,char *client_addr, int client_port);

  static const int BufSize=2048;
  uchar buf[BufSize];
  uchar *curBufLoc;  
};

#endif
