Wang
Wed Jun 01 08:40:58 CDT 2005
Thank you,Huang,
Now eboot as client can communicate with tftp server.But it always
encounters errors when transporting about 30 tftp packets.
After transporting about 30 tftp packets successfully,eboot can not send ACK
packet,Host will report "Time out occured" after trying sending DATA packets
several times.
Is my tftp server not working properly? But I have tested with Windows tftp
client and works ok. And this time it is Eboot that can not send ACK signal.
I don't know why.Can you give me some suggestions?
Thanks very much.
BTW:I get tftp server from this website(
http://www.WinAgents.com). And I
sniffer network through Iris Network Traffic Analyzer.
"K. S. Huang" <ksh_AT_bsquare_DOT_com> дÈëÏûÏ¢ÐÂÎÅ:O2$DZToZFHA.2916@TK2MSFTNGP14.phx.gbl...
> The attachment is the modified version of EBoot library for tftp client
> mode.
> You may need to modify the default server IP in ebsimp.c at about line
> 358.
>
> "Wang Yeqing" <wangyeqing1982@163.com> ¼¶¼g©ó¶l¥ó·s»D:O31DjWnZFHA.2916@TK2MSFTNGP14.phx.gbl...
>> Hi,Huang,
>> I have done as you said,and I succeeded when eboot as tftp server,because
>> it
>> is very simple.
>>
>> I failed when I used eboot as client.
>> Eboot can send tftp request to host,but host failed to response.I am sure
>> host tftp server is right.Because I can get file through windows tftp
>> client.
>> I don't know why.
>> I change EbootSendBootmeAndWaitForTftp as the following:
>> BOOL EbootSendBootmeAndWaitForTftp (EDBG_ADDR *pEdbgAddr, UCHAR
>> VersionMajor, UCHAR VersionMinor,
>> char *szPlatformString, char *szDeviceName,
>> UCHAR CPUId, DWORD dwBootFlags)
>> {
>> DWORD dwCurSec = OEMEthGetSecs () - BOOTME_INTERVAL;
>> USHORT wLen, wDestPort, wSrcPort, wUDPDataLen, *pwUDPData;
>> int nRetries = 0;
>> UINT16 fTftpLinked = 0;
>>
>> EdbgOutputDebugString ("+EbootSendBootmeAndWaitForTftp\r\n");
>> while (!fTftpLinked) {
>> if ((nRetries < MAX_BOOTME_CNT) && (OEMEthGetSecs () - dwCurSec >=
>> BOOTME_INTERVAL)) {
>> nRetries ++;
>> dwCurSec += BOOTME_INTERVAL;
>> // send a bootme message
>> EbootSendBootme (pEdbgAddr, VersionMajor, VersionMinor,
>> szPlatformString, szDeviceName, CPUId, dwBootFlags);
>> }
>> // get another frame and pass it to TFTP handler
>> wLen = sizeof (gFrameBuffer);
>> /* if (OEMEthGetFrame (gFrameBuffer, &wLen)) { // frame
>> available?
>> switch (FRAMETYPE (gFrameBuffer)) {
>> case 0x0800: // IP packet
>> if (!EbootCheckUDP(pEdbgAddr, gFrameBuffer, &wDestPort,
>> &wSrcPort, &pwUDPData, &wUDPDataLen)) { // UDP?
>> // EDBG command? (should only occur if eshell asked us
>> to jump to existing image)
>> if (!EbootProcessEDBG (pEdbgAddr, &gHostAddr,
>> gFrameBuffer, pwUDPData, wUDPDataLen, &fTftpLinked, &gpCfgData)) {
>> // no, pass it to TFTP
>> EbootTFtpReceiver (pEdbgAddr, gFrameBuffer,
>> wDestPort, wSrcPort, pwUDPData, wUDPDataLen);
>> }
>> }
>> break;
>> case 0x0806: // ARP packet
>> if (EbootProcessARP (pEdbgAddr, gFrameBuffer) ==
>> PROCESS_ARP_RESPONSE) {
>> EdbgOutputDebugString( "Some other station has IP
>> Address: %s !!! Aborting.\r\n", inet_ntoa(pEdbgAddr->dwIP));
>> return FALSE;
>> }
>> break;
>> default:
>> break;
>> }
>> }*/ /////I delete all these lines,because it servers as tftp
>> server,when as a client,it only need to send a connection request.
>> EbootTFtpReceiver (pEdbgAddr, gFrameBuffer, wDestPort, wSrcPort,
>> pwUDPData, wUDPDataLen, &fTftpLinked);
>> }
>>
>> EdbgOutputDebugString ("-EbootSendBootmeAndWaitForTftp\r\n");
>> return TRUE;
>> }
>>
>>
>>
>> And change EbootTFtpReceiver as following:
>>
>> WORD EbootTFtpReceiver( EDBG_ADDR *pMyAddr, BYTE *pFrameBuffer, UINT16
>> wDestPort, UINT16 wSrcPort, UINT16 *pwUDPData, UINT16 cwUDPDataLength,
>> UINT16 *fTftpLinked ) {
>>
>> int i;
>> UINT16 iLinkSlot = MAX_TFTP_LINKS;
>>
>> EDBG_ADDR HostAddr;
>> HostAddr.wMAC[0] = 0x4000;
>> HostAddr.wMAC[1] = 0x51B8;
>> HostAddr.wMAC[2] = 0xE5A7;
>> HostAddr.dwIP = 0x03BEA8C0; //192.168.190.3
>> HostAddr.wPort = 0x45; //69
>>
>> /*char szFileName[10];
>> strcpy(pszFileName, "nk.bin");*/
>>
>> // Check to see if this is for a link that is currently in use
>> for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
>> // Here I don't compare the destination (Odo) port, only the source
>> (host)
>> because
>> // this could be a repeat open packet, which we don't want to cause a
>> second link.
>> // This could happen if a second open packet comes because we will have
>> changed the
>> // destination port with the acknowledge.
>> if (TFtpLinks[i].State != TFTP_STATE_IDLE && wSrcPort ==
>> TFtpLinks[i].DestAddr.wPort
>> && wDestPort == TFtpLinks[i].SrcAddr.wPort) {
>> iLinkSlot = i;
>> break;
>> }
>> else if (TFtpLinks[i].State == TFTP_STATE_IDLE)
>> iLinkSlot = i;
>> }
>>
>> // If we broke out of the loop early, then the packet is for a link that
>> is
>> already open
>> if (i < MAX_TFTP_LINKS) {
>> // iLinkSlot is the index of the link this packet belongs too
>> TFtpStateMachine( wSrcPort, iLinkSlot, pwUDPData, cwUDPDataLength );
>> }
>> // Check to see if someone is trying to start a new connection,
>> // If so, guarantee that there are always TFTP_TX_LINKS link(s) available
>> to transmit information
>> else //if (wDestPort == wOdoWellKnownServerPort && MAX_TFTP_LINKS -
>> nNumTFtpLinksInUse > TFTP_TX_LINKS)
>> {
>>
>> // iLinkSlot is the index of a link that is in the IDLE state, giving
>> the
>> number of a free link
>> // slot that can be used, the wDestTID and the TFTP Message
>> //TFtpdFormNewLink( pMyAddr, pFrameBuffer, iLinkSlot, pwUDPData );
>> TFtpOpen(&HostAddr, pMyAddr, "nk.bin", H2OLink, fTftpLinked);
>> return 1;
>> }
>> /*else {
>>
>> for( i = 0; i < MAX_TFTP_LINKS; i++ ) {
>> EdbgOutputDebugString("TFTP link[%u]: State:%u,
>> DestAddr.wPort:
>> %u, SrcAddr.wPort: %u\n",
>> i,TFtpLinks[i].State,
>> ntohs(TFtpLinks[i].DestAddr.wPort),
>> ntohs(TFtpLinks[i].SrcAddr.wPort));
>> }
>> EdbgOutputDebugString("TftpReceiver, port: 0x%X, wkp:
>> 0x%X\n\r",wDestPort,wOdoWellKnownServerPort);
>> }*/
>>
>> return 0;
>>
>> } // TFtpReceiver()
>>
>>
>>
>> Change TFtpOpen as following:
>>
>> UINT16 TFtpOpen( EDBG_ADDR *pHostAddr, EDBG_ADDR *pMyAddr, char
>> *pszFileName, TFtpLinkDir DataDir, UINT16 *fTftpLinked ) {
>>
>> 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;
>> }
>> }
>>
>> EdbgOutputDebugString( "Begin TFtpOpen function\r\n");
>> 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 ) +1; // A bug.File
>> should end with '\0'.WangYQ@Jun.1.2005
>> // 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;
>>
>> *fTftpLinked = 1;
>>
>> return iLinkSlot+1;
>>
>> }
>>
>> Is all these changes right?
>>
>> Thanks.
>
>
>