Dependencies:   XBeeLib mbed HvZAlphaNumLib HvZServerLib

Committer:
etherealflaim
Date:
Sun Dec 12 19:38:47 2010 +0000
Revision:
1:d1b5cd8b2c18
Parent:
0:9cdba0589ba2

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
etherealflaim 0:9cdba0589ba2 1 #include "mbed.h"
etherealflaim 0:9cdba0589ba2 2 #include "iHvZ.hpp"
etherealflaim 0:9cdba0589ba2 3 #include "XBee.hpp"
etherealflaim 0:9cdba0589ba2 4
etherealflaim 0:9cdba0589ba2 5 #include <vector>
etherealflaim 0:9cdba0589ba2 6 #include <string>
etherealflaim 0:9cdba0589ba2 7
etherealflaim 0:9cdba0589ba2 8 Tag::Tag(iHvZ *game, PinName tagbtn)
etherealflaim 0:9cdba0589ba2 9 : m_game(game), m_tag(tagbtn), m_tag_int(tagbtn)
etherealflaim 0:9cdba0589ba2 10 {
etherealflaim 0:9cdba0589ba2 11 m_tag_int.rise(this, &Tag::rise);
etherealflaim 0:9cdba0589ba2 12 m_game->xbee_device().attach(this, &Tag::rx);
etherealflaim 0:9cdba0589ba2 13 }
etherealflaim 0:9cdba0589ba2 14
etherealflaim 0:9cdba0589ba2 15 void Tag::rise()
etherealflaim 0:9cdba0589ba2 16 {
etherealflaim 0:9cdba0589ba2 17 Serial usb(USBTX,USBRX);
etherealflaim 0:9cdba0589ba2 18
etherealflaim 0:9cdba0589ba2 19 // debounce
etherealflaim 0:9cdba0589ba2 20 wait(.1);
etherealflaim 0:9cdba0589ba2 21 if (!m_tag) return;
etherealflaim 0:9cdba0589ba2 22
etherealflaim 0:9cdba0589ba2 23 event(TAG_EVENT_BUTTON);
etherealflaim 0:9cdba0589ba2 24 }
etherealflaim 0:9cdba0589ba2 25
etherealflaim 0:9cdba0589ba2 26 void Tag::rx()
etherealflaim 0:9cdba0589ba2 27 {
etherealflaim 0:9cdba0589ba2 28 event(TAG_EVENT_RX);
etherealflaim 0:9cdba0589ba2 29 }
etherealflaim 0:9cdba0589ba2 30
etherealflaim 0:9cdba0589ba2 31 void Tag::timeout()
etherealflaim 0:9cdba0589ba2 32 {
etherealflaim 0:9cdba0589ba2 33 event(TAG_EVENT_TIMEOUT);
etherealflaim 0:9cdba0589ba2 34 }
etherealflaim 0:9cdba0589ba2 35
etherealflaim 0:9cdba0589ba2 36 void Tag::event(TagEvent ev)
etherealflaim 0:9cdba0589ba2 37 {
etherealflaim 0:9cdba0589ba2 38 Serial usb(USBTX,USBRX);
etherealflaim 0:9cdba0589ba2 39 static TagState state = TAG_STATE_WAITING;
etherealflaim 0:9cdba0589ba2 40 static string peer = "";
etherealflaim 0:9cdba0589ba2 41 static string peer_tagid = "";
etherealflaim 0:9cdba0589ba2 42 static string type = ""; // = (m_game.status()==STATUS_HUMAN)?"STUN":"TAG";
etherealflaim 0:9cdba0589ba2 43 static string ack = "";
etherealflaim 0:9cdba0589ba2 44
etherealflaim 0:9cdba0589ba2 45 XBeePacket pkt;
etherealflaim 0:9cdba0589ba2 46
etherealflaim 0:9cdba0589ba2 47 if (ev == TAG_EVENT_TIMEOUT)
etherealflaim 0:9cdba0589ba2 48 {
etherealflaim 0:9cdba0589ba2 49 // Display the timeout character (TODO)
etherealflaim 0:9cdba0589ba2 50 usb.printf("!! TIMEOUT !!\r\n");
etherealflaim 0:9cdba0589ba2 51 m_game->alphanumdisplay_device().display('*');
etherealflaim 0:9cdba0589ba2 52 //wait(1);
etherealflaim 0:9cdba0589ba2 53 state = TAG_STATE_WAITING;
etherealflaim 0:9cdba0589ba2 54 }
etherealflaim 0:9cdba0589ba2 55
etherealflaim 0:9cdba0589ba2 56 if (ev == TAG_EVENT_RX)
etherealflaim 0:9cdba0589ba2 57 {
etherealflaim 0:9cdba0589ba2 58 // Get the packet that triggered this event
etherealflaim 0:9cdba0589ba2 59 pkt = m_game->xbee_device().read();
etherealflaim 0:9cdba0589ba2 60 }
etherealflaim 0:9cdba0589ba2 61
etherealflaim 0:9cdba0589ba2 62 do switch (state)
etherealflaim 0:9cdba0589ba2 63 {
etherealflaim 0:9cdba0589ba2 64 case TAG_STATE_WAITING:
etherealflaim 0:9cdba0589ba2 65 // Zero everything
etherealflaim 0:9cdba0589ba2 66 peer = "";
etherealflaim 0:9cdba0589ba2 67 peer_tagid = "";
etherealflaim 0:9cdba0589ba2 68 type = "";
etherealflaim 0:9cdba0589ba2 69 ack = "";
etherealflaim 0:9cdba0589ba2 70 // Display H/Z
etherealflaim 0:9cdba0589ba2 71 // m_game->alphanumdisplay_device().display((m_game->status()==STATUS_HUMAN)?'H':'Z');
etherealflaim 0:9cdba0589ba2 72 // Check transitions
etherealflaim 0:9cdba0589ba2 73 if (ev == TAG_EVENT_BUTTON) state = TAG_STATE_TX_SEND;
etherealflaim 0:9cdba0589ba2 74 else if (ev == TAG_EVENT_RX) state = TAG_STATE_RX_RECV;
etherealflaim 0:9cdba0589ba2 75 else return;
etherealflaim 0:9cdba0589ba2 76 continue;
etherealflaim 0:9cdba0589ba2 77 // Sending states
etherealflaim 0:9cdba0589ba2 78 case TAG_STATE_TX_SEND:
etherealflaim 0:9cdba0589ba2 79 // First, check if this zombie is stunned (if so, they can't do anything)
etherealflaim 0:9cdba0589ba2 80 if (m_game->stun_tracker().stunned()) return;
etherealflaim 0:9cdba0589ba2 81 // Get whether we are tagging or stunning
etherealflaim 0:9cdba0589ba2 82 type = (m_game->status()==STATUS_HUMAN)?"STUN":"TAG";
etherealflaim 0:9cdba0589ba2 83 // Generate a random acknowledge character for display
etherealflaim 0:9cdba0589ba2 84 do { ack = string(1, 'A'+rand()%26); } while (ack == "H" || ack == "Z");
etherealflaim 0:9cdba0589ba2 85 // Send the SYN message
etherealflaim 0:9cdba0589ba2 86 m_game->xbee_device().broadcast(type + "\001SYN\001" + ack);
etherealflaim 0:9cdba0589ba2 87 // Display the acknowledge character (TODO)
etherealflaim 0:9cdba0589ba2 88 usb.printf("CHECK: %s (send)\r\n", ack.c_str());
etherealflaim 0:9cdba0589ba2 89 m_game->alphanumdisplay_device().display(ack[0]);
etherealflaim 0:9cdba0589ba2 90 // Attach a timeout that will revert to waiting
etherealflaim 0:9cdba0589ba2 91 m_timeout.attach(this, &Tag::timeout, TAG_TIMEOUT_TIME);
etherealflaim 0:9cdba0589ba2 92 state = TAG_STATE_TX_WAITACK;
etherealflaim 0:9cdba0589ba2 93 continue;
etherealflaim 0:9cdba0589ba2 94 case TAG_STATE_TX_WAITACK:
etherealflaim 0:9cdba0589ba2 95 if (ev == TAG_EVENT_RX)
etherealflaim 0:9cdba0589ba2 96 {
etherealflaim 0:9cdba0589ba2 97 // Make sure it is an ack packet with the right ack character
etherealflaim 0:9cdba0589ba2 98 vector<string> pieces = pkt.split_data();
etherealflaim 0:9cdba0589ba2 99 if (pieces.size() != 5) return;
etherealflaim 0:9cdba0589ba2 100 if (pieces[0] != type) return;
etherealflaim 0:9cdba0589ba2 101 if (pieces[1] != "ACK") return;
etherealflaim 0:9cdba0589ba2 102 if (pieces[2] != ack) return;
etherealflaim 0:9cdba0589ba2 103 ack = pieces[3];
etherealflaim 0:9cdba0589ba2 104 // Store the peer ID and tag ID
etherealflaim 0:9cdba0589ba2 105 peer = pkt.source();
etherealflaim 0:9cdba0589ba2 106 peer_tagid = pieces[4];
etherealflaim 0:9cdba0589ba2 107 // Display the new character for verification (TODO)
etherealflaim 0:9cdba0589ba2 108 usb.printf("CHECK: %s (send ack)\r\n", ack.c_str());
etherealflaim 0:9cdba0589ba2 109 m_game->alphanumdisplay_device().display(ack[0]);
etherealflaim 0:9cdba0589ba2 110 // Attach a timeout
etherealflaim 0:9cdba0589ba2 111 m_timeout.attach(this, &Tag::timeout, TAG_TIMEOUT_TIME);
etherealflaim 0:9cdba0589ba2 112 state = TAG_STATE_TX_WAITBTN;
etherealflaim 0:9cdba0589ba2 113 }
etherealflaim 0:9cdba0589ba2 114 return;
etherealflaim 0:9cdba0589ba2 115 case TAG_STATE_TX_WAITBTN:
etherealflaim 0:9cdba0589ba2 116 if (ev == TAG_EVENT_BUTTON)
etherealflaim 0:9cdba0589ba2 117 {
etherealflaim 0:9cdba0589ba2 118 state = TAG_STATE_TX_SENDCOMP;
etherealflaim 0:9cdba0589ba2 119 continue;
etherealflaim 0:9cdba0589ba2 120 }
etherealflaim 0:9cdba0589ba2 121 return;
etherealflaim 0:9cdba0589ba2 122 case TAG_STATE_TX_SENDCOMP:
etherealflaim 0:9cdba0589ba2 123 // Send the FIN message indicating that the transaction is complete
etherealflaim 0:9cdba0589ba2 124 m_game->xbee_device().send(peer, type+"\001FIN\001"+ack);
etherealflaim 0:9cdba0589ba2 125 // Display the completion character (TODO)
etherealflaim 0:9cdba0589ba2 126 usb.printf("COMPLETE: %s\r\n", type.c_str());
etherealflaim 0:9cdba0589ba2 127 m_game->alphanumdisplay_device().display('^');
etherealflaim 0:9cdba0589ba2 128 state = TAG_STATE_WAITING;
etherealflaim 0:9cdba0589ba2 129 m_timeout.detach();
etherealflaim 0:9cdba0589ba2 130
etherealflaim 0:9cdba0589ba2 131 // Register the successful tag or stun
etherealflaim 0:9cdba0589ba2 132 if (type == "TAG" && m_game->status() == STATUS_ZOMBIE)
etherealflaim 0:9cdba0589ba2 133 m_game->register_tag(peer_tagid);
etherealflaim 0:9cdba0589ba2 134 if (type == "STUN" && m_game->status() == STATUS_HUMAN)
etherealflaim 0:9cdba0589ba2 135 m_game->register_stun(peer_tagid);
etherealflaim 0:9cdba0589ba2 136 return;
etherealflaim 0:9cdba0589ba2 137 // Receiving states
etherealflaim 0:9cdba0589ba2 138 case TAG_STATE_RX_RECV:
etherealflaim 0:9cdba0589ba2 139 if (ev == TAG_EVENT_RX)
etherealflaim 0:9cdba0589ba2 140 {
etherealflaim 0:9cdba0589ba2 141 vector<string> pieces = pkt.split_data();
etherealflaim 0:9cdba0589ba2 142 if (pieces.size() != 3) return;
etherealflaim 0:9cdba0589ba2 143 type = pieces[0];
etherealflaim 0:9cdba0589ba2 144 if (pieces[1] != "SYN") return;
etherealflaim 0:9cdba0589ba2 145 ack = pieces[2];
etherealflaim 0:9cdba0589ba2 146 // Register the source
etherealflaim 0:9cdba0589ba2 147 peer = pkt.source();
etherealflaim 0:9cdba0589ba2 148 // Display the verification character (TODO)
etherealflaim 0:9cdba0589ba2 149 usb.printf("CHECK: %s (receive)\r\n", ack.c_str());
etherealflaim 0:9cdba0589ba2 150 m_game->alphanumdisplay_device().display(ack[0]);
etherealflaim 0:9cdba0589ba2 151 // Attach a timeout
etherealflaim 0:9cdba0589ba2 152 m_timeout.attach(this, &Tag::timeout, TAG_TIMEOUT_TIME);
etherealflaim 0:9cdba0589ba2 153 state = TAG_STATE_RX_WAITBTN;
etherealflaim 0:9cdba0589ba2 154 }
etherealflaim 0:9cdba0589ba2 155 return;
etherealflaim 0:9cdba0589ba2 156 case TAG_STATE_RX_WAITBTN:
etherealflaim 0:9cdba0589ba2 157 if (ev == TAG_EVENT_BUTTON)
etherealflaim 0:9cdba0589ba2 158 {
etherealflaim 0:9cdba0589ba2 159 state = TAG_STATE_RX_SENDACK;
etherealflaim 0:9cdba0589ba2 160 continue;
etherealflaim 0:9cdba0589ba2 161 }
etherealflaim 0:9cdba0589ba2 162 return;
etherealflaim 0:9cdba0589ba2 163 case TAG_STATE_RX_SENDACK:
etherealflaim 0:9cdba0589ba2 164 {
etherealflaim 0:9cdba0589ba2 165 // Generate a new acknowledgment character
etherealflaim 0:9cdba0589ba2 166 string oldack = ack;
etherealflaim 0:9cdba0589ba2 167 ack = string(1, '0'+rand()%9);
etherealflaim 0:9cdba0589ba2 168 // Send the ack packet
etherealflaim 0:9cdba0589ba2 169 m_game->xbee_device().send(peer, type+"\001ACK\001"+oldack+"\001"+ack+"\001"+m_game->life());
etherealflaim 0:9cdba0589ba2 170 // Display the verification character (TODO)
etherealflaim 0:9cdba0589ba2 171 usb.printf("CHECK: %s (receive ack)\r\n", ack.c_str());
etherealflaim 0:9cdba0589ba2 172 m_game->alphanumdisplay_device().display(ack[0]);
etherealflaim 0:9cdba0589ba2 173 // Attach a timeout
etherealflaim 0:9cdba0589ba2 174 m_timeout.attach(this, &Tag::timeout, TAG_TIMEOUT_TIME);
etherealflaim 0:9cdba0589ba2 175 state = TAG_STATE_RX_WAITCOMP;
etherealflaim 0:9cdba0589ba2 176 }
etherealflaim 0:9cdba0589ba2 177 return;
etherealflaim 0:9cdba0589ba2 178 case TAG_STATE_RX_WAITCOMP:
etherealflaim 0:9cdba0589ba2 179 if (ev == TAG_EVENT_RX)
etherealflaim 0:9cdba0589ba2 180 {
etherealflaim 0:9cdba0589ba2 181 vector<string> pieces = pkt.split_data();
etherealflaim 0:9cdba0589ba2 182 // Make sure the completion packet is well-formed
etherealflaim 0:9cdba0589ba2 183 if (pieces.size() != 3) return;
etherealflaim 0:9cdba0589ba2 184 if (pieces[0] != type) return;
etherealflaim 0:9cdba0589ba2 185 if (pieces[1] != "FIN") return;
etherealflaim 0:9cdba0589ba2 186 if (pieces[2] != ack) return;
etherealflaim 0:9cdba0589ba2 187 // Make sure the peer is the same
etherealflaim 0:9cdba0589ba2 188 if (peer != pkt.source()) return;
etherealflaim 0:9cdba0589ba2 189 // Display the completion character (TODO)
etherealflaim 0:9cdba0589ba2 190 usb.printf("COMPLETE: %s\r\n", type.c_str());
etherealflaim 0:9cdba0589ba2 191 m_game->alphanumdisplay_device().display('^');
etherealflaim 0:9cdba0589ba2 192 m_timeout.detach();
etherealflaim 0:9cdba0589ba2 193 state = TAG_STATE_WAITING;
etherealflaim 0:9cdba0589ba2 194
etherealflaim 0:9cdba0589ba2 195 // Stun or tag the player
etherealflaim 0:9cdba0589ba2 196 if (type == "TAG" && m_game->status() == STATUS_HUMAN)
etherealflaim 0:9cdba0589ba2 197 m_game->tagged();
etherealflaim 0:9cdba0589ba2 198 if (type == "STUN" && m_game->status() == STATUS_ZOMBIE)
etherealflaim 0:9cdba0589ba2 199 m_game->stunned();
etherealflaim 0:9cdba0589ba2 200 }
etherealflaim 0:9cdba0589ba2 201 return;
etherealflaim 0:9cdba0589ba2 202 } while (1);
etherealflaim 0:9cdba0589ba2 203 }