Kyle Lemons / Mbed 2 deprecated HvZ

Dependencies:   XBeeLib mbed HvZAlphaNumLib HvZServerLib

Revision:
0:9cdba0589ba2
Child:
1:d1b5cd8b2c18
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/udp.cpp	Sun Dec 12 19:35:00 2010 +0000
@@ -0,0 +1,342 @@
+#include "mbed.h"
+#include "iHvZ.hpp"
+#include "if/net/netudpsocket.h"
+
+#include "udp.hpp"
+
+UDP::UDP(iHvZ *game, PinName eth_in) 
+:  m_game(game), m_eth(eth_in), m_eth_int(eth_in),
+   m_pNetUdpSocket(NULL), m_pCbItem(NULL), m_pCbMeth(NULL), m_pCb(NULL),
+   conn(IpAddr(192,168,1,2),IpAddr(255,255,255,0), IpAddr(), IpAddr())
+{
+    // Set the game ID
+    char mac[8];
+    char macaddr[12+1];
+    eth.address(mac);
+    sprintf(macaddr, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+    m_game->id(macaddr);
+    
+    //m_eth_int.rise(this, &UDP::check);
+    m_eth_chk.attach(this, &UDP::check, 5);
+    registered = 0;
+}
+ 
+UDP::~UDP()
+{
+  close();
+}
+
+void UDP::check()
+{   
+    // debounce (if attached to a button)
+    wait(.1);
+    //if (m_eth)
+    //{        
+    //    usb.printf("- Connection found, starting sync\r\n");
+        ethlink();
+    //}
+    m_eth_chk.attach(this, &UDP::check, 10);
+}
+     
+int UDP::sendto(const char* buf, int len, Host* pHost)
+{
+  UDPErr udpSocketErr = checkInst();
+  if(udpSocketErr)
+    return udpSocketErr; 
+  return m_pNetUdpSocket->sendto(buf, len, pHost);  
+}
+
+int UDP::recvfrom(char* buf, int len, Host* pHost)
+{
+  UDPErr udpSocketErr = checkInst();
+  if(udpSocketErr)
+    return udpSocketErr;
+  return m_pNetUdpSocket->recvfrom(buf, len, pHost);
+}
+
+UDPErr UDP::close()
+{
+  if(!m_pNetUdpSocket)
+    return UDPSOCKET_SETUP;
+  m_pNetUdpSocket->resetOnEvent();
+  UDPErr udpSocketErr = (UDPErr) m_pNetUdpSocket->close(); //Close (can already be closed)
+  Net::releaseUdpSocket(m_pNetUdpSocket); //And release it so it can be freed when properly removed
+  m_pNetUdpSocket = NULL;
+  return udpSocketErr;
+} 
+
+void UDP::ethlink()
+{
+    Serial usb(USBTX,USBRX);
+    usb.printf("Checking for Ethernet connection...\r\n");
+    
+    //Host game_server(IpAddr(128, 61, 89, 71), HVZ_PORT, HVZ_HOSTNAME);
+    Host game_server(IpAddr(192, 168, 1, 1), HVZ_PORT, HVZ_HOSTNAME);
+    
+    /* Function to call upon Server response */    
+    setOnEvent(this, &UDP::read);
+     
+    if( !eth.link() ) return;
+    usb.printf(" - Link active\r\n");
+    
+    m_game->alphanumdisplay_device().display('*');
+      
+    if( registered == 0 ) {
+        conn.setup();
+                      
+        //Get the MAC address of this device
+        eth.address((char *)mac.octet);     
+                                           
+        // Send to Game Server until receive a response 
+        // and wait for a response                                                                                                                                 
+        do {
+        
+             register_device(mac, &game_server);
+             wait(0.1);
+                           
+             Net::poll();
+                             
+          } while ( memcmp("i",&(srvr_resp[0]),1) );
+        
+        printf("srvr_resp = %s\r\n", srvr_resp); 
+        
+        // If the response is an acknowledgement
+        // get the IDs from the response and
+        // set the game device and tag IDs
+        if( get_ack_err(srvr_resp,HVZ_REG) ) {
+            set_ids(srvr_resp); 
+           //printf( "deviceID = %s\r\n", m_game->id() );
+           //printf( "tagID = %s\r\n", m_game->tagid() );
+        
+            // Clear the response string 
+            memset(srvr_resp,0,sizeof(srvr_resp));
+        
+            // Upon registration there will be no tags or 
+            // updates for this device, so just return here   
+            return;
+        }          
+        
+        // Set as already registered
+        registered = 1;
+        
+        // Clear the response string 
+        memset(srvr_resp,0,sizeof(srvr_resp));
+    }
+    
+    // Submit any tags to the server
+    // and wait for a response 
+    do {    
+        send_tag(&game_server, m_game->get_victims());
+        wait(0.1);
+                       
+        Net::poll();                        
+    //} while ( memcmp("i",&(srvr_resp[0]),1) );
+    } while ( 'i' != srvr_resp[0] );
+    
+    printf("srvr_resp = %s\r\n", srvr_resp);
+    
+    // On successfully reporting tags to Server
+    // clear the tagged list
+    if( get_ack_err(srvr_resp,HVZ_TAG) ) 
+        m_game->clear_victims(); 
+    
+    // Clear the response string 
+    memset(srvr_resp,0,sizeof(srvr_resp));
+    
+    // Next request updates to the server 
+    do {
+        // If the deviceID is set at update request
+        send_pull(&game_server);    
+        
+        wait(0.1);
+                       
+        Net::poll(); 
+    //} while ( !srvr_resp[0] );
+    } while ( 'i' != srvr_resp[0] );
+    
+    printf("srvr_resp = %s\r\n", srvr_resp);  
+    
+    // If pull request ack, update settings of the game
+    if( get_ack_err(srvr_resp,HVZ_PULL) )  
+        update_settings(srvr_resp);
+    
+    // Clear the response string 
+    memset(srvr_resp,0,sizeof(srvr_resp));
+    
+    // Display a completion mark
+    m_game->alphanumdisplay_device().display('^');
+    wait(1);
+    m_game->alphanumdisplay_device().display(m_game->status()==STATUS_HUMAN?'H':'Z');
+}
+
+void UDP::read(UDPSocketEvent e)
+{
+    //Host host(IpAddr(128, 61, 89, 71), HVZ_PORT, HVZ_HOSTNAME);
+    Host host(IpAddr(192, 168, 1, 1), HVZ_PORT, HVZ_HOSTNAME);
+    
+    if ( e == UDPSOCKET_READABLE )
+    {
+        while( int len = recvfrom(srvr_resp, sizeof(srvr_resp), &host) )
+        {
+            if( len <= 0 )
+              break;   
+        }
+    }
+}
+
+void UDP::set_ids(char *response)
+{
+    char buf[9];
+        
+    /* First set the deviceID */
+    memcpy(buf,response+13,8);
+    buf[8] = '\0';
+    m_game->id(buf);
+  
+    /* Next set the tagID */
+    memcpy(buf,response+22,8);
+    buf[8] = '\0';
+    m_game->life(buf);  
+    
+    m_game->save(); 
+}
+
+void UDP::update_settings(char *response)
+{
+    char *tok;
+    // Clear the lives so we can add them all back
+    m_game->clear_lives();
+    
+    // Start tokenizing the response
+    tok = strtok(response,"\001"); 
+    
+    typedef enum { RNONE,RDEV,RLIVES,RSTUN,RINC } readtype;
+    readtype type = RNONE; 
+    
+    while (tok != NULL)
+    {
+        //printf ("%s\r\n",tok);
+        tok = strtok (NULL, "\001");
+        
+        if( strcmp(tok,"deviceid") == 0 ) {
+            type = RDEV;
+            continue;
+        }
+        
+        else if( strcmp(tok,"tagids") == 0 ) {
+            type = RLIVES;
+            continue;
+        }
+        
+        else if( strcmp(tok,"stuntime") == 0 ) {
+            type = RSTUN;
+            continue;
+        }
+        
+        else if( strcmp(tok,"incubate") == 0 ) {
+            type = RINC;
+            continue;
+        }
+        
+        switch (type)
+        {
+        case RDEV:
+            m_game->id(tok);
+            break;
+        case RLIVES:
+            m_game->life(tok);
+            continue; // possibility of more than one
+        case RSTUN:
+            m_game->stun_duration((unsigned)atoi(tok));
+            break;
+        case RINC:
+            m_game->incubation_time((unsigned)atoi(tok));
+            break;
+        }
+        
+        // go back to no parsing
+        type = RNONE;
+    }  
+    
+    m_game->save(); 
+}
+
+void UDP::send_pull(Host *host)
+{
+    char data[64];
+//     char buff[12];
+//     
+//     memset(data,0,sizeof(data));
+ 
+//     if( type == PULL_DEV )
+//         sprintf(buff, "%c%c%c%c%c%c%c%c", pullId[0], pullId[1], pullId[2],
+//             pullId[3], pullId[4], pullId[5], pullId[6], pullId[7]); 
+ 
+//     else
+//         sprintf(buff, "%02X%02X%02X%02X%02X%02X", pullId[0], pullId[1], pullId[2],
+//             pullId[3], pullId[4], pullId[5]); 
+ 
+//     strcat(data, "iHvZ\001pull\001");
+//     strcat(data, buff);
+//     strcat(data, "\001end");
+
+    sprintf(data, "iHvZ\001pull\001%s\001end", m_game->id().c_str());
+    
+    sendto(data, strlen(data), host);
+}
+
+  inline void UDP::send_tag(Host *host, vector<string> taggedIDs)
+  {
+     int totalsize = 32;
+          
+     for (int i = 0; i < taggedIDs.size(); i++)
+     {
+        totalsize += taggedIDs[i].size();
+     }
+     
+     char tmp[totalsize];
+     
+     // Clear out buffers
+     memset(tmp, 0, sizeof(tmp));
+     
+     // Append tagIDs
+     for (int i = 0; i < taggedIDs.size(); i++)
+     {
+        strcat(tmp, taggedIDs[i].c_str());
+        strcat(tmp, "\001");
+     }
+     string tagids = tmp;
+          
+     sprintf(tmp, "iHvZ\001tag\001%s\001%send", m_game->id().c_str(), tagids.c_str());
+
+     sendto(tmp, strlen(tmp), host);
+  }
+  
+void UDP::resetOnEvent() //Disable callback
+{
+  m_pCb = NULL;
+  m_pCbItem = NULL;
+  m_pCbMeth = NULL;
+}
+
+void UDP::onNetUdpSocketEvent(NetUdpSocketEvent e)
+{
+  if(m_pCbItem && m_pCbMeth)
+    (m_pCbItem->*m_pCbMeth)((UDPSocketEvent) e);
+  else if(m_pCb)
+    m_pCb((UDPSocketEvent) e);
+}
+
+UDPErr UDP::checkInst()
+{
+  if(!m_pNetUdpSocket)
+  {
+    m_pNetUdpSocket = Net::udpSocket();
+    if(!m_pNetUdpSocket)
+    {
+      return UDPSOCKET_IF; //Interface did not return a socket (usually because a default interface does not exist)
+    }
+    m_pNetUdpSocket->setOnEvent(this, &UDP::onNetUdpSocketEvent);
+  }
+  return UDPSOCKET_OK;
+} 
\ No newline at end of file