/********************************************************************* * Function: TFTP_RESULT TFPTIsFileClosed(void) * * PreCondition: TFTPCloseFile() is already called. * * Input: None * * Output: TFTP_OK if file was successfully closdd * * TFTP_RETRY if file mode was Write and remote * server did not receive last packet. * Application must retry with last block. * * TFTP_TIMEOUT if all attempts were exhausted * in closing file. * * TFTP_ERROR if remote server sent an error * in response to last block. * Actual error code may be read by calling * TFTPGetError() * * TFTP_NOT_READY if file is not closed yet. * * Side Effects: None * * Overview: If file mode is Read, it simply makes that * last block is acknowledged. * If file mode is Write, it waits for server ack. * If no ack was received within specified timeout * instructs appliaction to resend last block. * It keeps track of retries and declares timeout * all attempts were exhausted. * * Note: None ********************************************************************/ TFTP_RESULT TFTPIsFileClosed(void) { if ( _tftpFlags.bits.bIsReading ) return TFTPIsGetReady(); else return TFTPIsPutReady(); }
/***************************************************************************** Function: CHAR TFTPGetUploadStatus(void) Summary: Returns the TFTP file upload status started by calling the TFTPUploadRAMFileToHost() or TFTPUploadFragmentedRAMFileToHost() functions. Description: Returns the TFTP file upload status started by calling the TFTPUploadRAMFileToHost() or TFTPUploadFragmentedRAMFileToHost() functions. Precondition: None Parameters: None Returns: A status code. Negative results are fatal errors. Positive results indicate the TFTP upload operation is still being processed. A zero result indicates successful file upload completion (TFTP API is now idle and available for further calls). Specific return values are as follows: 0 (TFTP_UPLOAD_COMPLETE): Upload completed successfully 1 (TFTP_UPLOAD_GET_DNS): Attempting to obtain DNS client module 2 (TFTP_UPLOAD_RESOLVE_HOST): Attempting to resolve TFTP hostname 3 (TFTP_UPLOAD_CONNECT): Attempting to ARP and contact the TFTP server 4 (TFTP_UPLOAD_SEND_FILENAME): Attempting to send the filename and receive acknowledgement. 5 (TFTP_UPLOAD_SEND_DATA): Attempting to send the file contents and receive acknowledgement. 6 (TFTP_UPLOAD_WAIT_FOR_CLOSURE): Attempting to send the final packet of file contents and receive acknowledgement. -1 (TFTP_UPLOAD_HOST_RESOLVE_TIMEOUT): Couldn't resolve hostname -2 (TFTP_UPLOAD_CONNECT_TIMEOUT): Couldn't finish ARP and reach server -3 (TFTP_UPLOAD_SERVER_ERROR): TFTP server returned an error (ex: access denial) or file upload failed due to a timeout (partial file may have been uploaded). Remarks: The DNS client module must be enabled to use this function. i.e. STACK_USE_DNS must be defined in TCPIPConfig.h. ***************************************************************************/ CHAR TFTPGetUploadStatus(void) { TFTP_RESULT result; IP_ADDR ipRemote; WORD w, w2; BYTE *vData; if(UDPIsOpened(_tftpSocket)== FALSE) { _tftpSocket = UDPOpenEx((DWORD)(ROM_PTR_BASE)vUploadRemoteHost, UDP_OPEN_ROM_HOST,TFTP_CLIENT_PORT, TFTP_SERVER_PORT); } switch(smUpload) { case TFTP_UPLOAD_GET_DNS: if(!DNSBeginUsage()) break; DNSResolveROM(vUploadRemoteHost, DNS_TYPE_A); smUpload = TFTP_UPLOAD_RESOLVE_HOST; break; case TFTP_UPLOAD_RESOLVE_HOST: if(!DNSIsResolved(&ipRemote)) break; DNSEndUsage(); if(ipRemote.Val == 0u) { smUpload = TFTP_UPLOAD_HOST_RESOLVE_TIMEOUT; break; } TFTPOpen(&ipRemote); smUpload = TFTP_UPLOAD_CONNECT; break; case TFTP_UPLOAD_CONNECT: switch(TFTPIsOpened()) { case TFTP_OK: TFTPOpenROMFile(vUploadFilename, TFTP_FILE_MODE_WRITE); smUpload = TFTP_UPLOAD_SEND_FILENAME; break; case TFTP_TIMEOUT: smUpload = TFTP_UPLOAD_CONNECT_TIMEOUT; break; default: break; } break; case TFTP_UPLOAD_SEND_FILENAME: result = TFTPIsFileOpened(); switch(result) { case TFTP_OK: smUpload = TFTP_UPLOAD_SEND_DATA; break; case TFTP_RETRY: TFTPOpenROMFile(vUploadFilename, TFTP_FILE_MODE_WRITE); break; case TFTP_TIMEOUT: smUpload = TFTP_UPLOAD_CONNECT_TIMEOUT; break; case TFTP_ERROR: smUpload = TFTP_UPLOAD_SERVER_ERROR; break; default: break; } if(result != TFTP_OK) break; // No break when TFTPIsFileOpened() returns TFTP_OK -- we need to immediately start sending data case TFTP_UPLOAD_SEND_DATA: switch(TFTPIsPutReady()) { case TFTP_OK: // Write blocksize bytes of data uploadChunkDescriptorForRetransmit = uploadChunkDescriptor; wUploadChunkOffsetForRetransmit = wUploadChunkOffset; vData = uploadChunkDescriptor->vDataPointer + wUploadChunkOffset; w = TFTP_BLOCK_SIZE; while(w) { w2 = uploadChunkDescriptor->wDataLength - wUploadChunkOffset; if(w2 > w) w2 = w; w -= w2; wUploadChunkOffset += w2; if(vData == NULL) { TFTPCloseFile(); smUpload = TFTP_UPLOAD_WAIT_FOR_CLOSURE; break; } while(w2--) { TFTPPut(*vData++); } if(wUploadChunkOffset == uploadChunkDescriptor->wDataLength) { uploadChunkDescriptor++; wUploadChunkOffset = 0; vData = uploadChunkDescriptor->vDataPointer; } } break; case TFTP_RETRY: uploadChunkDescriptor = uploadChunkDescriptorForRetransmit; wUploadChunkOffset = wUploadChunkOffsetForRetransmit; break; case TFTP_TIMEOUT: case TFTP_ERROR: smUpload = TFTP_UPLOAD_SERVER_ERROR; break; default: break; } break; case TFTP_UPLOAD_WAIT_FOR_CLOSURE: switch(TFTPIsFileClosed()) { case TFTP_OK: smUpload = TFTP_UPLOAD_COMPLETE; UDPClose(_tftpSocket); break; case TFTP_RETRY: uploadChunkDescriptor = uploadChunkDescriptorForRetransmit; wUploadChunkOffset = wUploadChunkOffsetForRetransmit; smUpload = TFTP_UPLOAD_SEND_DATA; break; case TFTP_TIMEOUT: case TFTP_ERROR: smUpload = TFTP_UPLOAD_SERVER_ERROR; break; default: break; } break; default: break; } return smUpload; }