ftp.c

Go to the documentation of this file.
00001 
00022 /*
00023  * Copyright (c) 2006, Aurion s.r.l.
00024  * All rights reserved. 
00025  *
00026  * Redistribution and use in source and binary forms, with or without 
00027  * modification, are permitted provided that the following conditions 
00028  * are met: 
00029  * 1. Redistributions of source code must retain the above copyright 
00030  *    notice, this list of conditions and the following disclaimer. 
00031  * 2. Redistributions in binary form must reproduce the above copyright 
00032  *    notice, this list of conditions and the following disclaimer in the 
00033  *    documentation and/or other materials provided with the distribution. 
00034  * 3. The name of the author may not be used to endorse or promote
00035  *    products derived from this software without specific prior
00036  *    written permission.  
00037  *
00038  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00039  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00040  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00041  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00042  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00043  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00044  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00045  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00046  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00047  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00048  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00049  *
00050  * This file is part of the uIP TCP/IP stack.
00051  *
00052  * $Id: ftp.c,v 1.0.0.0 2007/01/31 21:21:01 fabio Exp $
00053  *
00054  */
00055 #include <ctype.h>
00056 #include <stdlib.h>
00057 #include "uip.h"
00058 #include "ftp.h"
00059 #include "../mult/api_services.h"
00060 
00061 //#define DEBUG
00062 #ifdef DEBUG
00063 #include "arnDebug.h"
00064 #define PRINT(x) arnDEBUG("%s",x) /*printf("%s", x)*/
00065 #define PRINTLN(x) arnDEBUG("%s\n",x) /*printf("%s\n", x)*/
00066 #define PRINTNUM(x) arnDEBUG("%d",x) 
00067 #define PRINTNUMLN(x) arnDEBUG("%d\n",x)
00068 #else /* DEBUG */
00069 #define PRINT(x)
00070 #define PRINTLN(x)
00071 #define PRINTNUMLN(x)
00072 #define PRINTNUM(x)
00073 #endif /* NOT DEBUG */
00074 
00075 #ifdef __cplusplus
00076 extern "C" {
00077 #endif
00078 
00079 static arn_BOOL HostToIp(arn_CHAR* host,arn_uSHORT ipaddr[2]);
00080 
00081 static void _abort(struct ftp_state *s);
00082 static void _timeout(struct ftp_state *s);
00083 static void _close(struct ftp_state *s);
00084 static void _connect(struct ftp_state *s);
00085 static void _newdata(struct ftp_state *s);
00086 static void _ack(struct ftp_state *s);
00087 static void _poll(struct ftp_state *s);
00088 static void _senddata(struct ftp_state *s);
00089 static void _retrasmit(struct ftp_state *s);
00090 
00091 static void _abort_data(struct ftp_state *s);
00092 static void _timeout_data(struct ftp_state *s);
00093 static void _close_data(struct ftp_state *s);
00094 static void _connect_data(struct ftp_state *s);
00095 static void _newdata_data(struct ftp_state *s);
00096 static void _ack_data(struct ftp_state *s);
00097 static void _poll_data(struct ftp_state *s);
00098 static void _senddata_data(struct ftp_state *s);
00099 static void _retrasmit_data(struct ftp_state *s);
00100 
00101 static const arn_CHAR cmd_cwd_P[] = "CWD";
00102 static const arn_CHAR cmd_dele_P[] = "DELE";
00103 static const arn_CHAR cmd_list_P[] = "LIST";
00104 static const arn_CHAR cmd_mkd_P[] = "MKD";
00105 static const arn_CHAR cmd_xmkd_P[] = "XMKD";
00106 static const arn_CHAR cmd_nlst_P[] = "NLST";
00107 static const arn_CHAR cmd_noop_P[] = "NOOP";
00108 static const arn_CHAR cmd_pass_P[] = "PASS";
00109 static const arn_CHAR cmd_pasv_P[] = "PASV";
00110 static const arn_CHAR cmd_port_P[] = "PORT";
00111 static const arn_CHAR cmd_pwd_P[] = "PWD";
00112 static const arn_CHAR cmd_xpwd_P[] = "XPWD";
00113 static const arn_CHAR cmd_quit_P[] = "QUIT";
00114 static const arn_CHAR cmd_retr_P[] = "RETR";
00115 static const arn_CHAR cmd_rmd_P[] = "RMD";
00116 static const arn_CHAR cmd_xrmd_P[] = "XRMD";
00117 static const arn_CHAR cmd_size_P[] = "SIZE";
00118 static const arn_CHAR cmd_stor_P[] = "STOR";
00119 static const arn_CHAR cmd_syst_P[] = "SYST";
00120 static const arn_CHAR cmd_type_P[] = "TYPE";
00121 static const arn_CHAR cmd_user_P[] = "USER";
00122 
00123 static const arn_CHAR okCode125[] = "125";
00124 static const arn_CHAR okCode150[] = "150";
00125 static const arn_CHAR okCode200[] = "200";
00126 static const arn_CHAR okCode215[] = "215";
00127 static const arn_CHAR okCode220[] = "220";
00128 static const arn_CHAR okCode221[] = "221";
00129 static const arn_CHAR okCode225[] = "225";
00130 static const arn_CHAR okCode226[] = "226";
00131 static const arn_CHAR okCode230[] = "230";
00132 static const arn_CHAR okCode331[] = "331";
00133 
00134 static const arn_CHAR FailCode500[] =  "500";
00135 static const arn_CHAR FailCode501[] =  "501";
00136 static const arn_CHAR FailCode502[] =  "502";
00137 static const arn_CHAR FailCode504[] =  "504";
00138 static const arn_CHAR FailCode421[] =  "421";
00139 
00140 
00141 #define CMDSND_NONE                                                     0
00142 #define CMDSND_CONNECT                                          (CMDSND_NONE + 1)
00143 #define CMDSND_LOGIN                                            (CMDSND_CONNECT + 1)
00144 #define CMDSND_SYST                                                     (CMDSND_LOGIN + 1)
00145 #define CMDSND_PORT                                                     (CMDSND_SYST + 1)
00146 #define CMDSND_STOR                                                     (CMDSND_PORT + 1)
00147 #define CMDSND_QUIT                                                     (CMDSND_STOR + 1)
00148 #define CMDSND_PASS                                                     (CMDSND_QUIT + 1)
00149 
00150 #define ANSRCV_NONE                                                     0
00151 #define ANSRCV_WELCOME                                          (ANSRCV_NONE + 1)
00152 #define ANSRCV_WELCOMERR                                        (ANSRCV_WELCOME + 1)
00153 #define ANSRCV_LOGGEDIN                                         (ANSRCV_WELCOMERR + 1)
00154 #define ANSRCV_LOGGEDERR                                        (ANSRCV_LOGGEDIN + 1)
00155 #define ANSRCV_SYSTOK                                           (ANSRCV_LOGGEDERR + 1)
00156 #define ANSRCV_SYSTERR                                          (ANSRCV_SYSTOK + 1)
00157 #define ANSRCV_PORTOK                                           (ANSRCV_SYSTERR + 1)
00158 #define ANSRCV_PORTERR                                          (ANSRCV_PORTOK + 1)
00159 #define ANSRCV_STOROK                                           (ANSRCV_PORTERR + 1)
00160 #define ANSRCV_STORERR                                          (ANSRCV_STOROK + 1)
00161 #define ANSRCV_QUITOK                                           (ANSRCV_STORERR + 1)
00162 #define ANSRCV_QUITERR                                          (ANSRCV_QUITOK + 1)
00163 #define ANSRCV_PASSERR                                          (ANSRCV_QUITERR + 1)
00164 #define ANSRCV_PASSREQ                                          (ANSRCV_PASSERR + 1)
00165 //------------------------------------------------------------
00166 //----------- API AND NEEDED CALLBACK ------------------------
00167 //------------------------------------------------------------
00168 ftp_cmd_status_t ftp_connect(arn_CHAR* host,arn_uSHORT rport,struct uip_conn **sconn) 
00169 {
00170         char deb[100];
00171         DEBUG_ENTER;
00172         if (*sconn == NULL) {
00173                 arn_uSHORT ipHostAddr[2];
00174                 DEBUG_FTP(host);
00175                 if (!HostToIp(host,ipHostAddr)) return ftpcs_FAILED;
00176                 *sconn = uip_connect(ipHostAddr, htons(rport));
00177                 DEBUG_FTP("Conectando..");
00178                 if(sconn == NULL) return ftpcs_FAILED;
00179                 DEBUG_FTP("Conectado com sucesso.");
00180                 ((struct ftp_state *)((*sconn)->appstate.ftp_st))->remotectrlport = rport;
00181                 DEBUG_FTP("porta");
00182                 ((struct ftp_state *)((*sconn)->appstate.ftp_st))->CmdSnt = CMDSND_CONNECT;
00183                 DEBUG_FTP("CmdSnt");
00184                 ((struct ftp_state *)((*sconn)->appstate.ftp_st))->Status = STS_WAITFORCONN;
00185                 DEBUG_FTP("Configurado conexao.");
00186                 }
00187         else {
00188                 struct ftp_state *s = (struct ftp_state *)(*sconn)->appstate.ftp_st;
00189                 DEBUG_FTP("ja esta conectado..");
00190                 sprintf(deb, "Status: %s\t %d",s->Status,s->Status);
00191                 DEBUG_FTP(deb);
00192                 if (s->Status == STS_CONNECTED) {
00193                         if (s->AnsRcv == ANSRCV_WELCOME) {
00194                                 s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE;
00195                                 s->dconn = 0;
00196                                 return ftpcs_SUCCESS;
00197                                 }
00198                         else if (s->AnsRcv == ANSRCV_WELCOMERR) {
00199                                 s->Status = STS_ERROR;
00200                                 s->errorCode = ERRC_CONN;
00201                                 return ftpcs_FAILED;
00202                                 }
00203                         }
00204                 }
00205         DEBUG_EXIT;
00206         return ftpcs_INPROGRESS;
00207 }
00208 
00209 ftp_cmd_status_t ftp_login(const struct uip_conn *sconn,arn_CHAR* username)
00210 {
00211         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00212         if (s->Status != STS_CONNECTED) return ftpcs_FAILED;
00213         if (s->CmdSnt == CMDSND_NONE) {
00214                 strcpy((arn_CHAR*)s->data,cmd_user_P);
00215                 strcat((arn_CHAR*)s->data," ");
00216                 strcat((arn_CHAR*)s->data,username);
00217                 strcat((arn_CHAR*)s->data,"\r\n");
00218                 s->CmdSnt = CMDSND_LOGIN;
00219                 s->flags |= FTP_FLAG_CMDREQUEST;
00220                 }
00221         else if (s->CmdSnt == CMDSND_LOGIN) {
00222                 if (s->AnsRcv == ANSRCV_LOGGEDIN) {
00223                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE; 
00224                         return ftpcs_SUCCESS;
00225                         }
00226                 else if (s->AnsRcv == ANSRCV_PASSREQ) {
00227                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE; 
00228                         return ftpcs_PASSWORD_REQ;
00229                         }
00230                 else if (s->AnsRcv == ANSRCV_LOGGEDERR) {
00231                         s->Status = STS_ERROR;
00232                         s->errorCode = ERRC_LOGIN;
00233                         return ftpcs_FAILED;
00234                         }
00235                 }
00236         return ftpcs_INPROGRESS;
00237 }
00238 
00239 ftp_cmd_status_t ftp_password(const struct uip_conn *sconn,arn_CHAR* password)
00240 {
00241         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00242         if (s->Status != STS_CONNECTED) return ftpcs_FAILED;
00243         if (s->CmdSnt == CMDSND_NONE) {
00244                 strcpy((arn_CHAR*)s->data,cmd_pass_P);
00245                 strcat((arn_CHAR*)s->data," ");
00246                 strcat((arn_CHAR*)s->data,password);
00247                 strcat((arn_CHAR*)s->data,"\r\n");
00248                 s->CmdSnt = CMDSND_PASS;
00249                 s->flags |= FTP_FLAG_CMDREQUEST;
00250                 }
00251         else if (s->CmdSnt == CMDSND_PASS) {
00252                 if (s->AnsRcv == ANSRCV_LOGGEDIN) {
00253                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE; 
00254                         return ftpcs_SUCCESS;
00255                         }
00256                 else if (s->AnsRcv == ANSRCV_PASSERR) {
00257                         s->Status = STS_ERROR;
00258                         s->errorCode = ERRC_PASS;
00259                         return ftpcs_FAILED;
00260                         }
00261                 }
00262         return ftpcs_INPROGRESS;
00263 }
00264 
00265 ftp_cmd_status_t ftp_syst(const struct uip_conn *sconn,arn_CHAR* res)
00266 {
00267         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00268         if (s->Status != STS_CONNECTED) return ftpcs_FAILED;
00269         if (s->CmdSnt == CMDSND_NONE) {
00270                 strcpy((arn_CHAR*)s->data,cmd_syst_P);
00271                 strcat((arn_CHAR*)s->data,"\r\n");
00272                 s->CmdSnt = CMDSND_SYST;
00273                 s->flags |= FTP_FLAG_CMDREQUEST;
00274                 }
00275         else if (s->CmdSnt == CMDSND_SYST) {
00276                 if (s->AnsRcv == ANSRCV_SYSTOK) {
00277                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE;
00278                         strcpy(res,(const arn_CHAR*)(s->data));
00279                         return ftpcs_SUCCESS;
00280                         }
00281                 else if (s->AnsRcv == ANSRCV_SYSTERR) {
00282                         s->Status = STS_ERROR;
00283                         s->errorCode = ERRC_SYST;
00284                         return ftpcs_FAILED;
00285                         }
00286                 }
00287         return ftpcs_INPROGRESS;
00288 }
00289 
00290 ftp_cmd_status_t ftp_port(const struct uip_conn *sconn,arn_uSHORT ldataport)
00291 {
00292         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00293         if (s->Status != STS_CONNECTED) return ftpcs_FAILED;
00294         if (s->CmdSnt == CMDSND_NONE) {
00295                 strcpy((arn_CHAR*)s->data,cmd_port_P);
00296                 sprintf((arn_CHAR*)(s->data + (sizeof(cmd_port_P) - 1))," %u,%u,%u,%u,%u,%u\r\n",
00297                          htons(uip_hostaddr[0]) >> 8,
00298                          htons(uip_hostaddr[0]) & 0xff,
00299                          htons(uip_hostaddr[1]) >> 8,
00300                          htons(uip_hostaddr[1]) & 0xff,
00301                          htons(ldataport) >> 8,
00302                          htons(ldataport) & 0xff
00303                         );
00304                 s->localdataport = ldataport;
00305                 s->remotedataport = 20;
00306                 s->CmdSnt = CMDSND_PORT;
00307                 s->flags |= FTP_FLAG_CMDREQUEST;
00308                 }
00309         else if (s->CmdSnt == CMDSND_PORT) {
00310                 if (s->AnsRcv == ANSRCV_PORTOK) {
00311                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE;
00312                         return ftpcs_SUCCESS;
00313                         }
00314                 else if (s->AnsRcv == ANSRCV_PORTERR) {
00315                         s->Status = STS_ERROR;
00316                         s->errorCode = ERRC_PORT;
00317                         return ftpcs_FAILED;
00318                         }
00319                 }
00320         return ftpcs_INPROGRESS;
00321 }
00322 
00323 ftp_cmd_status_t ftp_pasv(const struct uip_conn *sconn)
00324 {
00325         return ftpcs_FAILED;
00326 }
00327 
00328 ftp_cmd_status_t ftp_send(const struct uip_conn *sconn,arn_CHAR* filename,arn_uCHAR* sadd,arn_uLONG size)
00329 {
00330         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00331         if (s->Status != STS_CONNECTED) return ftpcs_FAILED;
00332         if (s->CmdSnt == CMDSND_NONE) {
00333                 strcpy((arn_CHAR*)s->data,cmd_stor_P);
00334                 strcat((arn_CHAR*)s->data," ");
00335                 strcat((arn_CHAR*)s->data,filename);
00336                 strcat((arn_CHAR*)s->data,"\r\n");
00337                 s->fSAddr = sadd;
00338                 s->fSize = size;
00339                 s->CmdSnt = CMDSND_STOR;
00340                 s->flags |= FTP_FLAG_CMDREQUEST;
00341                 }
00342         else if (s->CmdSnt == CMDSND_STOR) {
00343                 if (s->AnsRcv == ANSRCV_STOROK) {
00344                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE;
00345                         return ftpcs_SUCCESS;
00346                         }
00347                 else if (s->AnsRcv == ANSRCV_STORERR) {
00348                         s->Status = STS_ERROR;
00349                         s->errorCode = ERRC_STOR;
00350                         return ftpcs_FAILED;
00351                         }
00352                 }
00353         return ftpcs_INPROGRESS;
00354 }
00355 
00356 ftp_cmd_status_t ftp_quit(const struct uip_conn *sconn)
00357 {
00358         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00359         if (s->Status != STS_CONNECTED) return ftpcs_FAILED;
00360         if (s->CmdSnt == CMDSND_NONE) {
00361                 strcpy((arn_CHAR*)s->data,cmd_quit_P);
00362                 strcat((arn_CHAR*)s->data,"\r\n");
00363                 s->CmdSnt = CMDSND_QUIT;
00364                 s->flags |= FTP_FLAG_CMDREQUEST;
00365                 }
00366         else if (s->CmdSnt == CMDSND_QUIT) {
00367                 if (s->AnsRcv == ANSRCV_QUITOK) {
00368                         s->CmdSnt = CMDSND_NONE; s->AnsRcv = ANSRCV_NONE;
00369                         return ftpcs_SUCCESS;
00370                         }
00371                 else if (s->AnsRcv == ANSRCV_QUITERR) {
00372                         s->Status = STS_ERROR;
00373                         s->errorCode = ERRC_QUIT;
00374                         return ftpcs_FAILED;
00375                         }
00376                 }
00377         return ftpcs_INPROGRESS;
00378 }
00379 
00380 arn_uCHAR ftp_getStatus(const struct uip_conn *sconn)
00381 {
00382         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00383         return s->Status;
00384 }
00385 
00386 arn_uCHAR ftp_getErrorCode(const struct uip_conn *sconn)
00387 {
00388         struct ftp_state *s = (struct ftp_state *)sconn->appstate.ftp_st;
00389         return s->errorCode;
00390 }
00391 
00392 //------------------------------------------------------------
00393 //----------- END - API AND NEEDED CALLBACK ------------------
00394 //------------------------------------------------------------
00395 
00396 void ftp_init(void)
00397 {
00398 }
00399 
00400 void ftp_appcall(void)
00401 {
00402         struct ftp_state *s = (struct ftp_state *)uip_conn->appstate.ftp_st;
00403         //DEBUG_FTP("FTP APPCALL");
00404         if (uip_conn->rport == htons(s->remotectrlport)) {
00405         // preparazione in relazione agli aventi
00406                 if(uip_connected()) {_connect(s);return;}
00407                 if(uip_closed()) {_close(s);return;}
00408                 if(uip_aborted()) {_abort(s);return;}
00409                 if(uip_timedout()) {_timeout(s);return;}
00410                 if(uip_acked()) {_ack(s);}
00411                 if(uip_newdata()) {_newdata(s);}
00412                 if(uip_poll()) {_poll(s);}
00413         //END --- preparazione in relazione agli aventi
00414         // eventi che determinano una eventuale trasmissione
00415                 if(uip_rexmit() ||
00416                         uip_newdata() ||
00417                         uip_acked()) {
00418                         _senddata(s);
00419                         }
00420                 else if (uip_poll()) {
00421                         _senddata(s);
00422                         }
00423         //END --- eventi che determinano una eventuale trasmissione
00424                 }
00425         else if (uip_conn->rport == HTONS(20)/*htons(s->remotedataport)*/) {
00426         // preparazione in relazione agli aventi
00427                 if(uip_closed()) {_close_data(s);return;}
00428                 if(uip_aborted()) {_abort_data(s);return;}
00429                 if(uip_timedout()) {_timeout_data(s);return;}
00430                 if(uip_connected()) {_connect_data(s);return;}
00431                 if(uip_acked()) {_ack_data(s);}
00432                 if(uip_newdata()) {_newdata(s);}
00433                 if(uip_poll()) {_poll_data(s);}
00434         //END --- preparazione in relazione agli aventi
00435         // eventi che determinano una eventuale trasmissione
00436                 if(uip_connected() ||
00437                         uip_rexmit() ||
00438                         uip_newdata() ||
00439                         uip_acked()) {
00440                         _senddata_data(s);
00441                         }
00442                 else if (uip_poll()) {
00443                         _senddata_data(s);
00444                         }
00445         //END --- eventi che determinano una eventuale trasmissione
00446                 }
00447 }
00448 
00449 
00450 void _abort(struct ftp_state *s)
00451 {
00452 }
00453 
00454 void _timeout(struct ftp_state *s)
00455 {
00456         //uip_close();
00457 }
00458 //test test test
00459 arn_uCHAR TSTclose;
00460 //END
00461 void _close(struct ftp_state *s)
00462 {
00463 //test test test
00464 TSTclose++;
00465 //END
00466         if (s->Status == STS_CONNECTED) {
00467                 switch (s->CmdSnt) {
00468                         case CMDSND_QUIT:
00469                                 s->AnsRcv = ANSRCV_QUITOK;
00470                                 break;
00471                         default: break;
00472                         }
00473                 }
00474 }
00475 
00476 // test test test
00477 arn_uCHAR TSTconn;
00478 arn_CHAR TSTgetBff[8][16];
00479 //END
00480 void _connect(struct ftp_state *s)
00481 {
00482         s->Status = STS_CONNECTED;
00483         uip_len = 0;
00484 }
00485 
00486 void _newdata(struct ftp_state *s)
00487 {
00488 // test test test
00489 strncpy(TSTgetBff[TSTconn],(arn_CHAR*)uip_appdata,16);
00490 TSTconn++;
00491 if (TSTconn == 8) TSTconn = 0;
00492 //END
00493         uip_len = 0;
00494         if (s->Status == STS_CONNECTED) {
00495                 switch (s->CmdSnt) {
00496                         case CMDSND_CONNECT:
00497                                 if (!memcmp(okCode220,(void*)uip_appdata,sizeof(okCode220)-1)) s->AnsRcv = ANSRCV_WELCOME;
00498                                 else s->AnsRcv = ANSRCV_WELCOMERR;
00499                                 break;
00500                         case CMDSND_LOGIN:
00501                                 if (!memcmp(okCode230,(void*)uip_appdata,sizeof(okCode230)-1)) s->AnsRcv = ANSRCV_LOGGEDIN;
00502                                 else if (!memcmp(okCode331,(void*)uip_appdata,sizeof(okCode331)-1)) s->AnsRcv = ANSRCV_PASSREQ;
00503                                 else s->AnsRcv = ANSRCV_LOGGEDERR;
00504                                 break;
00505                         case CMDSND_PASS:
00506                                 if (!memcmp(okCode230,(void*)uip_appdata,sizeof(okCode230)-1)) s->AnsRcv = ANSRCV_LOGGEDIN;
00507                                 else s->AnsRcv = ANSRCV_LOGGEDERR;
00508                                 break;
00509                         case CMDSND_SYST:
00510                                 if (!memcmp(okCode215,(void*)uip_appdata,sizeof(okCode215)-1)) {
00511                                         strncpy((arn_CHAR*)(s->data),(arn_CHAR*)(uip_appdata + sizeof(okCode215)),24);
00512                                         s->AnsRcv = ANSRCV_SYSTOK;
00513                                         }
00514                                 else s->AnsRcv = ANSRCV_SYSTERR;
00515                                 break;
00516                         case CMDSND_PORT:
00517                                 if (!memcmp(okCode200,(void*)uip_appdata,sizeof(okCode200)-1)) s->AnsRcv = ANSRCV_PORTOK;
00518                                 else s->AnsRcv = ANSRCV_PORTERR;
00519                                 break;
00520                         case CMDSND_STOR:
00521                                 if (s->dconn) {
00522                                         struct ftp_state *cs = (struct ftp_state*)((s->dconn)->appstate.ftp_st);
00523                                         if (!(cs->flags & FTP_FLAG_CMDREQUEST) &&
00524                                                 !memcmp(okCode150,(void*)uip_appdata,sizeof(okCode150)-1)) {
00525                                                 cs->flags |= (FTP_FLAG_CMDREQUEST | FTP_FLAG_DATAPENDING);
00526                                                 }
00527                                         else if (!(cs->flags & FTP_FLAG_DATAPENDING)) s->AnsRcv = ANSRCV_STOROK;
00528                                         else s->AnsRcv = ANSRCV_STORERR;
00529                                         }
00530                                 else s->AnsRcv = ANSRCV_STORERR;
00531                                 break;
00532 /*                      case CMDSND_QUIT:
00533                                 if (!memcmp(okCode221,(void*)uip_appdata,sizeof(okCode221)-1)) s->AnsRcv = ANSRCV_QUITOK;
00534                                 else s->AnsRcv = ANSRCV_QUITERR;
00535                                 break;*/
00536                         default: break;
00537                         }
00538                 }
00539 }
00540 
00541 // test test test
00542 arn_uCHAR TSTack;
00543 //END
00544 void _ack(struct ftp_state *s)
00545 {
00546 TSTack++;
00547 uip_len = 0;
00548 }
00549 // test test test
00550 arn_CHAR TSTpss[32];
00551 //END
00552 void _poll(struct ftp_state *s)
00553 {
00554         arn_uSHORT lLen;
00555         if ((s->Status == STS_CONNECTED) && (s->flags & FTP_FLAG_CMDREQUEST)) {
00556                 switch (s->CmdSnt) {
00557                         case CMDSND_STOR:
00558                                 uip_listen(s->localdataport);
00559                                 s->flags |= FTP_FLAG_CTRL;
00560                                 break;
00561                         case CMDSND_QUIT:
00562                                 s->flags &= ~FTP_FLAG_CMDREQUEST;
00563                                 uip_close();
00564                                 //s->AnsRcv = ANSRCV_QUITOK;
00565                                 return;
00566                         default: 
00567                                 break;
00568                         }
00569 // test test test
00570 if (s->CmdSnt == CMDSND_PASS) strcpy(TSTpss,(const arn_CHAR*)s->data);
00571 //END
00572                 strcpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)s->data);
00573                 lLen = strlen((arn_CHAR*)uip_appdata);
00574                 uip_len = ((lLen > uip_mss()) ? uip_mss() : lLen);
00575                 s->flags &= ~FTP_FLAG_CMDREQUEST;
00576                 }
00577 }
00578 
00579 void _senddata(struct ftp_state *s)
00580 {
00581         if (uip_len > 0) {
00582                 uip_send(uip_appdata,uip_len);
00583                 }
00584 }
00585 
00586 void _retrasmit(struct ftp_state *s)
00587 {
00588         arn_uSHORT lLen;
00589         if (s->Status == STS_CONNECTED) {
00590                 switch (s->CmdSnt) {
00591                         case CMDSND_STOR:
00592                                 uip_listen(s->localdataport);
00593                                 s->flags |= FTP_FLAG_CTRL;
00594                                 break;
00595                         default: 
00596                                 break;
00597                         }
00598                 strcpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)s->data);
00599                 lLen = strlen((arn_CHAR*)uip_appdata);
00600                 uip_len = ((lLen > uip_mss()) ? uip_mss() : lLen);
00601                 }
00602 }
00603 
00604 
00605 arn_BOOL HostToIp(arn_CHAR* host,arn_uSHORT ipaddr[2])
00606 {
00607         arn_uCHAR ipTmp[4];
00608         arn_uCHAR indx = 0;
00609         arn_CHAR* pHost = host;
00610         if (!pHost) return arnFALSE;
00611         if (!isdigit(pHost[0])) return arnFALSE;
00612         while (*pHost) {
00613                 if (*pHost == '.') {
00614                         ipTmp[indx++] = atoi(host);
00615                         pHost++;
00616                         host = pHost;
00617                         }
00618                 pHost++;
00619                 }
00620         ipTmp[indx++] = atoi(host);
00621         if (indx < 4) return arnFALSE;
00622         uip_ipaddr(ipaddr,ipTmp[0],ipTmp[1],ipTmp[2],ipTmp[3]);
00623         return arnTRUE;
00624 }
00625 
00626 
00627 //--------------------------------------------------------------------------------
00628 
00629 // data part
00630 
00631 void _abort_data(struct ftp_state *s)
00632 {
00633 }
00634 
00635 void _timeout_data(struct ftp_state *s)
00636 {
00637 }
00638 
00639 void _close_data(struct ftp_state *s)
00640 {
00641 //      fc_state.DataStatus = STS_DATACONN_CLOSED_OK;
00642 }
00643 
00644 void _connect_data(struct ftp_state *s)
00645 {
00646         arn_uCHAR i;
00647         s->flags = 0;
00648         for (i = 0; i < UIP_CONNS; i++) {
00649                 struct uip_conn* cn = (&(uip_conns[i]));
00650                 if (cn->tcpstateflags == UIP_ESTABLISHED && (cn->rport == FTP_PORT)) {
00651                         struct ftp_state *cs = (struct ftp_state *)cn->appstate.ftp_st;
00652                         if (!(cs->dconn) && (cs->flags & FTP_FLAG_CTRL)) {
00653                                 cs->dconn = uip_conn;
00654                                 s->fSAddr = cs->fSAddr;
00655                                 s->fSize = cs->fSize;
00656                                 break;
00657                                 }
00658                         }
00659                 }
00660         if (i == UIP_CONNS) {
00661                 uip_abort(); 
00662                 return;
00663                 }
00664         s->flags |= FTP_FLAG_DATA;
00665         s->Status = STS_CONNECTED;
00666 }
00667 
00668 void _newdata_data(struct ftp_state *s)
00669 {
00670 }
00671 
00672 void _ack_data(struct ftp_state *s)
00673 {
00674         if (s->flags & FTP_FLAG_DATAPENDING) {
00675                 if (!(s->flags & FTP_FLAG_LASTDATAACK)) {
00676                         if (s->count >= uip_mss()) {
00677                                 s->dataptr += uip_mss();
00678                                 s->count -= uip_mss();
00679                                 }
00680                         else {
00681                                 s->dataptr = 0;
00682                                 s->count = 0;
00683                                 s->flags &= ~FTP_FLAG_DATAPENDING;
00684                                 uip_close();
00685                                 }
00686                         if (s->count >= uip_mss()) {
00687                                 strncpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)(s->dataptr),uip_mss());
00688                                 uip_len = uip_mss();
00689                                 }
00690                         else {
00691                                 strncpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)(s->dataptr),s->count);
00692                                 uip_len = s->count;
00693                                 s->flags |= FTP_FLAG_LASTDATAACK;
00694                                 }
00695                         }
00696                 else {
00697                         s->count = 0;
00698                         s->dataptr = 0;
00699                         s->flags &= ~FTP_FLAG_DATAPENDING;
00700                         uip_close();
00701                         }
00702                 }
00703 }
00704 
00705 void _poll_data(struct ftp_state *s)
00706 {
00707         if (s->flags & FTP_FLAG_CMDREQUEST) {
00708                 s->dataptr = s->fSAddr;
00709                 s->count = s->fSize;
00710                 if (s->count >= uip_mss()) {
00711                         strncpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)(s->dataptr),uip_mss());
00712                         uip_len = uip_mss();
00713                         }
00714                 else {
00715                         strncpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)(s->dataptr),s->count);
00716                         uip_len = s->count;
00717                         }
00718                 s->flags &= ~FTP_FLAG_CMDREQUEST;
00719                 }
00720 }
00721 
00722 void _senddata_data(struct ftp_state *s)
00723 {
00724         if (uip_len > 0) {
00725                 uip_send(uip_appdata,uip_len);
00726                 }
00727 }
00728 
00729 void _retrasmit_data(struct ftp_state *s)
00730 {
00731         if (s->count >= uip_mss()) {
00732                 strncpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)(s->dataptr),uip_mss());
00733                 uip_len = uip_mss();
00734                 }
00735         else {
00736                 strncpy((arn_CHAR*)uip_appdata,(const arn_CHAR*)(s->dataptr),s->count);
00737                 uip_len = s->count;
00738                 }
00739 }
00740 
00741 #ifdef __cplusplus
00742 }
00743 #endif