Project

General

Profile

Statistics
| Revision:

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

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