Dependencies:   XBeeLib mbed HvZAlphaNumLib HvZServerLib

lib/udp.hpp

Committer:
etherealflaim
Date:
2010-12-12
Revision:
1:d1b5cd8b2c18
Parent:
0:9cdba0589ba2

File content as of revision 1:d1b5cd8b2c18:

#ifndef _UDP
#define _UDP

#include <string>
#include <vector>
#include <queue>
#include <cctype>
#include <iostream>

#include "mbed.h"
#include "if/eth/EthernetNetIf.h"
#include "iHvZ.hpp"

#include "util/types.h"
#include "net/net.h"

#include "core/net.h"
#include "core/host.h"

#define HVZ_PORT 4489
#define HVZ_HOSTNAME "kylelemons.net"

enum UDPErr
{
  __UDPSOCKET_MIN = -0xFFFF,
  UDPSOCKET_SETUP, ///<UDPSocket not properly configured
  UDPSOCKET_IF, ///<Interface has problems, does not exist or is not initialized
  UDPSOCKET_MEM, ///<Not enough mem
  UDPSOCKET_INUSE, ///<Interface / Port is in use
//...
  UDPSOCKET_OK = 0 ///<Success
};

///UDP Socket Event(s)
enum UDPSocketEvent //Only one event here for now, but keeps that model in case we need to implement some others
{
  UDPSOCKET_READABLE, ///<Data in buf
};

enum responseType
{
   HVZ_REG = 0,
   HVZ_TAG,
   HVZ_PULL
};

enum pullType
{
   PULL_DEV = 0,
   PULL_MAC
};

class NetUdpSocket;
enum NetUdpSocketEvent;

class UDP {
public:

  iHvZ *m_game;                     //< Maintain a connection to the active game
  
  Ethernet_MAC mac;                 
  Ethernet eth;                     
  EthernetNetIf conn;
  char srvr_resp[128];
  int registered;
  
  DigitalIn   m_eth;
  InterruptIn m_eth_int;            //< Get an interrupt whenever the ethernet button is hit
  Timeout     m_eth_chk;
          
public:

  /* Creates a new socket */
  UDP(iHvZ *game, PinName eth_in);
  
  /* Closes and destroys socket */
  ~UDP(); //close()
  
  /* Check to see if theres an ethernet connection */
  void check();
      
  /* Sends data to Server */
  int sendto(const char* buf, int len, Host* pHost);
  
  /* Receive from Server */
  int recvfrom(char* buf, int len, Host* pHost);
  
  /* Closes the socket */
  UDPErr close();
  
  /* Checks to see if theres an ethernet link */
  void ethlink();
  
  /* Read response from Server */
  void read(UDPSocketEvent e);
  
  /* Set the game device and tag IDs */
  void set_ids(char *response);
   
  /* Registers the new device */
  inline void register_device(Ethernet_MAC originMAC, Host *host)
  {
     char data[34];
     
     sprintf(data, "iHvZ\001reg\001%02X%02X%02X%02X%02X%02X\001end", originMAC.octet[0], originMAC.octet[1], 
         originMAC.octet[2], originMAC.octet[3], originMAC.octet[4], originMAC.octet[5]);              

     sendto(data, strlen(data), host);           
  }
    
  /* Sends a player tag to the server of the tagged device */
  inline void send_tag(Host *host, vector<string> taggedIDs);
  
  //Requests an update of all settings from Server
  inline void send_pull(Host *host);
  
  inline int get_ack_err(char *response, responseType type)
  {  
      char ack_err[3];
      int i;
      
      memset(ack_err,0,3);
      
      for( i = 5; i < 8; i++ )
          memcpy(&(ack_err[i-5]),&(response[i]),1);
          
      if( strcmp(ack_err,"ack") == 0 ) {
            
          switch( type ) {
            case HVZ_REG:                          
              return 1;           
        
            case HVZ_PULL:            
              return 1;           
            
            case HVZ_TAG:
              // If sent invalid taggedIDs to server, the response will be ack
              // but it will not have valid tagged IDs, this is the size
              // of such a response
              if( strlen(response) > 16 ) 
                  return 1;
              
              else 
                  return 0;
              
          }
      }
      
      return 0;      
  }
  
  /* Update the Settings for the game */
  void update_settings(char *response);
 
  class CDummy;
  
  ///Setups callback
  template<class T> 
  void setOnEvent( T* pItem, void (T::*pMethod)(UDPSocketEvent) )
  {
    m_pCbItem = (CDummy*) pItem;
    m_pCbMeth = (void (CDummy::*)(UDPSocketEvent)) pMethod;
  }
  
  ///Disables callback
  void resetOnEvent();

protected:
  void onNetUdpSocketEvent(NetUdpSocketEvent e);
  UDPErr checkInst();

private:
  NetUdpSocket* m_pNetUdpSocket;
  
  CDummy* m_pCbItem;
  void (CDummy::*m_pCbMeth)(UDPSocketEvent);
  
  void (*m_pCb)(UDPSocketEvent);
      
};

#endif