00001
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
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
00062 #ifdef DEBUG
00063 #include "arnDebug.h"
00064 #define PRINT(x) arnDEBUG("%s",x)
00065 #define PRINTLN(x) arnDEBUG("%s\n",x)
00066 #define PRINTNUM(x) arnDEBUG("%d",x)
00067 #define PRINTNUMLN(x) arnDEBUG("%d\n",x)
00068 #else
00069 #define PRINT(x)
00070 #define PRINTLN(x)
00071 #define PRINTNUMLN(x)
00072 #define PRINTNUM(x)
00073 #endif
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
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
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
00404 if (uip_conn->rport == htons(s->remotectrlport)) {
00405
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
00414
00415 if(uip_rexmit() ||
00416 uip_newdata() ||
00417 uip_acked()) {
00418 _senddata(s);
00419 }
00420 else if (uip_poll()) {
00421 _senddata(s);
00422 }
00423
00424 }
00425 else if (uip_conn->rport == HTONS(20)) {
00426
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
00435
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
00446 }
00447 }
00448
00449
00450 void _abort(struct ftp_state *s)
00451 {
00452 }
00453
00454 void _timeout(struct ftp_state *s)
00455 {
00456
00457 }
00458
00459 arn_uCHAR TSTclose;
00460
00461 void _close(struct ftp_state *s)
00462 {
00463
00464 TSTclose++;
00465
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
00477 arn_uCHAR TSTconn;
00478 arn_CHAR TSTgetBff[8][16];
00479
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
00489 strncpy(TSTgetBff[TSTconn],(arn_CHAR*)uip_appdata,16);
00490 TSTconn++;
00491 if (TSTconn == 8) TSTconn = 0;
00492
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
00533
00534
00535
00536 default: break;
00537 }
00538 }
00539 }
00540
00541
00542 arn_uCHAR TSTack;
00543
00544 void _ack(struct ftp_state *s)
00545 {
00546 TSTack++;
00547 uip_len = 0;
00548 }
00549
00550 arn_CHAR TSTpss[32];
00551
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
00565 return;
00566 default:
00567 break;
00568 }
00569
00570 if (s->CmdSnt == CMDSND_PASS) strcpy(TSTpss,(const arn_CHAR*)s->data);
00571
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
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
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