Exemple #1
0
/*=r=*************************************************************************/
static void m__release_a_file_data_pdu (MACHINE *m, FD *fd)
     /* WHAT IT DOES:  Outputs a Filedata PDU */
{
  TRANS_STATUS      *mp = &(m->publik);   /* useful shorthand */
  /*------------------------------------------------------------*/

  /*----------------*/
  /* Output the PDU */
  /*----------------*/

  aaa__send_one_file_data_pdu (m, fd);

  /*----------------------------------------------------*/
  /* Perform actions required after the PDU is released */
  /*----------------------------------------------------*/

  /* Update the list of data to be sent (bookkeeping) */
  nak__data_sent (&(m->nak), fd->offset, fd->offset + fd->buffer_length);
  
  /* If the entire file has been sent, build and queue an EOF PDU */
  if (nak__how_many_filedata_gaps (&(m->nak)) == 0)
    {
      m->eof = aaa__build_eof (mp->condition_code,
                               mp->file_checksum_as_calculated,
                               mp->md.file_size);
      m->is_outgoing_eof_buffered = YES;
    }
}
Exemple #2
0
/*=r=************************************************************************/
char *nak__list_as_string (NAK *nak_ptr)
   {
#define LONGEST_STRING 256
#define LONGEST_SUBSTRING 32
     boolean         out_of_room = NO;
     NODE           *p;
     static char     string [LONGEST_STRING];
     char            substring [LONGEST_SUBSTRING];
   /*------------------------------------------------------------*/

     /* Include the scope of the Nak */
     sprintf (string, "(%lu-%lu)", nak_ptr->start_of_scope, 
              nak_ptr->end_of_scope);

     /* Include whether or not Metadata is missing */
     if (nak_ptr->is_metadata_missing)
       APPEND (string, " Metadata");

     /* Include as many File-data gaps as will fit in the string */
     if (nak_ptr->head != NULL)
       for (p=nak_ptr->head; p!=NULL; p=p->next)
         {
           if (!out_of_room)
             {
               if (strlen(string) + LONGEST_SUBSTRING + 64 >= LONGEST_STRING)
                 /* Careful.  We are in danger of writing past the end of the
                  * allotted memory for 'string' (i.e. we are out of room).
                  * We'll have to skip some gaps.
                  * Hopefully, the user understands that "..." indicates
                  * that there are more gaps.
                  */
                 {
                   out_of_room = YES;
                   APPEND (string, " ... ");
                 }
               else
                 /* The normal case; add this gap to the string */
                 {
                   sprintf (substring, " %lu-%lu", p->begin, p->end);
                   APPEND (string, substring);
                 }
             }
           else
             /* We already ran out of room; ignore all but the last gap */
             {
               if (p->next == NULL)
                 /* This is the last gap */
                 {
                   sprintf (substring, " %lu-%lu", p->begin, p->end);
                   APPEND (string, substring);
                 }
             }
         }

     /* Show how many gaps there are */
     sprintf (substring, " (%lu total gaps)\n", 
              nak__how_many_filedata_gaps (nak_ptr));
     APPEND (string, substring);
     return (string);
   }
Exemple #3
0
/*=r=************************************************************************/
void s1__state_table (MACHINE *m, int event,
                      PDU_AS_STRUCT *pdu_ptr, REQUEST *req_ptr)
     /* NOTE:  Why is there no mention of 'state' in this routine?
      *   Although the state tables originally used two states for the
      *   Class 1 Sender (as published in a CCSDS Green Book for CFDP),
      *   the logic has since been rearranged so that only one state
      *   is necessary.
      */
{
  static FD          fd;
  TRANS_STATUS      *mp = &(m->publik);   /* useful shorthand */
  /*------------------------------------------------------------*/
  
  /* Possibly display some debug info */
  if (cfdp_is_message_class_enabled (CFDP_MSG_STATE_ALL))
    aaa__display_state_and_event ("S1", m->publik.state, event);


  /*-----------------------*/
  /* Respond to each Event */
  /*-----------------------*/



  if (event == THROTTLE_OUTGOING_FILE_DIR_PDU)
    /* Release, at most, one outgoing File Directive PDU */
    {
      if (mp->frozen || mp->suspended)
        /* We can't release any PDUs while frozen or suspended */
        ;

      else if (m->is_outgoing_md_buffered)
        /* We're not frozen or suspended, so we can release any PDU.
         * A Metadata is ready.  Do we have the "green light"?
         */
        {
          if (pdu_output__ready (FILE_DIR_PDU, mp->trans, m->hdr.dest_id))
            /* Light is green. Send it. */
            m__release_a_metadata_pdu (m);
        }

      else if (m->is_outgoing_eof_buffered)
        /* We're not frozen or suspended, so we can release any PDU.
         * An EOF is ready.  Do we have the "green light"?
         */
        {
          if (pdu_output__ready (FILE_DIR_PDU, mp->trans, m->hdr.dest_id))
            /* Light is green. Send it. */
            m__release_an_eof_pdu (m);
        }

    }



  else if (event == THROTTLE_OUTGOING_FILE_DATA_PDU)
    /* Release, at most, one outgoing Filedata PDU. */
    {
      if (mp->frozen || mp->suspended)
        /* We can't release Filedata PDUs while frozen or suspended */
        ;

      else if (nak__how_many_filedata_gaps (&(m->nak)) > 0)
        /* There is File Data ready.  Do we have the "green light?" */
        {
          if (pdu_output__ready (FILE_DATA_PDU, mp->trans, m->hdr.dest_id))
            /* Light is green. Send it. */
            m__release_a_file_data_pdu (m, &fd);
        }
    }



  else if (event == RECEIVED_PUT_REQUEST)
    /* Received a Put Request */
    {
      /* Generate a Metadata pdu */
      aaa__build_metadata_from_put_req (*req_ptr, &m->hdr, &mp->md);

      /* Store some Header info for public viewing */
      mp->trans = m->hdr.trans;
      mp->partner_id = req_ptr->info.put.dest_id;

      /* 'Indication' callback allows engine user to respond to events */
      indication__ (IND_TRANSACTION, &(m->publik));
      indication__ (IND_MACHINE_ALLOCATED, &(m->publik));
      
      /* Queue the Metadata PDU for output */
      m->is_outgoing_md_buffered = YES;
    }



  else if (event == RECEIVED_SUSPEND_REQUEST)
    /* A Suspend Request was received; suspend */
    aaa__notice_of_suspension (m);



  else if (event == RECEIVED_RESUME_REQUEST)
    /* A Resume Request was received; resume */
    {
      /* 'Indication' callback allows engine user to respond to events */
      indication__ (IND_RESUMED, &(m->publik));
      mp->suspended = NO;
    }



  else if (event == RECEIVED_CANCEL_REQUEST)
    /* A Cancel Request was received; cancel the transaction */
    {
      mp->cancelled = YES;
      mp->condition_code = CANCEL_REQUEST_RECEIVED;
      m__ask_partner_to_cancel (m);
    }


  
  else if (event == RECEIVED_ABANDON_REQUEST)
    /* Abandon this transaction */
    aaa__abandon_this_transaction (m);



  else if (event == RECEIVED_REPORT_REQUEST)
    /* A Report Request was received; issue a Report */
    indication__ (IND_REPORT, &(m->publik));


  
  else if (event == RECEIVED_FREEZE_REQUEST)
    /* A "Freeze" was received, so Freeze */
    mp->frozen = YES;


  
  else if (event == RECEIVED_THAW_REQUEST)
    /* A "Thaw" was received, so Thaw */
    mp->frozen = NO;



  else if (event == EXTERNAL_FILE_TRANSFER_COMPLETED)
    /* This event was added in May 2007 to support high-speed (external)
     * file transfer by the engine user.  When this event fires, we know
     * that the engine user has completed sending the first round of
     * Filedata PDUs.  Therefore, we can send the EOF PDU.
     */
    {
      m->eof = aaa__build_eof (mp->condition_code, 
                               mp->file_checksum_as_calculated,
                               mp->md.file_size);
      m->is_outgoing_eof_buffered = YES;
      /* Clear the flags related to external xfer */
      m->is_external_xfer_open = NO;
      m->should_external_xfer_be_closed = NO;
    }



  else 
    /* The above events are the only ones that should occur.  If some
     * other event occurs, ignore it (but warn the user).
     */
    w_msg__ ("cfdp_engine: ignored event '%s' for trans '%s' <S1>.\n",
             event__event_as_string(event),
             cfdp_trans_as_string (mp->trans));
}