luat_ftp_client.c 33 KB

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