msl2007.cpp

00001 
00002 /***************************************************************************
00003  *  msl2007.cpp - Fawkes mid-size refbox repeater
00004  *
00005  *  Created: Wed Apr 09 10:38:16 2008
00006  *  Copyright  2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <tools/refboxrep/msl2007.h>
00024 #include <netcomm/socket/stream.h>
00025 
00026 #include <cstring>
00027 #include <cstdio>
00028 #include <unistd.h>
00029 
00030 using namespace fawkes;
00031 
00032 // REFBOX_CODES //////////////////////////
00033 static const char REFBOX_TEST                = '*';
00034 static const char REFBOX_CANCEL              = 'x';
00035 static const char REFBOX_START               = 's';
00036 static const char REFBOX_HALT                = 'H';
00037 static const char REFBOX_STOP                = 'S';
00038 static const char REFBOX_ENDHALF             = 'H';
00039 static const char REFBOX_DROPPED_BALL        = 'N';
00040 
00041 static const char REFBOX_FIRST_HALF          = '1';
00042 static const char REFBOX_SECOND_HALF         = '2';
00043 static const char REFBOX_HALF_TIME           = 'h';
00044 static const char REFBOX_END_GAME            = 'e';
00045 
00046 static const char REFBOX_GOAL_CYAN           = 'A';
00047 static const char REFBOX_GOAL_MAGENTA        = 'a';
00048 
00049 static const char REFBOX_KICK_OFF_CYAN       = 'K';
00050 static const char REFBOX_KICK_OFF_MAGENTA    = 'k';
00051 static const char REFBOX_FREE_KICK_CYAN      = 'F';
00052 static const char REFBOX_FREE_KICK_MAGENTA   = 'f';
00053 static const char REFBOX_GOAL_KICK_CYAN      = 'G';
00054 static const char REFBOX_GOAL_KICK_MAGENTA   = 'g';
00055 static const char REFBOX_THROW_IN_CYAN       = 'T';
00056 static const char REFBOX_THROW_IN_MAGENTA    = 't';
00057 static const char REFBOX_CORNER_KICK_CYAN    = 'C';
00058 static const char REFBOX_CORNER_KICK_MAGENTA = 'c';
00059 static const char REFBOX_PENALTY_CYAN        = 'P';
00060 static const char REFBOX_PENALTY_MAGENTA     = 'p';
00061 
00062 static const char *  REFBOX_WELCOME          = "Welcome..";
00063 //static const char *  REFBOX_RECONNECT        = "Reconnect";
00064 
00065 /** @class MidsizeRefBoxRepeater <tools/refboxrep/msl2007.h>
00066  * Mid-size league refbox repeater.
00067  * This class will communicate with the mid-size league refbox and derive matching
00068  * game states from the communiation stream and send this via the world info.
00069  * @author Tim Niemueller
00070  */
00071 
00072 /** Constructor.
00073  * @param rss refbox state sender
00074  * @param refbox_host refbox host
00075  * @param refbox_port refbox port
00076  */
00077 MidsizeRefBoxRepeater::MidsizeRefBoxRepeater(RefBoxStateSender &rss,
00078                                              const char *refbox_host,
00079                                              unsigned short int refbox_port)
00080   : __rss(rss)
00081 {
00082   __quit = false;
00083   __s = NULL;
00084   __score_cyan = __score_magenta = 0;
00085 
00086   __refbox_host = strdup(refbox_host);
00087   __refbox_port = refbox_port;
00088 
00089   reconnect();
00090 }
00091 
00092 
00093 /** Destructor. */
00094 MidsizeRefBoxRepeater::~MidsizeRefBoxRepeater()
00095 {
00096   free(__refbox_host);
00097   __s->close();
00098   delete __s;
00099 }
00100 
00101 
00102 /** Reconnect to refbox. */
00103 void
00104 MidsizeRefBoxRepeater::reconnect()
00105 {
00106   if ( __s ) {
00107     __s->close();
00108     delete __s;
00109   }
00110   printf("Trying to connect to refbox at %s:%u\n", __refbox_host, __refbox_port);
00111   do {
00112     try {
00113       __s = new StreamSocket();
00114       __s->connect(__refbox_host, __refbox_port);
00115 
00116       char welcomebuf[strlen(REFBOX_WELCOME) + 1];
00117       welcomebuf[strlen(REFBOX_WELCOME)] = 0;
00118       __s->read(welcomebuf, strlen(REFBOX_WELCOME));
00119       printf("Connected, received welcome string: %s\n", welcomebuf);
00120     } catch (Exception &e) {
00121       delete __s;
00122       __s = NULL;
00123       printf(".");
00124       fflush(stdout);
00125       usleep(500000);
00126     }
00127   } while ( ! __s );
00128 }
00129 
00130 
00131 /** Process received string. */
00132 void
00133 MidsizeRefBoxRepeater::process_string(char *buf, size_t len)
00134 {
00135   for (size_t b = 0; b < len; ++b) {
00136     switch (buf[b]) {
00137     case REFBOX_TEST:
00138       // immediately reply
00139       printf("Received connection test, replying\n");
00140       __s->write("*", 1);
00141       break;
00142 
00143     case REFBOX_CANCEL:
00144       printf("RefBox cancelled last command\n");
00145       break;
00146 
00147     case REFBOX_START:
00148       __rss.set_gamestate(GS_PLAY, TEAM_BOTH);
00149       break;
00150 
00151     case REFBOX_HALT:
00152     case REFBOX_STOP:
00153       __rss.set_gamestate(GS_FROZEN, TEAM_BOTH);
00154       break;
00155 
00156     case REFBOX_DROPPED_BALL:
00157       __rss.set_gamestate(GS_DROP_BALL, TEAM_BOTH);
00158       break;
00159 
00160     case REFBOX_GOAL_CYAN:
00161       __rss.set_score(++__score_cyan, __score_magenta);
00162       __rss.set_gamestate(GS_FROZEN, TEAM_BOTH);
00163       break;
00164 
00165     case REFBOX_GOAL_MAGENTA:
00166       __rss.set_score(__score_cyan, ++__score_magenta);
00167       __rss.set_gamestate(GS_FROZEN, TEAM_BOTH);
00168       break;
00169 
00170     case REFBOX_KICK_OFF_CYAN:
00171       __rss.set_gamestate(GS_KICK_OFF, TEAM_CYAN);
00172       break;
00173 
00174     case REFBOX_KICK_OFF_MAGENTA:
00175       __rss.set_gamestate(GS_KICK_OFF, TEAM_MAGENTA);
00176       break;
00177 
00178     case REFBOX_PENALTY_CYAN:
00179       __rss.set_gamestate(GS_PENALTY, TEAM_CYAN);
00180       break;
00181 
00182     case REFBOX_PENALTY_MAGENTA:
00183       __rss.set_gamestate(GS_PENALTY, TEAM_MAGENTA);
00184       break;
00185       
00186     case REFBOX_CORNER_KICK_CYAN:
00187       __rss.set_gamestate(GS_CORNER_KICK, TEAM_CYAN);
00188       break;
00189 
00190     case REFBOX_CORNER_KICK_MAGENTA:
00191       __rss.set_gamestate(GS_CORNER_KICK, TEAM_MAGENTA);
00192       break;
00193 
00194     case REFBOX_THROW_IN_CYAN:
00195       __rss.set_gamestate(GS_THROW_IN, TEAM_CYAN);
00196       break;
00197 
00198     case REFBOX_THROW_IN_MAGENTA:
00199       __rss.set_gamestate(GS_THROW_IN, TEAM_MAGENTA);
00200       break;
00201 
00202     case REFBOX_FREE_KICK_CYAN:
00203        __rss.set_gamestate(GS_FREE_KICK, TEAM_CYAN);
00204       break;
00205 
00206     case REFBOX_FREE_KICK_MAGENTA:
00207       __rss.set_gamestate(GS_FREE_KICK, TEAM_MAGENTA);
00208       break;
00209 
00210     case REFBOX_GOAL_KICK_CYAN:
00211        __rss.set_gamestate(GS_GOAL_KICK, TEAM_CYAN);
00212       break;
00213 
00214     case REFBOX_GOAL_KICK_MAGENTA:
00215       __rss.set_gamestate(GS_GOAL_KICK, TEAM_MAGENTA);
00216       break;
00217 
00218     case REFBOX_FIRST_HALF:
00219       __rss.set_half(HALF_FIRST);
00220       break;
00221 
00222     case REFBOX_SECOND_HALF:
00223       __rss.set_half(HALF_SECOND);
00224       break;
00225 
00226     case REFBOX_HALF_TIME:
00227       __rss.set_gamestate(GS_HALF_TIME, TEAM_BOTH);
00228       break;
00229 
00230     default:
00231       printf("Received unknown command: '%c'\n", buf[b]);
00232       break;
00233     }    
00234   }
00235 
00236   __rss.send();
00237 }
00238 
00239 
00240 /** Run.
00241  * Reads messages from the network, processes them and calls the refbox state sender.
00242  */
00243 void
00244 MidsizeRefBoxRepeater::run()
00245 {
00246   char tmpbuf[100];
00247   while ( ! __quit ) {
00248     size_t bytes_read = __s->read(tmpbuf, sizeof(tmpbuf), /* read all */ false);
00249     if ( bytes_read == 0 ) {
00250       // seems that the remote has died, reconnect
00251       printf("Connection died, reconnecting\n");
00252       reconnect();
00253     } else {
00254       process_string(tmpbuf, bytes_read);
00255     }
00256   }
00257 }

Generated on Tue Feb 22 13:32:32 2011 for Fawkes API by  doxygen 1.4.7