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
udp.cpp
00001 #include "mbed.h" 00002 #include "iHvZ.hpp" 00003 #include "if/net/netudpsocket.h" 00004 00005 #include "udp.hpp" 00006 00007 UDP::UDP(iHvZ *game, PinName eth_in) 00008 : m_game(game), m_eth(eth_in), m_eth_int(eth_in), 00009 m_pNetUdpSocket(NULL), m_pCbItem(NULL), m_pCbMeth(NULL), m_pCb(NULL), 00010 //conn(IpAddr(192,168,1,2),IpAddr(255,255,255,0), IpAddr(), IpAddr()) 00011 { 00012 // Set the game ID 00013 char mac[8]; 00014 char macaddr[12+1]; 00015 eth.address(mac); 00016 sprintf(macaddr, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 00017 m_game->id(macaddr); 00018 00019 //m_eth_int.rise(this, &UDP::check); 00020 m_eth_chk.attach(this, &UDP::check, 5); 00021 registered = 0; 00022 } 00023 00024 UDP::~UDP() 00025 { 00026 close(); 00027 } 00028 00029 void UDP::check() 00030 { 00031 // debounce (if attached to a button) 00032 wait(.1); 00033 //if (m_eth) 00034 //{ 00035 // usb.printf("- Connection found, starting sync\r\n"); 00036 ethlink(); 00037 //} 00038 m_eth_chk.attach(this, &UDP::check, 10); 00039 } 00040 00041 int UDP::sendto(const char* buf, int len, Host* pHost) 00042 { 00043 UDPErr udpSocketErr = checkInst(); 00044 if(udpSocketErr) 00045 return udpSocketErr; 00046 return m_pNetUdpSocket->sendto(buf, len, pHost); 00047 } 00048 00049 int UDP::recvfrom(char* buf, int len, Host* pHost) 00050 { 00051 UDPErr udpSocketErr = checkInst(); 00052 if(udpSocketErr) 00053 return udpSocketErr; 00054 return m_pNetUdpSocket->recvfrom(buf, len, pHost); 00055 } 00056 00057 UDPErr UDP::close() 00058 { 00059 if(!m_pNetUdpSocket) 00060 return UDPSOCKET_SETUP; 00061 m_pNetUdpSocket->resetOnEvent(); 00062 UDPErr udpSocketErr = (UDPErr) m_pNetUdpSocket->close(); //Close (can already be closed) 00063 Net::releaseUdpSocket(m_pNetUdpSocket); //And release it so it can be freed when properly removed 00064 m_pNetUdpSocket = NULL; 00065 return udpSocketErr; 00066 } 00067 00068 void UDP::ethlink() 00069 { 00070 Serial usb(USBTX,USBRX); 00071 usb.printf("Checking for Ethernet connection...\r\n"); 00072 00073 Host game_server(IpAddr(128, 61, 89, 71), HVZ_PORT, HVZ_HOSTNAME); 00074 //Host game_server(IpAddr(192, 168, 1, 1), HVZ_PORT, HVZ_HOSTNAME); 00075 00076 /* Function to call upon Server response */ 00077 setOnEvent(this, &UDP::read); 00078 00079 if( !eth.link() ) return; 00080 usb.printf(" - Link active\r\n"); 00081 00082 m_game->alphanumdisplay_device().display('*'); 00083 00084 if( registered == 0 ) { 00085 conn.setup(); 00086 00087 //Get the MAC address of this device 00088 eth.address((char *)mac.octet); 00089 00090 // Send to Game Server until receive a response 00091 // and wait for a response 00092 do { 00093 00094 register_device(mac, &game_server); 00095 wait(0.1); 00096 00097 Net::poll(); 00098 00099 } while ( memcmp("i",&(srvr_resp[0]),1) ); 00100 00101 printf("srvr_resp = %s\r\n", srvr_resp); 00102 00103 // If the response is an acknowledgement 00104 // get the IDs from the response and 00105 // set the game device and tag IDs 00106 if( get_ack_err(srvr_resp,HVZ_REG) ) { 00107 set_ids(srvr_resp); 00108 //printf( "deviceID = %s\r\n", m_game->id() ); 00109 //printf( "tagID = %s\r\n", m_game->tagid() ); 00110 00111 // Clear the response string 00112 memset(srvr_resp,0,sizeof(srvr_resp)); 00113 00114 // Upon registration there will be no tags or 00115 // updates for this device, so just return here 00116 return; 00117 } 00118 00119 // Set as already registered 00120 registered = 1; 00121 00122 // Clear the response string 00123 memset(srvr_resp,0,sizeof(srvr_resp)); 00124 } 00125 00126 // Submit any tags to the server 00127 // and wait for a response 00128 do { 00129 send_tag(&game_server, m_game->get_victims()); 00130 wait(0.1); 00131 00132 Net::poll(); 00133 //} while ( memcmp("i",&(srvr_resp[0]),1) ); 00134 } while ( 'i' != srvr_resp[0] ); 00135 00136 printf("srvr_resp = %s\r\n", srvr_resp); 00137 00138 // On successfully reporting tags to Server 00139 // clear the tagged list 00140 if( get_ack_err(srvr_resp,HVZ_TAG) ) 00141 m_game->clear_victims(); 00142 00143 // Clear the response string 00144 memset(srvr_resp,0,sizeof(srvr_resp)); 00145 00146 // Next request updates to the server 00147 do { 00148 // If the deviceID is set at update request 00149 send_pull(&game_server); 00150 00151 wait(0.1); 00152 00153 Net::poll(); 00154 //} while ( !srvr_resp[0] ); 00155 } while ( 'i' != srvr_resp[0] ); 00156 00157 printf("srvr_resp = %s\r\n", srvr_resp); 00158 00159 // If pull request ack, update settings of the game 00160 if( get_ack_err(srvr_resp,HVZ_PULL) ) 00161 update_settings(srvr_resp); 00162 00163 // Clear the response string 00164 memset(srvr_resp,0,sizeof(srvr_resp)); 00165 00166 // Display a completion mark 00167 m_game->alphanumdisplay_device().display('^'); 00168 wait(1); 00169 m_game->alphanumdisplay_device().display(m_game->status()==STATUS_HUMAN?'H':'Z'); 00170 } 00171 00172 void UDP::read(UDPSocketEvent e) 00173 { 00174 Host host(IpAddr(128, 61, 89, 71), HVZ_PORT, HVZ_HOSTNAME); 00175 //Host host(IpAddr(192, 168, 1, 1), HVZ_PORT, HVZ_HOSTNAME); 00176 00177 if ( e == UDPSOCKET_READABLE ) 00178 { 00179 while( int len = recvfrom(srvr_resp, sizeof(srvr_resp), &host) ) 00180 { 00181 if( len <= 0 ) 00182 break; 00183 } 00184 } 00185 } 00186 00187 void UDP::set_ids(char *response) 00188 { 00189 char buf[9]; 00190 00191 /* First set the deviceID */ 00192 memcpy(buf,response+13,8); 00193 buf[8] = '\0'; 00194 m_game->id(buf); 00195 00196 /* Next set the tagID */ 00197 memcpy(buf,response+22,8); 00198 buf[8] = '\0'; 00199 m_game->life(buf); 00200 00201 m_game->save(); 00202 } 00203 00204 void UDP::update_settings(char *response) 00205 { 00206 char *tok; 00207 // Clear the lives so we can add them all back 00208 m_game->clear_lives(); 00209 00210 // Start tokenizing the response 00211 tok = strtok(response,"\001"); 00212 00213 typedef enum { RNONE,RDEV,RLIVES,RSTUN,RINC } readtype; 00214 readtype type = RNONE; 00215 00216 while (tok != NULL) 00217 { 00218 //printf ("%s\r\n",tok); 00219 tok = strtok (NULL, "\001"); 00220 00221 if( strcmp(tok,"deviceid") == 0 ) { 00222 type = RDEV; 00223 continue; 00224 } 00225 00226 else if( strcmp(tok,"tagids") == 0 ) { 00227 type = RLIVES; 00228 continue; 00229 } 00230 00231 else if( strcmp(tok,"stuntime") == 0 ) { 00232 type = RSTUN; 00233 continue; 00234 } 00235 00236 else if( strcmp(tok,"incubate") == 0 ) { 00237 type = RINC; 00238 continue; 00239 } 00240 00241 switch (type) 00242 { 00243 case RDEV: 00244 m_game->id(tok); 00245 break; 00246 case RLIVES: 00247 m_game->life(tok); 00248 continue; // possibility of more than one 00249 case RSTUN: 00250 m_game->stun_duration((unsigned)atoi(tok)); 00251 break; 00252 case RINC: 00253 m_game->incubation_time((unsigned)atoi(tok)); 00254 break; 00255 } 00256 00257 // go back to no parsing 00258 type = RNONE; 00259 } 00260 00261 m_game->save(); 00262 } 00263 00264 void UDP::send_pull(Host *host) 00265 { 00266 char data[64]; 00267 // char buff[12]; 00268 // 00269 // memset(data,0,sizeof(data)); 00270 00271 // if( type == PULL_DEV ) 00272 // sprintf(buff, "%c%c%c%c%c%c%c%c", pullId[0], pullId[1], pullId[2], 00273 // pullId[3], pullId[4], pullId[5], pullId[6], pullId[7]); 00274 00275 // else 00276 // sprintf(buff, "%02X%02X%02X%02X%02X%02X", pullId[0], pullId[1], pullId[2], 00277 // pullId[3], pullId[4], pullId[5]); 00278 00279 // strcat(data, "iHvZ\001pull\001"); 00280 // strcat(data, buff); 00281 // strcat(data, "\001end"); 00282 00283 sprintf(data, "iHvZ\001pull\001%s\001end", m_game->id().c_str()); 00284 00285 sendto(data, strlen(data), host); 00286 } 00287 00288 inline void UDP::send_tag(Host *host, vector<string> taggedIDs) 00289 { 00290 int totalsize = 32; 00291 00292 for (int i = 0; i < taggedIDs.size(); i++) 00293 { 00294 totalsize += taggedIDs[i].size(); 00295 } 00296 00297 char tmp[totalsize]; 00298 00299 // Clear out buffers 00300 memset(tmp, 0, sizeof(tmp)); 00301 00302 // Append tagIDs 00303 for (int i = 0; i < taggedIDs.size(); i++) 00304 { 00305 strcat(tmp, taggedIDs[i].c_str()); 00306 strcat(tmp, "\001"); 00307 } 00308 string tagids = tmp; 00309 00310 sprintf(tmp, "iHvZ\001tag\001%s\001%send", m_game->id().c_str(), tagids.c_str()); 00311 00312 sendto(tmp, strlen(tmp), host); 00313 } 00314 00315 void UDP::resetOnEvent() //Disable callback 00316 { 00317 m_pCb = NULL; 00318 m_pCbItem = NULL; 00319 m_pCbMeth = NULL; 00320 } 00321 00322 void UDP::onNetUdpSocketEvent(NetUdpSocketEvent e) 00323 { 00324 if(m_pCbItem && m_pCbMeth) 00325 (m_pCbItem->*m_pCbMeth)((UDPSocketEvent) e); 00326 else if(m_pCb) 00327 m_pCb((UDPSocketEvent) e); 00328 } 00329 00330 UDPErr UDP::checkInst() 00331 { 00332 if(!m_pNetUdpSocket) 00333 { 00334 m_pNetUdpSocket = Net::udpSocket(); 00335 if(!m_pNetUdpSocket) 00336 { 00337 return UDPSOCKET_IF; //Interface did not return a socket (usually because a default interface does not exist) 00338 } 00339 m_pNetUdpSocket->setOnEvent(this, &UDP::onNetUdpSocketEvent); 00340 } 00341 return UDPSOCKET_OK; 00342 }
Generated on Wed Jul 13 2022 16:17:46 by
1.7.2