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

📄 tftp.c

📁 windows mobile 5 下的底层驱动包
💻 C
📖 第 1 页 / 共 2 页
字号:
							TFtpLinks[iLinkSlot].DestAddr.wPort = wSrcPort;

						// Copy the data out of the temporary buffer
						TFtpLinks[iLinkSlot].cwMsgLen = cwMsgLen;
						TFtpLinks[iLinkSlot].wBlockNumber++;
						memcpy( TFtpLinks[iLinkSlot].Buffer, pwMsg, cwMsgLen );
						// Flip the state back to BUSY so that TFtpRead() can succeed.
						TFtpLinks[iLinkSlot].State = TFTP_STATE_XFER_BUSY;
						if (TFtpLinks[iLinkSlot].pfCallBack != NULL)
							TFtpdCallBack( iLinkSlot, TFTPD_WRITE );
						// Check to see if this is the last packet, if so we close
						if (cwMsgLen != MAX_TFTP_DATA) {
							TFtpLinks[iLinkSlot].State = TFTP_STATE_IDLE;
							nNumTFtpLinksInUse--;
						}
					} else if (ntohs(*(pwMsg+1)) == TFtpLinks[iLinkSlot].wBlockNumber) {
						// desktop lost the ACK for previous write, ack it again
						UINT16 ack[2] = { htons(4), htons(TFtpLinks[iLinkSlot].wBlockNumber) };
						BYTE buf[UDP_DATA_FRAME_OFFSET+sizeof(ack)];
						EdbgOutputDebugString ("TFTP: Desktop losing ACK, block number = %d, Ack again\r\n", 
							TFtpLinks[iLinkSlot].wBlockNumber);
						EbootSendUDP(buf, &(TFtpLinks[iLinkSlot].DestAddr), &(TFtpLinks[iLinkSlot].SrcAddr),
							(LPBYTE) ack, sizeof (ack));
					}
				}
			}
			else {
				// See if this is the acknowledge packet we've been waiting for
				if (ntohs(*pwMsg) == 4 && ntohs(*(pwMsg+1)) == TFtpLinks[iLinkSlot].wBlockNumber) {
					// Flip the state back to BUSY so that TFtpWrite() can succeed.
					TFtpLinks[iLinkSlot].State = TFTP_STATE_XFER_BUSY;
					if (TFtpLinks[iLinkSlot].pfCallBack != NULL)
						TFtpdCallBack( iLinkSlot, TFTPD_READ );
					// Check to see if this is the last packet, if so we close
					if (TFtpLinks[iLinkSlot].cwMsgLen != MAX_TFTP_DATA)
						TFtpLinks[iLinkSlot].State = TFTP_STATE_CLOSE;
				}
			}
			break;
		case TFTP_STATE_CLOSE:
			// This was an O2HLink (Write), and we're just waiting for that last data packet to be acknowledged.
			//	If it has been, we'll close the link and go back to IDLE
			if (ntohs(*pwMsg) == 4 && ntohs(*(pwMsg+1)) == TFtpLinks[iLinkSlot].wBlockNumber) {
				TFtpLinks[iLinkSlot].State = TFTP_STATE_IDLE;
				nNumTFtpLinksInUse--;
				EdbgOutputDebugString( "TFtpStateMachine::TFTP_STATE_CLOSE Link Deleted\r\n" );
			}
			break;
	} // switch(State)

}



// This routine will open a new link to the host.  The DataDir parameter specifies if this is going to
//	be a request to read (H2OLink) or write (O2HLink) data.	 The routine will return a non-zero link handle,
//	which is actually the iLinkSlot+1, if there is a link slot available.  Otherwise, it will return 0.
UINT16 TFtpOpen( EDBG_ADDR *pHostAddr, EDBG_ADDR *pMyAddr, char *pszFileName, TFtpLinkDir DataDir ) {

	int i, iLinkSlot = (MAX_TFTP_LINKS - 1);

	if (nNumTFtpLinksInUse >= MAX_TFTP_LINKS)
		return 0;

    if ((strlen(pszFileName) + 1) > MAX_TFTP_FILENAME) return 0;

	// Find a link that isn't currently in use
	for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
		if (TFtpLinks[i].State == TFTP_STATE_IDLE) {
			iLinkSlot = i;
			break;
		}
	}

	TFtpLinks[iLinkSlot].DataDir = DataDir;
	TFtpLinks[iLinkSlot].State = (DataDir == H2OLink) ? TFTP_STATE_XFER_WAIT : TFTP_STATE_OPEN;
	TFtpLinks[iLinkSlot].pfCallBack = NULL;
	strcpy( TFtpLinks[iLinkSlot].szFileName, pszFileName );
	TFtpLinks[iLinkSlot].wBlockNumber = 0;

	// Put in Read Request or Write Request as appropriate
	*((UINT16*)(TFtpLinks[iLinkSlot].Buffer)) = htons((DataDir == H2OLink) ? 1 : 2);
	TFtpLinks[iLinkSlot].cwMsgLen = 2;
	// Put in the file name
	strcpy( TFtpLinks[iLinkSlot].Buffer + 2, pszFileName );
	TFtpLinks[iLinkSlot].cwMsgLen += strlen( pszFileName );
	// Specify octet (binary) mode
	strcpy( TFtpLinks[iLinkSlot].Buffer + TFtpLinks[iLinkSlot].cwMsgLen, "octet" );
	TFtpLinks[iLinkSlot].cwMsgLen += 6;
	
	// Send the read/write request packet back to the host
	TFtpLinks[iLinkSlot].DestAddr = *pHostAddr;
	TFtpLinks[iLinkSlot].DestAddr.wPort = wHostWellKnownServerPort;
	TFtpLinks[iLinkSlot].SrcAddr = *pMyAddr;
	TFtpLinks[iLinkSlot].SrcAddr.wPort = GenerateSrcPort();
	EbootSendUDP(TFTPFrameBuffer, &(TFtpLinks[iLinkSlot].DestAddr), &(TFtpLinks[iLinkSlot].SrcAddr),
                 TFtpLinks[iLinkSlot].Buffer, TFtpLinks[iLinkSlot].cwMsgLen );
	TFtpLinks[iLinkSlot].tLastTransmit = OEMEthGetSecs();
	TFtpLinks[iLinkSlot].cwRetries = 0;

	return iLinkSlot+1;

}



// This routine is called by a process that wants to read data from an existing link.
//	The routine will return TFTP_WAIT if the read failed because no new data packet has arrived.
//	A TFTP_ERROR will be returned if an error has occured and the link has been terminated
//	It will return TFTP_SUCCESS if the read succeeded.	The number of data bytes read indicates
//	whether or not the link is closing.	 If the number of data bytes is 512, then more
//	data is forthcoming.  If the number of data bytes is < 512, then this is the last
//	packet and the data link is now closed.
TFtpReturnCodes TFtpRead( UINT16 wLinkHandle, BYTE *pbData, UINT16 *cwDataLen ) {

	UINT16 iLinkSlot;

	iLinkSlot = wLinkHandle - 1;

	// For the sake of speed, I will assume that the wLinkHandle is valid

	if (TFtpLinks[iLinkSlot].State == TFTP_STATE_ERROR) {
        EdbgOutputDebugString("!TftpReturnCodes, STATE_ERROR\n");
        
		TFtpLinks[iLinkSlot].State = TFTP_STATE_IDLE;
		nNumTFtpLinksInUse--;
		return TFTP_ERROR;
	}
	else if (TFtpLinks[iLinkSlot].State == TFTP_STATE_XFER_BUSY) {
		// Copy the data to the process' buffer
		*cwDataLen = TFtpLinks[iLinkSlot].cwMsgLen - 4;
		memcpy( TFtpLinks[iLinkSlot].Buffer + 4, pbData, *cwDataLen );

		// Send an acknowlege packet back to the host
		*((UINT16 *)TFtpLinks[iLinkSlot].Buffer) = htons(4);
		*((UINT16 *)TFtpLinks[iLinkSlot].Buffer + 1) = htons(TFtpLinks[iLinkSlot].wBlockNumber);
		TFtpLinks[iLinkSlot].cwMsgLen = 4;
		EbootSendUDP(TFTPFrameBuffer, &(TFtpLinks[iLinkSlot].DestAddr), &(TFtpLinks[iLinkSlot].SrcAddr),
                     TFtpLinks[iLinkSlot].Buffer, TFtpLinks[iLinkSlot].cwMsgLen );
		TFtpLinks[iLinkSlot].tLastTransmit = OEMEthGetSecs();
		TFtpLinks[iLinkSlot].cwRetries = 0;

		// I need to check to see if this is the last packet in the stream.	 If so, I
		//	need to close the link
		if (TFtpLinks[iLinkSlot].cwMsgLen != MAX_TFTP_DATA) {
			TFtpLinks[iLinkSlot].State = TFTP_STATE_IDLE;
			nNumTFtpLinksInUse--;
		}
		// Otherwise, wait for the next data packet
		else
			TFtpLinks[iLinkSlot].State = TFTP_STATE_XFER_WAIT;
		return TFTP_SUCCESS;
	}

	return TFTP_WAIT;
}



// This routine is called by a process that wants to write data to an existing link.
//	The routine will return TFTP_WAIT if the write failed because the last data packet has not been 
//	acknowledged.  A TFTP_ERROR will be returned if an error has occured and the link has been 
//	terminated.	 It will return TFTP_SUCCESS if the write succeeded.  The number of data bytes written 
//	indicates whether or not the link is closing.  If the number of data bytes is 512, then more
//	data is forthcoming.  If the number of data bytes is < 512, then this is the last
//	packet and the data link is now closed.
TFtpReturnCodes TFtpWrite( UINT16 wLinkHandle, BYTE *pbData, UINT16 cwDataLen ) {

	UINT16 iLinkSlot;

	iLinkSlot = wLinkHandle - 1;

	// For the sake of speed, I will assume that the wLinkHandle is valid

	if (TFtpLinks[iLinkSlot].State == TFTP_STATE_ERROR) {
        EdbgOutputDebugString("!!!! TFTP Errror\n");
		TFtpLinks[iLinkSlot].State = TFTP_STATE_IDLE;
		nNumTFtpLinksInUse--;
		return TFTP_ERROR;
	}
	else if (TFtpLinks[iLinkSlot].State == TFTP_STATE_XFER_BUSY) {
		// Send a new data packet to the host
		*((UINT16 *)TFtpLinks[iLinkSlot].Buffer) = htons(3);
		TFtpLinks[iLinkSlot].wBlockNumber++;
		*((UINT16 *)TFtpLinks[iLinkSlot].Buffer + 1) = htons(TFtpLinks[iLinkSlot].wBlockNumber);
		memcpy( TFtpLinks[iLinkSlot].Buffer + 4, pbData, cwDataLen );
		TFtpLinks[iLinkSlot].cwMsgLen = cwDataLen + 4;

		EbootSendUDP(TFTPFrameBuffer, &(TFtpLinks[iLinkSlot].DestAddr), &(TFtpLinks[iLinkSlot].SrcAddr),
                     TFtpLinks[iLinkSlot].Buffer, TFtpLinks[iLinkSlot].cwMsgLen );
		TFtpLinks[iLinkSlot].tLastTransmit = OEMEthGetSecs();
		TFtpLinks[iLinkSlot].cwRetries = 0;

		// I need to check to see if this is the last packet in the stream.	 If so, I
		//	need go to TFTP_STATE_CLOSE so that we can wait for the last acknowledge packet.
		if (TFtpLinks[iLinkSlot].cwMsgLen != MAX_TFTP_DATA)
			TFtpLinks[iLinkSlot].State = TFTP_STATE_CLOSE;
		// Otherwise, wait for the next acknowledge packet
		else
			TFtpLinks[iLinkSlot].State = TFTP_STATE_XFER_WAIT;

		return TFTP_SUCCESS;
	}

	return TFTP_WAIT;
}



⌨️ 快捷键说明

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