luat_ftp_client.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. /*
  2. @module ftp
  3. @summary ftp 客户端
  4. @version 1.0
  5. @date 2022.09.05
  6. @demo ftp
  7. @tag LUAT_USE_FTP
  8. */
  9. #include "luat_base.h"
  10. #include "luat_network_adapter.h"
  11. #include "luat_rtos.h"
  12. #include "luat_msgbus.h"
  13. #include "luat_fs.h"
  14. #include "luat_malloc.h"
  15. #include "luat_ftp.h"
  16. #define LUAT_LOG_TAG "ftp"
  17. #include "luat_log.h"
  18. #define FTP_DEBUG 0
  19. #if FTP_DEBUG == 0
  20. #undef LLOGD
  21. #define LLOGD(...)
  22. #endif
  23. enum
  24. {
  25. FTP_REQ_LOGIN = 1,
  26. FTP_REQ_COMMAND ,
  27. FTP_REQ_PULL ,
  28. FTP_REQ_PUSH ,
  29. FTP_REQ_CLOSE ,
  30. FTP_EVENT_LOGIN = USER_EVENT_ID_START + FTP_REQ_LOGIN,
  31. FTP_EVENT_COMMAND ,
  32. FTP_EVENT_PULL ,
  33. FTP_EVENT_PUSH ,
  34. FTP_EVENT_CLOSE ,
  35. FTP_EVENT_DATA_CONNECT ,
  36. FTP_EVENT_DATA_TX_DONE ,
  37. FTP_EVENT_DATA_WRITE_FILE ,
  38. FTP_EVENT_DATA_CLOSED ,
  39. };
  40. typedef struct{
  41. network_ctrl_t *cmd_netc; // ftp netc
  42. network_ctrl_t *data_netc; // ftp data_netc
  43. luat_ip_addr_t ip_addr; // ftp ip
  44. const char *addr; // ftp addr
  45. const char *username; // ftp username
  46. const char *password; // ftp password
  47. const char *remote_name;//去掉?
  48. size_t upload_done_size;
  49. size_t local_file_size;
  50. uint8_t cmd_send_data[FTP_CMD_SEND_MAX];
  51. uint32_t cmd_send_len;
  52. uint8_t cmd_recv_data[FTP_CMD_RECV_MAX];
  53. uint32_t cmd_recv_len;
  54. uint16_t port; // 端口号
  55. uint8_t is_tls; // 是否SSL
  56. uint8_t adapter_index;
  57. uint8_t data_netc_online;
  58. uint8_t data_netc_connecting;
  59. }luat_ftp_network_t;
  60. typedef struct{
  61. uint64_t idp;
  62. luat_rtos_task_handle task_handle;
  63. luat_ftp_network_t *network;
  64. FILE* fd; //下载 FILE
  65. Buffer_Struct result_buffer;
  66. uint8_t is_run;
  67. }luat_ftp_ctrl_t;
  68. static luat_ftp_ctrl_t g_s_ftp;
  69. static uint32_t luat_ftp_close(void) {
  70. if (!g_s_ftp.network) return 0;
  71. if (g_s_ftp.network->cmd_netc){
  72. if (network_close(g_s_ftp.network->cmd_netc,FTP_SOCKET_TIMEOUT) < 0)
  73. {
  74. network_force_close_socket(g_s_ftp.network->cmd_netc);
  75. }
  76. network_release_ctrl(g_s_ftp.network->cmd_netc);
  77. g_s_ftp.network->cmd_netc = NULL;
  78. }
  79. if (g_s_ftp.network->data_netc){
  80. network_force_close_socket(g_s_ftp.network->data_netc);
  81. network_release_ctrl(g_s_ftp.network->data_netc);
  82. g_s_ftp.network->data_netc = NULL;
  83. }
  84. if (g_s_ftp.network->addr){
  85. luat_heap_free(g_s_ftp.network->addr);
  86. g_s_ftp.network->addr = NULL;
  87. }
  88. if (g_s_ftp.network->username){
  89. luat_heap_free(g_s_ftp.network->username);
  90. g_s_ftp.network->username = NULL;
  91. }
  92. if (g_s_ftp.network->password){
  93. luat_heap_free(g_s_ftp.network->password);
  94. g_s_ftp.network->password = NULL;
  95. }
  96. if (g_s_ftp.network->remote_name){
  97. luat_heap_free(g_s_ftp.network->remote_name);
  98. g_s_ftp.network->remote_name = NULL;
  99. }
  100. luat_heap_free(g_s_ftp.network);
  101. g_s_ftp.network = NULL;
  102. return 0;
  103. }
  104. static uint32_t luat_ftp_data_send(luat_ftp_ctrl_t *ftp_ctrl, uint8_t* send_data, uint32_t send_len) {
  105. if (send_len == 0)
  106. return 0;
  107. uint32_t tx_len = 0;
  108. LLOGD("luat_ftp_data_send data:%d",send_len);
  109. network_tx(g_s_ftp.network->data_netc, send_data, send_len, 0, NULL, 0, &tx_len, 0);
  110. return tx_len;
  111. }
  112. static uint32_t luat_ftp_cmd_send(luat_ftp_ctrl_t *ftp_ctrl, uint8_t* send_data, uint32_t send_len,uint32_t timeout_ms) {
  113. if (send_len == 0)
  114. return 0;
  115. uint32_t tx_len = 0;
  116. LLOGD("luat_ftp_cmd_send data:%.*s",send_len,send_data);
  117. network_tx(g_s_ftp.network->cmd_netc, send_data, send_len, 0, NULL, 0, &tx_len, timeout_ms);
  118. return tx_len;
  119. }
  120. static int luat_ftp_cmd_recv(luat_ftp_ctrl_t *ftp_ctrl,uint8_t *recv_data,uint32_t *recv_len,uint32_t timeout_ms){
  121. uint32_t total_len = 0;
  122. uint8_t is_break = 0,is_timeout = 0;
  123. int ret = network_wait_rx(g_s_ftp.network->cmd_netc, timeout_ms, &is_break, &is_timeout);
  124. LLOGD("network_wait_rx ret:%d is_break:%d is_timeout:%d",ret,is_break,is_timeout);
  125. if (ret)
  126. return -1;
  127. if (is_timeout)
  128. return 1;
  129. else if (is_break)
  130. return 2;
  131. int result = network_rx(g_s_ftp.network->cmd_netc, NULL, 0, 0, NULL, NULL, &total_len);
  132. if (0 == result){
  133. if (total_len>0){
  134. next:
  135. result = network_rx(g_s_ftp.network->cmd_netc, recv_data, total_len, 0, NULL, NULL, recv_len);
  136. LLOGD("result:%d recv_len:%d",result,*recv_len);
  137. LLOGD("recv_data %.*s",total_len, recv_data);
  138. if (result)
  139. goto next;
  140. if (*recv_len == 0||result!=0) {
  141. return -1;
  142. }
  143. return 0;
  144. }
  145. }else{
  146. LLOGE("ftp network_rx fail");
  147. return -1;
  148. }
  149. return 0;
  150. }
  151. static int32_t l_ftp_callback(lua_State *L, void* ptr){
  152. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  153. LLOGD("l_ftp_callback arg1:%d arg2:%d idp:%lld",msg->arg1,msg->arg2,g_s_ftp.idp);
  154. if (g_s_ftp.idp)
  155. {
  156. if (msg->arg1)
  157. {
  158. lua_pushboolean(L, 0);
  159. }
  160. else if (msg->arg2)
  161. {
  162. lua_pushlstring(L,(const char *)(g_s_ftp.result_buffer.Data),g_s_ftp.result_buffer.Pos);
  163. }
  164. else
  165. {
  166. lua_pushboolean(L, 1);
  167. }
  168. luat_cbcwait(L, g_s_ftp.idp, 1);
  169. g_s_ftp.idp = 0;
  170. }
  171. OS_DeInitBuffer(&g_s_ftp.result_buffer);
  172. if (g_s_ftp.fd){
  173. luat_fs_fclose(g_s_ftp.fd);
  174. g_s_ftp.fd = NULL;
  175. }
  176. return 0;
  177. }
  178. static int32_t luat_ftp_data_callback(void *data, void *param){
  179. OS_EVENT *event = (OS_EVENT *)data;
  180. uint8_t *rx_buffer;
  181. int ret = 0;
  182. uint32_t rx_len = 0;
  183. if (!g_s_ftp.network)
  184. {
  185. return 0;
  186. }
  187. // LLOGD("event->ID %d LINK %d ON_LINE %d EVENT %d TX_OK %d CLOSED %d",event->ID,EV_NW_RESULT_LINK & 0x0fffffff,EV_NW_RESULT_CONNECT & 0x0fffffff,EV_NW_RESULT_EVENT & 0x0fffffff,EV_NW_RESULT_TX & 0x0fffffff,EV_NW_RESULT_CLOSE & 0x0fffffff);
  188. LLOGD("luat_ftp_data_callback %d %d",event->ID - EV_NW_RESULT_BASE, event->Param1);
  189. if (event->Param1){
  190. if (EV_NW_RESULT_CONNECT == event->ID)
  191. {
  192. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_DATA_CONNECT, 0xffffffff, 0, 0, LUAT_WAIT_FOREVER);
  193. }
  194. else
  195. {
  196. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_DATA_CLOSED, 0, 0, 0, LUAT_WAIT_FOREVER);
  197. }
  198. return -1;
  199. }
  200. switch (event->ID)
  201. {
  202. case EV_NW_RESULT_TX:
  203. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_DATA_TX_DONE, 0, 0, 0, LUAT_WAIT_FOREVER);
  204. break;
  205. case EV_NW_RESULT_EVENT:
  206. rx_buffer = luat_heap_malloc(4096);
  207. do
  208. {
  209. ret = network_rx(g_s_ftp.network->data_netc, rx_buffer, 4096, 0, NULL, NULL, &rx_len);
  210. // LLOGD("luat_ftp_data_callback network_rx ret:%d rx_len:%d",ret,rx_len);
  211. if (!ret && rx_len > 0)
  212. {
  213. if (g_s_ftp.fd)
  214. {
  215. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_DATA_WRITE_FILE, rx_buffer, rx_len, 0, LUAT_WAIT_FOREVER);
  216. rx_buffer = luat_heap_malloc(4096);
  217. }
  218. else
  219. {
  220. OS_BufferWrite(&g_s_ftp.result_buffer, rx_buffer, rx_len);
  221. }
  222. }
  223. } while (!ret && rx_len);
  224. luat_heap_free(rx_buffer);
  225. break;
  226. case EV_NW_RESULT_CLOSE:
  227. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_DATA_CLOSED, 0, 0, 0, LUAT_WAIT_FOREVER);
  228. return 0;
  229. break;
  230. case EV_NW_RESULT_CONNECT:
  231. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_DATA_CONNECT, 0, 0, 0, LUAT_WAIT_FOREVER);
  232. break;
  233. case EV_NW_RESULT_LINK:
  234. return 0;
  235. }
  236. ret = network_wait_event(g_s_ftp.network->data_netc, NULL, 0, NULL);
  237. if (ret < 0){
  238. network_close(g_s_ftp.network->data_netc, 0);
  239. return -1;
  240. }
  241. return 0;
  242. }
  243. static int32_t ftp_task_cb(void *pdata, void *param)
  244. {
  245. OS_EVENT *event = pdata;
  246. uint8_t *rx_buffer;
  247. int ret = 0;
  248. uint32_t rx_len = 0;
  249. if (event->ID >= FTP_EVENT_LOGIN && event->ID <= FTP_EVENT_PUSH)
  250. {
  251. LLOGE("last cmd not finish, ignore %d,%u,%u,%x", event->ID - USER_EVENT_ID_START, event->Param1, event->Param2, param);
  252. return -1;
  253. }
  254. switch(event->ID)
  255. {
  256. case FTP_EVENT_DATA_WRITE_FILE:
  257. if (g_s_ftp.fd)
  258. {
  259. luat_fs_fwrite(event->Param1, event->Param2, 1, g_s_ftp.fd);
  260. luat_heap_free(event->Param1);
  261. }
  262. break;
  263. case FTP_EVENT_DATA_TX_DONE:
  264. g_s_ftp.network->upload_done_size = (size_t)g_s_ftp.network->data_netc->ack_size;
  265. if (g_s_ftp.network->upload_done_size >= g_s_ftp.network->local_file_size)
  266. {
  267. LLOGD("ftp data upload done!");
  268. network_close(g_s_ftp.network->data_netc, 0);
  269. }
  270. break;
  271. case FTP_EVENT_DATA_CONNECT:
  272. if (g_s_ftp.network->data_netc_connecting)
  273. {
  274. g_s_ftp.network->data_netc_connecting = 0;
  275. g_s_ftp.network->data_netc_online = !event->Param1;
  276. }
  277. break;
  278. case FTP_EVENT_DATA_CLOSED:
  279. LLOGD("ftp data channel close");
  280. g_s_ftp.network->data_netc_online = 0;
  281. if (g_s_ftp.network->data_netc)
  282. {
  283. network_force_close_socket(g_s_ftp.network->data_netc);
  284. network_release_ctrl(g_s_ftp.network->data_netc);
  285. g_s_ftp.network->data_netc = NULL;
  286. }
  287. break;
  288. case FTP_EVENT_CLOSE:
  289. g_s_ftp.is_run = 0;
  290. break;
  291. default:
  292. // LLOGE("ignore %x,%x,%x", event->ID, param, EV_NW_RESULT_EVENT);
  293. break;
  294. }
  295. return 0;
  296. }
  297. static int luat_ftp_pasv_connect(luat_ftp_ctrl_t *ftp_ctrl,uint32_t timeout_ms){
  298. char h1[4]={0},h2[4]={0},h3[4]={0},h4[4]={0},p1[4]={0},p2[4]={0},data_addr[20]={0};
  299. uint8_t port1,port2;
  300. uint16_t data_port;
  301. luat_ftp_cmd_send(g_s_ftp.network, (uint8_t*)"PASV\r\n", strlen("PASV\r\n"),FTP_SOCKET_TIMEOUT);
  302. int ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  303. if (ret){
  304. return -1;
  305. }else{
  306. LLOGD("luat_ftp_pasv_connect cmd_recv_data",g_s_ftp.network->cmd_recv_data);
  307. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_ENTER_PASSIVE, 3)){
  308. LLOGD("ftp pasv_connect wrong");
  309. return -1;
  310. }
  311. }
  312. char *temp = memchr(g_s_ftp.network->cmd_recv_data, '(', strlen((const char *)(g_s_ftp.network->cmd_recv_data)));
  313. char *temp1 = memchr(temp+1, ',', strlen(temp)-1);
  314. memcpy(h1, temp+1, temp1-temp-1);
  315. char *temp2 = memchr(temp1+1, ',', strlen(temp1)-1);
  316. memcpy(h2, temp1+1, temp2-temp1-1);
  317. char *temp3 = memchr(temp2+1, ',', strlen(temp2)-1);
  318. memcpy(h3, temp2+1, temp3-temp2-1);
  319. char *temp4 = memchr(temp3+1, ',', strlen(temp3)-1);
  320. memcpy(h4, temp3+1, temp4-temp3-1);
  321. char *temp5 = memchr(temp4+1, ',', strlen(temp4)-1);
  322. memcpy(p1, temp4+1, temp5-temp4-1);
  323. char *temp6 = memchr(temp5+1, ')', strlen(temp5)-1);
  324. memcpy(p2, temp5+1, temp6-temp5-1);
  325. snprintf_(data_addr, 20, "%s.%s.%s.%s",h1,h2,h3,h4);
  326. port1 = (uint8_t)atoi(p1);
  327. port2 = (uint8_t)atoi(p2);
  328. data_port = port1 * 256 + port2;
  329. LLOGD("data_addr:%s data_port:%d",data_addr,data_port);
  330. if (memcmp(data_addr,"172.",4)==0||memcmp(data_addr,"192.",4)==0||memcmp(data_addr,"10.",3)==0||memcmp(data_addr,"127.0.0.1",9)==0||memcmp(data_addr,"169.254.0.0",11)==0||memcmp(data_addr,"169.254.0.16",12)==0){
  331. memset(data_addr,0,20);
  332. LLOGD("g_s_ftp.network->addr:%s",g_s_ftp.network->addr);
  333. memcpy(data_addr, g_s_ftp.network->addr, strlen(g_s_ftp.network->addr)+1);
  334. }
  335. LLOGD("data_addr:%s data_port:%d",data_addr,data_port);
  336. if (g_s_ftp.network->data_netc)
  337. {
  338. LLOGE("data_netc already create");
  339. return -1;
  340. }
  341. g_s_ftp.network->data_netc = network_alloc_ctrl(g_s_ftp.network->adapter_index);
  342. if (!g_s_ftp.network->data_netc){
  343. LLOGE("data_netc create fail");
  344. return -1;
  345. }
  346. network_init_ctrl(g_s_ftp.network->data_netc,NULL, luat_ftp_data_callback, g_s_ftp.network);
  347. network_set_base_mode(g_s_ftp.network->data_netc, 1, 10000, 0, 0, 0, 0);
  348. network_set_local_port(g_s_ftp.network->data_netc, 0);
  349. network_deinit_tls(g_s_ftp.network->data_netc);
  350. if(network_connect(g_s_ftp.network->data_netc, data_addr, strlen(data_addr), NULL, data_port, 0)<0){
  351. LLOGE("ftp data network connect fail");
  352. network_force_close_socket(g_s_ftp.network->data_netc);
  353. network_release_ctrl(g_s_ftp.network->data_netc);
  354. g_s_ftp.network->data_netc = NULL;
  355. return -1;
  356. }
  357. uint8_t is_timeout;
  358. OS_EVENT event;
  359. g_s_ftp.network->data_netc_connecting = 1;
  360. g_s_ftp.network->data_netc_online = 0;
  361. while(g_s_ftp.network->data_netc_connecting)
  362. {
  363. if (network_wait_event(g_s_ftp.network->cmd_netc, &event, timeout_ms, &is_timeout))
  364. {
  365. return -1;
  366. }
  367. if (is_timeout)
  368. {
  369. return -1;
  370. }
  371. if (event.ID)
  372. {
  373. ftp_task_cb(&event, NULL);
  374. }
  375. else
  376. {
  377. if (g_s_ftp.network->cmd_netc->new_rx_flag)
  378. {
  379. network_rx(g_s_ftp.network->cmd_netc, g_s_ftp.network->cmd_recv_data, 1024, 0, NULL, NULL, &g_s_ftp.network->cmd_recv_len);
  380. LLOGD("ftp cmd rx %.*s", g_s_ftp.network->cmd_recv_len, g_s_ftp.network->cmd_recv_data);
  381. }
  382. }
  383. }
  384. if (g_s_ftp.network->data_netc_online)
  385. {
  386. LLOGD("ftp pasv_connect ok");
  387. return 0;
  388. }
  389. return -1;
  390. }
  391. static int ftp_login(void)
  392. {
  393. int ret;
  394. if(network_connect(g_s_ftp.network->cmd_netc, g_s_ftp.network->addr, strlen(g_s_ftp.network->addr), NULL, g_s_ftp.network->port, FTP_SOCKET_TIMEOUT)){
  395. LLOGE("ftp network_connect fail");
  396. return -1;
  397. }
  398. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  399. if (ret){
  400. return -1;
  401. }else{
  402. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_SERVICE_NEW_OK, 3)){
  403. LLOGE("ftp connect error");
  404. return -1;
  405. }
  406. }
  407. LLOGD("ftp connect ok");
  408. memset(g_s_ftp.network->cmd_send_data,0,FTP_CMD_SEND_MAX);
  409. snprintf_((char *)(g_s_ftp.network->cmd_send_data), FTP_CMD_SEND_MAX, "USER %s\r\n",g_s_ftp.network->username);
  410. luat_ftp_cmd_send(g_s_ftp.network, g_s_ftp.network->cmd_send_data, strlen((const char *)(g_s_ftp.network->cmd_send_data)),FTP_SOCKET_TIMEOUT);
  411. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  412. if (ret){
  413. LLOGE("ftp username wrong");
  414. return -1;
  415. }else{
  416. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_USERNAME_OK, 3)){
  417. LLOGE("ftp username wrong");
  418. return -1;
  419. }
  420. }
  421. LLOGD("ftp username ok");
  422. memset(g_s_ftp.network->cmd_send_data,0,FTP_CMD_SEND_MAX);
  423. snprintf_((char *)(g_s_ftp.network->cmd_send_data), FTP_CMD_SEND_MAX, "PASS %s\r\n",g_s_ftp.network->password);
  424. luat_ftp_cmd_send(g_s_ftp.network, g_s_ftp.network->cmd_send_data, strlen((const char *)(g_s_ftp.network->cmd_send_data)),FTP_SOCKET_TIMEOUT);
  425. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  426. if (ret){
  427. LLOGE("ftp login wrong");
  428. return -1;
  429. }else{
  430. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_LOGIN_OK, 3)){
  431. LLOGE("ftp login wrong");
  432. return -1;
  433. }
  434. }
  435. LLOGD("ftp login ok");
  436. return 0;
  437. }
  438. static void ftp_task(void *param){
  439. int ret;
  440. luat_rtos_task_handle task_handle = g_s_ftp.task_handle;
  441. OS_EVENT task_event;
  442. rtos_msg_t msg = {0};
  443. uint8_t is_timeout = 0;
  444. uint8_t is_online = 0;
  445. g_s_ftp.is_run = 1;
  446. msg.handler = l_ftp_callback;
  447. luat_rtos_event_recv(g_s_ftp.task_handle, FTP_EVENT_LOGIN, &task_event, NULL, LUAT_WAIT_FOREVER);
  448. if (ftp_login())
  449. {
  450. LLOGE("ftp login fail");
  451. luat_ftp_close();
  452. msg.arg1 = 1;
  453. luat_msgbus_put(&msg, 0);
  454. g_s_ftp.task_handle = NULL;
  455. luat_rtos_task_delete(task_handle);
  456. return;
  457. }
  458. else
  459. {
  460. msg.arg1 = 0;
  461. msg.arg2 = 0;
  462. luat_msgbus_put(&msg, 0);
  463. }
  464. while (g_s_ftp.is_run) {
  465. is_timeout = 0;
  466. ret = network_wait_event(g_s_ftp.network->cmd_netc, &task_event, 3600000, &is_timeout);
  467. if (ret < 0)
  468. {
  469. LLOGE("ftp network error");
  470. goto wait_event_and_out;
  471. }
  472. else if (is_timeout || !task_event.ID)
  473. {
  474. if (g_s_ftp.network->cmd_netc->new_rx_flag)
  475. {
  476. network_rx(g_s_ftp.network->cmd_netc, g_s_ftp.network->cmd_recv_data, 1024, 0, NULL, NULL, &ret);
  477. LLOGD("ftp rx %dbyte", ret);
  478. }
  479. continue;
  480. }
  481. msg.arg1 = 0;
  482. msg.arg2 = 0;
  483. switch (task_event.ID)
  484. {
  485. case FTP_EVENT_LOGIN:
  486. break;
  487. case FTP_EVENT_PULL:
  488. if (g_s_ftp.network->data_netc)
  489. {
  490. network_force_close_socket(g_s_ftp.network->data_netc);
  491. network_release_ctrl(g_s_ftp.network->data_netc);
  492. g_s_ftp.network->data_netc = NULL;
  493. }
  494. if(luat_ftp_pasv_connect(g_s_ftp.network,FTP_SOCKET_TIMEOUT)){
  495. LLOGE("ftp pasv_connect fail");
  496. goto operation_failed;
  497. }
  498. snprintf_((char *)(g_s_ftp.network->cmd_send_data), FTP_CMD_SEND_MAX, "RETR %s\r\n",g_s_ftp.network->remote_name);
  499. luat_ftp_cmd_send(g_s_ftp.network, g_s_ftp.network->cmd_send_data, strlen((const char *)g_s_ftp.network->cmd_send_data),FTP_SOCKET_TIMEOUT);
  500. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  501. if (ret){
  502. goto operation_failed;
  503. }else{
  504. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_STATUS_OK, 3)){
  505. LLOGD("ftp RETR wrong");
  506. goto operation_failed;
  507. }
  508. }
  509. if (!g_s_ftp.network->data_netc_online)
  510. {
  511. g_s_ftp.network->cmd_recv_data[g_s_ftp.network->cmd_recv_len] = 0;
  512. LLOGD("ftp RETR maybe done!");
  513. if (strstr((const char *)(g_s_ftp.network->cmd_recv_data), "226 "))
  514. {
  515. LLOGD("ftp RETR ok!");
  516. if (g_s_ftp.fd){
  517. luat_fs_fclose(g_s_ftp.fd);
  518. g_s_ftp.fd = NULL;
  519. }
  520. luat_msgbus_put(&msg, 0);
  521. break;
  522. }
  523. }
  524. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  525. if (ret){
  526. goto operation_failed;
  527. }else{
  528. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_CLOSE_CONNECT, 3)){
  529. LLOGD("ftp RETR wrong");
  530. goto operation_failed;
  531. }
  532. }
  533. luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT/10);
  534. if (g_s_ftp.fd){
  535. luat_fs_fclose(g_s_ftp.fd);
  536. g_s_ftp.fd = NULL;
  537. }
  538. luat_msgbus_put(&msg, 0);
  539. break;
  540. case FTP_EVENT_PUSH:
  541. if(luat_ftp_pasv_connect(g_s_ftp.network,FTP_SOCKET_TIMEOUT)){
  542. LLOGD("ftp pasv_connect fail");
  543. goto operation_failed;
  544. }
  545. memset(g_s_ftp.network->cmd_send_data,0,FTP_CMD_SEND_MAX);
  546. snprintf_((char *)(g_s_ftp.network->cmd_send_data), FTP_CMD_SEND_MAX, "STOR %s\r\n",g_s_ftp.network->remote_name);
  547. luat_ftp_cmd_send(g_s_ftp.network, g_s_ftp.network->cmd_send_data, strlen((const char *)g_s_ftp.network->cmd_send_data),FTP_SOCKET_TIMEOUT);
  548. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  549. if (ret){
  550. goto operation_failed;
  551. }else{
  552. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_STATUS_OK, 3)){
  553. LLOGD("ftp STOR wrong");
  554. goto operation_failed;
  555. }
  556. }
  557. uint8_t* buff = luat_heap_malloc(PUSH_BUFF_SIZE);
  558. int offset = 0;
  559. g_s_ftp.network->upload_done_size = 0;
  560. while (1) {
  561. memset(buff, 0, PUSH_BUFF_SIZE);
  562. int len = luat_fs_fread(buff, sizeof(uint8_t), PUSH_BUFF_SIZE, g_s_ftp.fd);
  563. if (len < 1)
  564. break;
  565. luat_ftp_data_send(g_s_ftp.network, buff, len);
  566. offset += len;
  567. }
  568. luat_heap_free(buff);
  569. LLOGD("offset:%d file_size:%d",offset,g_s_ftp.network->local_file_size);
  570. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  571. if (g_s_ftp.network->upload_done_size != g_s_ftp.network->local_file_size)
  572. {
  573. LLOGE("upload not finish !!! %d,%d", g_s_ftp.network->upload_done_size, g_s_ftp.network->local_file_size);
  574. }
  575. if (ret){
  576. goto operation_failed;
  577. }else{
  578. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_CLOSE_CONNECT, 3)){
  579. LLOGD("ftp STOR wrong");
  580. }
  581. }
  582. luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT/10);
  583. if (g_s_ftp.fd){
  584. luat_fs_fclose(g_s_ftp.fd);
  585. g_s_ftp.fd = NULL;
  586. }
  587. luat_msgbus_put(&msg, 0);
  588. break;
  589. case FTP_EVENT_CLOSE:
  590. g_s_ftp.is_run = 0;
  591. break;
  592. case FTP_EVENT_COMMAND:
  593. OS_DeInitBuffer(&g_s_ftp.result_buffer);
  594. if(!memcmp(g_s_ftp.network->cmd_send_data, "LIST", 4))
  595. {
  596. if(luat_ftp_pasv_connect(g_s_ftp.network,FTP_SOCKET_TIMEOUT)){
  597. LLOGD("ftp pasv_connect fail");
  598. goto operation_failed;
  599. }
  600. luat_ftp_cmd_send(g_s_ftp.network, g_s_ftp.network->cmd_send_data, strlen((const char *)(g_s_ftp.network->cmd_send_data)),FTP_SOCKET_TIMEOUT);
  601. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  602. if (ret){
  603. goto operation_failed;
  604. }else{
  605. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_STATUS_OK, 3)){
  606. LLOGE("ftp LIST wrong");
  607. goto operation_failed;
  608. }
  609. }
  610. if (!g_s_ftp.network->data_netc_online)
  611. {
  612. g_s_ftp.network->cmd_recv_data[g_s_ftp.network->cmd_recv_len] = 0;
  613. LLOGD("ftp LIST maybe done!");
  614. if (strstr((const char *)(g_s_ftp.network->cmd_recv_data), FTP_CLOSE_CONNECT))
  615. {
  616. LLOGD("ftp LIST ok!");
  617. msg.arg2 = 1;
  618. luat_msgbus_put(&msg, 0);
  619. break;
  620. }
  621. }
  622. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  623. if (ret){
  624. goto operation_failed;
  625. }else{
  626. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_CLOSE_CONNECT, 3)){
  627. LLOGE("ftp LIST wrong");
  628. goto operation_failed;
  629. }
  630. }
  631. msg.arg2 = 1;
  632. luat_msgbus_put(&msg, 0);
  633. break;
  634. }
  635. luat_ftp_cmd_send(g_s_ftp.network, g_s_ftp.network->cmd_send_data, strlen((const char *)(g_s_ftp.network->cmd_send_data)),FTP_SOCKET_TIMEOUT);
  636. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  637. if (ret){
  638. goto operation_failed;
  639. }else{
  640. if (memcmp(g_s_ftp.network->cmd_send_data, "NOOP", 4)==0){
  641. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_COMMAND_OK, 3)){
  642. LLOGD("ftp COMMAND wrong");
  643. }
  644. }else if(memcmp(g_s_ftp.network->cmd_send_data, "TYPE", 4)==0){
  645. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_COMMAND_OK, 3)){
  646. LLOGD("ftp COMMAND wrong");
  647. }
  648. }else if(memcmp(g_s_ftp.network->cmd_send_data, "SYST", 4)==0){
  649. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_SYSTEM_TYPE, 3)){
  650. LLOGD("ftp COMMAND wrong");
  651. }
  652. }else if(memcmp(g_s_ftp.network->cmd_send_data, "PWD", 3)==0){
  653. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_PATHNAME_OK, 3)){
  654. LLOGD("ftp COMMAND wrong");
  655. }
  656. }else if(memcmp(g_s_ftp.network->cmd_send_data, "MKD", 3)==0){
  657. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_PATHNAME_OK, 3)){
  658. LLOGD("ftp COMMAND wrong");
  659. }
  660. }else if(memcmp(g_s_ftp.network->cmd_send_data, "CWD", 3)==0){
  661. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_REQUESTED_OK, 3)){
  662. LLOGD("ftp COMMAND wrong");
  663. }
  664. }else if(memcmp(g_s_ftp.network->cmd_send_data, "CDUP", 4)==0){
  665. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_REQUESTED_OK, 3)){
  666. LLOGD("ftp COMMAND wrong");
  667. }
  668. }else if(memcmp(g_s_ftp.network->cmd_send_data, "RMD", 3)==0){
  669. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_REQUESTED_OK, 3)){
  670. LLOGD("ftp COMMAND wrong");
  671. }
  672. }else if(memcmp(g_s_ftp.network->cmd_send_data, "DELE", 4)==0){
  673. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_FILE_REQUESTED_OK, 3)){
  674. LLOGD("ftp COMMAND wrong");
  675. }
  676. }else if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_DATA_CON_FAIL, 3)==0){
  677. LLOGD("ftp need pasv_connect");
  678. }
  679. }
  680. OS_BufferWrite(&g_s_ftp.result_buffer, g_s_ftp.network->cmd_recv_data, g_s_ftp.network->cmd_recv_len);
  681. msg.arg2 = 1;
  682. luat_msgbus_put(&msg, 0);
  683. break;
  684. default:
  685. break;
  686. }
  687. continue;
  688. operation_failed:
  689. msg.arg1 = 1;
  690. luat_msgbus_put(&msg, 0);
  691. }
  692. msg.arg1 = 0;
  693. msg.arg2 = 0;
  694. luat_ftp_cmd_send(g_s_ftp.network, (uint8_t*)"QUIT\r\n", strlen("QUIT\r\n"),FTP_SOCKET_TIMEOUT);
  695. ret = luat_ftp_cmd_recv(g_s_ftp.network,g_s_ftp.network->cmd_recv_data,&g_s_ftp.network->cmd_recv_len,FTP_SOCKET_TIMEOUT);
  696. if (ret){
  697. msg.arg1 = 1;
  698. }else{
  699. if (memcmp(g_s_ftp.network->cmd_recv_data, FTP_CLOSE_CONTROL, 3)){
  700. LLOGE("ftp QUIT wrong");
  701. msg.arg1 = 1;
  702. }
  703. }
  704. OS_BufferWrite(&g_s_ftp.result_buffer, g_s_ftp.network->cmd_recv_data, g_s_ftp.network->cmd_recv_len);
  705. msg.arg2 = 1;
  706. luat_ftp_close();
  707. luat_msgbus_put(&msg, 0);
  708. g_s_ftp.task_handle = NULL;
  709. luat_rtos_task_delete(task_handle);
  710. return;
  711. wait_event_and_out:
  712. while(1)
  713. {
  714. luat_rtos_event_recv(g_s_ftp.task_handle, 0, &task_event, NULL, LUAT_WAIT_FOREVER);
  715. if (task_event.ID >= FTP_EVENT_LOGIN && task_event.ID <= FTP_EVENT_CLOSE)
  716. {
  717. luat_ftp_close();
  718. msg.arg1 = 1;
  719. luat_msgbus_put(&msg, 0);
  720. g_s_ftp.task_handle = NULL;
  721. luat_rtos_task_delete(task_handle);
  722. return;
  723. }
  724. }
  725. }
  726. /*
  727. FTP客户端
  728. @api ftp.login(adapter,ip_addr,port,username,password)
  729. @int 适配器序号, 只能是socket.ETH0, socket.STA, socket.AP,如果不填,会选择平台自带的方式,然后是最后一个注册的适配器
  730. @string ip_addr 地址
  731. @string port 端口,默认21
  732. @string username 用户名
  733. @string password 密码
  734. @bool/table 是否为ssl加密连接,默认不加密,true为无证书最简单的加密,table为有证书的加密 <br>server_cert 服务器ca证书数据 <br>client_cert 客户端ca证书数据 <br>client_key 客户端私钥加密数据 <br>client_password 客户端私钥口令数据
  735. @return bool/string 成功返回true 失败返回string
  736. @usage
  737. ftp_login = ftp.login(nil,"xxx")
  738. */
  739. static int l_ftp_login(lua_State *L) {
  740. size_t server_cert_len,client_cert_len, client_key_len, client_password_len,addr_len,username_len,password_len;
  741. const char *server_cert = NULL;
  742. const char *client_cert = NULL;
  743. const char *client_key = NULL;
  744. const char *client_password = NULL;
  745. const char *username = NULL;
  746. const char *password = NULL;
  747. uint8_t is_timeout = 0;
  748. int result = 0;
  749. // mbedtls_debug_set_threshold(4);
  750. if (g_s_ftp.network){
  751. LLOGE("ftp already login, please close first");
  752. result = FTP_ERROR_STATE;
  753. goto error;
  754. }
  755. g_s_ftp.network = (luat_ftp_network_t *)luat_heap_malloc(sizeof(luat_ftp_network_t));
  756. if (!g_s_ftp.network){
  757. LLOGE("out of memory when malloc g_s_ftp.network");
  758. result = FTP_ERROR_NO_MEM;
  759. goto error;
  760. }
  761. memset(g_s_ftp.network, 0, sizeof(luat_ftp_network_t));
  762. g_s_ftp.network->adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
  763. if (g_s_ftp.network->adapter_index < 0 || g_s_ftp.network->adapter_index >= NW_ADAPTER_QTY){
  764. LLOGE("bad network adapter index %d", g_s_ftp.network->adapter_index);
  765. result = FTP_ERROR_STATE;
  766. goto error;
  767. }
  768. g_s_ftp.network->cmd_netc = network_alloc_ctrl(g_s_ftp.network->adapter_index);
  769. if (!g_s_ftp.network->cmd_netc){
  770. LLOGE("cmd_netc create fail");
  771. result = FTP_ERROR_NO_MEM;
  772. goto error;
  773. }
  774. luat_rtos_task_create(&g_s_ftp.task_handle, 2048, 40, "ftp", ftp_task, NULL, 16);
  775. network_init_ctrl(g_s_ftp.network->cmd_netc,g_s_ftp.task_handle, ftp_task_cb, NULL);
  776. network_set_base_mode(g_s_ftp.network->cmd_netc, 1, 30000, 0, 0, 0, 0);
  777. network_set_local_port(g_s_ftp.network->cmd_netc, 0);
  778. const char *addr = luaL_checklstring(L, 2, &addr_len);
  779. g_s_ftp.network->addr = luat_heap_malloc(addr_len + 1);
  780. memset(g_s_ftp.network->addr, 0, addr_len + 1);
  781. memcpy(g_s_ftp.network->addr, addr, addr_len);
  782. g_s_ftp.network->port = luaL_optinteger(L, 3, 21);
  783. username = luaL_optlstring(L, 4, "",&username_len);
  784. g_s_ftp.network->username = luat_heap_malloc(username_len + 1);
  785. memset(g_s_ftp.network->username, 0, username_len + 1);
  786. memcpy(g_s_ftp.network->username, username, username_len);
  787. password = luaL_optlstring(L, 5, "",&password_len);
  788. g_s_ftp.network->password = luat_heap_malloc(password_len + 1);
  789. memset(g_s_ftp.network->password, 0, password_len + 1);
  790. memcpy(g_s_ftp.network->password, password, password_len);
  791. // 加密相关
  792. if (lua_isboolean(L, 6)){
  793. g_s_ftp.network->is_tls = lua_toboolean(L, 6);
  794. }
  795. if (lua_istable(L, 6)){
  796. g_s_ftp.network->is_tls = 1;
  797. lua_pushstring(L, "server_cert");
  798. if (LUA_TSTRING == lua_gettable(L, 6)) {
  799. server_cert = luaL_checklstring(L, -1, &server_cert_len);
  800. }
  801. lua_pop(L, 1);
  802. lua_pushstring(L, "client_cert");
  803. if (LUA_TSTRING == lua_gettable(L, 6)) {
  804. client_cert = luaL_checklstring(L, -1, &client_cert_len);
  805. }
  806. lua_pop(L, 1);
  807. lua_pushstring(L, "client_key");
  808. if (LUA_TSTRING == lua_gettable(L, 6)) {
  809. client_key = luaL_checklstring(L, -1, &client_key_len);
  810. }
  811. lua_pop(L, 1);
  812. lua_pushstring(L, "client_password");
  813. if (LUA_TSTRING == lua_gettable(L, 6)) {
  814. client_password = luaL_checklstring(L, -1, &client_password_len);
  815. }
  816. lua_pop(L, 1);
  817. }
  818. if (g_s_ftp.network->is_tls){
  819. if (lua_isstring(L, 6)){
  820. server_cert = luaL_checklstring(L, 6, &server_cert_len);
  821. }
  822. if (lua_isstring(L, 7)){
  823. client_cert = luaL_checklstring(L, 7, &client_cert_len);
  824. }
  825. if (lua_isstring(L, 8)){
  826. client_key = luaL_checklstring(L, 8, &client_key_len);
  827. }
  828. if (lua_isstring(L, 9)){
  829. client_password = luaL_checklstring(L, 9, &client_password_len);
  830. }
  831. if (network_init_tls(g_s_ftp.network->cmd_netc, (server_cert || client_cert)?2:0)){
  832. result = FTP_ERROR_CLOSE;
  833. goto error;
  834. }
  835. if (server_cert){
  836. network_set_server_cert(g_s_ftp.network->cmd_netc, (const unsigned char *)server_cert, server_cert_len+1);
  837. }
  838. if (client_cert){
  839. network_set_client_cert(g_s_ftp.network->cmd_netc, (const unsigned char *)client_cert, client_cert_len+1,
  840. (const unsigned char *)client_key, client_key_len+1,
  841. (const unsigned char *)client_password, client_password_len+1);
  842. }
  843. }else{
  844. network_deinit_tls(g_s_ftp.network->cmd_netc);
  845. }
  846. network_set_ip_invaild(&g_s_ftp.network->ip_addr);
  847. g_s_ftp.idp = luat_pushcwait(L);
  848. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_LOGIN, 0, 0, 0, LUAT_WAIT_FOREVER);
  849. return 1;
  850. error:
  851. LLOGE("ftp login fail");
  852. luat_ftp_close();
  853. lua_pushinteger(L, result);
  854. luat_pushcwait_error(L,1);
  855. return 1;
  856. }
  857. /*
  858. FTP命令
  859. @api ftp.command(cmd)
  860. @string cmd 命令 目前支持:NOOP SYST TYPE PWD MKD CWD CDUP RMD DELE LIST
  861. @return string 成功返回true 失败返回string
  862. @usage
  863. print(ftp.command("NOOP").wait())
  864. print(ftp.command("SYST").wait())
  865. print(ftp.command("TYPE I").wait())
  866. print(ftp.command("PWD").wait())
  867. print(ftp.command("MKD QWER").wait())
  868. print(ftp.command("CWD /QWER").wait())
  869. print(ftp.command("CDUP").wait())
  870. print(ftp.command("RMD QWER").wait())
  871. print(ftp.command("DELE /1/12222.txt").wait())
  872. */
  873. static int l_ftp_command(lua_State *L) {
  874. if (!g_s_ftp.network){
  875. LLOGE("please login first");
  876. goto error;
  877. }
  878. g_s_ftp.idp = luat_pushcwait(L);
  879. size_t len;
  880. const char *cmd = luaL_checklstring(L, 1, &len);
  881. if (memcmp(cmd, "NOOP", 4)==0){
  882. LLOGD("command: NOOP");
  883. }else if(memcmp(cmd, "SYST", 4)==0){
  884. LLOGD("command: SYST");
  885. }else if(memcmp(cmd, "MKD", 3)==0){
  886. LLOGD("command: MKD");
  887. }else if(memcmp(cmd, "CWD", 3)==0){
  888. LLOGD("command: CWD");
  889. }else if(memcmp(cmd, "CDUP", 4)==0){
  890. LLOGD("command: CDUP");
  891. }else if(memcmp(cmd, "RMD", 3)==0){
  892. LLOGD("command: RMD");
  893. }else if(memcmp(cmd, "PWD", 3)==0){
  894. LLOGD("command: RMD");
  895. }else if(memcmp(cmd, "DELE", 4)==0){
  896. LLOGD("command: DELE");
  897. }else if(memcmp(cmd, "TYPE", 4)==0){
  898. LLOGD("command: TYPE");
  899. }else if(memcmp(cmd, "LIST", 4)==0){
  900. LLOGD("command: LIST");
  901. }else{
  902. LLOGE("not support cmd:%s",cmd);
  903. lua_pushinteger(L,FTP_ERROR_FILE);
  904. luat_pushcwait_error(L,1);
  905. return 1;
  906. }
  907. memset(g_s_ftp.network->cmd_send_data,0,FTP_CMD_SEND_MAX);
  908. snprintf_((char *)(g_s_ftp.network->cmd_send_data), FTP_CMD_SEND_MAX, "%s\r\n",cmd);
  909. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_COMMAND, (uint32_t)g_s_ftp.idp, (uint32_t)(g_s_ftp.idp >> 32), 0, LUAT_WAIT_FOREVER);
  910. return 1;
  911. error:
  912. LLOGE("ftp command fail");
  913. lua_pushinteger(L,FTP_ERROR_FILE);
  914. luat_pushcwait_error(L,1);
  915. return 1;
  916. }
  917. /*
  918. FTP文件下载
  919. @api ftp.pull(local_name,remote_name)
  920. @string local_name 本地文件
  921. @string remote_name 服务器文件
  922. @return bool/string 成功返回true 失败返回string
  923. @usage
  924. ftp.pull("/1222.txt","/1222.txt").wait()
  925. */
  926. static int l_ftp_pull(lua_State *L) {
  927. size_t len;
  928. if (!g_s_ftp.network){
  929. LLOGE("please login first");
  930. goto error;
  931. }
  932. g_s_ftp.idp = luat_pushcwait(L);
  933. const char * local_name = luaL_optlstring(L, 1, "",&len);
  934. luat_fs_remove(local_name);
  935. if (g_s_ftp.fd)
  936. {
  937. luat_fs_fclose(g_s_ftp.fd);
  938. g_s_ftp.fd = NULL;
  939. }
  940. g_s_ftp.fd = luat_fs_fopen(local_name, "wb+");
  941. if (g_s_ftp.fd == NULL) {
  942. LLOGE("open download file fail %s", local_name);
  943. goto error;
  944. }
  945. g_s_ftp.network->local_file_size = luat_fs_fsize(local_name);
  946. const char * remote_name = luaL_optlstring(L, 2, "",&len);
  947. if (g_s_ftp.network->remote_name) {
  948. luat_heap_free(g_s_ftp.network->remote_name);
  949. g_s_ftp.network->remote_name = NULL;
  950. }
  951. g_s_ftp.network->remote_name = luat_heap_malloc(len + 1);
  952. memset(g_s_ftp.network->remote_name, 0, len + 1);
  953. memcpy(g_s_ftp.network->remote_name, remote_name, len);
  954. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_PULL, 0, 0, 0, NULL);
  955. return 1;
  956. error:
  957. LLOGE("ftp pull fail");
  958. lua_pushinteger(L,FTP_ERROR_FILE);
  959. luat_pushcwait_error(L,1);
  960. return 1;
  961. }
  962. /*
  963. FTP文件上传
  964. @api ftp.push(local_name,remote_name)
  965. @string local_name 本地文件
  966. @string remote_name 服务器文件
  967. @return bool/string 成功返回true 失败返回string
  968. @usage
  969. ftp.push("/1222.txt","/1222.txt").wait()
  970. */
  971. static int l_ftp_push(lua_State *L) {
  972. size_t len;
  973. if (!g_s_ftp.network){
  974. LLOGE("please login first");
  975. goto error;
  976. }
  977. g_s_ftp.idp = luat_pushcwait(L);
  978. const char * local_name = luaL_optlstring(L, 1, "",&len);
  979. if (g_s_ftp.fd)
  980. {
  981. luat_fs_fclose(g_s_ftp.fd);
  982. g_s_ftp.fd = NULL;
  983. }
  984. g_s_ftp.fd = luat_fs_fopen(local_name, "rb");
  985. if (g_s_ftp.fd == NULL) {
  986. LLOGE("open download file fail %s", local_name);
  987. goto error;
  988. }
  989. g_s_ftp.network->local_file_size = luat_fs_fsize(local_name);
  990. const char * remote_name = luaL_optlstring(L, 2, "",&len);
  991. if (g_s_ftp.network->remote_name) {
  992. luat_heap_free(g_s_ftp.network->remote_name);
  993. g_s_ftp.network->remote_name = NULL;
  994. }
  995. g_s_ftp.network->remote_name = luat_heap_malloc(len + 1);
  996. memset(g_s_ftp.network->remote_name, 0, len + 1);
  997. memcpy(g_s_ftp.network->remote_name, remote_name, len);
  998. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_PUSH, 0, 0, 0, LUAT_WAIT_FOREVER);
  999. return 1;
  1000. error:
  1001. LLOGE("ftp push fail");
  1002. lua_pushinteger(L,FTP_ERROR_CONNECT);
  1003. luat_pushcwait_error(L,1);
  1004. return 1;
  1005. }
  1006. /*
  1007. FTP客户端关闭
  1008. @api ftp.close()
  1009. @return bool/string 成功返回true 失败返回string
  1010. @usage
  1011. ftp.close().wait()
  1012. */
  1013. static int l_ftp_close(lua_State *L) {
  1014. if (!g_s_ftp.network){
  1015. LLOGE("please login first");
  1016. goto error;
  1017. }
  1018. g_s_ftp.idp = luat_pushcwait(L);
  1019. luat_rtos_event_send(g_s_ftp.task_handle, FTP_EVENT_CLOSE, 0, 0, 0, LUAT_WAIT_FOREVER);
  1020. return 1;
  1021. error:
  1022. lua_pushinteger(L,FTP_ERROR_CONNECT);
  1023. luat_pushcwait_error(L,1);
  1024. return 1;
  1025. }
  1026. #include "rotable2.h"
  1027. #ifdef LUAT_USE_NETWORK
  1028. static const rotable_Reg_t reg_ftp[] =
  1029. {
  1030. {"login", ROREG_FUNC(l_ftp_login)},
  1031. {"command", ROREG_FUNC(l_ftp_command)},
  1032. {"pull", ROREG_FUNC(l_ftp_pull)},
  1033. {"push", ROREG_FUNC(l_ftp_push)},
  1034. {"close", ROREG_FUNC(l_ftp_close)},
  1035. { NULL, ROREG_INT(0)}
  1036. };
  1037. #else
  1038. static const rotable_Reg_t reg_ftp_emtry[] =
  1039. {
  1040. { NULL, ROREG_INT(0)}
  1041. };
  1042. #endif
  1043. LUAMOD_API int luaopen_ftp( lua_State *L ) {
  1044. #ifdef LUAT_USE_NETWORK
  1045. luat_newlib2(L, reg_ftp);
  1046. #else
  1047. luat_newlib2(L, reg_ftp_emtry);
  1048. LLOGE("reg_ftp require network enable!!");
  1049. #endif
  1050. return 1;
  1051. }