114 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#include <rtthread.h>
							 | 
						||
| 
								 | 
							
								#include <ymodem.h>
							 | 
						||
| 
								 | 
							
								#include <dfs_posix.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <board.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct custom_ctx
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct rym_ctx parent;
							 | 
						||
| 
								 | 
							
								    int fd;
							 | 
						||
| 
								 | 
							
								    int flen;
							 | 
						||
| 
								 | 
							
								    char fpath[256];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static enum rym_code _rym_bg(
							 | 
						||
| 
								 | 
							
								        struct rym_ctx *ctx,
							 | 
						||
| 
								 | 
							
								        rt_uint8_t *buf,
							 | 
						||
| 
								 | 
							
								        rt_size_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct custom_ctx *cctx = (struct custom_ctx*)ctx;
							 | 
						||
| 
								 | 
							
								    cctx->fpath[0] = '/';
							 | 
						||
| 
								 | 
							
								    /* the buf should be the file name */
							 | 
						||
| 
								 | 
							
								    strcpy(&(cctx->fpath[1]), (const char*)buf);
							 | 
						||
| 
								 | 
							
								    cctx->fd = open(cctx->fpath, O_CREAT | O_WRONLY | O_TRUNC, 0);
							 | 
						||
| 
								 | 
							
								    if (cctx->fd < 0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        rt_err_t err = rt_get_errno();
							 | 
						||
| 
								 | 
							
								        rt_kprintf("error creating file: %d\n", err);
							 | 
						||
| 
								 | 
							
								        rt_kprintf("abort transmission\n");
							 | 
						||
| 
								 | 
							
								        return RYM_CODE_CAN;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    cctx->flen = atoi((const char*)buf+strlen((const char*)buf)+1);
							 | 
						||
| 
								 | 
							
								    if (cctx->flen == 0)
							 | 
						||
| 
								 | 
							
								        cctx->flen = -1;
							 | 
						||
| 
								 | 
							
								    return RYM_CODE_ACK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static enum rym_code _rym_tof(
							 | 
						||
| 
								 | 
							
								        struct rym_ctx *ctx,
							 | 
						||
| 
								 | 
							
								        rt_uint8_t *buf,
							 | 
						||
| 
								 | 
							
								        rt_size_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct custom_ctx *cctx = (struct custom_ctx*)ctx;
							 | 
						||
| 
								 | 
							
								    RT_ASSERT(cctx->fd >= 0);
							 | 
						||
| 
								 | 
							
								    if (cctx->flen == -1)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        write(cctx->fd, buf, len);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        int wlen = len > cctx->flen ? cctx->flen : len;
							 | 
						||
| 
								 | 
							
								        write(cctx->fd, buf, wlen);
							 | 
						||
| 
								 | 
							
								        cctx->flen -= wlen;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return RYM_CODE_ACK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static enum rym_code _rym_end(
							 | 
						||
| 
								 | 
							
								        struct rym_ctx *ctx,
							 | 
						||
| 
								 | 
							
								        rt_uint8_t *buf,
							 | 
						||
| 
								 | 
							
								        rt_size_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct custom_ctx *cctx = (struct custom_ctx*)ctx;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RT_ASSERT(cctx->fd >= 0);
							 | 
						||
| 
								 | 
							
								    close(cctx->fd);
							 | 
						||
| 
								 | 
							
								    cctx->fd = -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return RYM_CODE_ACK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								rt_err_t rym_write_to_file(rt_device_t idev)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    rt_err_t res;
							 | 
						||
| 
								 | 
							
								    struct custom_ctx *ctx = rt_malloc(sizeof(*ctx));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RT_ASSERT(idev);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rt_kprintf("entering RYM mode\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    res = rym_recv_on_device(&ctx->parent, idev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
							 | 
						||
| 
								 | 
							
								                             _rym_bg, _rym_tof, _rym_end, 1000);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* there is no Ymodem traffic on the line so print out info. */
							 | 
						||
| 
								 | 
							
								    rt_kprintf("leaving RYM mode with code %d\n", res);
							 | 
						||
| 
								 | 
							
								    rt_kprintf("file %s has been created.\n", ctx->fpath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rt_free(ctx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef RT_USING_FINSH
							 | 
						||
| 
								 | 
							
								#include <finsh.h>
							 | 
						||
| 
								 | 
							
								rt_err_t ry(char *dname)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    rt_err_t res;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rt_device_t dev = rt_device_find(dname);
							 | 
						||
| 
								 | 
							
								    if (!dev)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        rt_kprintf("could not find device:%s\n", dname);
							 | 
						||
| 
								 | 
							
								        return -RT_ERROR;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    res = rym_write_to_file(dev);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								FINSH_FUNCTION_EXPORT(ry, receive files by ymodem protocol);
							 | 
						||
| 
								 | 
							
								#endif
							 |