2 * Copyright (c) 2008, Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
29 * This file is part of the Contiki operating system.
31 * $Id: shell-sendtest.c,v 1.6 2009/11/03 10:04:23 adamdunkels Exp $
36 * A small pogram to measure the communication performance between two nodes
38 * Adam Dunkels <adam@sics.se>
48 #if CONTIKI_TARGET_NETSIM
50 #endif /* CONTIKI_TARGET_NETSIM */
52 int snprintf(char *str
, size_t size
, const char *format
, ...);
53 #endif /* HAVE_SNPRINTF */
55 /*---------------------------------------------------------------------------*/
56 PROCESS(shell_sendtest_process
, "sendtest");
57 SHELL_COMMAND(sendtest_command
,
59 "sendtest: measure single-hop throughput",
60 &shell_sendtest_process
);
61 /*---------------------------------------------------------------------------*/
62 static clock_time_t start_time_rucb
, end_time_rucb
;
63 static unsigned long filesize
, bytecount
, packetsize
;
64 static int download_complete
;
66 write_chunk(struct rucb_conn
*c
, int offset
, int flag
,
67 char *data
, int datalen
)
69 #if CONTIKI_TARGET_NETSIM
72 printf("received %d; %d\n", offset
, datalen
);
73 sprintf(buf
, "%lu%%", (100 * (offset
+ datalen
)) / filesize
);
76 #endif /* CONTIKI_TARGET_NETSIM */
80 read_chunk(struct rucb_conn
*c
, int offset
, char *to
, int maxsize
)
85 if(bytecount
+ maxsize
>= filesize
) {
86 size
= filesize
- bytecount
;
88 if(size
> packetsize
) {
92 if(bytecount
== filesize
) {
93 end_time_rucb
= clock_time();
94 download_complete
= 1;
95 process_post(&shell_sendtest_process
, PROCESS_EVENT_CONTINUE
, NULL
);
96 /* profile_aggregates_print(); */
97 /* profile_print_stats(); */
101 /* printf("bytecount %lu\n", bytecount);*/
104 const static struct rucb_callbacks rucb_callbacks
= {write_chunk
,
107 static struct rucb_conn rucb
;
108 /*---------------------------------------------------------------------------*/
112 shell_output_str(&sendtest_command
,
113 "sendtest <receiver> <size> [packetsize]: recevier must be specified", "");
116 /*---------------------------------------------------------------------------*/
117 PROCESS_THREAD(shell_sendtest_process
, ev
, data
)
119 static rimeaddr_t receiver
;
123 static unsigned long cpu
, lpm
, rx
, tx
;
124 unsigned long cpu2
, lpm2
, rx2
, tx2
;
129 receiver
.u8
[0] = shell_strtolong(args
, &nextptr
);
130 if(nextptr
== data
|| *nextptr
!= '.') {
135 receiver
.u8
[1] = shell_strtolong(args
, &nextptr
);
139 while(*args
== ' ') {
142 filesize
= shell_strtolong(args
, &nextptr
);
143 if(nextptr
== data
|| filesize
== 0) {
149 while(*args
== ' ') {
153 packetsize
= shell_strtolong(args
, &nextptr
);
154 if(packetsize
== 0) {
159 snprintf(buf
, sizeof(buf
), "%d.%d, %lu bytes, packetsize %lu",
160 receiver
.u8
[0], receiver
.u8
[1], filesize
, packetsize
);
161 shell_output_str(&sendtest_command
, "Sending data to ", buf
);
164 download_complete
= 0;
166 start_time_rucb
= clock_time();
167 rucb_send(&rucb
, &receiver
);
170 lpm
= energest_type_time(ENERGEST_TYPE_LPM
);
171 cpu
= energest_type_time(ENERGEST_TYPE_CPU
);
172 rx
= energest_type_time(ENERGEST_TYPE_LISTEN
);
173 tx
= energest_type_time(ENERGEST_TYPE_TRANSMIT
);
175 PROCESS_WAIT_UNTIL(download_complete
);
178 lpm2
= energest_type_time(ENERGEST_TYPE_LPM
);
179 cpu2
= energest_type_time(ENERGEST_TYPE_CPU
);
180 rx2
= energest_type_time(ENERGEST_TYPE_LISTEN
);
181 tx2
= energest_type_time(ENERGEST_TYPE_TRANSMIT
);
183 sprintf(buf
, "%d seconds, %lu bytes/second",
184 (int)((end_time_rucb
- start_time_rucb
) / CLOCK_SECOND
),
185 CLOCK_SECOND
* filesize
/ (end_time_rucb
- start_time_rucb
));
186 shell_output_str(&sendtest_command
, "Completed in ", buf
);
188 sprintf(buf
, "%lu/%d rx %lu/%d tx (seconds)",
189 (rx2
- rx
), RTIMER_ARCH_SECOND
,
190 (tx2
- tx
), RTIMER_ARCH_SECOND
);
191 shell_output_str(&sendtest_command
, "Radio total on time ", buf
);
193 sprintf(buf
, "%lu/%lu = %lu%%",
195 (cpu2
+ lpm2
- cpu
- lpm
),
196 100 * (rx2
- rx
)/(cpu2
+ lpm2
- cpu
- lpm
));
197 shell_output_str(&sendtest_command
, "Radio rx duty cycle ", buf
);
199 sprintf(buf
, "%lu/%lu = %lu%%",
201 (cpu2
+ lpm2
- cpu
- lpm
),
202 100 * (tx2
- tx
)/(cpu2
+ lpm2
- cpu
- lpm
));
203 shell_output_str(&sendtest_command
, "Radio tx duty cycle ", buf
);
207 /*---------------------------------------------------------------------------*/
209 shell_sendtest_init(void)
211 rucb_open(&rucb
, SHELL_RIME_CHANNEL_SENDTEST
, &rucb_callbacks
);
212 shell_register_command(&sendtest_command
);
214 /*---------------------------------------------------------------------------*/