Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: XBeeLib mbed HvZAlphaNumLib HvZServerLib
Diff: lib/udp.cpp
- 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