From 708435ecc8fd7de81360253a232e2c1863e5abd4 Mon Sep 17 00:00:00 2001 From: nvt Date: Mon, 5 Sep 2011 21:25:01 +0200 Subject: [PATCH 1/3] Improved the clarity of the Coffee test. --- examples/sky/test-coffee.c | 305 ++++++++++++++--------- tools/cooja/contiki_tests/sky_coffee.csc | 250 +++++++++---------- 2 files changed, 301 insertions(+), 254 deletions(-) diff --git a/examples/sky/test-coffee.c b/examples/sky/test-coffee.c index 77b86b400..c4c9e9a0b 100644 --- a/examples/sky/test-coffee.c +++ b/examples/sky/test-coffee.c @@ -56,43 +56,14 @@ AUTOSTART_PROCESSES(&testcoffee_process); /*---------------------------------------------------------------------------*/ static int -coffee_gc_test(void) -{ - int i; - - cfs_remove("alpha"); - cfs_remove("beta"); - - - for (i = 0; i < 100; i++) { - if (i & 1) { - if(cfs_coffee_reserve("alpha", random_rand() & 0xffff) < 0) { - return -i; - } - cfs_remove("beta"); - } else { - if(cfs_coffee_reserve("beta", 93171) < 0) { - return -1; - } - cfs_remove("alpha"); - } - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -coffee_file_test(void) +coffee_test_basic(void) { int error; int wfd, rfd, afd; - unsigned char buf[256], buf2[11]; - int r, i, j, total_read; - unsigned offset; + unsigned char buf[256]; + int r; cfs_remove("T1"); - cfs_remove("T2"); - cfs_remove("T3"); wfd = rfd = afd = -1; @@ -103,130 +74,207 @@ coffee_file_test(void) /* Test 1: Open for writing. */ wfd = cfs_open("T1", CFS_WRITE); if(wfd < 0) { - FAIL(-1); + FAIL(1); } - /* Test 2: Write buffer. */ + /* Test 2 and 3: Write buffer. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(-2); + FAIL(2); } else if(r < sizeof(buf)) { - FAIL(-3); + FAIL(3); } - /* Test 3: Deny reading. */ + /* Test 4: Deny reading. */ r = cfs_read(wfd, buf, sizeof(buf)); if(r >= 0) { - FAIL(-4); + FAIL(4); } - /* Test 4: Open for reading. */ + /* Test 5: Open for reading. */ rfd = cfs_open("T1", CFS_READ); if(rfd < 0) { - FAIL(-5); + FAIL(5); } - /* Test 5: Write to read-only file. */ + /* Test 6: Write to read-only file. */ r = cfs_write(rfd, buf, sizeof(buf)); if(r >= 0) { - FAIL(-6); + FAIL(6); } - /* Test 7: Read the buffer written in Test 2. */ + /* Test 7 and 8: Read the buffer written in Test 2. */ memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(-8); + FAIL(7); } else if(r < sizeof(buf)) { printf("r=%d\n", r); - FAIL(-9); + FAIL(8); } - /* Test 8: Verify that the buffer is correct. */ + /* Test 9: Verify that the buffer is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { printf("r=%d. buf[r]=%d\n", r, buf[r]); - FAIL(-10); + FAIL(9); } } - /* Test 9: Seek to beginning. */ + /* Test 10: Seek to beginning. */ if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - FAIL(-11); + FAIL(10); } - /* Test 10: Write to the log. */ + /* Test 11 and 12: Write to the log. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(-12); + FAIL(11); } else if(r < sizeof(buf)) { - FAIL(-13); + FAIL(12); } - /* Test 11: Read the data from the log. */ + /* Test 13 and 14: Read the data from the log. */ cfs_seek(rfd, 0, CFS_SEEK_SET); memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(-14); + FAIL(14); } else if(r < sizeof(buf)) { - FAIL(-15); + FAIL(15); } - /* Test 12: Verify that the data is correct. */ + /* Test 16: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { - FAIL(-16); + FAIL(16); } } - /* Test 13: Write a reversed buffer to the file. */ + /* Test 17 to 20: Write a reversed buffer to the file. */ for(r = 0; r < sizeof(buf); r++) { buf[r] = sizeof(buf) - r - 1; } if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { - FAIL(-17); + FAIL(17); } r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { - FAIL(-18); + FAIL(18); } else if(r < sizeof(buf)) { - FAIL(-19); + FAIL(19); } if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { - FAIL(-20); + FAIL(20); } - /* Test 14: Read the reversed buffer. */ + /* Test 21 and 22: Read the reversed buffer. */ cfs_seek(rfd, 0, CFS_SEEK_SET); memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { - FAIL(-21); + FAIL(21); } else if(r < sizeof(buf)) { printf("r = %d\n", r); - FAIL(-22); + FAIL(22); } - /* Test 15: Verify that the data is correct. */ + /* Test 23: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != sizeof(buf) - r - 1) { - FAIL(-23); + FAIL(23); } } - cfs_close(rfd); + error = 0; +end: cfs_close(wfd); + cfs_close(rfd); + return error; +} +/*---------------------------------------------------------------------------*/ +static int +coffee_test_append(void) +{ + int error; + int afd; + unsigned char buf[256], buf2[11]; + int r, i, j, total_read; +#define APPEND_BYTES 1000 +#define BULK_SIZE 10 - if(cfs_coffee_reserve("T2", FILE_SIZE) < 0) { - FAIL(-24); + cfs_remove("T2"); + + /* Test 1 and 2: Append data to the same file many times. */ + for(i = 0; i < APPEND_BYTES; i += BULK_SIZE) { + afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); + if(afd < 0) { + FAIL(1); + } + for(j = 0; j < BULK_SIZE; j++) { + buf[j] = 1 + ((i + j) & 0x7f); + } + if((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { + printf("r=%d\n", r); + FAIL(2); + } + cfs_close(afd); + } + + /* Test 3-6: Read back the data written previously and verify that it + is correct. */ + afd = cfs_open("T3", CFS_READ); + if(afd < 0) { + FAIL(3); + } + total_read = 0; + while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { + for(j = 0; j < r; j++) { + if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { + FAIL(4); + } + } + total_read += r; + } + if(r < 0) { + FAIL(5); + } + if(total_read != APPEND_BYTES) { + FAIL(6); + } + cfs_close(afd); + + error = 0; +end: + cfs_close(afd); + return error; +} +/*---------------------------------------------------------------------------*/ +static int +coffee_test_modify(void) +{ + int error; + int wfd; + unsigned char buf[256]; + int r, i; + unsigned offset; + + cfs_remove("T3"); + wfd = -1; + + if(cfs_coffee_reserve("T3", FILE_SIZE) < 0) { + FAIL(1); + } + + if(cfs_coffee_configure_log("T3", FILE_SIZE / 2, 11) < 0) { + FAIL(2); } /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { wfd = cfs_open("T2", CFS_WRITE | CFS_READ); if(wfd < 0) { - FAIL(-25); + FAIL(3); } offset = random_rand() % FILE_SIZE; @@ -236,88 +284,101 @@ coffee_file_test(void) } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { - FAIL(-26); + FAIL(4); } if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { - FAIL(-27); + FAIL(5); } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { - FAIL(-28); + FAIL(6); } memset(buf, 0, sizeof(buf)); if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { - FAIL(-29); + FAIL(7); } for(i = 0; i < sizeof(buf); i++) { if(buf[i] != i) { printf("buf[%d] != %d\n", i, buf[i]); - FAIL(-30); + FAIL(8); } } } - /* Test 17: Append data to the same file many times. */ -#define APPEND_BYTES 1000 -#define BULK_SIZE 10 - for(i = 0; i < APPEND_BYTES; i += BULK_SIZE) { - afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); - if(afd < 0) { - FAIL(-31); - } - for(j = 0; j < BULK_SIZE; j++) { - buf[j] = 1 + ((i + j) & 0x7f); - } - if((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { - printf("r=%d\n", r); - FAIL(-32); - } - cfs_close(afd); - } - - /* Test 18: Read back the data written in Test 17 and verify that it - is correct. */ - afd = cfs_open("T3", CFS_READ); - if(afd < 0) { - FAIL(-33); - } - total_read = 0; - while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { - for(j = 0; j < r; j++) { - if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { - FAIL(-34); - } - } - total_read += r; - } - if(r < 0) { - FAIL(-35); - } - if(total_read != APPEND_BYTES) { - FAIL(-36); - } - cfs_close(afd); - error = 0; end: - cfs_close(wfd); cfs_close(rfd); cfs_close(afd); + cfs_close(wfd); return error; } /*---------------------------------------------------------------------------*/ +static int +coffee_test_gc(void) +{ + int i; + + cfs_remove("alpha"); + cfs_remove("beta"); + + + for (i = 0; i < 100; i++) { + if (i & 1) { + if(cfs_coffee_reserve("alpha", random_rand() & 0xffff) < 0) { + return i; + } + cfs_remove("beta"); + } else { + if(cfs_coffee_reserve("beta", 93171) < 0) { + return i; + } + cfs_remove("alpha"); + } + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +print_result(const char *test_name, int result) +{ + printf("%s: ", test_name); + if(result == 0) { + printf("OK\n"); + } else { + printf("ERROR (test %d)\n", result); + } +} +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(testcoffee_process, ev, data) { int start; + int result; PROCESS_BEGIN(); start = clock_seconds(); - printf("Coffee format: %d\n", cfs_coffee_format()); - printf("Coffee file test: %d\n", coffee_file_test()); - printf("Coffee garbage collection test: %d\n", coffee_gc_test()); - printf("Test time: %d seconds\n", (int)(clock_seconds() - start)); + + printf("Coffee test started\n"); + + result = cfs_coffee_format(); + print_result("Formatting", result); + + result = coffee_test_basic(); + print_result("Basic operations", result); + + result = coffee_test_append(); + print_result("File append", result); + + result = coffee_test_modify(); + print_result("File modification", result); + + result = coffee_test_gc(); + print_result("Garbage collection", result); + + printf("Coffee test finished. Duration: %d seconds\n", + (int)(clock_seconds() - start)); PROCESS_END(); } diff --git a/tools/cooja/contiki_tests/sky_coffee.csc b/tools/cooja/contiki_tests/sky_coffee.csc index cd04e6c88..98152825a 100644 --- a/tools/cooja/contiki_tests/sky_coffee.csc +++ b/tools/cooja/contiki_tests/sky_coffee.csc @@ -1,132 +1,118 @@ - - - ../apps/mrm - ../apps/mspsim - ../apps/avrora - ../apps/native_gateway - - test - 0 - generated - 0 - - se.sics.cooja.radiomediums.UDGM - 50.0 - 100.0 - 1.0 - 1.0 - - - se.sics.cooja.mspmote.SkyMoteType - sky1 - Sky Mote Type #1 - ../../../examples/sky/test-coffee.c - make clean TARGET=sky -make test-coffee.sky TARGET=sky - ../../../examples/sky/test-coffee.sky - se.sics.cooja.interfaces.Position - se.sics.cooja.interfaces.IPAddress - se.sics.cooja.interfaces.Mote2MoteRelations - se.sics.cooja.mspmote.interfaces.MspClock - se.sics.cooja.mspmote.interfaces.MspMoteID - se.sics.cooja.mspmote.interfaces.SkyButton - se.sics.cooja.mspmote.interfaces.SkyFlash - se.sics.cooja.mspmote.interfaces.SkyByteRadio - se.sics.cooja.mspmote.interfaces.SkySerial - se.sics.cooja.mspmote.interfaces.SkyLED - - - se.sics.cooja.mspmote.SkyMote - sky1 - - - se.sics.cooja.interfaces.Position - 97.11078411573273 - 56.790978919276014 - 0.0 - - - se.sics.cooja.mspmote.interfaces.MspMoteID - 1 - - - - - se.sics.cooja.plugins.SimControl - 248 - 3 - 200 - 0 - 0 - false - - - se.sics.cooja.plugins.Visualizer - - Mote IDs - Log output: printf()'s - - 246 - 2 - 170 - 1 - 200 - false - - - se.sics.cooja.plugins.LogListener - - - - 846 - 1 - 209 - 2 - 370 - false - - - se.sics.cooja.plugins.ScriptRunner - - - true - - 601 - 0 - 370 - 247 - 0 - false - - - + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + test + 0 + generated + 0 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + sky1 + Sky Mote Type #1 + [CONTIKI_DIR]/examples/sky/test-coffee.c + make clean TARGET=sky +make test-coffee.sky TARGET=sky + [CONTIKI_DIR]/examples/sky/test-coffee.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + + + + + se.sics.cooja.interfaces.Position + 97.11078411573273 + 56.790978919276014 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + se.sics.cooja.plugins.SimControl + 248 + 0 + 200 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.LogVisualizerSkin + 0.9090909090909091 0.0 0.0 0.9090909090909091 28.717468985697536 3.3718373461127142 + + 246 + 3 + 170 + 1 + 200 + + + se.sics.cooja.plugins.LogListener + + + + 846 + 2 + 209 + 2 + 370 + + + se.sics.cooja.plugins.ScriptRunner + + + true + + 601 + 1 + 370 + 247 + 0 + + + From 84105f4e4723ec4579330e67fb67da91ac8b5ded Mon Sep 17 00:00:00 2001 From: Niko Pollner Date: Tue, 30 Aug 2011 13:31:26 +0200 Subject: [PATCH 2/3] Improved multihop/mesh route discovery. Packetbuffer is now saved before route discovery and resent when a route is found. This solves the following problems: - First packet sent to a certain node is corrupted. - Packet to be forwarded that triggers route discovery is lost. --- core/net/rime/mesh.c | 26 ++++++++++++++++---------- core/net/rime/multihop.c | 17 +++++++++++------ core/net/rime/multihop.h | 1 + 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/core/net/rime/mesh.c b/core/net/rime/mesh.c index 779628c97..bb11f1a2a 100644 --- a/core/net/rime/mesh.c +++ b/core/net/rime/mesh.c @@ -94,7 +94,15 @@ data_packet_forward(struct multihop_conn *multihop, rt = route_lookup(dest); if(rt == NULL) { + if(c->queued_data != NULL) { + queuebuf_free(c->queued_data); + } + + PRINTF("data_packet_forward: queueing data, sending rreq\n"); + c->queued_data = queuebuf_new_from_packetbuf(); + rimeaddr_copy(&c->queued_data_dest, dest); route_discovery_discover(&c->route_discovery_conn, dest, PACKET_TIMEOUT); + return NULL; } else { route_refresh(rt); @@ -106,15 +114,21 @@ data_packet_forward(struct multihop_conn *multihop, static void found_route(struct route_discovery_conn *rdc, const rimeaddr_t *dest) { + struct route_entry *rt; struct mesh_conn *c = (struct mesh_conn *) ((char *)rdc - offsetof(struct mesh_conn, route_discovery_conn)); + PRINTF("found_route\n"); + if(c->queued_data != NULL && rimeaddr_cmp(dest, &c->queued_data_dest)) { queuebuf_to_packetbuf(c->queued_data); queuebuf_free(c->queued_data); c->queued_data = NULL; - if(multihop_send(&c->multihop, dest)) { + + rt = route_lookup(dest); + if (rt != NULL) { + multihop_resend(&c->multihop, &rt->nexthop); c->cb->sent(c); } else { c->cb->timedout(c); @@ -175,15 +189,7 @@ mesh_send(struct mesh_conn *c, const rimeaddr_t *to) could_send = multihop_send(&c->multihop, to); if(!could_send) { - if(c->queued_data != NULL) { - queuebuf_free(c->queued_data); - } - - PRINTF("mesh_send: queueing data, sending rreq\n"); - c->queued_data = queuebuf_new_from_packetbuf(); - rimeaddr_copy(&c->queued_data_dest, to); - route_discovery_discover(&c->route_discovery_conn, to, - PACKET_TIMEOUT); + PRINTF("mesh_send: could not send\n"); return 0; } c->cb->sent(c); diff --git a/core/net/rime/multihop.c b/core/net/rime/multihop.c index 5f45b9106..486c7f969 100644 --- a/core/net/rime/multihop.c +++ b/core/net/rime/multihop.c @@ -94,11 +94,10 @@ data_packet_received(struct unicast_conn *uc, const rimeaddr_t *from) } else { nexthop = NULL; if(c->cb->forward) { - nexthop = c->cb->forward(c, &sender, &receiver, - from, packetbuf_attr(PACKETBUF_ATTR_HOPS)); - packetbuf_set_attr(PACKETBUF_ATTR_HOPS, packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1); + nexthop = c->cb->forward(c, &sender, &receiver, + from, packetbuf_attr(PACKETBUF_ATTR_HOPS) - 1); } if(nexthop) { PRINTF("forwarding to %d.%d\n", nexthop->u8[0], nexthop->u8[1]); @@ -133,6 +132,9 @@ multihop_send(struct multihop_conn *c, const rimeaddr_t *to) return 0; } packetbuf_compact(); + packetbuf_set_addr(PACKETBUF_ADDR_ERECEIVER, to); + packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr); + packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1); nexthop = c->cb->forward(c, &rimeaddr_node_addr, to, NULL, 0); if(nexthop == NULL) { @@ -141,12 +143,15 @@ multihop_send(struct multihop_conn *c, const rimeaddr_t *to) } else { PRINTF("multihop_send: sending data towards %d.%d\n", nexthop->u8[0], nexthop->u8[1]); - packetbuf_set_addr(PACKETBUF_ADDR_ERECEIVER, to); - packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr); - packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1); unicast_send(&c->c, nexthop); return 1; } } /*---------------------------------------------------------------------------*/ +void +multihop_resend(const struct multihop_conn *const c, const rimeaddr_t *const nexthop) +{ + unicast_send(&c->c, nexthop); +} +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/net/rime/multihop.h b/core/net/rime/multihop.h index 23acb41fb..978005ed4 100644 --- a/core/net/rime/multihop.h +++ b/core/net/rime/multihop.h @@ -104,6 +104,7 @@ void multihop_open(struct multihop_conn *c, uint16_t channel, const struct multihop_callbacks *u); void multihop_close(struct multihop_conn *c); int multihop_send(struct multihop_conn *c, const rimeaddr_t *to); +void multihop_resend(const struct multihop_conn *const c, const rimeaddr_t *const nexthop); #endif /* __MULTIHOP_H__ */ /** @} */ From 942ba1f7bdd7e8ceec478445cb561950dcdb547e Mon Sep 17 00:00:00 2001 From: nvt Date: Mon, 5 Sep 2011 22:05:41 +0200 Subject: [PATCH 3/3] Removed const qualifier to conform with the rest of the Rime interface. --- core/net/rime/multihop.c | 2 +- core/net/rime/multihop.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/rime/multihop.c b/core/net/rime/multihop.c index 486c7f969..c46f1be20 100644 --- a/core/net/rime/multihop.c +++ b/core/net/rime/multihop.c @@ -149,7 +149,7 @@ multihop_send(struct multihop_conn *c, const rimeaddr_t *to) } /*---------------------------------------------------------------------------*/ void -multihop_resend(const struct multihop_conn *const c, const rimeaddr_t *const nexthop) +multihop_resend(struct multihop_conn *c, const rimeaddr_t *nexthop) { unicast_send(&c->c, nexthop); } diff --git a/core/net/rime/multihop.h b/core/net/rime/multihop.h index 978005ed4..070a148b8 100644 --- a/core/net/rime/multihop.h +++ b/core/net/rime/multihop.h @@ -104,7 +104,7 @@ void multihop_open(struct multihop_conn *c, uint16_t channel, const struct multihop_callbacks *u); void multihop_close(struct multihop_conn *c); int multihop_send(struct multihop_conn *c, const rimeaddr_t *to); -void multihop_resend(const struct multihop_conn *const c, const rimeaddr_t *const nexthop); +void multihop_resend(struct multihop_conn *c, const rimeaddr_t *nexthop); #endif /* __MULTIHOP_H__ */ /** @} */