52 #define RUNICAST_CHANNEL SHELL_RIME_CHANNEL_DOWNLOAD
53 #define RUCB_CHANNEL (SHELL_RIME_CHANNEL_DOWNLOAD+1)
54 #define MAX_RETRANSMISSIONS 8
59 #define PRINTF(...) printf(__VA_ARGS__)
65 PROCESS(shell_download_process,
"download");
66 PROCESS(shell_download_server_process,
"download server");
69 "download <node addr> <filename>: download file from remote node",
70 &shell_download_process);
72 static struct runicast_conn runicast;
73 static struct rucb_conn rucb;
74 static uint8_t downloading;
75 static uint8_t req_seq_counter;
76 static uint8_t req_last_seq;
80 write_chunk(
struct rucb_conn *c,
int offset,
int flag,
char *data,
int datalen)
84 data, datalen,
NULL, 0);
85 PRINTF(
"write_chunk %d at %d bytes\n", datalen, offset);
88 if(flag == RUCB_FLAG_NEWFILE) {
89 PRINTF(
"RUCB_FLAG_NEWFILE\n");
90 }
else if(flag == RUCB_FLAG_NONE) {
91 PRINTF(
"RUCB_FLAG_NONE\n");
93 if(flag == RUCB_FLAG_LASTCHUNK) {
94 PRINTF(
"RUCB_FLAG_LASTCHUNK\n");
101 read_chunk(
struct rucb_conn *c,
int offset,
char *to,
int maxsize)
111 ret = cfs_read(fd, to, maxsize);
112 PRINTF(
"read_chunk %d bytes at %d\n", ret, offset);
115 PRINTF(
"read_chunk DONE\n");
124 timedout(
struct rucb_conn *c)
128 static const struct rucb_callbacks rucb_call = { write_chunk, read_chunk, timedout };
133 static linkaddr_t addr;
141 if(nextptr == data || *nextptr !=
'.') {
143 "download <node addr> <filename>: need node address",
"");
150 while(nextptr[0] ==
' ') {
153 len = strlen(nextptr);
159 snprintf(buf,
sizeof(buf),
"%d", len);
168 rucb_open(&rucb, RUCB_CHANNEL, &rucb_call);
173 PRINTF(
"requesting '%s'\n", nextptr);
174 runicast_send(&runicast, &addr, MAX_RETRANSMISSIONS);
188 request_recv(
struct runicast_conn *c,
const linkaddr_t *from, uint8_t seqno)
190 const char *filename;
195 printf(
"download: bad filename request (null)\n");
200 if(seq == req_last_seq) {
201 PRINTF(
"download: ignoring duplicate request\n");
207 PRINTF(
"file requested: '%s'\n", filename);
216 printf(
"download: bad filename request (no read access): %s\n", filename);
218 PRINTF(
"download: sending file: %s\n", filename);
222 rucb_open(&rucb, RUCB_CHANNEL, &rucb_call);
223 rucb_send(&rucb, from);
227 request_sent(
struct runicast_conn *c,
const linkaddr_t *to,
228 uint8_t retransmissions)
234 request_timedout(
struct runicast_conn *c,
const linkaddr_t *to,
235 uint8_t retransmissions)
242 static const struct runicast_callbacks runicast_callbacks =
243 {request_recv, request_sent, request_timedout};
251 runicast_open(&runicast, RUNICAST_CHANNEL, &runicast_callbacks);
258 shell_download_init(
void)
#define PROCESS_WAIT_UNTIL(c)
Wait for a condition to occur.
void process_poll(struct process *p)
Request a process to be polled.
int cfs_open(const char *name, int flags)
Open a file.
void shell_output_str(struct shell_command *c, char *text1, const char *text2)
Output strings from a shell command.
#define PROCESS_EXIT()
Exit the currently running process.
cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)
Seek to a specified position in an open file.
#define PROCESS_BEGIN()
Define the beginning of a process.
Main header file for the Contiki shell
#define NULL
The null pointer.
#define CFS_READ
Specify that cfs_open() should open a file for reading.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Header file for the Rime stack
void shell_output(struct shell_command *c, void *data1, int len1, const void *data2, int len2)
Output data from a shell command.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
#define LEDS_GREEN
LED3 (Green) -> PC2.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
unsigned long shell_strtolong(const char *str, const char **retstr)
Convert a string to a number.
#define PROCESS_EXITHANDLER(handler)
Specify an action when a process exits.
void shell_register_command(struct shell_command *c)
Register a command with the shell.
#define PROCESS(name, strname)
Declare a process.
void packetbuf_clear(void)
Clear and reset the packetbuf.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
#define CFS_SEEK_SET
Specify that cfs_seek() should compute the offset from the beginning of the file. ...
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
#define SHELL_COMMAND(name, command, description, process)
Define a shell command.
void cfs_close(int fd)
Close an open file.