ev3duder  0.3.0
EV3 Downloader/Uploader
up.c
Go to the documentation of this file.
1 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <errno.h>
12 
13 #include "ev3_io.h"
14 
15 #include "defs.h"
16 #include "packets.h"
17 #include "error.h"
18 #include "funcs.h"
19 
20 #define CHUNK_SIZE 1000 // The EV3 doesn't do packets > 1024B
21 
29 int up(FILE *fp, const char *dst)
30 {
31  int res;
32 
33  fseek(fp, 0, SEEK_END);
34  long fsize = ftell(fp);
35  fseek(fp, 0, SEEK_SET);
36 
37  if ((unsigned long)fsize > (u32)-1)
38  return ERR_FTOOBIG;
39 
40  unsigned chunks = fsize / CHUNK_SIZE;
41  unsigned final_chunk_sz = fsize % CHUNK_SIZE;
42 
43  //fprintf(stderr, "Attempting file upload (%ldb total; %u chunks): \n", fsize, chunks + 1);
44 
45  size_t dst_len = strlen(dst) + 1;
47  bd->fileSize = fsize;
48  memcpy(bd->fileName, dst, dst_len);
49 
50  res = ev3_write(handle, (u8 *)bd, bd->packetLen + PREFIX_SIZE);
51  if (res < 0)
52  {
53  errmsg = "Unable to write BEGIN_DOWNLOAD.";
54  return ERR_COMM;
55  }
56 
58  res = ev3_read_timeout(handle, (u8 *)&bdrep, sizeof bdrep, TIMEOUT);
59  if (res <= 0)
60  {
61  errmsg = "Unable to read BEGIN_DOWNLOAD";
62  return ERR_COMM;
63  }
64 
65  if (bdrep.type == VM_ERROR)
66  {
67  errno = bdrep.ret;
68  errmsg = "BEGIN_DOWNLOAD was denied.";
69  return ERR_VM;
70  }
71 
73  for (size_t i = 0; i < chunks; ++i)
74  {
75  cd->fileHandle = bdrep.fileHandle;
76  fread(cd->fileChunk, 1, CHUNK_SIZE, fp);
77  res = ev3_write(handle, (u8 *)cd, cd->packetLen + PREFIX_SIZE);
78 
79  if (res < 0)
80  {
81  errmsg = "Unable to write CONTINUE_DOWNLOAD.";
82  return ERR_COMM;
83  }
84  res = ev3_read_timeout(handle, (u8 *)&bdrep, sizeof bdrep, TIMEOUT);
85  if (res <= 0)
86  {
87  errmsg = "Unable to read CONTINUE_DOWNLOAD";
88  return ERR_COMM;
89  }
90  }
91  cd->packetLen = sizeof(CONTINUE_DOWNLOAD) + final_chunk_sz - PREFIX_SIZE;
92  fread(cd->fileChunk, 1, final_chunk_sz, fp);
93  ev3_write(handle, (u8*)cd, cd->packetLen + PREFIX_SIZE);
94  if (res < 0)
95  {
96  errmsg = "Unable to write CONTINUE_DOWNLOAD.";
97  return ERR_COMM;
98  }
99  res = ev3_read_timeout(handle, (u8 *)&bdrep, sizeof bdrep, TIMEOUT);
100  if (res <= 0)
101  {
102  errmsg = "Unable to read CONTINUE_DOWNLOAD";
103  return ERR_COMM;
104  }
105  if (bdrep.type == VM_ERROR)
106  {
107  errno = bdrep.ret;
108 
109  fputs("Transfer failed.\nlast_reply=", stderr);
110 
111  print_bytes(&bdrep, bdrep.packetLen);
112 
113  errmsg = "CONTINUE_DOWNLOAD was denied.";
114  return ERR_VM;
115  }
116 
117  errmsg = "`upload` was successful.";
118  return ERR_UNK;
119 }
120 
EXTERN void * handle
Definition: ev3_io.h:17
send file chunk wise
Definition: packets.h:101
EV3_REPLY_FIELDS u8 fileHandle
Definition: packets.h:96
EV3_COMMAND_FIELDS u8 fileHandle
Definition: packets.h:105
Definition: error.h:20
Error enumerations and decriptions.
#define print_bytes(buf, len)
Definition: defs.h:34
#define packet_alloc(type, extra)
Definition: packets.h:328
uint32_t u32
Definition: defs.h:11
char fileName[]
Definition: packets.h:87
char fileChunk[]
Definition: packets.h:107
EXTERN int(* ev3_read_timeout)(void *, u8 *, size_t, int milliseconds)
Definition: ev3_io.h:14
#define TIMEOUT
Definition: defs.h:46
packed structs for the packets.
#define CHUNK_SIZE
Definition: up.c:20
upload to EV3
Definition: packets.h:79
Definition: error.h:20
uint8_t u8
Definition: defs.h:9
int up(FILE *fp, const char *dst)
Uploads file to the ev3. path is always relative to /home/root/lms2012/prjs/sys/
Definition: up.c:29
EV3_COMMAND_FIELDS u32 fileSize
Definition: packets.h:83
Definition: error.h:20
Th ev3's reply.
Definition: packets.h:92
Definition: error.h:22
EXTERN const char * errmsg
global variable for last error message
Definition: error.h:25
contains declarations for ev3 commands
EXTERN int(* ev3_write)(void *, const u8 *, size_t)
Definition: ev3_io.h:13
#define PREFIX_SIZE
Definition: packets.h:54