Skip to content. | Skip to navigation

Personal tools

remote/parse.cpp

remote/parse.cpp

remote/parse.cpp

/////////////////////////////////////////////////////////////////////////////
// PARSE.CPP
//
//  Last updated: 05/12/2002
//
//  Part of the source code for the remote M3 Program
//
// This file contains the functions that parse serial and keyboard input,
// and execute the appropriate functions to carry out the commands.
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// ParseKB: Parse a keyboard command line
int ParseKB(char *line,int SerialCommand,char *errmsg)
// This routine parses a keyboard command-line, and executes the
// appropriate code to accomplish the command.
// Returns a 0 if OK, >= 1 on a parse error
// SerialCommand = 1 if this is a free-form serial line we're parsing,
// SerialCommand = 0 if this is a local keyboard command.
// errmsg is filled with an error message to send to upstream computers.
// Note:
// Since this a remote program never SerialCommand == 1.
// So no need to add confirmation for SerialCommand == 0 in all ifs below
{
	int CmdError = 0;

	// Temporary parsing variables
	float ftemp,ftemp2,ftemp3;
	double longftemp;
	int itemp;
	dword longitemp;
	char *Cmds[10];	// Tokenized command line
	int CmdCount = 0;		// Number of command tokens
  char lineaux[255]; // Used 'cause strtok truncates the string

  strcpy(lineaux,line);

	// Display the entered command
	InputLog->Add("* %s",0,line);
	InputLog->DisplayAll();

	Log->Add("ParseKB(%d): Parsing \"%s\"",VERBOSE,__LINE__,line);

	// Blank input line
	if (strlen(line) == 0)
		return(0);

	// Break the line up into command tokens
	Cmds[0] = strtok(lineaux," ");

	while ( (Cmds[CmdCount] != NULL) && (CmdCount < 9) )
	{
  	CmdCount++;
		Cmds[CmdCount] = strtok(NULL," ");
  }

	// Identify the command and execute

	// Quit
	if ((!strcmp(Cmds[0],"Q") || !strcmp(Cmds[0],"EXIT")) && (CmdCount == 1))
		Quit = 1;
	else if (!strcmp(Cmds[0],"REXIT") && (CmdCount == 1))
	{
    sprintf(line,"Q");
    NewEDSCommand(line);
	}
	// Toggle stepper power (Tilts)
	else if (!strcmp(Cmds[0],"SP") && (CmdCount == 1))
	{
    NewEDSCommand(line);
	}
	// Toggle tilt brakes
	else if (!strcmp(Cmds[0],"TBRK") && (CmdCount == 1))
	{
    NewEDSCommand(line);
	}
	// Terminal on COM1: (Host)
	else if (!strcmp(Cmds[0],"T1") && (CmdCount == 1))
	{
  	//SetComPortSpeed(1,9600);
		COMTerminal(0);
		//RestoreComPortSpeed(1);
	}
  // Terminal on COM2: (?)
	else if (!strcmp(Cmds[0],"T2") && (CmdCount == 1))
	{
		//SetComPortSpeed(1,300);
		COMTerminal(1);
		//RestoreComPortSpeed(1);
  }
	// Tilt A Commands
	else if (!strcmp(Cmds[0],"TA") && (CmdCount == 2))
	{
		// Move tilt A
		if (sscanf(Cmds[1],"%ld",&longitemp) == 1)
    {
      if (labs(longitemp) > 100)
     	  InputLog->Add("Max 100 steps allowed",BRIEF);
			else
		  {
        CmdLine("(Move in progress)");
        NewEDSCommand(line);
      }
		}
    else
			CmdError = 1;
	}
	// Tilt B Commands
	else if (!strcmp(Cmds[0],"TB") && (CmdCount == 2))
	{
		// Move tilt B
	  if (sscanf(Cmds[1],"%ld",&longitemp) == 1)
    {
      if (labs(longitemp) > 100)
     	  InputLog->Add("Max 100 steps allowed",BRIEF);
		  else
      {
        CmdLine("(Move in progress)");
        NewEDSCommand(line);
      }
		}
    else
			CmdError = 1;
	}
	// Tilt C Commands
	else if (!strcmp(Cmds[0],"TC") && (CmdCount == 2))
	{
		// Move tilt C
		if (sscanf(Cmds[1],"%ld",&longitemp) == 1)
    {
      if (labs(longitemp) > 100)
     	  InputLog->Add("Max 100 steps allowed",BRIEF);
		  else
      {
        CmdLine("(Move in progress)");
        NewEDSCommand(line);
      }
		}
    else
			CmdError = 1;
	}
  // Compound Tilt Commands
	// PISTON type
	else if (!strcmp(Cmds[0],"PISTON") && (CmdCount == 2))
	{
		// Move tilt A-B-C = millimeters
		if (sscanf(Cmds[1],"%f",&ftemp) == 1)
		{
      longitemp = round(Tilt.Kstepmm * ftemp);
      if (fabs(ftemp) > 1.0)
				Log->AddX("Piston move aborted, max 1 mm allowed",20,SHECRED,BRIEF);
      else
      {
        CmdLine("(Move in progress)");
        NewEDSCommand(line);
      }
		}
		else
			CmdError = 1;
	}
	// Tilt around a horizontal line crossing the middle of M3
	else if (!strcmp(Cmds[0],"TH") && (CmdCount == 2))
	{
		//Tilt A=arcsec & B-C=-arcsec
		if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      CmdLine("(Move in progress)");
      NewEDSCommand(line);
    }
		else
			CmdError = 1;
	}
	// Tilt around a vertical line crossing the middle of M3
	else if (!strcmp(Cmds[0],"TV") && (CmdCount == 2))
	{
		//Tilt B=arcsec & C=-arcsec
		if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      CmdLine("(Move in progress)");
      NewEDSCommand(line);
    }
		else
			CmdError = 1;
	}
  else if (!strcmp(Cmds[0],"TILTS") && (CmdCount == 4))
  {
  	if ( (sscanf(Cmds[1],"%f",&ftemp) == 1) &&
    		 (sscanf(Cmds[2],"%f",&ftemp2) == 1) &&
         (sscanf(Cmds[3],"%f",&ftemp3) == 1) )
      NewEDSCommand(line);
		else
			CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TAS") && (CmdCount == 2))
  {
  	if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      NewEDSCommand(line);
		else
			CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TBS") && (CmdCount == 2))
  {
  	if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      NewEDSCommand(line);
		else
			CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TCS") && (CmdCount == 2))
  {
  	if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      NewEDSCommand(line);
		else
			CmdError = 1;
  }

	// Pressure/vacuum control commands
	// Toggle pressure
	else if (!strcmp(Cmds[0],"PRES") && (CmdCount == 1))
	{
    NewEDSCommand(line);
  }
	// Toggle vacuum
	else if (!strcmp(Cmds[0],"VAC") && (CmdCount == 1))
	{
    NewEDSCommand(line);
  }
	// Toggle pressure/vacuum control mode
	else if (!strcmp(Cmds[0],"PVM") && (CmdCount == 1))
	{
    NewEDSCommand(line);
		//PresVac.Display();
	}
	else if (!strcmp(Cmds[0],"KP") && (CmdCount == 2))
	{
 	  if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      NewEDSCommand(line);
  }
	else if (!strcmp(Cmds[0],"KI") && (CmdCount == 2))
	{
 	  if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      NewEDSCommand(line);
  }
	else if (!strcmp(Cmds[0],"KD") && (CmdCount == 2))
	{
 	  if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      NewEDSCommand(line);
  }
	// Change Pres/Vac chart scale
	else if (!strcmp(Cmds[0],"PVS") && (CmdCount == 2))
	{
		if (sscanf(Cmds[1],"%f",&ftemp) == 1)
		{
			ftemp = fabs(ftemp);
			if (ftemp > 5.0)
				ftemp = 5.0;
			PresVacChart.SetScale(ftemp);
    	PresVac.Display();
		}
		else
			CmdError = 1;
	}

	// Verbose command
	else if (!strcmp(Cmds[0],"VERB") && (CmdCount == 2))
	{
		if (sscanf(Cmds[1],"%d",&itemp) != 1)
			CmdError = 1;
		else if ((itemp < 0) || (itemp > 2))
			CmdError = 1;
		else
		{
			Log->VerboseLevel = itemp;
			InputLog->Add("Verbose level = %d",0,itemp);
		}
	}
	else
		CmdError = 1;

	if (CmdError == 1)
		strcpy(errmsg,"Command decode error");
	// Display error message locally if necessary
	if (CmdError >= 1)
		InputLog->Add("  %s",BRIEF,errmsg);
	return(CmdError);
}

/////////////////////////////////////////////////////////////////////////////
// ParseSer: Parse a serial command line
void ParseSer(char line[80])
// This routine parses a command line from the serial port, and executes the
// appropriate code to accomplish the command.
{
	int i,e;
	char s[255];
	char temp[80];
	struct dostime_t t;

	Log->Add("ParseSer(%d): Parsing \"%s\"",VERBOSE,__LINE__,line);
	// Is message for us?
	if ((line[0] == Prompt) && (line[1] == Address))
	{
		switch (line[2])
		{
			// Send next EDS message
			case '2':
				MasterEDSLog->SendNextMessage(); break;
			// Repeat last EDS message
			case '3':
				MasterEDSLog->RepeatLastMessage(); break;
			// Set UT
			case '4':
			{
				if (VerifyChecksum(line) ||
						(sscanf(&line[3],"%2d%2d%2d%2d",&t.hour,&t.minute,&t.second,
						 &t.hsecond) != 4))
				{
					RespondToHost("40\r");
					Log->AddX("Incorrectly formatted UT message from TCS",1,LIGHTRED,0);
				}
				else
				{
					Log->AddX("UT set by TCS to %02d %02d %02d.%02d",998,LIGHTGREEN,0,
										 t.hour,t.minute,t.second,t.hsecond);
					settime(&t);
					RespondToHost("41\r");
				}
			}	break;

			// TCS pushes telescope elevation. It is not used
			// currently on Clay m3, so we return always
			// success to keep the TCS happy for now.
			case '5':
			{
				RespondToHost("51\r");
			}; break;

			// Free-form command
			case '9':
			{
				if (VerifyChecksum(line) ||
						(line[3] < '0') || (line[3] > '9') ||
						(line[4] < '0') || (line[4] > '9'))
					RespondToHost("?\r");
				else
				{
					i = (line[3] - '0') * 10 + line[4] - '0';
					if (strlen(line) != i + 7)
						RespondToHost("?\r");
					else
					{
						strncpy(s,&line[5],i);
            s[i] = 0;
						if (e = ParseKB(s,1,temp))
						{
							sprintf(s,"9%d%02d%s",e,strlen(temp),temp);
							RespondToHostWithChecksum(s);
						}
						else
							RespondToHostWithChecksum("9000");
					}
				}
			} break;
			default:
				RespondToHost("?\r");
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// Parse: Checks for keyboard and serial input
void Parse()
{
	int c;
	char temp[255];
	char line[10];

	// Check for scroll-lock, and pause log if necessary
	Log->Paused = (*((byte *)0x417)) & 0x10;

	// Check for a character from the keyboard
	while (kbhit())
	{
		c = toupper(getch());
		if (HelpFlag)
		{
			HelpFlag = 0;
			DisplayEnable = 1;
			// Restore normal display
			InitDisplay();
			return;
		}
		// On a carriage return, we either need to parse a keyboard command
		// line (local mode), or check for the serial to keyboard mode change
		// password.
		if (c == 0)
		{
			// Check for arrow and pgup/pgdn keys for log scrolling
			c = getch();
			switch(c)
			{
				case 72:
				// Up arrow
				{
					Log->Up();
				} break;
				case 80:
				// Down arrow
				{
					Log->Down();
				} break;
				case 73:
				// Page up
				{
					Log->PageUp();
				} break;
				case 81:
				// Page down
				{
					Log->PageDown();
				} break;
				case 71:
				// Home
				{
					Log->Home();
				} break;
				case 79:
				// End
				{
					Log->End();
				} break;
				case 75:
				// Left
				{
					Log->Left();
				} break;
				case 77:
				// Right
				{
					Log->Right();
				} break;
				case 59:
				// User hit F1, so display help
				{
					DisplayHelp();
					DisplayEnable = 0;
					HelpFlag = 1;
				} break;
				case 60:
				// User hit F2, so dump log
				{
					Log->Dump(0);
				} break;
				case 61:
				// F3 = Dump Screen
				{
					ScreenDump();
					Log->AddX("Screen dumped to SCREEN.BMP",990,SHECGREEN,0);
				} break;
			}
		}
		// User hit enter
		else if (c == 13)
		{
			CmdLine("");
			ParseKB(kbline,0,temp);
			CmdLine("");
			// After processing a keyboard line, clear the buffer
			kbline[0] = 0;
			CmdLine(kbline);
		}
		// Process a backspace
		else if (c == '\b')
		{
			if (strlen(kbline) > 0)
			{
				kbline[strlen(kbline) - 1] = 0;
				CmdLine(kbline);
			}
		}
		// User hit Escape: stop tilts movement
		else if (c == 27)
		{
      //Tilt.AbortMove();
      sprintf(line,"%d",27);
      NewEDSCommand(line);
		}
		else if (strlen(kbline) < 70)
		{
			// Otherwise, add the new character to the current buffer
			kbline[strlen(kbline)+1] = 0;
			kbline[strlen(kbline)] = c;
			CmdLine(kbline);
		}
	}

	
  // Check for a command from the serial port
	if (SerialCharReady(Host))
	{
		c = toupper(SerialGetChar(Host));
		// On a carriage return, parse the serial command line
		if (c == 13)
		{
			ParseSer(serline);
			serline[0] = 0;
			ClearSerialBuffer(Host);
		}
		// On receiving our prompt character, flush the serial receive line
		else if (c == Prompt)
		{
			serline[0] = Prompt;
			serline[1] = 0;
		}
		// Otherwise, add the character to the buffer
		else if (strlen(serline) < 79)
		{
			serline[strlen(serline)+1] = 0;
			serline[strlen(serline)] = c;
		}
		else
		{
			serline[0] = 0;
		}
	}
}

Generated by GNU Enscript 1.6.5.2.
Document Actions