📄 tsipchat.c
字号:
/*
* *************************************************************************
*
* Trimble Navigation, Ltd.
* OEM Products Development Group
* P.O. Box 3642
* 645 North Mary Avenue
* Sunnyvale, California 94088-3642
*
* Corporate Headquarter:
* Telephone: (408) 481-8000
* Fax: (408) 481-6005
*
* Technical Support Center:
* Telephone: (800) 767-4822 (U.S. and Canada)
* (408) 481-6940 (outside U.S. and Canada)
* Fax: (408) 481-6020
* BBS: (408) 481-7800
* e-mail: trimble_support@trimble.com
*
* *************************************************************************
*
* Vers Date Changes Author
* ---- --------- ---------------------------------------- ----------
* 1.10 21 Jun 93 Initial version pvwl
* 1.11 31 Jul 93 Revisions pvwl
* 1.12 10 Feb 94 Revisions: SPDRIVE removed; Superpackets pvwl
* 1.12a 31 Mar 94 Revisions: added repeat display window pvwl
* 1.12b 4 Apr 94 Revisions: added 8E pvwl
* 1.20 5 Jun 95 Revisions: time, repeat window, od tracking ahl
* 1.40 16 Jul 95 simplifications pvwl
*
* *************************************************************************
*
* TSIPCHAT.C contains the main() entry function to the TSIPCHAT program.
* The main() function serves as a model for programs that interface with
* TSIP-based receivers. The files required for compilation include:
*
* TSIP_IFC.H - parse/format prototypes
* TSIP_IFC.C - TSIP standard command/report interface
*
* TSIPINCL.H - prototypes for commands, reports, serial I/O,
* and utilities
* TSIPCHAT.C - main program
* TSIP_UTL.C - user interface functions
* TSIP_CMD.C - command generator
* TSIP_RPT.C - report interpreter
* TSIP_ALM.C - receiver almanacs
* TSIP_SIO.C - serial input/output setting routines
* T_SERIAL.C - serail buffer routines
*
* Portability
* The code for TCHAT is written in ANSI C and is highly portable. The
* TSIPCHAT code is very restrictive and requires a Borland Compiler.
* TCHAT can be created using the Microsoft Visual C++ Compiler (version
* 1.0 or later) or the Borland C++ Compiler (version 3.1 or later).
*
* TSIPCHAT Features
* TSIPCHAT has the following capabilities:
*
* 1) Binary Output Storage: If a filename for binary output is specified,
* all reports will be saved into a binary file. The storage file can be
* opened at the start of TSIPCHAT by specifying a filename as argument.
* During a TSIPCHAT session, a new storage file can be opened, or an old
* storage file can be closed or re-opened, with '^F'. The TSIPPRNT program
* can be used to translate the binary file into ASCII format.
*
* 2) Serial Communications: There are BORLAND-specific functions in
* TSIP_SIO.C that supply a buffered serial port to operate TSIPCHAT.
* The computer port settings (eg, baud, data bits, stop bits, parity)
* can be changed using the '^I' keystroke.
*
* Developers of new applications are encouraged to use the functions in
* TSIP_IFC.C, and pattern their drivers on main() in TCHAT.C.
* For technical assistance about using TSIPCHAT or creating TSIP-based
* applications, please contact our Technical Support Center.
*
* *************************************************************************
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <time.h>
#include <dos.h> /* for ctrlbrk */
#include <math.h>
#include <signal.h>
#include "tsip_ifc.h"
#include "tsipincl.h"
static short
nprintchar, /* character count of ASCII line print */
repeat_report_code, /* report to be repeat-requested */
tsipfiletype = TSIPFILE, /* other choice = AUTOFILE */
reply [0x200], /* indexed by rpt.code; >0 if requested by cmd */
serial_port_hold = FALSE;
/* file for recording report data */
static FILE
*tsipstream = NULL;
/* file name for same */
static char
tsipfilename[80];
/* serial port interface 'primitives' required by TSIP_IFC.C */
short getb (void)
{
short this_byte;
this_byte = get_byte ();
if (this_byte == -1) return -1;
if (tsipstream != NULL) fputc (this_byte, tsipstream);
return this_byte;
}
short sendb (unsigned char outbyte)
{
return send_byte (outbyte);
}
/*
* three special functions of TSIPCHAT:
* repeat reports;
* print non-TSIP characters;
* hourly file opener.
*/
void ask_for_repeat_report (void)
{
if (!repeat_report_code)
return;
reply [repeat_report_code] = 1;
switch (repeat_report_code) {
case 0x41:
cmd_0x21();
break;
case 0x47:
cmd_0x27();
break;
case 0x4D:
cmd_0x2D();
break;
case 0x5A:
cmd_0x3A(0);
break;
case 0x5C:
cmd_0x3C(0);
break;
case 0x85:
cmd_0x65(0);
break;
default:
return;
}
}
void rawprint (short newbyte)
{
short
curr_window,
newlinechar,
newchar;
switch (newbyte)
{
case '\r': case '\n':
newlinechar = TRUE;
newchar = -1;
break;
case '$': case '>':
/* NMEA, TAIP starting characters */
newlinechar = TRUE;
newchar = newbyte;
nprintchar++;
break;
default:
newlinechar = FALSE;
if (newbyte < 0x20 || newbyte > 0xFF) newchar = ((newchar&0x3F)|0x40);
else newchar = newbyte;
nprintchar++;
break;
}
/* Save to reset screen at exit. */
curr_window = which_window();
switch_window (AUTOWIN);
if (newlinechar || nprintchar > 75)
{
if (nprintchar) show_crlf();
nprintchar = 0;
}
if (newchar > 0) {
xprintf ("%c", (char)newchar);
}
switch_window (curr_window);
}
static void open_auto_file (void)
{
static double
file_start_time = -4000.; /* allows file to open before first fix. */
double
current_time;
if (tsipfiletype != AUTOFILE) return;
current_time = get_tsip_time ();
if (current_time > file_start_time + 3600.) {
file_start_time = current_time - fmod(current_time, 3600.);
/* open up command window */
close_file_storage (&tsipstream, tsipfilename, tsipfiletype);
open_file_storage (&tsipstream, tsipfilename, tsipfiletype);
}
}
/*
* The following routine is used in main and any routines requiring
* user keyboard input.
* By using this routine, the incoming serial stream is serviced and output on
* the screen but can be pre-empted by processing of user keystrokes
* while inputting data.
*/
unsigned char read_rpts_wait_for_kbhit (void)
{
static TSIPPKT
rpt; /* structure for current incoming TSIP report */
short
newbyte,
ireply,
curr_window; /* if in dual window configuration, current window */
clock_t
now_clock;
static clock_t
last_repeat_clock;
static short
first_message,
new_repeat_report = FALSE;
/* Current screen state so we are able to reset screen at exit. */
curr_window = which_window();
/* do parsing until a kbhit is detected */
while (!kbhit ()) {
if (serial_port_hold)
{
/* suppress output if the serial port parmeters are being changed */
continue;
}
newbyte = getb();
tsip_input_proc (&rpt, newbyte);
if (rpt.status == TSIP_PARSED_FULL)
{
/* end of packet received, prepare for display */
first_message = TRUE;
ireply = reply_code (&rpt);
if (reply [ireply])
{
/*
** if this report has been requested, print in command window,
** and decrement the reply request. There may be 32 requests,
** one for each SV: e.g., cmd_0x3A.
*/
if (ireply==repeat_report_code && new_repeat_report)
{
new_cmd_window ();
/* the following will re-print the header if necessary */
print_msg_table_header (repeat_report_code);
new_repeat_report = FALSE;
}
else
{
switch_window (CMDWIN);
}
reply [ireply]--;
}
else
{
switch_window (AUTOWIN);
}
rpt_packet (&rpt);
/* return to active window */
switch_window (curr_window);
/* Check to see if time to open an hourly storage file. */
open_auto_file();
/* refresh repeat code for special display */
reply [repeat_report_code] = 1;
/* reset non-TSIP character printer */
nprintchar = 0;
/* prevent printing this packet again */
rpt.status = TSIP_PARSED_EMPTY;
}
else if (rpt.status == TSIP_PARSED_EMPTY && newbyte>=0)
{
/* non-TSIP character printer */
rawprint (newbyte);
}
/* repeat command alarm clock control every two seconds */
now_clock = clock();
if (now_clock >= last_repeat_clock + 2*CLK_TCK) {
ask_for_repeat_report ();
new_repeat_report = TRUE;
last_repeat_clock = now_clock;
}
}
repeat_report_code = 0;
return (getch ());
}
short closechat (void)
{
reset_serial_port ();
reset_screen ();
return 0;
}
void ctrlchandler (short sig)
{
closechat ();
exit (sig);
}
static void do_command (unsigned char kbch)
{
short
irpt;
KB_CMD
kb_cmd;
repeat_report_code = 0;
/* zero out all previous report requests */
for (irpt=0; irpt < 0x200; irpt++) reply [irpt] = 0;
/* open up command window */
new_cmd_window ();
/* 0x06, 0x07, 0x0C, 0x0D do not generate TSIP commands; */
/* service them separately. */
switch (kbch) {
case 0x06:
/* '^F' - continuous binary file storage control */
if (tsipstream == NULL)
{
tsipfiletype = TSIPFILE;
open_file_storage (&tsipstream, tsipfilename, tsipfiletype);
}
else
{
close_file_storage (&tsipstream, tsipfilename, tsipfiletype);
}
break;
case 0x07:
/* '^G' - continuous binary file storage control */
if (tsipfiletype == TSIPFILE && tsipstream != NULL) {
close_file_storage (&tsipstream, tsipfilename, tsipfiletype);
}
tsipfiletype = AUTOFILE;
break;
case 0x09:
/* '^I' - change serial port parameters.
/* When changing serial port settings, suppress TSIP parsing. */
serial_port_hold = TRUE;
set_buf_serial_port ();
serial_port_hold = FALSE;
break;
case 0x0D: /* <CR> - just blanks out command window */
break;
case 0x17: /* '^W' - setting continuous report command */
menu_cmd_prompt (REPEAT_MENU, &kb_cmd);
if (kb_cmd.kbch != 0x1B) {
repeat_report_code = kb_cmd.replycode;
ask_for_repeat_report ();
}
break;
case '?': /* '?' - Keystroke Command List */
kbch = menu_cmd_prompt (ALL_MENU, &kb_cmd);
if (kb_cmd.kbch != 0x1B) {
switch_window (AUTOWIN);
do_command (kb_cmd.kbch); /* recursive call */
}
break;
case '!':
/* Creates a file GPSALM.DAT that contains all information */
/* required to do a warm start. */
xprintf ("Transfer GPSALM.DAT from rcvr to PC?");
clreol ();
if (!ask_verify_nocmdcrlf ()) break;
if (!almgetb ()) {
show_crlf();
xprintf ("Storage aborted");
}
break;
case '@':
/* Load a file GPSALM.DAT that contains all information */
/* required to do a warm start. */
xprintf ("Transfer GPSALM.DAT from PC to rcvr?");
clreol ();
if (!ask_verify_nocmdcrlf ()) break;
if (!almputb ()) {
show_crlf();
xprintf ("Loading aborted");
}
break;
case '#':
show_crlf();
xprintf ("TSIP_IFC version %s:%d",
TSIP_VERNUM, TSIP_H_DEFINED);
show_crlf();
break;
case 0x1B:
/* open up command window */
highvideo ();
show_crlf();
show_crlf();
xprintf (
"******** Press ESC to exit program; or press any other key to continue *********");
show_crlf();
show_crlf();
normvideo ();
break;
default: /* normal TSIP commands */
proc_kbd (kbch, reply);
break;
}
/* return to auto-report mode */
switch_window (AUTOWIN);
}
short ParseCommandLine (short argc, char *argv[])
{
short
iarg, comport, retval;
char
*argvi;
retval = TRUE;
/* provisions for command line arguments starting with '-' or '/' */
for (iarg = 0; iarg < argc; iarg++) {
argvi = argv[iarg];
if (argvi[0] != '-' && argvi[0] != '/') continue;
if (argvi[1] == 'c' || argvi[1] == 'C')
{
comport = argvi[2] - '0';
/* returns TRUE if serial port failure */
retval = initialize_serial_port (comport);
}
if (argvi[1] == 'f' || argvi[1] == 'F') {
if (argvi[2] == '\0')
{
tsipfiletype = AUTOFILE;
}
else
{
strcpy (tsipfilename, &argvi[2]);
open_file_storage (&tsipstream, tsipfilename, tsipfiletype);
}
}
}
return retval;
}
/**/
/* ************************************************************** */
/* **************** main routine for tsiptalk ****************** */
/* ************************************************************** */
void main (short argc, char *argv[])
{
unsigned char
last_kbch,
kbch;
if (ParseCommandLine(argc, argv))
{
show_crlf();show_crlf();
printf ("\nSyntax error. Correct Syntax:");
printf ("\nTSIPCHAT -c<n> -f<filename>");
printf ("\nComm Port must be specified by command line argument");
printf ("\n-c1 for COM1, -c2 for COM2, -c0 for SPDRIVE");
printf ("\nBinary output file name optional: -f<filename>");
printf ("\nIf no filename specified, output is divided into hourly files.\n");
exit(0);
}
/* clear screen and start at the bottom */
initialize_screen ();
/* initialize two screen setup */
switch_window (CMDWIN);
highvideo ();
xprintf (
" TSIPCHAT %s(%s), TSIP Receiver Control Interface Software",
TSIPCHAT_VERNUM, TSIP_VERNUM);
show_crlf ();
xprintf (
" (c) Copyright 1993,94,95,96,97 Trimble Navigation, Ltd.");
show_crlf ();
xprintf (
" Press '?' to access the Keystroke Command List");
normvideo ();
switch_window (AUTOWIN);
signal (SIGINT, ctrlchandler);
kbch = last_kbch = 0;
/* MAIN LOOP: read bytes from buffered serial port input; */
/* if kbhit, do corresponding command */
/* double ESC to quit program */
for (;;)
{
kbch = read_rpts_wait_for_kbhit ();
if (kbch==0x1B && last_kbch==0x1B) break;
do_command (kbch);
last_kbch = kbch;
};
closechat ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -