Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / ColonetServer / Command.cpp @ 175

History | View | Annotate | Download (7.92 KB)

1 128 jknichel
/**
2
 * @file Command.cpp
3
 *
4
 * @author Jason Knichel
5
 * @date 10/9/07
6 144 jknichel
 *
7
 * @todo make it so command doesn't rely on connection pool.  have methods
8
 *       that may return a response return it by getting a response array passed in to them
9
 *       that they fill in and then colonet server takes the contents of that response array
10
 *       and sends it to the appropriate client
11 128 jknichel
 */
12
13 156 emarinel
#include <ctype.h>
14
#include <stdio.h>
15 128 jknichel
#include <stdlib.h>
16
#include <string.h>
17 156 emarinel
18 161 emarinel
#include <colonet_wireless.h>
19
20 128 jknichel
#include "includes/Command.h"
21
#include "includes/ConnectionPool.h"
22
23 139 jknichel
Command::Command(ConnectionPool * connection_pool_temp) {
24
  connection_pool = connection_pool_temp;
25 128 jknichel
}
26
27
Command::~Command() {
28
}
29
30 139 jknichel
int Command::parse_command(char* command, int pool_index) {
31 128 jknichel
  char tokens[MAX_TOKENS][MAX_TOKEN_SIZE];
32
  int number_tokens = 0;
33
  char* end_pointer = NULL;
34
  int command_id;
35
36 139 jknichel
  if (!connection_pool) {
37
    return -1;
38
  }
39
40 128 jknichel
  if (!command) {
41
    return -1;
42
  }
43
44
  if (pool_index < 0) {
45
    return -1;
46
  }
47
48
  if ((number_tokens = tokenize_command(command, tokens)) < 0) {
49
    return -1;
50
  }
51
52
  //the 10 in the function call indicates number is base 10
53
  command_id = strtol(tokens[0], &end_pointer, 10);
54
55
  if (!end_pointer || *end_pointer != '\0') {
56
    printf("There was an error converting first token into a number.\n");
57
    return -1;
58
  }
59
60
  if (command_id == SEND_TO_ROBOT) {
61 156 emarinel
    if (parse_send_to_robot(number_tokens, tokens, pool_index)) {
62 129 jknichel
      return -1;
63 128 jknichel
    }
64
  } else if (command_id == REQUEST_FROM_SERVER) {
65 139 jknichel
    if (parse_request_from_server(number_tokens, tokens, pool_index)) {
66 128 jknichel
      return -1;
67
    }
68
  }
69
70
  return 0;
71
}
72
73
/**
74
 * @brief Breaks a command up into tokens
75
 *
76
 * @param command The command to tokenize
77
 * @param tokens A two dimensional character array to store the tokens in
78
 *
79
 * @return 0 on success, negative error code on failure
80
 */
81
int Command::tokenize_command(char* command, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE]) {
82
  char* next_token = command;
83
  char* end_token = NULL;
84
  int number_tokens = 0;
85
86
  if (!command) {
87
    return -1;
88
  }
89
90
  while ((end_token = strstr(next_token, " "))) {
91
    *end_token = '\0';
92
93
    if (strlen(next_token) > MAX_TOKEN_SIZE-1) {
94
      return -1;
95
    }
96
97
    strcpy(tokens[number_tokens], next_token);
98
99
    number_tokens++;
100
    next_token = end_token + 1;
101
102
    while (isspace(*next_token) && *next_token != '\0') {
103
      next_token++;
104
    }
105
  }
106
107
  if (end_token == NULL && *next_token != '\0') {
108
    if (strlen(next_token) > MAX_TOKEN_SIZE-1) {
109
      return -1;
110
    }
111
112
    strcpy(tokens[number_tokens], next_token);
113
114
    number_tokens++;
115
  }
116
117
  return number_tokens;
118
}
119
120
121 161 emarinel
/**
122 128 jknichel
 * @brief checks a list of tokens to see if it's valid
123
 *
124
 * @param tokens The tokens to check
125
 * @param number_tokens The number of tokens contained in the tokens parameter
126
 *
127
 * @return 0 if tokens is valid
128
 */
129
int Command::check_tokens(unsigned char* tokens, int number_tokens) {
130
  if (number_tokens > 3 + PACKET_DATA_LEN) {
131
    /* Too many tokens */
132
    return -1;
133
  }
134
135
  if (number_tokens < 3) {
136
    /* Not enough tokens */
137
    return -1;
138
  }
139 161 emarinel
140 128 jknichel
  if (tokens[1] != COLONET_REQUEST && tokens[1] != COLONET_COMMAND) {
141
    /* Invalid message type */
142
    return -1;
143
  }
144
145
  return 0;
146
}
147 129 jknichel
148 175 emarinel
int Command::parse_send_to_robot(int number_tokens,
149
                                 char tokens[MAX_TOKENS][MAX_TOKEN_SIZE],
150
                                 int pool_index) {
151 129 jknichel
  int i;
152
  unsigned char int_tokens[MAX_TOKENS];
153
  int number_int_tokens = number_tokens;
154
  unsigned char arguments[PACKET_DATA_LEN];
155
156
  memset(arguments, 1, PACKET_DATA_LEN);
157
158 161 emarinel
  // Convert tokens to ints
159 129 jknichel
  for (i = ROBOT_COMMAND_OFFSET; i < number_int_tokens; i++) {
160
    int_tokens[i-ROBOT_COMMAND_OFFSET] = atoi(tokens[i]);
161
  }
162
163 161 emarinel
  // Fill arguments buffer with arguments
164 156 emarinel
  for (i = ROBOT_COMMAND_LEN; i < number_int_tokens-ROBOT_COMMAND_OFFSET; i++) {
165 129 jknichel
    arguments[i-ROBOT_COMMAND_LEN] = int_tokens[i];
166
  }
167
168 161 emarinel
  // Check the tokens
169 129 jknichel
  if (check_tokens(int_tokens, number_int_tokens) < 0) {
170 151 gtress
    fprintf(stderr, "%s: Error - Invalid robot command/request.\n", __FUNCTION__);
171 129 jknichel
    return -1;
172
  }
173
174 161 emarinel
  // Send packet to robot
175 175 emarinel
  fprintf(stderr, "Calling colonet_wl_send(%d, %d, %d, arguments)\n",
176
          int_tokens[0], int_tokens[1], int_tokens[2]);
177
  colonet_wl_send((short)pool_index, int_tokens[0],
178
                  (ColonetMessageType)int_tokens[1], int_tokens[2], arguments);
179 156 emarinel
180 129 jknichel
  return 0;
181
}
182 130 jknichel
183 139 jknichel
int Command::parse_request_from_server(int number_tokens, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE], int pool_index) {
184 130 jknichel
  char* end_pointer = NULL;
185
186 139 jknichel
  if (!connection_pool) {
187
    return -1;
188
  }
189
190 156 emarinel
  if (number_tokens < 2) {
191 130 jknichel
    return -1;
192 156 emarinel
  }
193 130 jknichel
194
  end_pointer=NULL;
195
  int second_token = strtol(tokens[1], &end_pointer, 10);
196
197
  if (!end_pointer || *end_pointer != '\0') {
198
    printf("There was an error converting second token into a number.\n");
199
    return -1;
200
  }
201 161 emarinel
202 130 jknichel
  if (second_token == REQUEST_BOM_MATRIX) {
203 139 jknichel
    if (parse_request_bom_matrix(pool_index)) {
204 131 jknichel
      return -1;
205 130 jknichel
    }
206 131 jknichel
  } else if (second_token == REQUEST_XBEE_IDS) {
207 139 jknichel
    if (parse_request_xbee_ids(pool_index)) {
208 131 jknichel
      return -1;
209
    }
210
  } else {
211
    char * my_current_message = "Hi, how are you?\n";
212
    printf("Sending %s\n", my_current_message);
213
    connection_pool->write_to_client(pool_index, my_current_message, strlen(my_current_message));
214
  }
215 130 jknichel
216 131 jknichel
  return 0;
217
}
218 130 jknichel
219 139 jknichel
int Command::parse_request_bom_matrix(int pool_index) {
220 135 jknichel
  char response_bom_matrix_buffer[MAX_RESPONSE_LEN];
221 131 jknichel
  char temp_bom_matrix_buffer[MAX_RESPONSE_LEN];
222 161 emarinel
223 139 jknichel
  if (!connection_pool) {
224
    return -1;
225
  }
226
227 131 jknichel
  //TODO: change after we start keeping track of bom matrix
228 146 jknichel
  /*
229 131 jknichel
  int number_robots = rand()%10;
230
  int bom_matrix[number_robots][number_robots];
231
  for (int ii = 0; ii < number_robots; ii++) {
232
    for (int j = 0; j < number_robots; j++) {
233
      //do this to generate some -1 values which mean they can't see each other
234
      int matrix_value = rand()%(number_robots+1)-1;
235
      bom_matrix[ii][j] = matrix_value;
236 130 jknichel
    }
237 131 jknichel
  }
238 146 jknichel
  */
239
  int number_robots = 3;
240
  int bom_matrix[number_robots][number_robots];
241
  for (int ii = 0; ii < number_robots; ii++) {
242
    for (int j = 0; j < number_robots; j++) {
243
      bom_matrix[ii][j] = ((ii*3+j)%17)-1;
244
    }
245
  }
246 130 jknichel
247 161 emarinel
248 131 jknichel
  printf("number of robots is %d\n", number_robots);
249 130 jknichel
250 131 jknichel
  //TODO: make this better
251
  //TODO: make sure I don't need to do MAX_RESPONSE_LENGTH-1
252 135 jknichel
  snprintf(response_bom_matrix_buffer,MAX_RESPONSE_LEN, "%d %d %d", RESPONSE_TO_CLIENT_REQUEST, REQUEST_BOM_MATRIX, number_robots);
253 131 jknichel
  for (int ii = 0; ii < number_robots; ii++) {
254
    for (int j = 0; j < number_robots; j++) {
255
      //TODO: don't use strcpy
256 135 jknichel
      strcpy(temp_bom_matrix_buffer, response_bom_matrix_buffer);
257 130 jknichel
      //TODO: put length checking in here so array doesn't go out of bounds
258
      //TODO: maybe use strncat?
259 131 jknichel
      strcat(temp_bom_matrix_buffer," %d");
260 135 jknichel
      snprintf(response_bom_matrix_buffer, MAX_RESPONSE_LEN, temp_bom_matrix_buffer, bom_matrix[ii][j]);
261 130 jknichel
    }
262
  }
263 135 jknichel
  strcat(response_bom_matrix_buffer,"\n");
264
  connection_pool->write_to_client(pool_index, response_bom_matrix_buffer, strlen(response_bom_matrix_buffer));
265
  printf("Sending %s", response_bom_matrix_buffer);
266 130 jknichel
267
  return 0;
268
}
269 131 jknichel
270 139 jknichel
int Command::parse_request_xbee_ids(int pool_index) {
271 131 jknichel
  //TODO: make this better
272 146 jknichel
  //TODO: change when we actually know this data
273
  //int number_robots = rand() % 10;
274
  int number_robots = 3;
275 131 jknichel
276
  char xbee_id_buffer[MAX_RESPONSE_LEN];
277
  char temp_xbee_id_buffer[MAX_RESPONSE_LEN];
278 161 emarinel
279 139 jknichel
  if (!connection_pool) {
280
    return -1;
281
  }
282
283 131 jknichel
  snprintf(xbee_id_buffer, MAX_RESPONSE_LEN, "%d %d %d", RESPONSE_TO_CLIENT_REQUEST, REQUEST_XBEE_IDS, number_robots);
284 161 emarinel
285 131 jknichel
  printf("number of robots is %d\n", number_robots);
286
287
  for (int ii = 0; ii < number_robots; ii++) {
288
    strcpy(temp_xbee_id_buffer, xbee_id_buffer);
289
    //TODO: put length checking in here so array doesn't go out of bounds
290
    //TODO: maybe use strncat?
291
    strcat(temp_xbee_id_buffer, " %d");
292
    snprintf(xbee_id_buffer, MAX_RESPONSE_LEN, temp_xbee_id_buffer, ii);
293
  }
294
  strcat(xbee_id_buffer, "\n");
295
  connection_pool->write_to_client(pool_index, xbee_id_buffer, strlen(xbee_id_buffer));
296
  printf("Sending %s", xbee_id_buffer);
297
298
  return 0;
299
}