Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages   Examples  

/opentcp/tftp/tftps.c

Go to the documentation of this file.
00001 /*
00002  *Copyright (c) 2000-2002 Viola Systems Ltd.
00003  *All rights reserved.
00004  *
00005  *Redistribution and use in source and binary forms, with or without 
00006  *modification, are permitted provided that the following conditions 
00007  *are met:
00008  *
00009  *1. Redistributions of source code must retain the above copyright 
00010  *notice, this list of conditions and the following disclaimer.
00011  *
00012  *2. Redistributions in binary form must reproduce the above copyright 
00013  *notice, this list of conditions and the following disclaimer in the 
00014  *documentation and/or other materials provided with the distribution.
00015  *
00016  *3. The end-user documentation included with the redistribution, if 
00017  *any, must include the following acknowledgment:
00018  *      "This product includes software developed by Viola 
00019  *      Systems (http://www.violasystems.com/)."
00020  *
00021  *Alternately, this acknowledgment may appear in the software itself, 
00022  *if and wherever such third-party acknowledgments normally appear.
00023  *
00024  *4. The names "OpenTCP" and "Viola Systems" must not be used to 
00025  *endorse or promote products derived from this software without prior 
00026  *written permission. For written permission, please contact 
00027  *opentcp@opentcp.org.
00028  *
00029  *5. Products derived from this software may not be called "OpenTCP", 
00030  *nor may "OpenTCP" appear in their name, without prior written 
00031  *permission of the Viola Systems Ltd.
00032  *
00033  *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 
00034  *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00035  *MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00036  *IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE 
00037  *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00038  *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00039  *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
00040  *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00041  *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00042  *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00043  *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00044  *====================================================================
00045  *
00046  *OpenTCP is the unified open source TCP/IP stack available on a series 
00047  *of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
00048  *
00049  *For more information on how to network-enable your devices, or how to 
00050  *obtain commercial technical support for OpenTCP, please see 
00051  *<http://www.violasystems.com/>.
00052  */
00053 
00070 #include <inet/debug.h>
00071 #include <inet/datatypes.h>
00072 #include <inet/globalvariables.h>
00073 #include <inet/system.h>
00074 #include <inet/timers.h>
00075 #include <inet/tcp_ip.h>
00076 #include <inet/tftp/tftps.h>
00077 
00078 UINT8 tftpsapp_init = 0; 
00081 /* TFTPS states                 */
00082 
00083 #define TFTPS_STATE_ENABLED             1
00084 #define TFTPS_STATE_CONNECTED   2
00085 
00086 
00087 
00088 /* TFTP Error codes             */
00089 
00090 #define TFTPS_NOTDEFINED                        0       /* Not Definet Error            */
00091 #define TFTPS_ACCESSVIOLATION   2       /* Access Violation     Error   */
00092 #define TFTPS_ILLEGALOPERATION  4       /* Not supported Opcode         */
00093 
00094 
00095 /* TFTP Opcodes         */
00096 
00097 #define TFTPS_OPCODE_WRQ                        2       /* Packet is Write Request      */
00098 #define TFTPS_OPCODE_DATA               3       /* Data Packet                          */
00099 #define TFTPS_OPCODE_ACK                        4       /* ACK Packet                           */
00100 #define TFTPS_OPCODE_ERROR              5       /* Error Packet                         */
00101 
00110 struct
00111 {
00112         UINT8   state;
00113         INT8    sochandle;      
00114         UINT16  tmrhandle;
00115         UINT32  remip;
00116         UINT16  remport;
00117         UINT16  blocknumber;
00118         UINT32  bytecount;
00119         UINT8   retries;
00120 
00121 } tftps;
00122 
00123 
00124 
00136 INT8 tftps_init (void){
00137         /* Already initialized? */
00138         
00139         if(tftpsapp_init)
00140                 return(1);
00141         
00142         /* Get socket handle            */
00143         
00144         tftps.sochandle = udp_getsocket(0, tftps_eventlistener, UDP_OPT_SEND_CS | UDP_OPT_CHECK_CS);
00145         
00146         if(tftps.sochandle < 0)
00147                 return(-1);
00148         
00149         /* Put it to listening mode     */
00150                 
00151         if( udp_open(tftps.sochandle, TFTPS_SERVERPORT) < 0 )
00152                 return(-1);
00153         
00154         /* Get timer handle                     */
00155         
00156         tftps.tmrhandle = get_timer();
00157         
00158         tftps.state = TFTPS_STATE_ENABLED;
00159         tftps.remip = 0;
00160         tftps.remport = 0;
00161         tftps.retries = 0;
00162         tftps.blocknumber = 0;
00163         tftps.bytecount = 0;
00164         tftpsapp_init = 1;
00165         
00166         return(1);              
00167         
00168 }
00169 
00170 /********************************************************************************
00171 Function:               tftps_run
00172 
00173 Parameters:             void
00174                                 
00175 Return val:             void
00176                                 
00177 Date:                   7.10.2002
00178 
00179 Desc:                   The main thread of TFTP server that should be called periodically
00180 *********************************************************************************/
00181 
00182 void tftps_run (void)
00183 {
00184         if(tftpsapp_init == 0)
00185                 return;
00186         
00187         /* Check for timeouts   */
00188         
00189         if(tftps.state == TFTPS_STATE_CONNECTED) {
00190                 if(check_timer(tftps.tmrhandle) == 0)
00191                         tftps_deletesocket();   
00192         }
00193                 
00194 }
00195 
00196 INT32 tftps_eventlistener (INT8 cbhandle, UINT8 event, UINT32 remip, UINT16 remport, UINT16 bufindex, UINT16 dlen)
00197 {
00198         UINT16 opcode;
00199         UINT16 i;
00200         UINT8 ch;
00201         UINT16 u16temp;
00202         UINT8 fname[TFTPS_FILENAME_MAXLEN];
00203 
00204         if(tftpsapp_init == 0)
00205                 return(-1);
00206                 
00207         if(cbhandle != tftps.sochandle)
00208                 return(-1);     
00209                 
00210         /* If we are on other state than enabled, check that we are talking with the same gyu   */
00211         
00212         if(     tftps.state != TFTPS_STATE_ENABLED)     {
00213                 if(remip != tftps.remip)
00214                         return(-1);
00215                 if(remport != tftps.remport)
00216                         return(-1);     
00217         }
00218         
00219         if(dlen < 2)
00220                 return(-1);
00221                 
00222         /* Bind socket  */
00223                         
00224         tftps.remip = remip;
00225         tftps.remport = remport;        
00226         
00227         /* Get information      */
00228         
00229         NETWORK_RECEIVE_INITIALIZE(bufindex);
00230         
00231         opcode = RECEIVE_NETWORK_B();
00232         opcode <<= 8;
00233         opcode |= RECEIVE_NETWORK_B();
00234         
00235         dlen -= 2;
00236         
00237         /* Process it   */
00238         
00239         switch(opcode) {
00240                 case TFTPS_OPCODE_WRQ:                                                  /* Write request?       */
00241                 
00242                         /* Get filename */ 
00243                         
00244                         fname[0] = '\0';
00245                         
00246                         for(i=0; i<dlen; i++) {
00247                                 if(i >= TFTPS_FILENAME_MAXLEN) {
00248                                         tftps_senderror(TFTPS_NOTDEFINED);
00249                                         tftps_deletesocket();
00250                                         return(1);
00251                                 }
00252                                 
00253                                 ch = RECEIVE_NETWORK_B();
00254                                 
00255                                 fname[i] = ch;
00256                                 
00257                                 if(ch == '\0') {
00258                                         i++;
00259                                         break;
00260                                 }
00261                         }
00262                         
00263                         dlen -= i;
00264                         /* !!!!!!!!!!!!!!!!!!!!!!!!     */
00265                         /* Check here the filename      */
00266                         /* if NOT OK, RETURN            */
00267                         /* !!!!!!!!!!!!!!!!!!!!!!!! */
00268                         
00269                         /* Check mode, only octet mode is supported     */
00270                         
00271                         if(dlen < 6) {
00272                                 tftps_senderror(TFTPS_NOTDEFINED);
00273                                 tftps_deletesocket();                   
00274                                 return(1);
00275                         }
00276                         
00277                         if( (RECEIVE_NETWORK_B() != 'o') || (RECEIVE_NETWORK_B() != 'c') || (RECEIVE_NETWORK_B() != 't') ||
00278                                 (RECEIVE_NETWORK_B() != 'e') || (RECEIVE_NETWORK_B() != 't') || (RECEIVE_NETWORK_B() != '\0')   ) {
00279                                 tftps_senderror(TFTPS_NOTDEFINED);
00280                                 tftps_deletesocket();
00281                                 return(1);
00282                         }
00283                         
00284                         /* All OK, send ACK     */
00285                         
00286                         tftps.state = TFTPS_STATE_CONNECTED;
00287                         tftps.blocknumber = 0;
00288                         tftps.bytecount = 0;
00289                         tftps.retries = TFTPS_DEF_RETRIES;
00290                         init_timer(tftps.tmrhandle, TFTPS_TIMEOUT*TIMERTIC);
00291                                         
00292                         tftps_sendack();
00293                                         
00294                         tftps.blocknumber++;
00295                                         
00296                         return(1);                      
00297                         
00298                 
00299                 case TFTPS_OPCODE_DATA:                                                                                 /* Data Packet ? */
00300                 
00301                         if(tftps.state != TFTPS_STATE_CONNECTED) {
00302                                 tftps_senderror(TFTPS_NOTDEFINED);
00303                                 tftps_deletesocket();
00304                                 return(1);
00305                         }               
00306                         
00307                         if(dlen < 2) {
00308                                 tftps_senderror(TFTPS_NOTDEFINED);
00309                                 tftps_deletesocket();                   
00310                                 return(1);
00311                         }                               
00312         
00313                         /* Get block number     */
00314                         
00315                         u16temp = RECEIVE_NETWORK_B();
00316                         u16temp <<= 8;
00317                         u16temp |= RECEIVE_NETWORK_B();
00318         
00319                         dlen -= 2;      
00320                         
00321                         if( (u16temp < tftps.blocknumber) && (tftps.blocknumber > 0) ) {
00322                                 /* Duplicate msg, send ACK again        */
00323                         
00324                                 if( tftps.retries > 0 ) {
00325                                         tftps.retries--;
00326                                         tftps.blocknumber--;
00327                                         tftps_sendack();
00328                                         tftps.blocknumber++;
00329                                 } else {
00330                                         tftps_senderror(TFTPS_NOTDEFINED);
00331                                         tftps_deletesocket();
00332                                 }
00333                 
00334                                 return(1);              
00335                         }
00336                 
00337                         if( u16temp != tftps.blocknumber ) {
00338                                 /* Something really wrong */
00339                 
00340                                 tftps_senderror(TFTPS_NOTDEFINED);
00341                                 tftps_deletesocket();
00342                                 return(1);
00343                         }                                       
00344                         
00345                         /* !!!!!!!!!!!!!!!!!!!!!!!!     */
00346                         /* Read the data here           */
00347                         /* !!!!!!!!!!!!!!!!!!!!!!!!     */
00348                         
00349                         if( dlen < 512 ) {
00350                                 /* Other side Wants to close */
00351                         
00352                                 tftps_sendack();
00353                                 tftps_deletesocket();
00354                                 return(1);
00355                         }                       
00356                         
00357                         /* All OK       */
00358                         
00359                         tftps.retries = TFTPS_DEF_RETRIES;
00360                         init_timer(tftps.tmrhandle, TFTPS_TIMEOUT*TIMERTIC);
00361                         tftps_sendack();
00362                         tftps.blocknumber++;                    
00363         
00364                         return(1);
00365                         
00366                 case TFTPS_OPCODE_ERROR:
00367                 
00368                         tftps_deletesocket();
00369         
00370                         return(1);
00371         
00372                 default:
00373                 
00374                         /* Unsupported Opcode, Send error */
00375                 
00376                         tftps_senderror(TFTPS_ILLEGALOPERATION);
00377                         tftps_deletesocket();                   
00378         
00379                         return(1);
00380         }       
00381                 
00382 }
00383 
00384 
00385 void tftps_sendack (void)
00386 {
00387         /* Send a TFTP ACK packet */
00388         
00389         net_buf[UDP_APP_OFFSET + 0] = 0;                /* Opcode       */
00390         net_buf[UDP_APP_OFFSET + 1] = 4;
00391         net_buf[UDP_APP_OFFSET + 2] = (UINT8)(tftps.blocknumber >> 8);
00392         net_buf[UDP_APP_OFFSET + 3] = (UINT8)tftps.blocknumber;
00393         
00394         udp_send(tftps.sochandle, tftps.remip, tftps.remport, &net_buf[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 4);
00395         
00396 
00397 }
00398 
00399 
00400 
00401 
00402 void tftps_senderror (UINT8 errno )
00403 {
00404         /* Send TFTP Error -packet */
00405         
00406         net_buf[UDP_APP_OFFSET + 0] = 0;                /* Opcode       */
00407         net_buf[UDP_APP_OFFSET + 1] = 5;
00408         net_buf[UDP_APP_OFFSET + 2] = (UINT8)(tftps.blocknumber >> 8);
00409         net_buf[UDP_APP_OFFSET + 3] = (UINT8)tftps.blocknumber;
00410         net_buf[UDP_APP_OFFSET + 4] = errno;
00411         net_buf[UDP_APP_OFFSET + 5] = '\0';
00412         net_buf[UDP_APP_OFFSET + 6] = 0;
00413         
00414         udp_send(tftps.sochandle, tftps.remip, tftps.remport, &net_buf[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 7);    
00415         
00416 }
00417 
00418 void tftps_deletesocket (void)
00419 {
00420         /* Clear Socket Data */
00421 
00422         tftps.blocknumber = 0;
00423         tftps.state = TFTPS_STATE_ENABLED;
00424         tftps.retries = 0;
00425         tftps.remip = 0;
00426         tftps.remport = 0;      
00427 
00428 
00429 }
00430 
00431 
00432 

Generated on Sun Aug 3 20:33:00 2003 for OpenTCP by doxygen1.2.18