00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "msl2010.h"
00025 #include <netcomm/socket/datagram_multicast.h>
00026 #include <utils/logging/logger.h>
00027
00028 #include <string>
00029 #include <sstream>
00030 #include <cstdlib>
00031 #include <cstring>
00032
00033 #include <libxml++/libxml++.h>
00034
00035
00036
00037
00038
00039 #ifdef __FreeBSD__
00040 # undef POLL_IN
00041 # undef POLL_ERR
00042 #endif
00043
00044 using namespace fawkes;
00045 using namespace xmlpp;
00046
00047
00048
00049
00050 static const std::string REFBOX_EVENT = "RefboxEvent";
00051 static const std::string REFBOX_GAMEINFO = "GameInfo";
00052 static const std::string REFBOX_EVENT_REFEREE = "Referee";
00053 static const std::string REFBOX_EVENT_TEAMSETUP = "TeamSetup";
00054
00055 static const std::string REFBOX_CANCEL = "Cancel";
00056
00057 static const std::string REFBOX_GAMESTART = "GameStart";
00058 static const std::string REFBOX_GAMESTOP = "GameStop";
00059
00060 static const std::string REFBOX_STAGE_CHANGED = "StageChanged";
00061 static const std::string REFBOX_STAGETYPE_PREGAME = "preGame";
00062 static const std::string REFBOX_STAGETYPE_FIRSTHALF = "firstHalf";
00063 static const std::string REFBOX_STAGETYPE_HALFTIME = "halfTime";
00064 static const std::string REFBOX_STAGETYPE_SECONDHALF = "secondHalf";
00065 static const std::string REFBOX_STAGETYPE_SHOOTOUT = "shootOut";
00066 static const std::string REFBOX_STAGETYPE_ENDGAME = "endGame";
00067
00068 static const std::string REFBOX_GOAL_AWARDED = "GoalAwarded";
00069 static const std::string REFBOX_GOAL_REMOVED = "GoalRemoved";
00070
00071 static const std::string REFBOX_CARD_AWARDED = "CardAwarded";
00072 static const std::string REFBOX_CARD_REMOVED = "CardRemoved";
00073
00074 static const std::string REFBOX_SUBSTITUTION = "Substitution";
00075 static const std::string REFBOX_PLAYER_OUT = "PlayerOut";
00076 static const std::string REFBOX_PLAYER_IN = "PlayerIn";
00077
00078 static const std::string REFBOX_DROPPEDBALL = "DroppedBall";
00079 static const std::string REFBOX_KICKOFF = "KickOff";
00080 static const std::string REFBOX_FREEKICK = "FreeKick";
00081 static const std::string REFBOX_GOALKICK = "GoalKick";
00082 static const std::string REFBOX_THROWIN = "ThrowIn";
00083 static const std::string REFBOX_CORNER = "Corner";
00084 static const std::string REFBOX_PENALTY = "Penalty";
00085
00086 static const std::string REFBOX_TEAMCOLOR_CYAN = "Cyan";
00087 static const std::string REFBOX_TEAMCOLOR_MAGENTA = "Magenta";
00088
00089 static const std::string REFBOX_GOALCOLOR_YELLOW = "yellow";
00090 static const std::string REFBOX_GOALCOLOR_BLUE = "blue";
00091
00092 static const std::string REFBOX_CARDCOLOR_YELLOW = "yellow";
00093 static const std::string REFBOX_CARDCOLOR_RED = "red";
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 Msl2010RefBoxProcessor::Msl2010RefBoxProcessor(Logger *logger,
00109 const char *refbox_host,
00110 unsigned short int refbox_port)
00111 : __name("Msl2010RefBoxProc")
00112 {
00113 __logger = logger;
00114 __quit = false;
00115 __s = NULL;
00116 __score_cyan = __score_magenta = 0;
00117 __connection_died = false;
00118
00119 __refbox_host = strdup(refbox_host);
00120 __refbox_port = refbox_port;
00121
00122 do {
00123 reconnect();
00124 } while (! __s);
00125 }
00126
00127
00128
00129 Msl2010RefBoxProcessor::~Msl2010RefBoxProcessor()
00130 {
00131 free(__refbox_host);
00132 __s->close();
00133 delete __s;
00134 }
00135
00136
00137
00138 void
00139 Msl2010RefBoxProcessor::reconnect()
00140 {
00141 if ( __s ) {
00142 __s->close();
00143 delete __s;
00144 }
00145 __logger->log_info(__name, "Trying to connect to refbox at %s:%u",
00146 __refbox_host, __refbox_port);
00147 try {
00148 __logger->log_info(__name, "Creating MulticastDatagramSocket");
00149 __s = new MulticastDatagramSocket(__refbox_host, __refbox_port, 2.3);
00150
00151 __s->set_loop(true);
00152
00153 __s->bind();
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 __connection_died = false;
00164
00165 } catch (Exception &e) {
00166 delete __s;
00167 __s = NULL;
00168
00169
00170
00171 }
00172
00173 __logger->log_info(__name, "Init done");
00174 }
00175
00176
00177
00178 void
00179 Msl2010RefBoxProcessor::process_string(char *buf, size_t len)
00180 {
00181 __logger->log_info(__name, "Received\n *****\n %s \n *****", buf);
00182
00183 std::istringstream iss( std::string(buf), std::istringstream::in);
00184
00185 dom = new DomParser();
00186
00187 dom->set_substitute_entities();
00188 dom->parse_stream(iss);
00189 root = dom->get_document()->get_root_node();
00190
00191
00192
00193 const Element * el = dynamic_cast<const Element *>(root);
00194
00195 if ( el ) {
00196
00197
00198 __logger->log_info(__name, "root-element name is '%s'", el->get_name().data() );
00199
00200 const Node::NodeList nl = el->get_children();
00201
00202 if( nl.size() == 0 ) {
00203 __logger->log_info(__name, "root has NO children!");
00204 }
00205 else {
00206
00207
00208 for (Node::NodeList::const_iterator it = nl.begin(); it != nl.end(); ++it) {
00209 const Node* node = *it;
00210 __logger->log_info(__name, "1st level child name is '%s'", node->get_name().data() );
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 const Node::NodeList cnl = node->get_children();
00223
00224 if( cnl.size() == 0 ) {
00225 __logger->log_info(__name, "child has NO children!");
00226 }
00227 else {
00228
00229
00230 for (Node::NodeList::const_iterator cit = cnl.begin(); cit != cnl.end(); ++cit) {
00231 const Node* cnode = *cit;
00232 const Element* cel = dynamic_cast<const Element *>(cnode);
00233 std::string cnodename(cnode->get_name().data());
00234
00235 __logger->log_info(__name, "2nd level child name is '%s'", cnode->get_name().data() );
00236
00237 const Attribute* cattr;
00238 std::string cteamcolor;
00239
00240
00241 std::string cstagetype;
00242
00243 if( cnodename == REFBOX_KICKOFF || cnodename == REFBOX_FREEKICK ||
00244 cnodename == REFBOX_GOALKICK || cnodename == REFBOX_THROWIN ||
00245 cnodename == REFBOX_CORNER || cnodename == REFBOX_PENALTY ||
00246 cnodename == REFBOX_GOAL_AWARDED || cnodename == REFBOX_GOAL_REMOVED ||
00247 cnodename == REFBOX_CARD_AWARDED || cnodename == REFBOX_CARD_REMOVED ||
00248 cnodename == REFBOX_PLAYER_OUT || cnodename == REFBOX_PLAYER_IN ||
00249 cnodename == REFBOX_SUBSTITUTION )
00250 {
00251 cattr = cel->get_attribute("team");
00252 cteamcolor = std::string( cattr->get_value().data() );
00253 }
00254
00255 if( cnodename == REFBOX_CANCEL ) {
00256
00257 __logger->log_info(__name, "RefBox cancelled last command");
00258 }
00259 else if( cnodename == REFBOX_GAMESTOP ) {
00260 _rsh->set_gamestate(GS_FROZEN, TEAM_BOTH);
00261 }
00262 else if( cnodename == REFBOX_GAMESTART ) {
00263 _rsh->set_gamestate(GS_PLAY, TEAM_BOTH);
00264 }
00265 else if( cnodename == REFBOX_DROPPEDBALL ) {
00266 _rsh->set_gamestate(GS_DROP_BALL, TEAM_BOTH);
00267 }
00268 else if( cnodename == REFBOX_GOAL_AWARDED ) {
00269
00270 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00271 _rsh->set_score(++__score_cyan, __score_magenta);
00272 }
00273 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00274 _rsh->set_score(__score_cyan, ++__score_magenta);
00275 }
00276 _rsh->set_gamestate(GS_FROZEN, TEAM_BOTH);
00277 }
00278 else if( cnodename == REFBOX_KICKOFF ) {
00279 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00280 _rsh->set_gamestate(GS_KICK_OFF, TEAM_CYAN);
00281 }
00282 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00283 _rsh->set_gamestate(GS_KICK_OFF, TEAM_MAGENTA);
00284 }
00285 }
00286 else if( cnodename == REFBOX_PENALTY ) {
00287 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00288 _rsh->set_gamestate(GS_PENALTY, TEAM_CYAN);
00289 }
00290 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00291 _rsh->set_gamestate(GS_PENALTY, TEAM_MAGENTA);
00292 }
00293 }
00294 else if( cnodename == REFBOX_CORNER ) {
00295 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00296 _rsh->set_gamestate(GS_CORNER_KICK, TEAM_CYAN);
00297 }
00298 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00299 _rsh->set_gamestate(GS_CORNER_KICK, TEAM_MAGENTA);
00300 }
00301 }
00302 else if( cnodename == REFBOX_THROWIN ) {
00303 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00304 _rsh->set_gamestate(GS_THROW_IN, TEAM_CYAN);
00305 }
00306 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00307 _rsh->set_gamestate(GS_THROW_IN, TEAM_MAGENTA);
00308 }
00309 }
00310 else if( cnodename == REFBOX_FREEKICK ) {
00311 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00312 _rsh->set_gamestate(GS_FREE_KICK, TEAM_CYAN);
00313 }
00314 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00315 _rsh->set_gamestate(GS_FREE_KICK, TEAM_MAGENTA);
00316 }
00317 }
00318 else if( cnodename == REFBOX_GOALKICK ) {
00319 if( cteamcolor == REFBOX_TEAMCOLOR_CYAN ) {
00320 _rsh->set_gamestate(GS_GOAL_KICK, TEAM_CYAN);
00321 }
00322 else if ( cteamcolor == REFBOX_TEAMCOLOR_MAGENTA ) {
00323 _rsh->set_gamestate(GS_GOAL_KICK, TEAM_MAGENTA);
00324 }
00325 }
00326 else if( cnodename == REFBOX_STAGE_CHANGED ) {
00327 cattr = cel->get_attribute("newStage");
00328 cstagetype = std::string( cattr->get_value().data() );
00329 if( cstagetype == REFBOX_STAGETYPE_PREGAME ) {
00330
00331 } else if( cstagetype == REFBOX_STAGETYPE_FIRSTHALF ) {
00332 _rsh->set_half(HALF_FIRST);
00333 } else if( cstagetype == REFBOX_STAGETYPE_HALFTIME ) {
00334 _rsh->set_gamestate(GS_HALF_TIME, TEAM_BOTH);
00335 } else if( cstagetype == REFBOX_STAGETYPE_SECONDHALF ) {
00336 _rsh->set_half(HALF_SECOND);
00337 } else if( cstagetype == REFBOX_STAGETYPE_SHOOTOUT ) {
00338
00339 } else if( cstagetype == REFBOX_STAGETYPE_ENDGAME ) {
00340
00341 }
00342
00343 }
00344
00345 }
00346 }
00347 }
00348 }
00349 }
00350 else {
00351
00352 __logger->log_info(__name, "root is NOT a valid element");
00353 }
00354
00355 }
00356
00357 void
00358 Msl2010RefBoxProcessor::refbox_process()
00359 {
00360 short pollrv = __s->poll(0, Socket::POLL_IN);
00361 do {
00362
00363 if (pollrv == Socket::POLL_ERR) {
00364 __logger->log_warn(__name, "Polling socket failed");
00365 } else if (pollrv & Socket::POLL_IN) {
00366 char tmpbuf[1024];
00367 size_t bytes_read = __s->read(tmpbuf, sizeof(tmpbuf), false);
00368 __logger->log_debug(__name, "Read %zu bytes", bytes_read);
00369 if ( bytes_read == 0 ) {
00370
00371 __connection_died = true;
00372 } else {
00373 tmpbuf[bytes_read] = '\0';
00374 process_string(tmpbuf, bytes_read);
00375 }
00376 }
00377 pollrv = __s->poll(0, Socket::POLL_IN);
00378 } while (pollrv & Socket::POLL_IN);
00379 }
00380
00381 bool
00382 Msl2010RefBoxProcessor::check_connection()
00383 {
00384 if (__connection_died) {
00385 reconnect();
00386 }
00387 return ! __connection_died;
00388 }