home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / stefanb_src / private_projects / fax / receivefax2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-06  |  5.6 KB  |  258 lines

  1. #include "serio.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <clib/dos_protos.h>
  6.  
  7. static struct ReadArgs *rda;
  8. static struct SerialStream *ss;
  9. static char Template[]="DEVICE/K,UNIT/K/N,BAUD/K/N,FILE/K/A";
  10. static struct {
  11.                char *device;
  12.                long *unit;
  13.                long *baud;
  14.                char *file;
  15.               } def={"serial.device",NULL,NULL,NULL};
  16. #define BUFLEN 1024
  17. static UBYTE buffer[BUFLEN];
  18. static ULONG GlobalReturnCode;
  19. static BOOL notendofsession;
  20.  
  21. /* Read one reply line from modem */
  22. static void ReadLine(void *buf)
  23. {
  24.  char c='\0',*cp=buf;
  25.  
  26.  /* Read until EOL is reached */
  27.  while (c!='\n')
  28.   {
  29.    if (ReadSerialSynch(ss,&c,1)==0) break;
  30.    *cp++=c;
  31.   }
  32.  
  33.  /* Terminate string */
  34.  *cp='\0';
  35. }
  36.  
  37. /* Read and analyse modem reply */
  38. /* Possible normal replies */
  39. #define REPLY_OK          0
  40. #define REPLY_CONNECT     1
  41. #define REPLY_NO_CARRIER  3
  42. #define REPLY_ERROR       4
  43. /* Possible FAX Class II replies */
  44. #define REPLY_FHNG        10
  45.  
  46. static ULONG ReadModemReply(void)
  47. {
  48.  ULONG rc;
  49.  
  50.  while (TRUE)
  51.   {
  52.    /* Read one line */
  53.    ReadLine(buffer);
  54.    printf("%s",buffer);
  55.  
  56.    /* Skip empty lines */
  57.    if (strlen(buffer)==2) continue;
  58.  
  59.    /* Check for normal replies */
  60.    if (!strncmp(buffer,"OK",2))
  61.     {
  62.      rc=REPLY_OK;
  63.      break;
  64.     }
  65.    if (!strncmp(buffer,"CONNECT",7))
  66.     {
  67.      rc=REPLY_CONNECT;
  68.      break;
  69.     }
  70.    if (!strncmp(buffer,"NO CARRIER",10))
  71.     {
  72.      rc=REPLY_NO_CARRIER;
  73.      break;
  74.     }
  75.    if (!strncmp(buffer,"ERROR",5))
  76.     {
  77.      rc=REPLY_ERROR;
  78.      break;
  79.     }
  80.  
  81.    /* Check for FAX Class II responses */
  82.    if (!strncmp(buffer,"+FHNG:",6))
  83.     {
  84.      rc=REPLY_FHNG;
  85.      GlobalReturnCode=atol(buffer+6);
  86.      break;
  87.     }
  88.    if (!strncmp(buffer,"+FET:2",6)) /* 2 == End of Document */
  89.     notendofsession=FALSE;
  90.  
  91.    /* Everything else is skipped */
  92.   }
  93.  
  94.  return(rc);
  95. }
  96.  
  97. /* Receive a FAX page */
  98. static void ReceiveFAXPage(char *filename)
  99. {
  100.  FILE *fh;
  101.  
  102.  /* Open file */
  103.  if (fh=fopen(filename,"w"))
  104.   {
  105.    BOOL notendofpage=TRUE;
  106.  
  107.    /* Flush any characters */
  108.    ClearSerial(ss);
  109.  
  110.    /* Send DC2 to start phase C data stream */
  111.    WriteSerialSynch(ss,"\x12",1);
  112.  
  113.    /* Phase C data receive loop */
  114.    while (notendofpage)
  115.     {
  116.      BOOL pdle=FALSE; /* No pending DLE */
  117.  
  118.      /* Get number of bytes in buffer */
  119.      QuerySerial(ss);
  120.  
  121.      /* Any bytes to read? */
  122.      if (ss->ss_Unread>0)
  123.       {
  124.        /* Yes, get them and process them */
  125.        LONG len=(ss->ss_Unread>BUFLEN)?BUFLEN:ss->ss_Unread;
  126.        UBYTE *cp=buffer;
  127.  
  128.        /* Read bytes into buffer */
  129.        if (ReadSerialSynch(ss,buffer,len)!=len) break;
  130.  
  131.        while (len--)
  132.         {
  133.          /* DLE character pending? */
  134.          if (pdle)
  135.           {
  136.            /* Yes. Analyse control code */
  137.            switch(*cp)
  138.             {
  139.              case '\x03':notendofpage=FALSE; /* DLE ETX -> End of page */
  140.                          len=0;
  141.                          break;
  142.              case '\x10':fputc('\x10',fh);   /* DLE DLE -> DLE */
  143.                          break;
  144.             }
  145.            pdle=FALSE; /* DLE handled */
  146.           }
  147.          else
  148.           /* No. Normal character */
  149.           if (*cp!='\x10')
  150.            fputc(*cp,fh); /* Normal character found */
  151.           else
  152.            pdle=TRUE;     /* DLE found */
  153.  
  154.          /* Next character */
  155.          cp++;
  156.         }
  157.       }
  158.      else
  159.       /* No, carrier lost? */
  160.       if (ss->ss_Status&0x0020) notendofpage=FALSE; /* Yep! */
  161.       else Delay(5);                                /* No. Wait a while */
  162.     }
  163.  
  164.    /* Close file */
  165.    fclose(fh);
  166.   }
  167.  else printf("Couldn't open '%s'!\n",filename);
  168. }
  169.  
  170. /* FAX session main loop */
  171. static void DoFAXSession(char *basename)
  172. {
  173.  ULONG page=0;
  174.  char *filename;
  175.  
  176.  /* Get memory for file name */
  177.  if (filename=malloc(strlen(basename)+9))
  178.   {
  179.    /* Repeat until session end */
  180.    notendofsession=TRUE;
  181.    while(notendofsession)
  182.     {
  183.      /* Signal modem: "Ready to receive phase C data!" */
  184.      WriteSerialSynch(ss,"AT+FDR\r",7);
  185.  
  186.      /* Got a CONNECT? */
  187.      switch(ReadModemReply())
  188.       {
  189.        case REPLY_CONNECT:    /* Yes. Receive next page */
  190.                               sprintf(filename,"%s.g3.%04d",basename,++page);
  191.                               ReceiveFAXPage(filename);
  192.                               break;
  193.        case REPLY_NO_CARRIER: /* No. Something has gone wrong */
  194.        case REPLY_ERROR:
  195.        case REPLY_FHNG:       notendofsession=FALSE;
  196.                               break;
  197.       }
  198.     }
  199.  
  200.    /* Free memory */
  201.    free(filename);
  202.   }
  203.  else puts("Not enough memory!");
  204.  
  205.  /* Signal modem: "End of transmission" */
  206.  WriteSerialSynch(ss,"AT+FET=2\r",9);
  207.  
  208.  /* Get hangup code */
  209.  ReadModemReply();
  210.  printf("Received %d page(s)\n",page);
  211. }
  212.  
  213. /* CTRL-C shut down routine */
  214. static int Shutdown(void)
  215. {
  216.  return(0);
  217. }
  218.  
  219. int main(int argc, char *argv[])
  220. {
  221.  int (*oldbreak)();
  222.  ULONG Unit,Baud;
  223.  
  224.  /* Read command line parameters */
  225.  if (!(rda=ReadArgs(Template,(LONG *) &def,NULL)))
  226.   {
  227.    PrintFault(IoErr(),argv[0]);
  228.    exit(20);
  229.   }
  230.  Unit=(def.unit)?(*def.unit):0;
  231.  Baud=(def.baud)?(*def.baud):19200;
  232.  
  233.  /* Install CTRL-C shut down routine */
  234.  GlobalReturnCode=20;
  235.  oldbreak=onbreak(Shutdown);
  236.  printf("'%s' %ld (%ldbps) file '%s'\n",def.device,Unit,Baud,def.file);
  237.  
  238.  if (ss=CreateSerialStream(def.device,Unit,
  239.                            SERF_SHARED|SERF_7WIRE|SERF_RAD_BOOGIE))
  240.   {
  241.    if (SetSerialParamsTags(ss,SIO_Baud,Baud,TAG_DONE))
  242.     {
  243.      if (ReadModemReply()==REPLY_OK) DoFAXSession(def.file);
  244.     }
  245.    else puts("Couldn't set parameters!");
  246.  
  247.    DeleteSerialStream(ss);
  248.   }
  249.  else puts("Couldn't open stream!");
  250.  
  251.  /* Free command line parameters */
  252.  FreeArgs(rda);
  253.  
  254.  /* Leave program */
  255.  onbreak(oldbreak);
  256.  return(GlobalReturnCode);
  257. }
  258.