/* motorserv.c */ /* * Motor Control with TCP/IP over SLIP * Student 1 Name, ID: * Student 2 Name, ID: * Lab Section: * Lab Date: */ #include "lwip/sys.h" #include "lwip/api.h" #define MAX_UNSIGNED_SHORT 65535 void ParseCommandBuffer(char *,char *, int *); static void sendstr(const char *str, struct netconn *conn) { netconn_write(conn, (void *)str, strlen(str), NETCONN_COPY); } static void motorserv_thread(void *arg) /* creates a socket and listens on port 8 */ { /* Your motorserv code goes here Ex 3 */ struct netconn *conn, *newconn; err_t err; char str_command[1024]; char str_token1[10]; char str_token2[10]; int int_steps = 0; /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); /* Bind connection to well known port number 8. */ netconn_bind(conn, NULL, 8); /* Tell connection to go into listening mode. */ netconn_listen(conn); while(1) { /* Grab new connection. */ outstr("Motor Server: listening on port 8...\n\r"); newconn = netconn_accept(conn); outstr("Motor Server: accepted new connection\n\r"); /* Process the new connection. */ if(newconn != NULL) { struct netbuf *buf; void *data; u16_t len; while(( (buf = netconn_recv(newconn)) != NULL)) { str_command[0] = '\0'; do { netbuf_data(buf, &data, &len); outstrn(data,len); strncat(str_command,data,len); err = netconn_write(newconn, data, len, NETCONN_COPY); if(err != ERR_OK) { outstr("Error writing in Motor Server\n\r"); } } while(netbuf_next(buf) >= 0); ParseCommandBuffer(str_command,str_token1, &int_steps); outstr(str_token1);outstr(" "); intstr(str_token2,int_steps); outstr(str_token2);cr(); netbuf_delete(buf); } } /* Close connection and discard connection identifier. */ netconn_delete(newconn); } } void motorserv_init(void) { sys_thread_new(motorserv_thread, NULL, 0); } /***************************************************************************** ParseCommandBuffer * Description: This function parses a complete string returned from the telnet session started on port 8. The commands are case sensitive. The do-while receive loop must finish for this code to work right. This function parses through the complete line (including spaces, tabs, carriage returns and line feeds) and returns the command as follows: rot -X or ccw X is returned as: str_command is set to ccw p_steps is set to X rot X or cw X is returned as: str_command is set to cw p_steps is set to X cleardata or cd is returned as: str_command is set to cd p_steps is set to zero getdata or gd is returned as: str_command is set to gd p_steps is set to zero; quit or bye is returned as: str_command is set to bye p_steps is set to zero all other cases: str_command is set to empty by setting str_command[0]to '\0' p_steps is set to zero * Parameters: char * str_orig -> the original string received over the tcp/ip socket. * Returns: char * str_command = one of ("" (or empty string), * "gd","cd","ccw" or "cw") int * p_steps = zero or number of steps requested. * Side Effects: str_original is reformatted into a series of NULL delimited strings representing the first three arguments. Spaces, Tabs and CR/LF characters have been removed. How to call this routine: You have received the entire command from the packet transmitted over telnet and copied it into str_command. declare these variables : char str_command[1024]; char str_token1[10]; int int_rotations call the function this way: ParseCommandBuffer(str_command,str_token1, &int_rotations); ******************************************************************************/ void ParseCommandBuffer(char * str_orig, char * str_command, int * p_steps){ char * ptr_token = (char*)NULL; /* ptr for each parsed token */ int int_tokens = 0; /* number of tokens on command line */ char str_token1[10]; /* char array for first token */ char str_token2[10]; /* char array for second token */ char flag_notdigit = FALSE; /* flag for non-digits in 2nd token */ str_command[0] = '\0'; /* set str_command to empty */ str_token1[0] = '\0'; /* set str_token1 to empty */ str_token2[0] ='\0'; /* set str_token2 to empty */ ptr_token = strtok(str_orig," \t\n\r"); /*get first token (if any) from string */ if (ptr_token){ /* copy first argument if ptr_token != NULL */ strncat(str_token1,ptr_token,10); /* whoa 10 chars only, no overflow please */ int_tokens = 1; } else { str_token1[0]='\0'; /* no token ->set str_token1 to empty */ } ptr_token = strtok(NULL," \t\n\r"); /* get 2nd token (if any) */ if (ptr_token){ strncat(str_token2,ptr_token,10); int_tokens += 1; } else { str_token2[0]='\0'; /* no token ->set str_token1 to empty */ } if ((ptr_token = strtok(NULL," \t\n\r")) != NULL){ /*check for more args but don't parse them */ int_tokens +=1; /*increment token count to indicate that we have too many */ str_command[0]='\0'; /* set returned string to empty */ *p_steps = 0; /* set returned # of steps to zero*/ } switch (int_tokens){ /* this case handles all one-argument commands */ case 1: if ((strcmp(str_token1,"getdata") == 0) || (strcmp(str_token1,"gd")== 0)) { strcpy(str_command, "gd"); *p_steps = 0; } else if ((strcmp(str_token1,"cleardata") == 0) || (strcmp(str_token1,"cd")== 0)){ strcpy(str_command,"cd"); *p_steps = 0; } else if ((strcmp(str_token1,"bye")== 0) || (strcmp(str_token1,"quit")== 0)) { strcpy(str_command,"bye"); *p_steps = 0; } else { outstr("Unregognized token in case 1\n\r"); str_command[0]='\0'; *p_steps = 0; } break; /* this case handles all two-argument commands */ case 2: if( ( ( (strcmp(str_token1,"rot") == 0) && (str_token2[0]=='-') ) ) || (strcmp(str_token1,"ccw") == 0)){ int i=0; if (strcmp(str_token1,"rot")==0){ i = 1; }else { i = 0; } strcpy(str_command,"ccw"); while(str_token2[i]!= '\0'){ if((isdigit(str_token2[i])==0)){ flag_notdigit = TRUE; str_token2[0]='\0'; *p_steps=0; break; } i++; } if(flag_notdigit == FALSE){ int i = 0; if (strcmp(str_token1,"rot")==0){ i = 1; } else { i = 0; } *p_steps = atoi(&str_token2[i]); if(*p_steps > MAX_UNSIGNED_SHORT){ *p_steps = 0; outstr("Number of steps is too big\n\r"); } } } else if ((((strcmp(str_token1, "rot") == 0) && (str_token2[0]!='-'))) || (strcmp(str_token1,"cw")==0) ){ int i=0; strcpy(str_command,"cw"); while(str_token2[i]!= '\0'){ if((isdigit(str_token2[i])==0)){ flag_notdigit = TRUE; str_token2[0]='\0'; *p_steps=0; break; } i++; } if(flag_notdigit == FALSE){ *p_steps = atoi(&str_token2[0]); if(*p_steps > MAX_UNSIGNED_SHORT){ *p_steps = 0; outstr("Number of steps is too big\n\r"); } } } else { outstr("Unrecognized token in case 2\n\r"); str_command[0]= '\0'; *p_steps =0; } break; /* This case handles zero and >2 arguments*/ default: outstr("Wrong number of arguments\n\r"); str_command[0]='\0'; *p_steps = 0; } }