rz.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /*
  2. * File : rz.c
  3. * the implemention of receiving files from the remote computers
  4. * through the zmodem protocol.
  5. * Change Logs:
  6. * Date Author Notes
  7. * 2011-03-29 itspy
  8. */
  9. #include <rtthread.h>
  10. #include <finsh.h>
  11. #include <shell.h>
  12. #include <rtdef.h>
  13. #include <dfs.h>
  14. #include <dfs_file.h>
  15. #include <dfs_posix.h>
  16. #include <stdio.h>
  17. #include "zdef.h"
  18. void zr_start(char *path);
  19. static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf);
  20. static rt_err_t zrec_files(struct zfile *zf);
  21. static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
  22. static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf);;
  23. static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf);
  24. static rt_err_t zget_file_info(char *name, struct zfile *zf);
  25. static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
  26. static void zrec_ack_bibi(void);
  27. /* start zmodem receive proccess */
  28. void zr_start(char *path)
  29. {
  30. struct zfile *zf;
  31. rt_uint8_t n;
  32. char ch,*p,*q;
  33. rt_err_t res = -RT_ERROR;
  34. zf = rt_malloc(sizeof(struct zfile));
  35. if (zf == RT_NULL)
  36. {
  37. rt_kprintf("zf: out of memory\r\n");
  38. return;
  39. }
  40. memset(zf, 0, sizeof(struct zfile));
  41. zf->fname = path;
  42. zf->fd = -1;
  43. res = zrec_files(zf);
  44. p = zf->fname;
  45. for (;;)
  46. {
  47. q = strstr(p,"/");
  48. if (q == RT_NULL) break;
  49. p = q+1;
  50. }
  51. if (res == RT_EOK)
  52. {
  53. rt_kprintf("\b\b\bfile: %s \r\n",p);
  54. rt_kprintf("size: %ld bytes\r\n",zf->bytes_received);
  55. rt_kprintf("receive completed.\r\n");
  56. close(zf->fd);
  57. rt_free(zf->fname);
  58. }
  59. else
  60. {
  61. rt_kprintf("\b\b\bfile: %s \r\n",p);
  62. rt_kprintf("size: 0 bytes\r\n");
  63. rt_kprintf("receive failed.\r\n");
  64. if (zf->fd >= 0)
  65. {
  66. close(zf->fd);
  67. unlink(zf->fname); /* remove this file */
  68. rt_free(zf->fname);
  69. }
  70. }
  71. rt_free(zf);
  72. /* waiting,clear console buffer */
  73. rt_thread_delay(RT_TICK_PER_SECOND/2);
  74. while(1)
  75. {
  76. n=rt_device_read(shell->device, 0, &ch, 1);
  77. if (n == 0) break;
  78. }
  79. return ;
  80. }
  81. /* receiver init, wait for ack */
  82. static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf)
  83. {
  84. rt_uint8_t err_cnt = 0;
  85. rt_err_t res = -RT_ERROR;
  86. for (;;)
  87. {
  88. zput_pos(0L);
  89. tx_header[ZF0] = ZF0_CMD;
  90. tx_header[ZF1] = ZF1_CMD;
  91. tx_header[ZF2] = ZF2_CMD;
  92. zsend_hex_header(ZRINIT, tx_header);
  93. again:
  94. res = zget_header(rx_header);
  95. switch(res)
  96. {
  97. case ZFILE:
  98. ZF0_CMD = rx_header[ZF0];
  99. ZF1_CMD = rx_header[ZF1];
  100. ZF2_CMD = rx_header[ZF2];
  101. ZF3_CMD = rx_header[ZF3];
  102. res = zget_data(rxbuf, RX_BUFFER_SIZE);
  103. if (res == GOTCRCW)
  104. {
  105. if ((res =zget_file_info((char*)rxbuf,zf))!= RT_EOK)
  106. {
  107. zsend_hex_header(ZSKIP, tx_header);
  108. return (res);
  109. }
  110. return RT_EOK;;
  111. }
  112. zsend_hex_header(ZNAK, tx_header);
  113. goto again;
  114. case ZSINIT:
  115. if (zget_data((rt_uint8_t*)Attn, ZATTNLEN) == GOTCRCW) /* send zack */
  116. {
  117. zsend_hex_header(ZACK, tx_header);
  118. goto again;
  119. }
  120. zsend_hex_header(ZNAK, tx_header); /* send znak */
  121. goto again;
  122. case ZRQINIT:
  123. continue;
  124. case ZEOF:
  125. continue;
  126. case ZCOMPL:
  127. goto again;
  128. case ZFIN: /* end file session */
  129. zrec_ack_bibi();
  130. return res;
  131. default:
  132. if (++err_cnt >1000) return -RT_ERROR;
  133. continue;
  134. }
  135. }
  136. }
  137. /* receive files */
  138. static rt_err_t zrec_files(struct zfile *zf)
  139. {
  140. rt_uint8_t *rxbuf;
  141. rt_err_t res = -RT_ERROR;
  142. zinit_parameter();
  143. rxbuf = rt_malloc(RX_BUFFER_SIZE*sizeof(rt_uint8_t));
  144. if (rxbuf == RT_NULL)
  145. {
  146. rt_kprintf("rxbuf: out of memory\r\n");
  147. return -RT_ERROR;
  148. }
  149. rt_kprintf("\r\nrz: ready...\r\n"); /* here ready to receive things */
  150. if ((res = zrec_init(rxbuf,zf))!= RT_EOK)
  151. {
  152. rt_kprintf("\b\b\breceive init failed\r\n");
  153. rt_free(rxbuf);
  154. return -RT_ERROR;
  155. }
  156. res = zrec_file(rxbuf,zf);
  157. if (res == ZFIN)
  158. {
  159. rt_free(rxbuf);
  160. return RT_EOK; /* if finish session */
  161. }
  162. else if (res == ZCAN)
  163. {
  164. rt_free(rxbuf);
  165. return ZCAN; /* cancel by sender */
  166. }
  167. else
  168. {
  169. zsend_can();
  170. rt_free(rxbuf);
  171. return res;
  172. }
  173. }
  174. /* receive file */
  175. static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf)
  176. {
  177. rt_err_t res = - RT_ERROR;
  178. rt_uint16_t err_cnt = 0;
  179. do
  180. {
  181. zput_pos(zf->bytes_received);
  182. zsend_hex_header(ZRPOS, tx_header);
  183. again:
  184. res = zget_header(rx_header);
  185. switch (res)
  186. {
  187. case ZDATA:
  188. zget_pos(Rxpos);
  189. if (Rxpos != zf->bytes_received)
  190. {
  191. zsend_break(Attn);
  192. continue;
  193. }
  194. err_cnt = 0;
  195. res = zrec_file_data(rxbuf,zf);
  196. if (res == -RT_ERROR)
  197. {
  198. zsend_break(Attn);
  199. continue;
  200. }
  201. else if (res == GOTCAN) return res;
  202. else goto again;
  203. case ZRPOS:
  204. zget_pos(Rxpos);
  205. continue;
  206. case ZEOF:
  207. err_cnt = 0;
  208. zget_pos(Rxpos);
  209. if (Rxpos != zf->bytes_received || Rxpos != zf->bytes_total)
  210. {
  211. continue;
  212. }
  213. return (zrec_init(rxbuf,zf)); /* resend ZRINIT packet,ready to receive next file */
  214. case ZFIN:
  215. zrec_ack_bibi();
  216. return ZCOMPL;
  217. case ZCAN:
  218. #ifdef ZDEBUG
  219. rt_kprintf("error code: sender cancelled \r\n");
  220. #endif
  221. zf->bytes_received = 0L; /* throw the received data */
  222. return res;
  223. case ZSKIP:
  224. return res;
  225. case -RT_ERROR:
  226. zsend_break(Attn);
  227. continue;
  228. case ZNAK:
  229. case TIMEOUT:
  230. default:
  231. continue;
  232. }
  233. } while(++err_cnt < 100);
  234. return res;
  235. }
  236. /* proccess file infomation */
  237. static rt_err_t zget_file_info(char *name, struct zfile *zf)
  238. {
  239. char *p;
  240. char *full_path,*ptr;
  241. rt_uint16_t i,len;
  242. rt_err_t res = -RT_ERROR;
  243. struct statfs buf;
  244. struct stat finfo;
  245. if (zf->fname == RT_NULL) /* extract file path */
  246. {
  247. len = strlen(name)+2;
  248. }
  249. else
  250. len = strlen(zf->fname)+strlen(name)+2;
  251. full_path = rt_malloc(len);
  252. if (full_path == RT_NULL)
  253. {
  254. zsend_can();
  255. rt_kprintf("\b\b\bfull_path: out of memory\n");
  256. rt_free(full_path);
  257. return -RT_ERROR;
  258. }
  259. memset(full_path,0,len);
  260. for (i=0,ptr=zf->fname;i<len-strlen(name)-2;i++)
  261. full_path[i] = *ptr++;
  262. full_path[len-strlen(name)-2] = '/';
  263. /* check if is a directory */
  264. if ((zf->fd=open(full_path, DFS_O_DIRECTORY,0)) < 0)
  265. {
  266. zsend_can();
  267. rt_kprintf("\b\b\bcan not open file:%s\r\n",zf->fname+1);
  268. close(zf->fd);
  269. zf->fd = -1;
  270. rt_free(full_path);
  271. return res;
  272. }
  273. fstat(zf->fd, &finfo);
  274. if ((finfo.st_mode&S_IFDIR) != S_IFDIR)
  275. {
  276. close(zf->fd);
  277. zf->fd = -1;
  278. return res;
  279. }
  280. close(zf->fd);
  281. /* get fullpath && file attributes */
  282. strcat(full_path,name);
  283. zf->fname = full_path;
  284. p = strlen(name)+name+1;
  285. sscanf((const char *)p, "%ld%lo%o", &zf->bytes_total,&zf->ctime,&zf->mode);
  286. #ifdef defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
  287. dfs_statfs(working_directory,&buf);
  288. if (zf->bytes_total > (buf.f_blocks * buf.f_bfree))
  289. {
  290. zsend_can();
  291. rt_kprintf("\b\b\bnot enough disk space\r\n");
  292. zf->fd = -1;
  293. rt_free(full_path);
  294. return -RT_ERROR;
  295. }
  296. #else
  297. buf = buf;
  298. #endif
  299. zf->bytes_received = 0L;
  300. if ((zf->fd = open(zf->fname,DFS_O_CREAT|DFS_O_WRONLY,0)) < 0) /* create or replace exist file */
  301. {
  302. zsend_can();
  303. rt_kprintf("\b\b\bcan not create file:%s \r\n",zf->fname);
  304. return -RT_ERROR;
  305. }
  306. return RT_EOK;
  307. }
  308. /* receive file data,continously, no ack */
  309. static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf)
  310. {
  311. rt_err_t res = -RT_ERROR;
  312. more_data:
  313. res = zget_data(buf,RX_BUFFER_SIZE);
  314. switch(res)
  315. {
  316. case GOTCRCW: /* zack received */
  317. zwrite_file(buf,Rxcount,zf);
  318. zf->bytes_received += Rxcount;
  319. zput_pos(zf->bytes_received);
  320. zsend_line(XON);
  321. zsend_hex_header(ZACK, tx_header);
  322. return RT_EOK;
  323. case GOTCRCQ:
  324. zwrite_file(buf,Rxcount,zf);
  325. zf->bytes_received += Rxcount;
  326. zput_pos(zf->bytes_received);
  327. zsend_hex_header(ZACK, tx_header);
  328. goto more_data;
  329. case GOTCRCG:
  330. zwrite_file(buf,Rxcount,zf);
  331. zf->bytes_received += Rxcount;
  332. goto more_data;
  333. case GOTCRCE:
  334. zwrite_file(buf,Rxcount,zf);
  335. zf->bytes_received += Rxcount;
  336. return RT_EOK;
  337. case GOTCAN:
  338. #ifdef ZDEBUG
  339. rt_kprintf("error code : ZCAN \r\n");
  340. #endif
  341. return res;
  342. case TIMEOUT:
  343. return res;
  344. case -RT_ERROR:
  345. zsend_break(Attn);
  346. return res;
  347. default:
  348. return res;
  349. }
  350. }
  351. /* write file */
  352. static rt_err_t zwrite_file(rt_uint8_t *buf,rt_uint16_t size, struct zfile *zf)
  353. {
  354. return (write(zf->fd,buf,size));
  355. }
  356. /* ack bibi */
  357. static void zrec_ack_bibi(void)
  358. {
  359. rt_uint8_t i;
  360. zput_pos(0L);
  361. for (i=0;i<3;i++)
  362. {
  363. zsend_hex_header(ZFIN, tx_header);
  364. switch (zread_line(100))
  365. {
  366. case 'O':
  367. zread_line(1);
  368. return;
  369. case RCDO:
  370. return;
  371. case TIMEOUT:
  372. default:
  373. break;
  374. }
  375. }
  376. }
  377. /* end of rz.c */