BOOTLOADER
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
ethernettftp.c
Go to the documentation of this file.
1 /******************************************************
2 * Function: etherent tftp protocol handler
3 *
4 * File: etherenttftp.c
5 * Author: Book Chen
6 * Date: 2008.07.18
7 *******************************************************
8 */
9 #include "includes.h"
10 
11 #if(DEBUG_ETHERNET_TFTP==1)
12  #define ETHERNET_TFTP_INFO 1
13 #else
14  #define ETHERNET_TFTP_INFO 0
15 #endif
16 
17 
18 #define EthernetTftpIdleState 0
19 #define EthernetTftpDownloadState 1
20 #define EthernetTftpUpLoadState 2
21 
23 void F_EthernetTftpInit(void);
24 void F_EthernetTftpSvc(void);
30 void F_EthernetTftpWrqReceive(ETHBUFFER *pBuffer);
33 void F_EthernetTftpPut(INT8U *pData,INT32U Length);
34 void F_EthernetTftpAckSend(TFTP_HEAD *pTftpHead,INT16U BlockNumber);
35 
36 void F_EthernetTftpInit(void){
37  EthTftpCtrl.ClientBlock=0;
38  EthTftpCtrl.Begin=FALSE;
39  EthTftpCtrl.End=FALSE;
40  EthTftpCtrl.HasData=FALSE;
41  EthTftpCtrl.Length=0;
42  EthTftpCtrl.Counter=0;
43  EthTftpCtrl.InUse=FALSE;
44  EthTftpCtrl.Id=ID_ETHERNET_TFTP;
45  EthTftpCtrl.Status=0;
46  EthTftpCtrl.State=EthernetTftpIdleState;
47 }
48 void F_EthernetTftpSvc(void){}
50  if(EthTftpCtrl.InUse==TRUE) return TRUE;
51  else return FALSE;
52 }
54  if(EthTftpCtrl.InUse==FALSE){
55  EthTftpCtrl.UserId=UserId;
56  EthTftpCtrl.InUse=TRUE;
57  return TRUE;
58  }
59  else return FALSE;
60 }
62  if((EthTftpCtrl.InUse==TRUE)&&(EthTftpCtrl.UserId==UserId)){
63  EthTftpCtrl.InUse=FALSE;
64  return TRUE;
65  }
66  else return FALSE;
67 }
68 INT8U F_EthernetTftpAddressSet(INT16U UserId,INT32U DownloadAddress){
69  if((EthTftpCtrl.InUse==TRUE)&&(EthTftpCtrl.UserId==UserId)){
70  EthTftpCtrl.DownloadAddress=DownloadAddress;
71  return TRUE;
72  }
73  else return FALSE;
74 }
76  if((EthTftpCtrl.InUse==TRUE)&&(EthTftpCtrl.UserId==UserId)){
77  EthTftpCtrl.Begin=FALSE;
78  EthTftpCtrl.End=FALSE;
79  EthTftpCtrl.HasData=FALSE;
80  EthTftpCtrl.Length=0;
81  EthTftpCtrl.Counter=0;
82  EthTftpCtrl.Status=0;
83  EthTftpCtrl.State=EthernetTftpIdleState;
84  return TRUE;
85  }
86  else return FALSE;
87 }
89  if(EthTftpCtrl.InUse==TRUE){
90  if(EthTftpCtrl.End==TRUE) return TRUE;
91  else return FALSE;
92  }
93  else return FALSE;
94 }
96  TFTP_HEAD *pTftpHead;
97 
98  #if(ETHERNET_TFTP_INFO==1)
99  printf("\n TFTP rx ");
100  #endif
101  pTftpHead=(TFTP_HEAD *)pBuffer->pData;
102  switch(F_EthernetUnsignedShortN2H(pTftpHead->Opcode)){
103  case TFTP_READ_REQUEST:
104  #if(ETHERNET_TFTP_INFO==1)
105  printf("READ PACKET ");
106  #endif
107  break;
108  case TFTP_WRITE_REQUEST:
109  #if(ETHERNET_TFTP_INFO==1)
110  printf("WRITE REQUEST ");
111  #endif
112  F_EthernetTftpWrqReceive(pBuffer);
113  break;
114  case TFTP_DATA_PACKET:
115  #if(ETHERNET_TFTP_INFO==1)
116  printf("DATA PACKET ");
117  #endif
118  F_EthernetTftpDataReceive(pBuffer);
119  break;
120  case TFTP_ACKNOWLEDGE:
121  #if(ETHERNET_TFTP_INFO==1)
122  printf("ACKNOWLEDGE ");
123  #endif
124  break;
125  case TFTP_ERROR:
126  #if(ETHERNET_TFTP_INFO==1)
127  printf("ERROR ");
128  #endif
129  F_EthernetTftpErrorReceive(pBuffer);
130  EthTftpCtrl.End=TRUE;
131  break;
132  default:
133  #if(ETHERNET_TFTP_INFO==1)
134  printf("NONE ");
135  #endif
136  break;
137  }
138 }
140  TFTP_HEAD *pTftpHead;
141 
143  EthTftpCtrl.ClientPort=F_EthernetUdpSourcePortGet(pBuffer);
144  pTftpHead=(TFTP_HEAD *)pBuffer->pData;
145  #if(ETHERNET_TFTP_INFO==1)
146  printf("\n ClientPort %x ",EthTftpCtrl.ClientPort);
147  #endif
148  F_EthernetTftpAckSend(pTftpHead,0); // send ack to host
149  EthTftpCtrl.ClientBlock=1; // 1.2.3.4.5...increase after each data receive
150  EthTftpCtrl.pData=(INT8U *)EthTftpCtrl.DownloadAddress;
151  EthTftpCtrl.Begin=TRUE; // set tftp download start flag
152  EthTftpCtrl.End=FALSE; // clear tftp download end flag
153  EthTftpCtrl.Length=0;
154  EthTftpCtrl.Counter=0;
155 }
157  TFTP_HEAD *pTftpHead;
158  INT32U Length;
159  //INT8U *pData;
160 
161  if((EthTftpCtrl.ClientIp[0]!=IpCtrl.SourceIp[0])||
162  (EthTftpCtrl.ClientIp[1]!=IpCtrl.SourceIp[1])||
163  (EthTftpCtrl.ClientIp[2]!=IpCtrl.SourceIp[2])||
164  (EthTftpCtrl.ClientIp[3]!=IpCtrl.SourceIp[3])){
165  return FALSE;
166  }
167  if(EthTftpCtrl.ClientPort!=F_EthernetUdpSourcePortGet(pBuffer)){
168  #if(ETHERNET_TFTP_INFO==1)
169  printf("PORT error");
170  #endif
171  return FALSE;
172  }
173  pTftpHead=(TFTP_HEAD *)pBuffer->pData;
174  if(EthTftpCtrl.ClientBlock==F_EthernetUnsignedShortN2H(pTftpHead->Un.BlockNumber)){
175  #if(ETHERNET_TFTP_INFO==1)
176  printf(" data 0 ");
177  #endif
178  Length=pBuffer->Length-sizeof(TFTP_HEAD);
179  F_EthernetTftpPut((INT8U *)pTftpHead+sizeof(TFTP_HEAD),Length); // get tftp data
180  F_EthernetTftpAckSend(pTftpHead,EthTftpCtrl.ClientBlock);
181  EthTftpCtrl.ClientBlock++;
182  if(Length<512){
183  EthTftpCtrl.End=TRUE;
184  }
185  }
186  else if(EthTftpCtrl.ClientBlock>F_EthernetUnsignedShortN2H(pTftpHead->Un.BlockNumber)){
187  #if(ETHERNET_TFTP_INFO==1)
188  printf(" data 1 ");
189  #endif
191  EthTftpCtrl.End=TRUE;
192  }
193  else{
194  #if(ETHERNET_TFTP_INFO==1)
195  printf(" data 2 ");
196  #endif
197  F_EthernetTftpAckSend(pTftpHead,EthTftpCtrl.ClientBlock);
198  EthTftpCtrl.End=TRUE;
199  }
200  return TRUE;
201 }
203  TFTP_HEAD *pTftpHead;
204 
205  if((EthTftpCtrl.ClientIp[0]!=IpCtrl.SourceIp[0])||
206  (EthTftpCtrl.ClientIp[1]!=IpCtrl.SourceIp[1])||
207  (EthTftpCtrl.ClientIp[2]!=IpCtrl.SourceIp[2])||
208  (EthTftpCtrl.ClientIp[3]!=IpCtrl.SourceIp[3])){
209  return FALSE;
210  }
211  if(EthTftpCtrl.ClientPort!=F_EthernetUdpSourcePortGet(pBuffer)) return FALSE;
212  pTftpHead=(TFTP_HEAD *)pBuffer->pData;
213  F_EthernetTftpAckSend(pTftpHead,EthTftpCtrl.ClientBlock);
214  return TRUE;
215 }
216 void F_EthernetTftpPut(INT8U *pData,INT32U Length){
217 
218  EthTftpCtrl.Counter=EthTftpCtrl.Counter+Length;
219  if(EthTftpCtrl.Counter>32*1024){
220  EthTftpCtrl.HasData=TRUE; // flag for each 32k data receive
221  EthTftpCtrl.Counter=0;
222  }
223  memcpy(EthTftpCtrl.pData+EthTftpCtrl.Length,pData,Length);
224  EthTftpCtrl.Length=EthTftpCtrl.Length+Length;
225 }
226 void F_EthernetTftpAckSend(TFTP_HEAD *pTftpHead,INT16U BlockNumber){
227  TFTP_HEAD *pTftpAck;
228  ETHBUFFER *pBuffer;
229 
230  #if(ETHERNET_TFTP_INFO==1)
231  printf(" ack send ");
232  #endif
233  pBuffer=F_EthernetBufferAllocate();
235  pTftpAck=(TFTP_HEAD *)F_EthernetBufferPut(pBuffer,sizeof(TFTP_HEAD));
237  pTftpAck->Un.BlockNumber=F_EthernetUnsignedShortH2N(BlockNumber);
238  F_EthernetUdpPacketSend(pBuffer,(INT8U *)EthTftpCtrl.ClientIp,TFTP,EthTftpCtrl.ClientPort); // TFTP=0x45 is a UDP protocol #
239 }
240 
241 
242