Contiki 3.x
shell-netfile.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * A brief description of what this file is.
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  */
39 
40 #include "contiki.h"
41 #include "shell-netfile.h"
42 #include "net/rime/rime.h"
43 #include "net/rime/rudolph0.h"
44 #include "dev/leds.h"
45 
46 #include "cfs/cfs.h"
47 
48 #include <stdio.h>
49 #include <string.h>
50 
51 #define FILENAME_LEN 20
52 
53 static struct rudolph0_conn rudolph0_conn;
54 static char filename[FILENAME_LEN];
55 static int receiving_file;
56 static struct pt recvnetfilept;
57 /*---------------------------------------------------------------------------*/
58 PROCESS(shell_netfile_process, "netfile");
59 SHELL_COMMAND(netfile_command,
60  "netfile",
61  "netfile: send file to entire network",
62  &shell_netfile_process);
63 PROCESS(shell_recvnetfile_process, "recvnetfile");
64 SHELL_COMMAND(recvnetfile_command,
65  "recvnetfile",
66  "recvnetfile: receive file from network and print to output",
67  &shell_recvnetfile_process);
68 /*---------------------------------------------------------------------------*/
69 static int
70 write_chunk_pt(struct rudolph0_conn *c, int offset, int flag,
71  uint8_t *data, int datalen)
72 {
73  PT_BEGIN(&recvnetfilept);
74 
75  PT_WAIT_UNTIL(&recvnetfilept, receiving_file);
76  leds_on(LEDS_YELLOW);
77  leds_on(LEDS_RED);
78  PT_WAIT_UNTIL(&recvnetfilept, flag == RUDOLPH0_FLAG_NEWFILE);
79  leds_off(LEDS_RED);
80 
81  do {
82  if(datalen > 0) {
83  shell_output(&recvnetfile_command, data, datalen, "", 0);
84  /* printf("write_chunk wrote %d bytes at %d\n", datalen, offset);*/
85  }
86  PT_YIELD(&recvnetfilept);
87  } while(flag != RUDOLPH0_FLAG_LASTCHUNK);
88 
89  shell_output(&recvnetfile_command, data, datalen, "", 0);
90  /* printf("write_chunk wrote %d bytes at %d\n", datalen, offset);*/
91  shell_output(&recvnetfile_command, "", 0, "", 0);
92  leds_off(LEDS_YELLOW);
93  receiving_file = 0;
94  process_post(&shell_recvnetfile_process, PROCESS_EVENT_CONTINUE, NULL);
95 
96  PT_END(&recvnetfilept);
97 }
98 static void
99 write_chunk(struct rudolph0_conn *c, int offset, int flag,
100  uint8_t *data, int datalen)
101 {
102  write_chunk_pt(c, offset, flag, data, datalen);
103 }
104 
105 static int
106 read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize)
107 {
108  int ret;
109  int fd;
110 
111  fd = cfs_open(filename, CFS_READ);
112 
113  cfs_seek(fd, offset, CFS_SEEK_SET);
114  ret = cfs_read(fd, to, maxsize);
115  /* printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);*/
116  cfs_close(fd);
117  return ret;
118 }
119 CC_CONST_FUNCTION static struct rudolph0_callbacks rudolph0_callbacks =
120  {/*(void (*)(struct rudolph0_conn *, int, int, uint8_t *, int))*/
121  write_chunk,
122  read_chunk};
123 /*---------------------------------------------------------------------------*/
124 PROCESS_THREAD(shell_netfile_process, ev, data)
125 {
126  int fd;
127 
128  PROCESS_BEGIN();
129 
130  if(data != NULL) {
131  rudolph0_send(&rudolph0_conn, CLOCK_SECOND);
132 
133  strncpy(filename, data, FILENAME_LEN);
134  fd = cfs_open(filename, CFS_READ);
135  if(fd < 0) {
136  shell_output_str(&netfile_command, "netfile: could not open file ", filename);
137  } else {
138  cfs_close(fd);
139  }
140  }
141 
142  PROCESS_END();
143 }
144 /*---------------------------------------------------------------------------*/
145 PROCESS_THREAD(shell_recvnetfile_process, ev, data)
146 {
147  PROCESS_BEGIN();
148 
149  PT_INIT(&recvnetfilept);
150  receiving_file = 1;
151  while(1) {
152  struct shell_input *input;
153 
155 
156  if(ev == shell_event_input) {
157  input = data;
158  if(input->len1 + input->len2 == 0) {
159  receiving_file = 0;
160  PROCESS_EXIT();
161  }
162  } else if(receiving_file == 0) {
163  PROCESS_EXIT();
164  }
165  }
166  PROCESS_END();
167 }
168 /*---------------------------------------------------------------------------*/
169 void
170 shell_netfile_init(void)
171 {
172  receiving_file = 0;
173  shell_register_command(&netfile_command);
174  shell_register_command(&recvnetfile_command);
175 
176  rudolph0_open(&rudolph0_conn, SHELL_RIME_CHANNEL_NETFILE,
177  &rudolph0_callbacks);
178 }
179 /*---------------------------------------------------------------------------*/
#define CC_CONST_FUNCTION
Configure if the C compiler have problems with const function pointers.
Definition: cc.h:86
int cfs_open(const char *name, int flags)
Open a file.
Definition: cfs-coffee.c:996
void shell_output_str(struct shell_command *c, char *text1, const char *text2)
Output strings from a shell command.
Definition: shell.c:383
#define LEDS_RED
LED1 (Red) -&gt; PC0.
Definition: board.h:89
#define PROCESS_EXIT()
Exit the currently running process.
Definition: process.h:200
cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)
Seek to a specified position in an open file.
Definition: cfs-coffee.c:1042
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PT_YIELD(pt)
Yield from the current protothread.
Definition: pt.h:289
#define NULL
The null pointer.
#define PT_INIT(pt)
Initialize a protothread.
Definition: pt.h:79
#define CFS_READ
Specify that cfs_open() should open a file for reading.
Definition: cfs.h:90
A brief description of what this file is.
Header file for the single-hop reliable bulk data transfer module
Header file for the Rime stack
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
void shell_output(struct shell_command *c, void *data1, int len1, const void *data2, int len2)
Output data from a shell command.
Definition: shell.c:395
#define LEDS_YELLOW
LED2 (Yellow) -&gt; PC1.
Definition: board.h:80
#define PT_WAIT_UNTIL(pt, condition)
Block and wait until condition is true.
Definition: pt.h:147
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
Structure for shell input data.
Definition: shell.h:365
void shell_register_command(struct shell_command *c)
Register a command with the shell.
Definition: shell.c:413
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PT_BEGIN(pt)
Declare the start of a protothread inside the C function implementing the protothread.
Definition: pt.h:114
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
int shell_event_input
The event number for shell input data.
Definition: shell.c:70
#define PT_END(pt)
Declare the end of a protothread.
Definition: pt.h:126
#define CFS_SEEK_SET
Specify that cfs_seek() should compute the offset from the beginning of the file. ...
Definition: cfs.h:127
#define SHELL_COMMAND(name, command, description, process)
Define a shell command.
Definition: shell.h:219
void cfs_close(int fd)
Close an open file.
Definition: cfs-coffee.c:1032
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
CFS header file.