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

📄 dcpgpkt.c

📁 大量的汇编程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*                                                                    */
/*          flags = (flags & B_SENT_INITA) | B_RECV_INITA;            */
/*                                                                    */
/*    works to turn off all the bits in flags except B_SENT_INITA     */
/*    if it was already on, and then turns on flag B_RECV_INITA.      */
/*    We use statements like this to reset most of the flags at       */
/*    once, leaving one or two bits on; this in turn allows us to     */
/*    check in later states that the previous two states were the     */
/*    expected ones.                                                  */
/*                                                                    */
/*    Likewise, the following statement:                              */
/*                                                                    */
/*          state = (flags & B_SENT_INITA) ?                          */
/*                         I_INITB_SEND : I_INITA_SEND;               */
/*                                                                    */
/*    tests to see if B_SENT_INITA was already set, and return the    */
/*    "true" condition (I_INITB_SEND) otherwise return the "false"    */
/*    (I_INITA_SEND).                                                 */
/*--------------------------------------------------------------------*/


   while( state != I_COMPLETE )
   {
      printmsg(4, "gopenpk: I State = %2d, flag = 0x%02x",
               (int) state, (int) flags);

      switch( state )
      {

/*--------------------------------------------------------------------*/
/*                          Receive a packet                          */
/*--------------------------------------------------------------------*/

         case I_GRPACK:
            switch (grpack(&yyy, &xxx, &len, NULL, M_gPacketTimeout ))
            {

               case INITA:
                  printmsg(5, "**got INITA");
                  state = I_INITA_RECV;
                  break;

               case INITB:
                  printmsg(5, "**got INITB");
                  state = I_INITB_RECV;
                  break;

               case INITC:
                  printmsg(5, "**got INITC");
                  state = I_INITC_RECV;
                  break;

               case DCP_EMPTY:
                  printmsg(GDEBUG, "**got EMPTY");
                  state = I_EMPTY;

                  if (bmodemflag[MODEM_CD] && !CD())
                  {
                     printmsg(0,"gopenpk: Modem carrier lost");
                     return DCP_FAILED;
                  }
                  break;

               case CLOSE:
                  printmsg(GDEBUG, "**got CLOSE");
                  gspack(CLOSE, 0, 0, 0, 0, NULL);
                  return DCP_FAILED;

               default:
                  printmsg(GDEBUG, "**got SCREW UP");
                  state = I_ERROR;
                  break;
            }

            if (bmodemflag[MODEM_CD] && !CD())
            {
               printmsg(0,"gopenpk: Modem carrier lost");
               return DCP_FAILED;
            }
            break;

/*--------------------------------------------------------------------*/
/*                         Initialize states                          */
/*--------------------------------------------------------------------*/

         case I_CALLER:
            state = I_INITA_SEND;
            break;

         case I_CALLEE:
            state = I_GRPACK;
            break;

/*--------------------------------------------------------------------*/
/*                  Process received or sent packets                  */
/*--------------------------------------------------------------------*/

         case I_INITA_RECV:
            if (yyy < (short) nwindows)
            {
               nwindows = yyy;
               rwu = nwindows - 1;
            }
            flags = (flags & B_SENT_INITA) | B_RECV_INITA;
            state = (flags & B_SENT_INITA) ? I_INITB_SEND : I_INITA_SEND;
            break;

         case I_INITA_SEND:
            gspack(INITA, 0, 0, 0, nwindows, NULL);
            flags = (flags & B_RECV_INITA) | B_SENT_INITA;
            state = I_GRPACK;
            break;

         case I_INITB_RECV:
            if ((flags & (B_RECV_INITA | B_SENT_INITA)) ==
                         (B_RECV_INITA | B_SENT_INITA))
            {
               i = (short) 8 * (2 << (yyy+1));
               if (i < (short) s_pktsize)
                  s_pktsize = i;
               flags = (flags & B_SENT_INITB) | B_RECV_INITB;
               state = (flags & B_SENT_INITB) ? I_INITC_SEND : I_INITB_SEND;
            } /* if */
            else
               state = I_RESTART;
            break;

         case I_INITB_SEND:
            gspack(INITB, 0, 0, 0, r_pktsize, NULL);
                                       /* Data segment (packet) size    */
            flags = (flags & (B_INITA | B_RECV_INITB)) | B_SENT_INITB;
            state = I_GRPACK;
            break;

         case I_INITC_RECV:
            if ((flags & (B_RECV_INITB | B_SENT_INITB)) ==
                           (B_RECV_INITB | B_SENT_INITB))
            {
               if (yyy < (short) nwindows)
               {
                  printmsg(0,"Unexpected INITC window size of %d",
                             nwindows );
                  nwindows = yyy;
                  rwu = nwindows - 1;
               }
               flags = (flags & B_SENT_INITC) | B_RECV_INITC;
               state = (flags & B_SENT_INITC) ? I_COMPLETE : I_INITC_SEND;
            }
            else
               state = I_RESTART;
            break;

         case I_INITC_SEND:
            gspack(INITC, 0, 0, 0, nwindows, NULL);
            flags = (flags & (B_INITB | B_RECV_INITC)) | B_SENT_INITC;
            state = (flags & B_RECV_INITC) ? I_COMPLETE : I_GRPACK;
            break;

/*--------------------------------------------------------------------*/
/*                            Error states                            */
/*--------------------------------------------------------------------*/

         case I_EMPTY:
            timeouts++;
            state = I_RESTART;
            break;

         case I_ERROR:
            screwups++;
            state = I_RESTART;
            break;

         case I_RESTART:
            printmsg(2,"gopenpk: Restarting initialize sequence");
            nerr++;
            flags = 0x00;
            state = I_INITA_SEND;
            break;

      } /* switch */

      if ( terminate_processing )
      {
         printmsg(0,"gopenpk: Terminated by user");
         return DCP_FAILED;
      }

      if (nerr >= M_MaxErr)
      {
         remote_stats.errors += nerr;
         nerr = 0;
         printmsg(0,
            "gopenpk: Consecutive error limit of %ld exceeded, "
                     "%ld total errors",
             (long) M_MaxErr, remote_stats.errors);
         return(DCP_FAILED);
      }
   } /* while */

/*--------------------------------------------------------------------*/
/*                    Allocate the needed buffers                     */
/*--------------------------------------------------------------------*/

   grpkt = realloc( grpkt, r_pktsize + HDRSIZE );
   checkref( grpkt );

#if !defined(BIT32ENV)
   gspkt = malloc( s_pktsize );
   checkref( gspkt );
#endif

   nerr = 0;
   lazynak = 0;


#if defined(BIT32ENV) || defined(_Windows)
   printmsg(2,"%s packets, "
              "Window size %d, "
              "Receive packet %d, "
              "Send packet %d",
            variablepacket ? "Variable" : "Fixed",
            nwindows,
            r_pktsize,
            s_pktsize );
#else
   printmsg(2,"%s packets, "
              "Window size %d, "
              "Receive packet %d, "
              "Send packet %d, "
              "Memory avail %u",
            variablepacket ? "Variable" : "Fixed",
            nwindows,
            r_pktsize,
            s_pktsize,
            memavail());
#endif

   return(DCP_OK); /* channel open */

} /*initialize*/

/*--------------------------------------------------------------------*/
/*    g f i l e p k t                                                 */
/*                                                                    */
/*    Begin a file transfer (not used by "g" protocol)                */
/*--------------------------------------------------------------------*/

short gfilepkt( void )
{

   return DCP_OK;

} /* gfilepkt */

/*--------------------------------------------------------------------*/
/*    g c l o s e p k                                                 */
/*                                                                    */
/*    Close packet machine                                            */
/*--------------------------------------------------------------------*/

short gclosepk()
{
   unsigned short i;

   for (i = 0; i < MAXTRY; i++)
   {
      gspack(CLOSE, 0, 0, 0, 0, NULL);
      if (gmachine(M_gPacketTimeout) == CLOSE)
         break;
   } /* for (i = 0; i < MAXTRY; i++) */

/*--------------------------------------------------------------------*/
/*                        Release our buffers                         */
/*--------------------------------------------------------------------*/

   free( grpkt );
   grpkt = NULL;

#if !defined(BIT32ENV)
   free( gspkt );
   gspkt = NULL;
#endif

/*--------------------------------------------------------------------*/
/*                Report the results of our adventures                */
/*--------------------------------------------------------------------*/

   gstats();

/*--------------------------------------------------------------------*/
/*                          Return to caller                          */
/*--------------------------------------------------------------------*/

   return(0);

} /*gclosepk*/

/*--------------------------------------------------------------------*/
/*    g s t a t s                                                     */
/*                                                                    */
/*    Report summary of errors for processing                         */
/*--------------------------------------------------------------------*/

static void gstats( void )
{
   remote_stats.errors += nerr;
   nerr = 0;
   if ( remote_stats.errors || badhdr )
   {
      printmsg(0,
         "%d time outs, %d port reinits, %d out of seq pkts, "
         "%d NAKs rec, %d NAKs sent",
            timeouts, reinit, outsequence, naksin, naksout);
      printmsg(0,
         "%d invalid pkt types, %d re-syncs, %d bad pkt hdrs, %d pkts resent",
            screwups, shifts, badhdr, resends);
   } /* if ( remote_stats.errors || shifts || badhdr ) */
} /* gstats */

/*--------------------------------------------------------------------*/
/*    g g e t p k t                                                   */
/*                                                                    */
/*    Gets no more than a packet's worth of data from                 */
/*    the "packet I/O state machine".  May have to                    */
/*    periodically run the packet machine to get some packets.        */
/*                                                                    */
/*    on input:   don't care                                          */
/*    on return:  data+\0 and length in len.                          */
/*                                                                    */
/*    ret(0)   if all's well                                          */
/*    ret(-1) if problems (failed)                                    */
/*--------------------------------------------------------------------*/

short ggetpkt(char *data, short *len)
{
   short   retry = M_MaxErr;
   time_t start;
#ifdef _DEBUG
   short savedebug = debuglevel;
#endif

   irec = 1;
   checkref( data );

/*--------------------------------------------------------------------*/
/*                Loop to wait for the desired packet                 */
/*--------------------------------------------------------------------*/

   time( &start );
   while (!arrived[rbl] && retry)
   {
      if (gmachine(M_gPacketTimeout) != POK)
         return(-1);

      if (!arrived[rbl] )
      {
         time_t now;
         if (time( &now ) > (start + M_gPacketTimeout) )
         {
#ifdef _DEBUG
            if ( debuglevel < 6 )
               debuglevel = 6;
#endif
            printmsg(GDEBUG,
                     "ggetpkt: Timeout %d waiting for inbound packet %d",
                     M_MaxErr - --retry, remote_stats.packets + 1);
            timeouts++;
            start = now;
         } /* if (time( now ) > (start + M_gPacketTimeout) ) */
      } /* if (!arrived[rbl] ) */
   } /* while (!arrived[rbl] && i) */

#ifdef _DEBUG
   debuglevel = savedebug;
#endif

   if (!arrived[rbl])
   {
      printmsg(0,"ggetpkt: Remote host failed to respond after %ld seconds",
               (long) M_gPacketTimeout * M_MaxErr);
      gclosepk();
      return -1;
   }

/*--------------------------------------------------------------------*/
/*                           Got a packet!                            */
/*--------------------------------------------------------------------*/

   *len = inlen[rbl];
   MEMCPY(data, inbuf[rbl], *len);

   arrived[rbl] = FALSE;      /* Buffer is now emptied               */
   rwu = nextpkt(rwu);        /* bump receive window                 */

   return(0);

} /*ggetpkt*/


/*
   g s e n d p k t

   Put at most a packet's worth of data in the packet state
   machine for transmission.
   May have to run the packet machine a few times to get
   an available output slot.

   on input: data=*data; len=length of data in data.

   return:
    0 if all's well
   -1 if problems (failed)
*/

short gsendpkt(char *data, short len)
{
   short delta;
#ifdef _DEBUG
   short savedebug = debuglevel;
#endif

   checkref( data );
   irec = 0;

/*--------------------------------------------------------------------*/
/*       WAIT FOR INPUT i.e. if we have sent SWINDOW pkts and none    */
/*       have been acked, wait for acks.  Note that we always go      */
/*       through the machine at least once to keep caught up with     */
/*       ACK's sent by remote machine.                                */
/*--------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -