/* 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 Open-R messages from the
    AIBOs over the wireless network. It then redirects the
    messages over a plain vanilla TCP/IP stream to a client.

    Basically, this lets us get network messages out of
    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 PetProxy : public OObject
{
public:
  static const int MaxClients=2;

private:
  sockaddr_in ClientAddress[MaxClients];
  int ClientSocket[MaxClients]; // tcp/ip stream connection to client program

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.
  */
  PetProxy(void);
 
  ~PetProxy();

  //
  //  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 ProcessBuffer(void *msg);

  void NetInput(const ONotifyEvent &event);

  void doNetInput(uchar *data);
  
  // tcp/ip methods
  void sendData(unsigned char *buf, int len);
  
 private:
  bool connectToClient(int client_num,char *client_addr, int client_port);
};

#endif
