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