Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (8.01 KB)

1
/**
2
 * @file Command.cpp
3
 *
4
 * @author Jason Knichel
5
 * @date 10/9/07
6
 *
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
 */
12

    
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <string.h>
16
#include <ctype.h>
17
#include "includes/Command.h"
18
#include "includes/ConnectionPool.h"
19

    
20
Command::Command(ConnectionPool * connection_pool_temp) {
21
  connection_pool = connection_pool_temp;
22
}
23

    
24
Command::~Command() {
25
}
26

    
27
int Command::parse_command(char* command, int pool_index) {
28
  char tokens[MAX_TOKENS][MAX_TOKEN_SIZE];
29
  int number_tokens = 0;
30
  char* end_pointer = NULL;
31
  int command_id;
32

    
33
  if (!connection_pool) {
34
    return -1;
35
  }
36

    
37
  if (!command) {
38
    return -1;
39
  }
40

    
41
  if (pool_index < 0) {
42
    return -1;
43
  }
44

    
45
  if ((number_tokens = tokenize_command(command, tokens)) < 0) {
46
    return -1;
47
  }
48

    
49
  //the 10 in the function call indicates number is base 10
50
  command_id = strtol(tokens[0], &end_pointer, 10);
51

    
52
  if (!end_pointer || *end_pointer != '\0') {
53
    printf("There was an error converting first token into a number.\n");
54
    return -1;
55
  }
56

    
57
  if (command_id == SEND_TO_ROBOT) {
58
    if (parse_send_to_robot(number_tokens, tokens)) {
59
      return -1;
60
    }
61
  } else if (command_id == REQUEST_FROM_SERVER) {
62
    if (parse_request_from_server(number_tokens, tokens, pool_index)) {
63
      return -1;
64
    }
65
  }
66

    
67
  return 0;
68
}
69

    
70
/**
71
 * @brief Breaks a command up into tokens
72
 *
73
 * @param command The command to tokenize
74
 * @param tokens A two dimensional character array to store the tokens in
75
 *
76
 * @return 0 on success, negative error code on failure
77
 */
78
int Command::tokenize_command(char* command, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE]) {
79
  char* next_token = command;
80
  char* end_token = NULL;
81
  int number_tokens = 0;
82

    
83
  if (!command) {
84
    return -1;
85
  }
86

    
87
  while ((end_token = strstr(next_token, " "))) {
88
    *end_token = '\0';
89

    
90
    if (strlen(next_token) > MAX_TOKEN_SIZE-1) {
91
      return -1;
92
    }
93

    
94
    strcpy(tokens[number_tokens], next_token);
95

    
96
    number_tokens++;
97
    next_token = end_token + 1;
98

    
99
    while (isspace(*next_token) && *next_token != '\0') {
100
      next_token++;
101
    }
102
  }
103

    
104
  if (end_token == NULL && *next_token != '\0') {
105
    if (strlen(next_token) > MAX_TOKEN_SIZE-1) {
106
      return -1;
107
    }
108

    
109
    strcpy(tokens[number_tokens], next_token);
110

    
111
    number_tokens++;
112
  }
113

    
114
  return number_tokens;
115
}
116

    
117

    
118
/** 
119
 * @brief checks a list of tokens to see if it's valid
120
 *
121
 * @param tokens The tokens to check
122
 * @param number_tokens The number of tokens contained in the tokens parameter
123
 *
124
 * @return 0 if tokens is valid
125
 */
126
int Command::check_tokens(unsigned char* tokens, int number_tokens) {
127

    
128
  printf("Checking tokens\n");
129

    
130
  if (number_tokens > 3 + PACKET_DATA_LEN) {
131
    /* Too many tokens */
132
    printf("Too many tokens\n");
133
    return -1;
134
  }
135

    
136
  if (number_tokens < 3) {
137
    /* Not enough tokens */
138
    printf("Too few tokens\n");
139
    return -1;
140
  }
141
  
142
  if (tokens[1] != COLONET_REQUEST && tokens[1] != COLONET_COMMAND) {
143
    /* Invalid message type */
144
    printf("Invalid message type. Was: %i Expected: %i %i\n", tokens[1], COLONET_REQUEST, COLONET_COMMAND);
145
    return -1;
146
  }
147

    
148
  return 0;
149
}
150

    
151

    
152

    
153

    
154

    
155

    
156
int Command::parse_send_to_robot(int number_tokens, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE]) {
157
  int i;
158
  unsigned char int_tokens[MAX_TOKENS];
159
  int number_int_tokens = number_tokens;
160
  unsigned char arguments[PACKET_DATA_LEN];
161

    
162
  memset(arguments, 1, PACKET_DATA_LEN);
163

    
164
  // Convert tokens to ints 
165
  for (i = ROBOT_COMMAND_OFFSET; i < number_int_tokens; i++) {
166
    int_tokens[i-ROBOT_COMMAND_OFFSET] = atoi(tokens[i]);
167
  }
168

    
169
  // Fill arguments buffer with arguments 
170
  for (i = ROBOT_COMMAND_LEN; i < number_int_tokens-ROBOT_COMMAND_OFFSET;
171
       i++) {
172
    arguments[i-ROBOT_COMMAND_LEN] = int_tokens[i];
173
  }
174

    
175
  // Check the tokens 
176
  if (check_tokens(int_tokens, number_int_tokens) < 0) {
177
    fprintf(stderr, "%s: Error - Invalid robot command/request.\n", __FUNCTION__);
178
    return -1;
179
  }
180

    
181
  /*  
182
  // Send packet to robot 
183
  fprintf(stderr, "Calling colonet_wl_send(%d, %d, %d, arguments)\n", 
184
  int_tokens[0], int_tokens[1], int_tokens[2]);
185
  colonet_wl_send(pool_index, int_tokens[0],
186
  (ColonetMessageType)int_tokens[1], int_tokens[2],
187
  arguments);
188
  */
189
  return 0;
190
}
191

    
192

    
193
int Command::parse_request_from_server(int number_tokens, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE], int pool_index) {
194
  char* end_pointer = NULL;
195

    
196
  if (!connection_pool) {
197
    return -1;
198
  }
199

    
200
  if (number_tokens < 2)
201
    return -1;
202

    
203
  end_pointer=NULL;
204
  int second_token = strtol(tokens[1], &end_pointer, 10);
205

    
206
  if (!end_pointer || *end_pointer != '\0') {
207
    printf("There was an error converting second token into a number.\n");
208
    return -1;
209
  }
210
    
211
  if (second_token == REQUEST_BOM_MATRIX) {
212
    if (parse_request_bom_matrix(pool_index)) {
213
      return -1;
214
    }
215
  } else if (second_token == REQUEST_XBEE_IDS) {
216
    if (parse_request_xbee_ids(pool_index)) {
217
      return -1;
218
    }
219
  } else {
220
    char * my_current_message = "Hi, how are you?\n";
221
    printf("Sending %s\n", my_current_message);
222
    connection_pool->write_to_client(pool_index, my_current_message, strlen(my_current_message));
223
  }
224

    
225
  return 0;
226
}
227

    
228
int Command::parse_request_bom_matrix(int pool_index) {
229
  char response_bom_matrix_buffer[MAX_RESPONSE_LEN];
230
  char temp_bom_matrix_buffer[MAX_RESPONSE_LEN];
231
 
232
  if (!connection_pool) {
233
    return -1;
234
  }
235

    
236
  //TODO: change after we start keeping track of bom matrix
237
  /*
238
  int number_robots = rand()%10;
239
  int bom_matrix[number_robots][number_robots];
240
  for (int ii = 0; ii < number_robots; ii++) {
241
    for (int j = 0; j < number_robots; j++) {
242
      //do this to generate some -1 values which mean they can't see each other
243
      int matrix_value = rand()%(number_robots+1)-1;
244
      bom_matrix[ii][j] = matrix_value;
245
    }
246
  }
247
  */
248
  int number_robots = 3;
249
  int bom_matrix[number_robots][number_robots];
250
  for (int ii = 0; ii < number_robots; ii++) {
251
    for (int j = 0; j < number_robots; j++) {
252
      bom_matrix[ii][j] = ((ii*3+j)%17)-1;
253
    }
254
  }
255
  
256

    
257
  printf("number of robots is %d\n", number_robots);
258

    
259
  //TODO: make this better
260
  //TODO: make sure I don't need to do MAX_RESPONSE_LENGTH-1
261
  snprintf(response_bom_matrix_buffer,MAX_RESPONSE_LEN, "%d %d %d", RESPONSE_TO_CLIENT_REQUEST, REQUEST_BOM_MATRIX, number_robots);
262
  for (int ii = 0; ii < number_robots; ii++) {
263
    for (int j = 0; j < number_robots; j++) {
264
      //TODO: don't use strcpy
265
      strcpy(temp_bom_matrix_buffer, response_bom_matrix_buffer);
266
      //TODO: put length checking in here so array doesn't go out of bounds
267
      //TODO: maybe use strncat?
268
      strcat(temp_bom_matrix_buffer," %d");
269
      snprintf(response_bom_matrix_buffer, MAX_RESPONSE_LEN, temp_bom_matrix_buffer, bom_matrix[ii][j]);
270
    }
271
  }
272
  strcat(response_bom_matrix_buffer,"\n");
273
  connection_pool->write_to_client(pool_index, response_bom_matrix_buffer, strlen(response_bom_matrix_buffer));
274
  printf("Sending %s", response_bom_matrix_buffer);
275

    
276
  return 0;
277
}
278

    
279
int Command::parse_request_xbee_ids(int pool_index) {
280
  //TODO: make this better
281
  //TODO: change when we actually know this data
282
  //int number_robots = rand() % 10;
283
  int number_robots = 3;
284

    
285
  char xbee_id_buffer[MAX_RESPONSE_LEN];
286
  char temp_xbee_id_buffer[MAX_RESPONSE_LEN];
287
      
288
  if (!connection_pool) {
289
    return -1;
290
  }
291

    
292
  snprintf(xbee_id_buffer, MAX_RESPONSE_LEN, "%d %d %d", RESPONSE_TO_CLIENT_REQUEST, REQUEST_XBEE_IDS, number_robots);
293
      
294
  printf("number of robots is %d\n", number_robots);
295

    
296
  for (int ii = 0; ii < number_robots; ii++) {
297
    strcpy(temp_xbee_id_buffer, xbee_id_buffer);
298
    //TODO: put length checking in here so array doesn't go out of bounds
299
    //TODO: maybe use strncat?
300
    strcat(temp_xbee_id_buffer, " %d");
301
    snprintf(xbee_id_buffer, MAX_RESPONSE_LEN, temp_xbee_id_buffer, ii);
302
  }
303
  strcat(xbee_id_buffer, "\n");
304
  connection_pool->write_to_client(pool_index, xbee_id_buffer, strlen(xbee_id_buffer));
305
  printf("Sending %s", xbee_id_buffer);
306

    
307
  return 0;
308
}