Fawkes API  Fawkes Development Version
msl2007.cpp
1 
2 /***************************************************************************
3  * msl2007.cpp - Fawkes mid-size refbox repeater
4  *
5  * Created: Wed Apr 09 10:38:16 2008
6  * Copyright 2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include <tools/refboxrep/msl2007.h>
24 #include <netcomm/socket/stream.h>
25 
26 #include <cstring>
27 #include <cstdio>
28 #include <unistd.h>
29 
30 using namespace fawkes;
31 
32 // REFBOX_CODES //////////////////////////
33 static const char REFBOX_TEST = '*';
34 static const char REFBOX_CANCEL = 'x';
35 static const char REFBOX_START = 's';
36 static const char REFBOX_HALT = 'H';
37 static const char REFBOX_STOP = 'S';
38 static const char REFBOX_ENDHALF = 'H';
39 static const char REFBOX_DROPPED_BALL = 'N';
40 
41 static const char REFBOX_FIRST_HALF = '1';
42 static const char REFBOX_SECOND_HALF = '2';
43 static const char REFBOX_HALF_TIME = 'h';
44 static const char REFBOX_END_GAME = 'e';
45 
46 static const char REFBOX_GOAL_CYAN = 'A';
47 static const char REFBOX_GOAL_MAGENTA = 'a';
48 
49 static const char REFBOX_KICK_OFF_CYAN = 'K';
50 static const char REFBOX_KICK_OFF_MAGENTA = 'k';
51 static const char REFBOX_FREE_KICK_CYAN = 'F';
52 static const char REFBOX_FREE_KICK_MAGENTA = 'f';
53 static const char REFBOX_GOAL_KICK_CYAN = 'G';
54 static const char REFBOX_GOAL_KICK_MAGENTA = 'g';
55 static const char REFBOX_THROW_IN_CYAN = 'T';
56 static const char REFBOX_THROW_IN_MAGENTA = 't';
57 static const char REFBOX_CORNER_KICK_CYAN = 'C';
58 static const char REFBOX_CORNER_KICK_MAGENTA = 'c';
59 static const char REFBOX_PENALTY_CYAN = 'P';
60 static const char REFBOX_PENALTY_MAGENTA = 'p';
61 
62 static const char * REFBOX_WELCOME = "Welcome..";
63 //static const char * REFBOX_RECONNECT = "Reconnect";
64 
65 /** @class MidsizeRefBoxRepeater <tools/refboxrep/msl2007.h>
66  * Mid-size league refbox repeater.
67  * This class will communicate with the mid-size league refbox and derive matching
68  * game states from the communiation stream and send this via the world info.
69  * @author Tim Niemueller
70  */
71 
72 /** Constructor.
73  * @param rss refbox state sender
74  * @param refbox_host refbox host
75  * @param refbox_port refbox port
76  */
78  const char *refbox_host,
79  unsigned short int refbox_port)
80  : __rss(rss)
81 {
82  __quit = false;
83  __s = NULL;
84  __score_cyan = __score_magenta = 0;
85 
86  __refbox_host = strdup(refbox_host);
87  __refbox_port = refbox_port;
88 
89  reconnect();
90 }
91 
92 
93 /** Destructor. */
95 {
96  free(__refbox_host);
97  __s->close();
98  delete __s;
99 }
100 
101 
102 /** Reconnect to refbox. */
103 void
104 MidsizeRefBoxRepeater::reconnect()
105 {
106  if ( __s ) {
107  __s->close();
108  delete __s;
109  }
110  printf("Trying to connect to refbox at %s:%u\n", __refbox_host, __refbox_port);
111  do {
112  try {
113  __s = new StreamSocket();
114  __s->connect(__refbox_host, __refbox_port);
115 
116  char welcomebuf[strlen(REFBOX_WELCOME) + 1];
117  welcomebuf[strlen(REFBOX_WELCOME)] = 0;
118  __s->read(welcomebuf, strlen(REFBOX_WELCOME));
119  printf("Connected, received welcome string: %s\n", welcomebuf);
120  } catch (Exception &e) {
121  delete __s;
122  __s = NULL;
123  printf(".");
124  fflush(stdout);
125  usleep(500000);
126  }
127  } while ( ! __s );
128 }
129 
130 
131 /** Process received string. */
132 void
133 MidsizeRefBoxRepeater::process_string(char *buf, size_t len)
134 {
135  for (size_t b = 0; b < len; ++b) {
136  switch (buf[b]) {
137  case REFBOX_TEST:
138  // immediately reply
139  printf("Received connection test, replying\n");
140  __s->write("*", 1);
141  break;
142 
143  case REFBOX_CANCEL:
144  printf("RefBox cancelled last command\n");
145  break;
146 
147  case REFBOX_START:
149  break;
150 
151  case REFBOX_HALT:
152  case REFBOX_STOP:
154  break;
155 
156  case REFBOX_DROPPED_BALL:
158  break;
159 
160  case REFBOX_GOAL_CYAN:
161  __rss.set_score(++__score_cyan, __score_magenta);
163  break;
164 
165  case REFBOX_GOAL_MAGENTA:
166  __rss.set_score(__score_cyan, ++__score_magenta);
168  break;
169 
170  case REFBOX_KICK_OFF_CYAN:
172  break;
173 
174  case REFBOX_KICK_OFF_MAGENTA:
176  break;
177 
178  case REFBOX_PENALTY_CYAN:
180  break;
181 
182  case REFBOX_PENALTY_MAGENTA:
184  break;
185 
186  case REFBOX_CORNER_KICK_CYAN:
188  break;
189 
190  case REFBOX_CORNER_KICK_MAGENTA:
192  break;
193 
194  case REFBOX_THROW_IN_CYAN:
196  break;
197 
198  case REFBOX_THROW_IN_MAGENTA:
200  break;
201 
202  case REFBOX_FREE_KICK_CYAN:
204  break;
205 
206  case REFBOX_FREE_KICK_MAGENTA:
208  break;
209 
210  case REFBOX_GOAL_KICK_CYAN:
212  break;
213 
214  case REFBOX_GOAL_KICK_MAGENTA:
216  break;
217 
218  case REFBOX_FIRST_HALF:
219  __rss.set_half(HALF_FIRST);
220  break;
221 
222  case REFBOX_SECOND_HALF:
223  __rss.set_half(HALF_SECOND);
224  break;
225 
226  case REFBOX_HALF_TIME:
228  break;
229 
230  default:
231  printf("Received unknown command: '%c'\n", buf[b]);
232  break;
233  }
234  }
235 
236  __rss.send();
237 }
238 
239 
240 /** Run.
241  * Reads messages from the network, processes them and calls the refbox state sender.
242  */
243 void
245 {
246  char tmpbuf[100];
247  while ( ! __quit ) {
248  size_t bytes_read = __s->read(tmpbuf, sizeof(tmpbuf), /* read all */ false);
249  if ( bytes_read == 0 ) {
250  // seems that the remote has died, reconnect
251  printf("Connection died, reconnecting\n");
252  reconnect();
253  } else {
254  process_string(tmpbuf, bytes_read);
255  }
256  }
257 }
virtual void connect(const char *hostname, const unsigned short int port)
Connect socket.
Definition: socket.cpp:270
Kick off.
Definition: enums.h:33
virtual void close()
Close socket.
Definition: socket.cpp:219
~MidsizeRefBoxRepeater()
Destructor.
Definition: msl2007.cpp:94
Goal kick.
Definition: enums.h:39
RefBox repeater state sender.
virtual void write(const void *buf, size_t count)
Write to the socket.
Definition: socket.cpp:481
Referee drops ball, both teams can wrestle for the ball.
Definition: enums.h:34
Throw in.
Definition: enums.h:37
Fawkes library namespace.
virtual void set_gamestate(int game_state, fawkes::worldinfo_gamestate_team_t state_team)
Set current game state.
TCP stream socket over IP.
Definition: stream.h:31
Magenta team.
Definition: enums.h:57
Play, normal play.
Definition: enums.h:32
First half.
Definition: enums.h:71
Base class for exceptions in Fawkes.
Definition: exception.h:36
Both teams.
Definition: enums.h:58
Frozen, nothing moves.
Definition: enums.h:31
virtual size_t read(void *buf, size_t count, bool read_all=true)
Read from socket.
Definition: socket.cpp:525
Second half.
Definition: enums.h:72
Penalty kick.
Definition: enums.h:35
Half time.
Definition: enums.h:40
Cyan team.
Definition: enums.h:56
virtual void send()
Send worldinfo.
virtual void set_half(fawkes::worldinfo_gamestate_half_t half)
Set current half of the game time.
MidsizeRefBoxRepeater(RefBoxStateSender &rss, const char *refbox_host, unsigned short int refbox_port)
Constructor.
Definition: msl2007.cpp:77
Free kick.
Definition: enums.h:38
virtual void set_score(unsigned int score_cyan, unsigned int score_magenta)
Set score.
Corner kick.
Definition: enums.h:36