292 |
292 |
*
|
293 |
293 |
* @return void
|
294 |
294 |
*/
|
295 |
|
//TODO: put error checking on listen_socket to make sure its a valid socket
|
296 |
295 |
void ConnectionPool::set_listen_socket_in_ready_set(int listen_socket) {
|
|
296 |
if (listen_socket < 0)
|
|
297 |
return;
|
|
298 |
|
297 |
299 |
FD_SET(listen_socket, &ready_set);
|
298 |
300 |
}
|
299 |
301 |
|
300 |
302 |
/**
|
301 |
|
* @todo Since the listen socket is now a member of the class, the first parameter can be removed
|
302 |
|
* @todo Does the select timeout need to be passed in? or can it be specified in the method?
|
303 |
|
*
|
304 |
303 |
* @brief Find out what file descriptors are ready to write to and read from
|
305 |
304 |
*
|
306 |
305 |
* @param listen_socket The socket to listen on
|
... | ... | |
308 |
307 |
*
|
309 |
308 |
* @return 0
|
310 |
309 |
*/
|
311 |
|
int ConnectionPool::perform_select(int listen_socket, struct timeval * select_timeout) {
|
|
310 |
int ConnectionPool::perform_select(int listen_socket) {
|
312 |
311 |
read_set = ready_set;
|
313 |
312 |
write_set = ready_set;
|
314 |
313 |
|
|
314 |
struct timeval select_timeout;
|
|
315 |
memset(&select_timeout, 0, sizeof(select_timeout));
|
|
316 |
|
315 |
317 |
//TODO(Jason): think about why I put this there
|
316 |
318 |
if (max_file_descriptor < listen_socket)
|
317 |
319 |
max_file_descriptor = listen_socket;
|
318 |
320 |
|
319 |
|
number_clients_ready = select(max_file_descriptor+1, &(read_set), &(write_set), NULL, select_timeout);
|
|
321 |
number_clients_ready = select(max_file_descriptor+1, &(read_set), &(write_set), NULL, &select_timeout);
|
320 |
322 |
|
321 |
323 |
return 0;
|
322 |
324 |
}
|
... | ... | |
369 |
371 |
write_set = new_set;
|
370 |
372 |
}
|
371 |
373 |
|
372 |
|
//TODO: write a function to write data into the write buffers
|
373 |
|
//TODO: fix names of variables to obey new style
|
|
374 |
//TODO: write a function to write data into the write buffers (jason: what was this referring to?)
|
374 |
375 |
int ConnectionPool::parse_command(char* command, int pool_index, ColonetWireless * wireless) {
|
375 |
376 |
char tokens[MAX_TOKENS][MAX_TOKEN_SIZE];
|
376 |
377 |
unsigned char int_tokens[MAX_TOKENS];
|
377 |
|
int numTokens = 0;
|
378 |
|
char* endptr = NULL;
|
379 |
|
int commandID;
|
|
378 |
int number_tokens = 0;
|
|
379 |
char* end_pointer = NULL;
|
|
380 |
int command_id;
|
380 |
381 |
int i;
|
381 |
|
unsigned char args[PACKET_DATA_LEN];
|
|
382 |
unsigned char arguments[PACKET_DATA_LEN];
|
382 |
383 |
|
383 |
|
memset(args, 1, PACKET_DATA_LEN);
|
|
384 |
memset(arguments, 1, PACKET_DATA_LEN);
|
384 |
385 |
|
385 |
386 |
if (!command) {
|
386 |
387 |
return -1;
|
... | ... | |
394 |
395 |
return -1;
|
395 |
396 |
}
|
396 |
397 |
|
397 |
|
if ((numTokens = tokenize_command(command, tokens)) < 0) {
|
|
398 |
if ((number_tokens = tokenize_command(command, tokens)) < 0) {
|
398 |
399 |
return -1;
|
399 |
400 |
}
|
400 |
401 |
|
401 |
402 |
//the 10 in the function call indicates number is base 10
|
402 |
|
commandID = strtol(tokens[0], &endptr, 10);
|
|
403 |
command_id = strtol(tokens[0], &end_pointer, 10);
|
403 |
404 |
|
404 |
|
if (!endptr || *endptr != '\0') {
|
|
405 |
if (!end_pointer || *end_pointer != '\0') {
|
405 |
406 |
printf("There was an error converting first token into a number.\n");
|
406 |
407 |
return -1;
|
407 |
408 |
}
|
408 |
409 |
|
409 |
|
if (commandID == SEND_TO_ROBOT || REQUEST_FROM_ROBOT) {
|
410 |
|
int numIntTokens = numTokens;
|
|
410 |
if (command_id == SEND_TO_ROBOT || REQUEST_FROM_ROBOT) {
|
|
411 |
int number_int_tokens = number_tokens;
|
411 |
412 |
|
412 |
413 |
/* Convert tokens to ints */
|
413 |
|
for (i = ROBOT_COMMAND_OFFSET; i < numIntTokens; i++) {
|
|
414 |
for (i = ROBOT_COMMAND_OFFSET; i < number_int_tokens; i++) {
|
414 |
415 |
int_tokens[i-ROBOT_COMMAND_OFFSET] = atoi(tokens[i]);
|
415 |
416 |
}
|
416 |
|
if (commandID == REQUEST_FROM_ROBOT) {
|
|
417 |
if (command_id == REQUEST_FROM_ROBOT) {
|
417 |
418 |
if (i < MAX_TOKENS) {
|
418 |
419 |
for (;i >= 4; i--) {
|
419 |
420 |
int_tokens[i] = int_tokens[i-1];
|
420 |
421 |
}
|
421 |
422 |
int_tokens[3] = pool_index;
|
422 |
|
numIntTokens++;
|
|
423 |
number_int_tokens++;
|
423 |
424 |
} else {
|
424 |
425 |
//TODO: send an error back to client here also
|
425 |
426 |
fprintf(stderr, "Client attempted to request data from the robot but there was not enough room to put in the client's id.\n");
|
... | ... | |
427 |
428 |
}
|
428 |
429 |
}
|
429 |
430 |
|
430 |
|
/* Fill args buffer with args */
|
431 |
|
for (i = ROBOT_COMMAND_LEN; i < numIntTokens-ROBOT_COMMAND_OFFSET; i++) {
|
432 |
|
args[i-ROBOT_COMMAND_LEN] = int_tokens[i];
|
|
431 |
/* Fill arguments buffer with arguments */
|
|
432 |
for (i = ROBOT_COMMAND_LEN; i < number_int_tokens-ROBOT_COMMAND_OFFSET; i++) {
|
|
433 |
arguments[i-ROBOT_COMMAND_LEN] = int_tokens[i];
|
433 |
434 |
}
|
434 |
435 |
|
435 |
436 |
/* Check the tokens */
|
436 |
|
if (check_tokens(int_tokens, numIntTokens) < 0) {
|
|
437 |
if (check_tokens(int_tokens, number_int_tokens) < 0) {
|
437 |
438 |
fprintf(stderr, "%s: Error - Invalid command/request.\n", __FUNCTION__);
|
438 |
439 |
return 0;
|
439 |
440 |
}
|
440 |
441 |
|
441 |
442 |
/* Send packet to robot */
|
442 |
|
fprintf(stderr, "Calling wireless->send(%d, %d, %d, args)\n",
|
|
443 |
fprintf(stderr, "Calling wireless->send(%d, %d, %d, arguments)\n",
|
443 |
444 |
int_tokens[0], int_tokens[1], int_tokens[2]);
|
444 |
|
wireless->send(int_tokens[0], int_tokens[1], int_tokens[2], args);
|
|
445 |
wireless->send(int_tokens[0], int_tokens[1], int_tokens[2], arguments);
|
445 |
446 |
}
|
446 |
447 |
|
447 |
448 |
return 0;
|
... | ... | |
456 |
457 |
* @return 0 on success, negative error code on failure
|
457 |
458 |
*/
|
458 |
459 |
int ConnectionPool::tokenize_command(char* command, char tokens[MAX_TOKENS][MAX_TOKEN_SIZE]) {
|
459 |
|
char* nextToken = command;
|
460 |
|
char* endToken = NULL;
|
461 |
|
int numTokens = 0;
|
|
460 |
char* next_token = command;
|
|
461 |
char* end_token = NULL;
|
|
462 |
int number_tokens = 0;
|
462 |
463 |
|
463 |
464 |
if (!command) {
|
464 |
465 |
return -1;
|
465 |
466 |
}
|
466 |
467 |
|
467 |
|
while ((endToken = strstr(nextToken, " "))) {
|
468 |
|
*endToken = '\0';
|
|
468 |
while ((end_token = strstr(next_token, " "))) {
|
|
469 |
*end_token = '\0';
|
469 |
470 |
|
470 |
|
if (strlen(nextToken) > MAX_TOKEN_SIZE-1) {
|
|
471 |
if (strlen(next_token) > MAX_TOKEN_SIZE-1) {
|
471 |
472 |
return -1;
|
472 |
473 |
}
|
473 |
474 |
|
474 |
|
strcpy(tokens[numTokens], nextToken);
|
|
475 |
strcpy(tokens[number_tokens], next_token);
|
475 |
476 |
|
476 |
|
numTokens++;
|
477 |
|
nextToken = endToken + 1;
|
|
477 |
number_tokens++;
|
|
478 |
next_token = end_token + 1;
|
478 |
479 |
|
479 |
|
while (isspace(*nextToken) && *nextToken != '\0') {
|
480 |
|
nextToken++;
|
|
480 |
while (isspace(*next_token) && *next_token != '\0') {
|
|
481 |
next_token++;
|
481 |
482 |
}
|
482 |
483 |
}
|
483 |
484 |
|
484 |
|
if (endToken == NULL && *nextToken != '\0') {
|
485 |
|
if (strlen(nextToken) > MAX_TOKEN_SIZE-1) {
|
|
485 |
if (end_token == NULL && *next_token != '\0') {
|
|
486 |
if (strlen(next_token) > MAX_TOKEN_SIZE-1) {
|
486 |
487 |
return -1;
|
487 |
488 |
}
|
488 |
489 |
|
489 |
|
strcpy(tokens[numTokens], nextToken);
|
|
490 |
strcpy(tokens[number_tokens], next_token);
|
490 |
491 |
|
491 |
|
numTokens++;
|
|
492 |
number_tokens++;
|
492 |
493 |
}
|
493 |
494 |
|
494 |
|
return numTokens;
|
|
495 |
return number_tokens;
|
495 |
496 |
}
|
496 |
497 |
|
497 |
498 |
/**
|
498 |
499 |
* @brief checks a list of tokens to see if it's valid
|
499 |
500 |
*
|
500 |
501 |
* @param tokens The tokens to check
|
501 |
|
* @param numTokens The number of tokens contained in the tokens parameter
|
|
502 |
* @param number_tokens The number of tokens contained in the tokens parameter
|
502 |
503 |
*
|
503 |
504 |
* @return 0 if tokens is valid
|
504 |
505 |
*/
|
505 |
|
int ConnectionPool::check_tokens(unsigned char* tokens, int numTokens) {
|
506 |
|
if (numTokens > 3 + PACKET_DATA_LEN) {
|
|
506 |
int ConnectionPool::check_tokens(unsigned char* tokens, int number_tokens) {
|
|
507 |
if (number_tokens > 3 + PACKET_DATA_LEN) {
|
507 |
508 |
/* Too many tokens */
|
508 |
509 |
return -1;
|
509 |
510 |
}
|
510 |
511 |
|
511 |
|
if (numTokens < 3) {
|
|
512 |
if (number_tokens < 3) {
|
512 |
513 |
/* Not enough tokens */
|
513 |
514 |
return -1;
|
514 |
515 |
}
|