rz.c 10 KB

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