📄 filer.c
字号:
/* --------------------------------------------------------------------
Project: HP200LX FILER PROTOCOL (CLIENT) COMMUNICATIONS FOR PAL
Module: FILER.C
Author: Harry Konstas & Andreas Garzotto
Started: 28. Nov. 95
Subject: Filer communications module for Linux
-------------------------------------------------------------------- */
/* --------------------------------------------------------------------
standard includes
-------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
char *copyright = "Copyright 1995, Andreas Garzotto "
"Portions Copyright, 1995, The PAL Group";
/* --------------------------------------------------------------------
local includes
-------------------------------------------------------------------- */
#include "pal.h"
#include "palpriv.h"
#include "config.h"
/* --------------------------------------------------------------------
Global variables
-------------------------------------------------------------------- */
static int ttyfd;
static int timeout_occured = 0;
static int timeout_secs = TIMEOUT_NORMAL;
/* --------------------------------------------------------------------
Alarm Handler
-------------------------------------------------------------------- */
static void alarm_handler(int sig)
{
if (timeout_secs == TIMEOUT_NORMAL)
{
printf("\nConnection broken!\n");
exit(1);
}
timeout_occured = 1;
signal(SIGALRM, alarm_handler);
}
/* --------------------------------------------------------------------
Set Baudrate and terminal settings
-------------------------------------------------------------------- */
void SetBaudRate(char *ttyname, unsigned long baud)
{
/* This is a quite innefficient and dirty hack to set up the
* serial port, but it is much more portable that using
* stty or ioctl */
char command[80];
sprintf(command, STTY_COMMAND, baud, ttyname);
system(command);
}
/* -------------------------------------------------------------------
Read a character from the tty
-------------------------------------------------------------------- */
static char read_char(void)
{
char ch;
read(ttyfd, &ch, 1);
return ch;
}
/* -------------------------------------------------------------------
Write a character to the tty
-------------------------------------------------------------------- */
static void write_char(char c)
{
char ch = c;
write(ttyfd, &ch, 1);
}
/* -------------------------------------------------------------------
Update CRC16 (Bisync) checksum
-------------------------------------------------------------------- */
WORD UpdateCRC16(WORD CRC, BYTE data)
{
WORD i, temp_crc, polynomial = 0xa001;
temp_crc = CRC;
temp_crc ^= data;
for (i=0; i<8; i++)
temp_crc = (temp_crc >> 1) ^ ((temp_crc & 1) ? polynomial : 0);
return temp_crc;
}
/* --------------------------------------------------------------------
Get RS232 byte, update CRC and return status
-------------------------------------------------------------------- */
int GetByte(WORD port, BYTE *value, WORD *Checksum)
{
alarm(timeout_secs);
*value = read_char();
alarm(0);
if (timeout_occured)
{
timeout_occured = 0;
return TIMEOUT;
}
/* '0x10' CRC trick, receive it twice */
if( ((*value)==0x10) && (Checksum!=NULL) ) {
read_char();
}
/* update & return checksum */
if(Checksum)
*Checksum = UpdateCRC16(*Checksum, *value);
#ifdef DEBUG_PORT
printf("r%X ", *value);
#endif
return 0;
}
/* --------------------------------------------------------------------
Send RS232 byte / update CRC
-------------------------------------------------------------------- */
WORD SendByte(WORD port, BYTE value, WORD Checksum)
{
/* now output our byte */
write_char(value);
/* '0x10' CRC trick! got to send it twice */
if( (Checksum!=0) && (value == 0x10) ) {
write_char(value);
}
#ifdef DEBUG_PORT
printf("s%X ", value);
#endif
/* update & return checksum */
return (UpdateCRC16(Checksum, value));
}
/* --------------------------------------------------------------------
Send packet to server, return status
-------------------------------------------------------------------- */
int SendPacket(FILERCOM *pPacket, int function, WORD count, WORD size, BYTE *pData)
{
WORD f, port, Checksum = 0;
BYTE Signature[] = { 0x16, 0x16, 0x16, 0x10, 0x02 }; /* packet signature */
if(size > PACKET_DATA_SIZE) return PACKET_TOO_LARGE;
port = pPacket->Port;
#ifdef DEBUG_FILER
printf("\n\nSENDING PACKET# : 0x%X\n", count);
printf("SENDING function: 0x%X\n", function);
#endif
/* send signature */
for(f=0;f<5;f++) {
SendByte(port, Signature[f], 0); /* no CRC yet */
}
/* send SOH (start of header) */
Checksum = SendByte(port, SOH, Checksum); /* CRC starts here */
/* send function (command request) */
Checksum = SendByte(port, function, Checksum);
/* send packet count */
Checksum = SendByte(port, count, Checksum);
/* send DM (data marker) */
Checksum = SendByte(port, 0x01, Checksum);
Checksum = SendByte(port, 0x02, Checksum);
/* process function request */
switch(function) {
case GET_DIR:
case CONNECT_SERVER:
case DISCONNECT_SERVER:
case INIT_GET:
break; /* nothing else to say */
case MAKE_DIR:
case DEL_DIR:
case DEL_FILE:
case SEND_PATH:
case SEND_FILENAME:
case GET_FILENAME:
case ASK_DIR:
/* send path/filename size LO, HI */
Checksum = SendByte(port, size & 0xff, Checksum);
Checksum = SendByte(port, size >>0x08, Checksum);
/* send path/filename */
for(f=0;f<size;f++)
Checksum = SendByte(port, pData[f], Checksum);
/* send Data End Marker */
Checksum = SendByte(port, 0x00, Checksum);
Checksum = SendByte(port, 0x00, Checksum);
break;
case SEND_DATA:
/* double word size, MSB always zero */
Checksum = SendByte(port, 0x00, Checksum);
Checksum = SendByte(port, 0x00, Checksum);
Checksum = SendByte(port, size & 0xff, Checksum);
Checksum = SendByte(port, size >>0x08, Checksum);
/* send data */
for(f=0;f<size;f++)
Checksum = SendByte(port, pData[f], Checksum);
break;
case GET_DATA:
/* double word size, MSB always zero */
Checksum = SendByte(port, 0x00, Checksum);
Checksum = SendByte(port, 0x00, Checksum);
Checksum = SendByte(port, size & 0xff, Checksum);
Checksum = SendByte(port, size >>0x08, Checksum);
break;
case DATA_END:
Checksum = SendByte(port, 0x00, Checksum);
break;
default:
return INVALID_FUNCTION;
}
/* send CRCM (CRC Marker) */
SendByte(port, 0x10, 0); /* No CRC on this one (tricky!) */
Checksum = SendByte(port, 0x03, Checksum);
/* Finally send Checksum LO, HI */
SendByte(port, (Checksum & 0xff), 0);
SendByte(port, (Checksum >> 8), 0);
return PACKET_SEND; /* everything O.K. */
}
/* --------------------------------------------------------------------
Get packet from server
-------------------------------------------------------------------- */
int GetPacket(FILERCOM *pPacket)
{
int c=0, f;
BYTE data = 0, crchi, crclo, sizehi, sizelo;
WORD port, Checksum = 0;
BYTE Signature[] = { 0x16, 0x16, 0x16, 0x10, 0x02 }; /* packet signature */
if(!pPacket) return SERVER_CLOSED;
port = pPacket->Port;
/* wait for signature till timeout */
for(;;) {
if(GetByte(port, &data, NULL)==TIMEOUT) return TIMEOUT;
if(data!=Signature[c++]) c=0;
if(c==5) break;
}
/* get SOH */
if(GetByte(port, &data, &Checksum)==TIMEOUT) return TIMEOUT;
if(data != SOH) return BAD_PACKET;
/* get function */
if(GetByte(port, &data, &Checksum)==TIMEOUT) return TIMEOUT;
pPacket->Function = data;
/* read_char(); */
/* get packet count */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -