⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filer.c

📁 通过串口存取HP100LX/HP200LX 掌上型电脑上的文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* --------------------------------------------------------------------
   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 + -