/*=r=*************************************************************************/ boolean cfdp_close_external_file_xfer (TRANSACTION trans) { MACHINE *machine_ptr; /*------------------------------------------------------------*/ /*----------------*/ /* Validate input */ /*----------------*/ machine_ptr = machine_list__get_this_trans (trans); if (machine_ptr == NULL) /* Given transaction is not known to us. */ return (0); else if (!machine_ptr->is_external_xfer_open) /* We can't close something that isn't open */ return (0); /*----------------------------*/ /* Input is valid, take action */ /*----------------------------*/ machine_ptr->publik.external_file_xfer = NO; machine_ptr->should_external_xfer_be_closed = YES; return (1); }
/*=r=*************************************************************************/ boolean cfdp_open_external_file_xfer (TRANSACTION trans) { MACHINE *machine_ptr; /*------------------------------------------------------------*/ /*----------------*/ /* Validate input */ /*----------------*/ machine_ptr = machine_list__get_this_trans (trans); if (machine_ptr == NULL) /* Given transaction is not known to us. */ return (0); else if ((machine_ptr->publik.role != CLASS_1_SENDER) && (machine_ptr->publik.role != CLASS_2_SENDER)) /* We can't disable Filedata output if we are not the Sender */ return (0); /*----------------------------*/ /* Input is valid, take action */ /*----------------------------*/ machine_ptr->publik.external_file_xfer = YES; machine_ptr->is_external_xfer_open = YES; return (1); }
/*=r=*************************************************************************/ boolean cfdp_set_file_checksum (TRANSACTION trans, u_int_4 checksum) { MACHINE *machine_ptr; /*------------------------------------------------------------*/ /*----------------*/ /* Validate input */ /*----------------*/ machine_ptr = machine_list__get_this_trans (trans); if (machine_ptr == NULL) /* Given transaction is not known to us. */ return (0); /*----------------------------*/ /* Input is valid, take action */ /*----------------------------*/ machine_ptr->publik.file_checksum_as_calculated = checksum; return (1); }
/*=r=************************************************************************/ boolean cfdp_give_pdu (PDU pdu) /* NOTE: The CFDP protocol requires a transaction's Inactivity-timer * to be started (or restarted) each time a PDU is received. * That action is taken here rather than in 25 different places in * all the state table modules. */ { HDR hdr; MACHINE *m; ROLE my_role; _PDU_TYPE_ pdu_type; boolean successful; /*------------------------------------------------------------*/ REPORT_VERSION_ONCE; /*------------------*/ /* Validate the pdu */ /*------------------*/ if (!pdu__is_this_pdu_acceptable (&pdu)) return (0); pdu_type = pdu__what_type (&pdu); if (pdu_type == _DONT_KNOW_) /* PDUs such as 'Keepalive' are simply ignored */ { d_msg__ ("cfdp_engine: ignored incoming PDU of unknown type.\n"); return (1); } hdr = pdu__hdr_struct_from_pdu (&pdu); my_role = pdu__receiver_role_from_pdu_hdr (hdr); /* If we are the sender of the file, there are some pdu-types that our * partner should never send (for example, EOF). If we are the receiver * of the file, there are other pdu-types that our partner should never * send (for example, Ack-EOF). */ if (!m__is_pdu_sane (pdu_type, my_role)) return (0); /* Perhaps put out some debug messages */ if (cfdp_is_message_class_enabled (CFDP_MSG_DEBUG_PDU)) { pdu__display_raw_pdu (pdu); pdu__display_disassembled_pdu (pdu); } /* Validation was successful; assume the response will also be successful * unless/until proven otherwise. */ successful = YES; /*----------------------------------------------------------------*/ /* If an existing state machine is assigned to this transaction, */ /* pass the PDU to that state machine. */ /*----------------------------------------------------------------*/ if ((m = machine_list__get_this_trans (hdr.trans)) != NULL) { /* Conceptually, re-starting the inactivity-timer belongs in each * of the state tables, but it's done here for practical purposes * (it would be duplicated in 20+ places otherwise). */ if (!m->publik.frozen && !m->publik.suspended) m->inactivity_timer = timer__start (mib__inactivity_timeout(NULL)); m__give_pdu_to_trans (m, &pdu); } /*----------------------------------------------------------------*/ /* If the incoming PDU is a MD/FD/EOF for a Receiver, then create */ /* a new state machine and pass the PDU to that state machine. */ /*----------------------------------------------------------------*/ else if (((pdu_type == _MD_) || (pdu_type == _FD_) || (pdu_type == _EOF_)) && ((my_role == R_1) || (my_role == R_2))) { if ((m = m__start_new_receiver_machine (hdr)) != NULL) m__give_pdu_to_trans (m, &pdu); else successful = NO; } /*--------------------------------------------------------------------*/ /* If the incoming PDU is a Finished PDU for a Class 2 Sender, then */ /* create a new state machine and pass the PDU to that state machine. */ /*--------------------------------------------------------------------*/ else if ((pdu_type == _FIN_) && (my_role == S_2)) { if ((m = m__restart_old_sender_machine (hdr)) != NULL) m__give_pdu_to_trans (m, &pdu); else successful = NO; } /*----------------------------*/ /* Any other PDUs are ignored */ /*----------------------------*/ else d_msg__ ("cfdp_engine: ignored an incoming PDU (trans %s).\n\n", cfdp_trans_as_string (hdr.trans)); return (successful); }
/*=r=************************************************************************/ boolean cfdp_give_request (const char *request_string) { CFDP_FILE *fp; MACHINE *m; REQUEST request; boolean successful = YES; /*------------------------------------------------------------*/ REPORT_VERSION_ONCE; /*---------------------------------*/ /* Validate the given User Request */ /*---------------------------------*/ if (request_string == NULL) { e_msg__ ("cfdp_engine: cfdp_give_request: given a null-pointer.\n"); successful = NO; } else if (!utils__request_from_string (request_string, &request)) /* The string does not represent a valid request */ { e_msg__ ("cfdp_engine: request is invalid (%s).\n", request_string); successful = NO; } else if ((request.type == REQ_PUT) && (cfdp_are_these_ids_equal (request.info.put.dest_id, mib__get_my_id()))) /* This Put Request is invalid */ { e_msg__ ("cfdp_engine: Won't allow you to send a file to yourself!\n"); successful = NO; } /* If the User Request is an "empty" one, just ignore it */ else if (request.type == REQ_NONE) /* No action needed */ d_msg__ ("cfdp_engine: ignoring an empty User Request.\n"); /*--------------------------------------------------------- * If the User Request is a Put Request, then create a new * state machine, and pass the Put Request to that machine *---------------------------------------------------------*/ else if (request.type == REQ_PUT) { /* Optimization: If the source-file doesn't exist, catch it now */ fp = fopen_callback (request.info.put.source_file_name, "rb"); if (fp == NULL) /* The source-file doesn't exist; no point in trying to transfer it */ { e_msg__ ("cfdp_engine: can't transfer non-existent file (%s).\n", request.info.put.source_file_name); successful = NO; } else { /* It does exist; close it and let the state machine re-open it */ fclose_callback (fp); /* Start a new state machine */ if ((m = m__start_new_sender_machine (request)) != NULL) /* Fire the state table event associated with a Put Request */ m__state_table (m, RECEIVED_PUT_REQUEST, NULL, &request); else successful = NO; } } /*------------------------------------------------------------------ * If the User Request applies to *all* transactions, then pass it * to all active state machines *------------------------------------------------------------------*/ else if (request.type == REQ_REPORT) /* Report all active transactions */ m__give_request_to_all_trans (request.type); else if (request.type == REQ_FREEZE) /* Freeze all active transactions, and any future ones too */ { m__give_request_to_all_trans (request.type); misc__freeze_all_partners (); } else if (request.type == REQ_THAW) /* Thaw all active transactions, and any future ones too */ { m__give_request_to_all_trans (request.type); misc__thaw_all_partners (); } else if (request.type == REQ_ABANDON_ALL_TRANSACTIONS) m__give_request_to_all_trans (REQ_ABANDON); else if (request.type == REQ_CANCEL_ALL_TRANSACTIONS) m__give_request_to_all_trans (REQ_CANCEL); else if (request.type == REQ_SUSPEND_ALL_TRANSACTIONS) m__give_request_to_all_trans (REQ_SUSPEND); else if (request.type == REQ_RESUME_ALL_TRANSACTIONS) m__give_request_to_all_trans (REQ_RESUME); /*----------------------------------------------------------------- * If the User Request applies to one transaction, then attempt to * find an active state machine assigned to that transaction, and * pass the Request to that state machine. *-----------------------------------------------------------------*/ else if ((request.type == REQ_ABANDON) || (request.type == REQ_CANCEL) || (request.type == REQ_SUSPEND) || (request.type == REQ_RESUME)) { if ((m = machine_list__get_this_trans (request.info.trans)) != NULL) /* Success (a machine is assigned to this transaction) */ m__give_request_to_one_trans (m, request.type); else /* No state machine assigned */ { e_msg__ ("cfdp_engine: ignoring User-Request that references " "unknown transaction (%s).\n", cfdp_trans_as_string (request.info.trans)); successful = NO; } } else { w_msg__ ("cfdp_engine: ignoring unrecognized User-Request (%s).\n", request_string); successful = NO; } return (successful); }