[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/apps/DataCollector
FIFOBufferManagerM.nc, NONE, 1.1 StatisticsM.nc, NONE,
1.1 Compression.nc, NONE, 1.1 DatasetManagerM.nc, NONE,
1.1 FlashManagerReader.nc, NONE, 1.1 StatisticsReader.nc, NONE,
1.1 ProtocolStarter.nc, NONE, 1.1 CompressionM.nc, NONE,
1.1 FIFOBufferManager.nc, NONE, 1.1 ConnectionM.nc, NONE,
1.1 BufferManager.nc, NONE, 1.1 Connection.nc, NONE,
1.1 FlashManagerC.nc, NONE, 1.1 DatasetManager.nc, NONE,
1.1 Statistics.nc, NONE, 1.1 config.h, NONE,
1.1 FlashManagerM.nc, NONE, 1.1 ProtocolC.nc, NONE,
1.1 SamplingC.nc, NONE, 1.1 BufferManager.h, NONE,
1.1 FlashManagerWriter.nc, NONE, 1.1 StatisticsC.nc, NONE,
1.1 ProtocolM.nc, NONE, 1.1 BufferManagerM.nc, NONE,
1.1 SamplingM.nc, NONE, 1.1 DatasetManager.h, NONE,
1.1 CompressionC.nc, NONE, 1.1 ConnectionC.nc, NONE, 1.1
Marcus Chang
marcus_chang at users.sourceforge.net
Thu Mar 15 07:40:15 PDT 2007
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/tos/platform/micro4
LCGM.nc, NONE, 1.1 HPLKBIC.nc, NONE, 1.1 UARTFrameC.nc, NONE,
1.1 ThreeAxisAccel.nc, NONE, 1.1 MSP430ClockM.nc, NONE,
1.1 IntToLedsC.nc, NONE, 1.1 .platform, NONE, 1.1 UARTFrame.nc,
NONE, 1.1 UARTFrame.h, NONE, 1.1 LedsC.nc, NONE, 1.1 LCG.nc,
NONE, 1.1 HPLUARTM.nc, NONE, 1.1 UARTFrameM.nc, NONE,
1.1 msp430hardware.h, NONE, 1.1 Spi.nc, NONE, 1.1 CRC16.nc,
NONE, 1.1 HPL1wireM.nc, NONE, 1.1 HPLU510R1M.nc, NONE,
1.1 CRC16M.nc, NONE, 1.1 HPLSpiM.nc, NONE, 1.1 ExtLedsC.nc,
NONE, 1.1 AccelerometerC.nc, NONE, 1.1 StdOutC.nc, NONE,
1.1 HPL1wire.nc, NONE, 1.1 StdNullM.nc, NONE, 1.1 hardware.h,
NONE, 1.1 StdOut.nc, NONE, 1.1 StdNullC.nc, NONE,
1.1 hpl1wire.h, NONE, 1.1 StdOutM.nc, NONE, 1.1 ExtLeds.nc,
NONE, 1.1 IntToLedsM.nc, NONE, 1.1 TOSBoot_platform.h, NONE,
1.1 HPLSpi.h, NONE, 1.1 HPLKBI.nc, NONE, 1.1 HPLKBIM.nc, NONE, 1.1
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/tos/platform/micro4/radio
HALCC2420C.nc, NONE, 1.1 HPLCC2420M.nc, NONE,
1.1 SimpleMacC.nc, NONE, 1.1 cc2420.h, NONE, 1.1 SimpleMac.nc,
NONE, 1.1 SimpleMacM.nc, NONE, 1.1 hplcc2420.h, NONE,
1.1 HALCC2420M.nc, NONE, 1.1 HPLCC2420Status.nc, NONE,
1.1 HALCC2420.nc, NONE, 1.1 packet.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/contrib/diku/sensinode/apps/DataCollector
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv30685/sensinode/apps/DataCollector
Added Files:
FIFOBufferManagerM.nc StatisticsM.nc Compression.nc
DatasetManagerM.nc FlashManagerReader.nc StatisticsReader.nc
ProtocolStarter.nc CompressionM.nc FIFOBufferManager.nc
ConnectionM.nc BufferManager.nc Connection.nc FlashManagerC.nc
DatasetManager.nc Statistics.nc config.h FlashManagerM.nc
ProtocolC.nc SamplingC.nc BufferManager.h
FlashManagerWriter.nc StatisticsC.nc ProtocolM.nc
BufferManagerM.nc SamplingM.nc DatasetManager.h
CompressionC.nc ConnectionC.nc
Log Message:
* Sensinode Micro.4 platform support
* Hoghtrob Data Collection Application
--- NEW FILE: FIFOBufferManagerM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module FIFOBufferManagerM {
provides {
interface FIFOBufferManager;
}
}
implementation {
#include "config.h"
uint8_t next;
uint8_t realBuffers[COMPRESSION_BUFFERS][FLASH_PAGE_SIZE];
bool usedBuffers[COMPRESSION_BUFFERS];
uint8_t * fifoBuffers[COMPRESSION_BUFFERS];
int8_t free, fifo;
/*************************************************************************/
command result_t FIFOBufferManager.init()
{
uint8_t i;
for (i = 0; i < COMPRESSION_BUFFERS; i++)
{
usedBuffers[i] = FALSE;
fifoBuffers[i] = 0;
}
fifoBuffers[COMPRESSION_BUFFERS] = 0;
next = 0;
free = COMPRESSION_BUFFERS;
fifo = 0;
return SUCCESS;
}
/*************************************************************************/
command uint8_t * FIFOBufferManager.getFreeBuffer()
{
uint8_t i;
uint8_t * res = NULL;
/* try to allocate space */
for (i = 0; i < COMPRESSION_BUFFERS; i++)
{
if (usedBuffers[i] == FALSE)
{
usedBuffers[i] = TRUE;
res = realBuffers[i];
memset(res, 0, FLASH_PAGE_SIZE);
return res;
}
}
return 0;
}
/*************************************************************************/
command result_t FIFOBufferManager.releaseBuffer(uint8_t * ptr)
{
uint8_t i;
/* find page in buffer */
for (i = 0; i < COMPRESSION_BUFFERS; i++)
{
if (realBuffers[i] == ptr)
{
usedBuffers[i] = FALSE;
return SUCCESS;
}
}
return FAIL;
}
/*************************************************************************/
command result_t FIFOBufferManager.putFIFO(uint8_t * buffer)
{
uint8_t i, idx;
for (i = 0; i < COMPRESSION_BUFFERS; i++)
{
idx = (next + i) % COMPRESSION_BUFFERS;
if (fifoBuffers[idx] == 0)
{
fifoBuffers[idx] = buffer;
return SUCCESS;
}
}
return FAIL;
}
/*************************************************************************/
command result_t FIFOBufferManager.putFrontFIFO(uint8_t * buffer)
{
uint8_t try_next;
try_next = next;
if (try_next == 0)
try_next = COMPRESSION_BUFFERS - 1;
else
try_next--;
if (fifoBuffers[try_next] == 0)
{
next = try_next;
fifoBuffers[next] = buffer;
return SUCCESS;
}
return FAIL;
}
/*************************************************************************/
command uint8_t * FIFOBufferManager.getFIFO()
{
uint8_t * res;
res = fifoBuffers[next];
if (res == 0)
{
return 0;
}
/* */
fifoBuffers[next] = 0;
next++;
if (next == COMPRESSION_BUFFERS)
next = 0;
return res;
}
}
--- NEW FILE: StatisticsM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module StatisticsM {
provides {
interface StdControl;
interface Statistics[uint8_t id];
interface StatisticsReader;
}
uses {
interface InternalFlash;
interface Statistics as SelfCounter;
interface StdOut;
}
}
implementation {
#define STAT_COUNTERS uniqueCount("Statistic")
#define STAT_NAME_SIZE 8
struct counter_t {
char name[STAT_NAME_SIZE];
uint32_t current;
bool public;
};
enum {
FLASH_STARTUP_ADDR = 0x0000,
FLASH_STARTUP_SIZE = 0x04,
};
/**************************************************************************
** Structure array containing the counters' name and value
**************************************************************************/
struct counter_t statisticCounters[STAT_COUNTERS];
/**************************************************************************
** StdControl
**************************************************************************/
command result_t StdControl.init()
{
call SelfCounter.init("Startup", TRUE);
call SelfCounter.load();
call SelfCounter.increment();
call SelfCounter.save();
return SUCCESS;
}
command result_t StdControl.start()
{
uint8_t i;
for (i = 0; i < STAT_COUNTERS; i++)
{
call Statistics.load[i]();
// call StdOut.print(statisticCounters[i].name);
// call StdOut.printHexlong(statisticCounters[i].current);
// call StdOut.printHex(statisticCounters[i].public);
// call StdOut.print("\n\r");
}
return SUCCESS;
}
command result_t StdControl.stop()
{
uint8_t i;
uint32_t tmp[STAT_COUNTERS];
atomic {
for (i = 0; i < STAT_COUNTERS; i++)
{
tmp[i] = statisticCounters[i].current;
}
}
call InternalFlash.write( (void*) 0, tmp, STAT_COUNTERS * 4);
return SUCCESS;
}
/**************************************************************************
** Statistics
**************************************************************************/
command void Statistics.init[uint8_t id](const char * name, const bool public)
{
atomic {
strncpy(statisticCounters[id].name, name, STAT_NAME_SIZE);
statisticCounters[id].current = 0;
statisticCounters[id].public = public;
}
}
command void Statistics.load[uint8_t id]()
{
uint32_t tmp;
call InternalFlash.read( (void*)(id * 4), &tmp, 4);
if (tmp != 0xFFFFFFFF)
atomic statisticCounters[id].current = tmp;
}
command void Statistics.save[uint8_t id]()
{
uint32_t tmp;
atomic tmp = statisticCounters[id].current;
call InternalFlash.write( (void*)(id * 4), &tmp, 4);
}
command void Statistics.set[uint8_t id](uint32_t value)
{
atomic statisticCounters[id].current = value;
}
command uint32_t Statistics.getValue[uint8_t id]()
{
uint32_t res;
atomic res = statisticCounters[id].current;
return res;
}
command const char *Statistics.getName[uint8_t id]()
{
const char *res;
atomic res = statisticCounters[id].name;
return res;
}
async command void Statistics.increment[uint8_t id]()
{
atomic statisticCounters[id].current++;
}
async command void Statistics.decrement[uint8_t id]()
{
statisticCounters[id].current--;
}
async command void Statistics.add[uint8_t id](int32_t value)
{
statisticCounters[id].current += value;
}
/**************************************************************************
** StatisticsReader
**************************************************************************/
command result_t StatisticsReader.getStatistics(uint8_t * buffer, uint16_t size)
{
uint16_t i, written = 0;
atomic {
for (i = 0; i < STAT_COUNTERS; i++)
{
if (statisticCounters[i].public)
{
memcpy(buffer, &statisticCounters[i].name, STAT_NAME_SIZE);
buffer += STAT_NAME_SIZE;
*buffer++ = statisticCounters[i].current >> 24;
*buffer++ = statisticCounters[i].current >> 16;
*buffer++ = statisticCounters[i].current >> 8;
*buffer++ = statisticCounters[i].current;
written += STAT_NAME_SIZE + 4;
if (written + STAT_NAME_SIZE + 4 > size)
break;
}
}
}
return SUCCESS;
}
command uint16_t StatisticsReader.getStatisticsBufferSize()
{
return (STAT_COUNTERS * (STAT_NAME_SIZE + 4));
}
command uint32_t StatisticsReader.getStatisticByName(char * name)
{
uint8_t id;
uint32_t retval = 0;
atomic {
// walk through array and compare strings
for (id = 0; id < STAT_COUNTERS; id++) {
if (strcmp(name,statisticCounters[id].name) == 0) {
retval = statisticCounters[id].current;
break;
}
}
}
return retval;
}
/**************************************************************************
** StdOut
**************************************************************************/
async event result_t StdOut.get(uint8_t data) {
return SUCCESS;
}
}
--- NEW FILE: Compression.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
interface Compression
{
///////////////////////////////////////////////////////////////////////
// Insert data to be compressed
//
// @param x,y,z Data to be compressed
// @return result_t SUCCESS/FAIL
///////////////////////////////////////////////////////////////////////
command result_t insertData(uint16_t x, uint16_t y, uint16_t z, uint32_t count);
}
--- NEW FILE: DatasetManagerM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module DatasetManagerM {
provides {
interface DatasetManager;
}
uses {
interface BufferManager;
interface StdOut;
}
}
implementation {
#define DATASET_SIZE 256
#define PREVIOUS_SETS_CACHE 10
/* current dataset status */
uint8_t datastruct[DATASET_SIZE];
bool isInSet(uint16_t page);
void putInSet(uint16_t page);
void removeFromSet(uint16_t page);
void clearSet();
/* previous completed datasets */
dataset_t previousSets[PREVIOUS_SETS_CACHE];
uint8_t previousPtr;
/* used for joining fragments */
dataset_t currentSet;
uint8_t currentPageBuffer[256];
uint8_t * currentPageBufferPtr;
uint16_t currentPageNumber;
uint8_t expectedPageFragment;
/**************************************************************************
**
**************************************************************************/
command void DatasetManager.clear()
{
currentPageBufferPtr = currentPageBuffer;
currentSet.source = 0xFFFF;
currentSet.number = 0xFFFFFFFF;
currentSet.size = 0;
clearSet();
call BufferManager.clear();
call StdOut.print("DBM - free buffers: ");
call StdOut.printHex(call BufferManager.freeBuffers());
call StdOut.print("\r\n");
}
/**************************************************************************
**
**************************************************************************/
command void DatasetManager.insertFragment(dataset_t * set, fragment_t * part)
{
uint16_t i;
page_t * bufferPage = 0;
/* consistency check */
if ( (set->source != currentSet.source) || (set->number != currentSet.number) )
return;
/* get buffer */
bufferPage = call BufferManager.get(part->pageNumber);
/* buffer allocation successfull */
if (bufferPage != 0)
{
/* copy page fragment to buffer */
for (i = 0; i < part->length; i++)
{
bufferPage->page[i + part->start] = part->pagePtr[i];
}
/* flag current fragment as received */
bufferPage->status |= (0x01 << (part->fragment - 1));
//call StdOut.print("MAN - page status: ");
//call StdOut.printHexword(bufferPage->pageNumber);
//call StdOut.printHex(bufferPage->status);
//call StdOut.printHex( (0xFF >> (8 - part->total)) );
//call StdOut.print("\r\n");
//call StdOut.print("\r\n");
/* all fragments received */
if ( bufferPage->status == (0xFF >> (8 - part->total)) )
{
putInSet(part->pageNumber);
call BufferManager.free(part->pageNumber);
//for (i = 0; i < 256; i++)
//{
// call StdOut.printHex(bufferPage->page[i]);
//}
//call StdOut.print("\r\n");
call StdOut.print("Page complete: ");
call StdOut.printHex(bufferPage->page[0]);
call StdOut.printHex(bufferPage->page[1]);
call StdOut.print("\r\n");
call StdOut.print("MAN - free buffers: ");
call StdOut.printHex(call BufferManager.freeBuffers());
call StdOut.print("\r\n");
}
}
else
/* all buffers full - use running fragment collection */
{
/* first fragment of page or fragment was expected */
if ((part->fragment == 1) ||
(part->fragment == expectedPageFragment && currentPageNumber == part->pageNumber))
{
/* reset current page number */
currentPageNumber = part->pageNumber;
/* copy page fragment to buffer */
for (i = 0; i < part->length; i++)
{
currentPageBufferPtr[i + part->start] = part->pagePtr[i];
}
/* all fragments in buffer */
if (part->fragment == part->total)
{
expectedPageFragment = 1;
putInSet(part->pageNumber);
//for (i = 0; i < 256; i++)
//{
// call StdOut.printHex(currentPageBufferPtr[i]);
//}
//call StdOut.print("\r\n");
call StdOut.print("Page complete: ");
call StdOut.printHex(bufferPage->page[0]);
call StdOut.printHex(bufferPage->page[1]);
call StdOut.print("\r\n");
call StdOut.print("MAN - free buffers: ");
call StdOut.printHex(call BufferManager.freeBuffers());
call StdOut.print("\r\n");
}
else
/* increment expected page fragment */
expectedPageFragment = part->fragment + 1;
}
}
}
/**************************************************************************
**
**************************************************************************/
command void DatasetManager.checkDataset(dataset_t * set, intervals_t * list, uint8_t * statistics)
{
uint8_t size;
uint32_t tmp;
uint16_t i;
bool start = TRUE;
list->length = 0;
size = statistics[0];
for (i = 1; i < size; i += 12)
{
call StdOut.print(&(statistics[i]));
call StdOut.print(" ");
tmp = statistics[i + 8];
tmp = (tmp << 8) + statistics[i + 9];
tmp = (tmp << 8) + statistics[i + 10];
tmp = (tmp << 8) + statistics[i + 11];
call StdOut.printHexlong(tmp);
call StdOut.print("\n\r");
}
/* check if dataset is different than the current one */
if ( (set->source != currentSet.source) || (set->number != currentSet.number) )
{
/* check if dataset is in cache */
for (i = 0; i < PREVIOUS_SETS_CACHE; i++)
{
/* dataset found -> complete */
if ( (set->source == previousSets[i].source) && (set->number == previousSets[i].number) )
{
return;
}
}
/* clear dataset */
call DatasetManager.clear();
/* set new set as current */
currentSet.source = set->source;
currentSet.number = set->number;
currentSet.size = set->size;
/* set interval to entire set */
list->length = 1;
list->intervalPtr[0] = set->size - 1;
return;
}
/* step through pages in set */
for (i = 0; i < set->size; i++)
{
if (start)
{
/* find start */
if (!isInSet(i))
{
list->length++;
list->intervalPtr[list->length-1] = i;
start = FALSE;
}
}
else
{
/* find end */
if (isInSet(i))
{
list->intervalPtr[list->length-1] =
(list->intervalPtr[list->length-1] << 16) + (i - 1);
/* interval buffer full? */
if (list->length == list->max)
return;
/* restart search */
start = TRUE;
}
}
}
/* check if end was ever found */
if (!start)
list->intervalPtr[list->length-1] =
(list->intervalPtr[list->length-1] << 16) + (set->size - 1);
/* dataset complete */
if (list->length == 0)
{
/* put set information in cache */
previousSets[previousPtr].source = set->source;
previousSets[previousPtr].number = set->number;
previousSets[previousPtr].size = set->size;
previousPtr = (previousPtr + 1) % PREVIOUS_SETS_CACHE;
}
return;
}
/**************************************************************************
** Internal functions
**************************************************************************/
bool isInSet(uint16_t page)
{
uint8_t bitIndex, byte, bit;
uint16_t byteIndex;
byteIndex = page >> 3;
bitIndex = page & 0x0007;
byte = datastruct[byteIndex];
bit = byte & (0x01 << bitIndex);
return bit;
}
void putInSet(uint16_t page)
{
uint8_t bitIndex;
uint16_t byteIndex;
byteIndex = page >> 3;
bitIndex = page & 0x0007;
datastruct[byteIndex] |= (0x01 << bitIndex);
}
void removeFromSet(uint16_t page)
{
uint8_t bitIndex;
uint16_t byteIndex;
byteIndex = page >> 3;
bitIndex = page & 0x0007;
datastruct[byteIndex] &= ~(0x01 << bitIndex);
}
void clearSet()
{
uint16_t i;
for (i = 0; i < DATASET_SIZE; i++)
{
datastruct[i] = 0;
}
}
/**************************************************************************
** StdOut
**************************************************************************/
async event result_t StdOut.get(uint8_t data) {
return SUCCESS;
}
}
--- NEW FILE: FlashManagerReader.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
interface FlashManagerReader
{
/////////////////////////////////////////////////////////////////////////
// Retrieves the number of pages currently in use, by the flash
// manager.
//
// @return uint16_t The number of pages in currently in use.
/////////////////////////////////////////////////////////////////////////
command uint16_t getPagesInUse();
/////////////////////////////////////////////////////////////////////////
// Retrieve a logical page from the flash manager. The first page in
// the circular buffer is page 0. The page is stored in the memory
// pointed to by buffer, but is not accessible until a pageReady()
// event have been received for the requested page.
//
// @param uint16_t page_no The number of the page to retrieve.
// @param uint8_t* buffer A buffer to retrieve the page into.
// @return result_t SUCCESS if the page can be retrieved.
/////////////////////////////////////////////////////////////////////////
command result_t getPage(uint16_t page_no, uint8_t *buffer);
/////////////////////////////////////////////////////////////////////////
// pageReady is signalled when the page requested by a call to
// getPage have been retrieved.
//
// @param uint16_t page_no
/////////////////////////////////////////////////////////////////////////
event void pageReady(uint16_t page_no);
}
--- NEW FILE: StatisticsReader.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
interface StatisticsReader
{
/////////////////////////////////////////////////////////////////////////
// Fill the memory space pointed to by buffer with a max. of size bytes
//
// @param uint8_t * buffer Memory buffer to store statistics
// @param uint16_t size The size of the buffer in bytes
// @return result_t SUCCESS - the called buffer is being filled
// @return result_t FAIL - another buffer is being filled
/////////////////////////////////////////////////////////////////////////
command result_t getStatistics(uint8_t * buffer, uint16_t size);
/////////////////////////////////////////////////////////////////////////
// Find out how much room is needed for a copy of the statistics.
//
// @return uint16_t The required buffer size to hold all stats
/////////////////////////////////////////////////////////////////////////
command uint16_t getStatisticsBufferSize();
/////////////////////////////////////////////////////////////////////////
// Get a single value
//
// @param char * name A string matching the name of the counter
/////////////////////////////////////////////////////////////////////////
command uint32_t getStatisticByName(char * name);
}
--- NEW FILE: ProtocolStarter.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
interface ProtocolStarter
{
///////////////////////////////////////////////////////////////////////
// startOffload informs the protocol module that it should initiate
// an offload. Once the offload have ended successfully, the
// offloadFinished event is issued.
//
// @return result_t SUCCESS if the offload have begun.
///////////////////////////////////////////////////////////////////////
command result_t startOffload();
///////////////////////////////////////////////////////////////////////
// offloadFinished is signaled when the offload have finished
// successfully.
//
// @param uint16_t acked_pages The number of pages that have been
// acked during the offload.
///////////////////////////////////////////////////////////////////////
event void offloadFinished(uint16_t acked_pages);
///////////////////////////////////////////////////////////////////////
// offloadLater is signaled when the protocol wishes to be notified at
// a later time.
//
///////////////////////////////////////////////////////////////////////
event void offloadLater();
}
--- NEW FILE: CompressionM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module CompressionM {
provides {
interface StdControl as CompressionControl;
interface Compression;
}
uses {
interface FlashManagerWriter;
interface FIFOBufferManager;
interface StdOut;
}
}
implementation {
#include "config.h"
bool lossyCompression = FALSE, lossyInProgress = FALSE;
uint16_t average[3][COMPRESSION_SAMPLES_IN_AVERAGE];
uint8_t averageIndex;
uint16_t last_x = 0, last_y = 0, last_z = 0;
uint8_t * bufferPtr, * bufferPos;
task void writeFifoToFlash();
bool postWriteTask = FALSE, writeTaskInProgress = FALSE;
uint8_t find_incommon_bits(uint16_t x, uint16_t y, uint16_t z);
void write_sample_to_buffer(uint16_t x, uint16_t y, uint16_t z, uint8_t flag, uint8_t size);
/**************************************************************************
** CompressionControl
**************************************************************************/
command result_t CompressionControl.init()
{
call FIFOBufferManager.init();
averageIndex = 0;
bufferPtr = 0;
bufferPos = 0;
return SUCCESS;
}
command result_t CompressionControl.start()
{
return SUCCESS;
}
command result_t CompressionControl.stop()
{
return SUCCESS;
}
/**************************************************************************
** Compresssion
**************************************************************************/
command result_t Compression.insertData(uint16_t x, uint16_t y, uint16_t z, uint32_t stamp)
{
uint8_t errors_detected = 0;
uint8_t i, this_size, this_average = 0;
uint16_t this_x, this_y, this_z;
uint32_t sum_x = 0, sum_y = 0, sum_z = 0;
/* store local copy */
this_x = x;
this_y = y;
this_z = z;
/* perform lossy compression when flash is stretched */
if (lossyInProgress || lossyCompression)
{
/* store value for later averaging */
average[0][averageIndex] = this_x;
average[1][averageIndex] = this_y;
average[2][averageIndex] = this_z;
averageIndex++;
/* if this is not the last sample in average, return */
if (averageIndex != COMPRESSION_SAMPLES_IN_AVERAGE)
{
lossyInProgress = TRUE;
return SUCCESS;
} else {
/* reset lossy compression */
lossyInProgress = FALSE;
averageIndex = 0;
/* calculate average */
/* errornous samples are discarded and not included in average */
for (i = 0; i < COMPRESSION_SAMPLES_IN_AVERAGE; i++)
{
/* check if any of the samples are errornous */
/* and keep count of discarded samples */
if ((average[0][i] == 0xFFFF)
&& (average[1][i] == 0xFFFF)
&& (average[2][i] == 0xFFFF))
{
errors_detected++;
}
else {
sum_x += average[0][i];
sum_y += average[1][i];
sum_z += average[2][i];
}
}
/* set averages as working copy */
this_x = sum_x / (COMPRESSION_SAMPLES_IN_AVERAGE - errors_detected);
this_y = sum_y / (COMPRESSION_SAMPLES_IN_AVERAGE - errors_detected);
this_z = sum_z / (COMPRESSION_SAMPLES_IN_AVERAGE - errors_detected);
/* do base-10 rounding */
if ( ((sum_x * 10) / (COMPRESSION_SAMPLES_IN_AVERAGE - errors_detected)) % 10 >= 5)
this_x += 1;
if ( ((sum_y * 10) / (COMPRESSION_SAMPLES_IN_AVERAGE - errors_detected)) % 10 >= 5)
this_y += 1;
if ( ((sum_z * 10) / (COMPRESSION_SAMPLES_IN_AVERAGE - errors_detected)) % 10 >= 5)
this_z += 1;
/* mark this sample as being an average */
this_average = 1;
}
}
/* find how many bits that have been changed */
this_size = find_incommon_bits(x, y, z);
/* currently holding a buffer page ? */
if (bufferPtr != 0)
{
/* holding buffer page - enough room for this sample? */
if (this_size <= (FLASH_PAGE_SIZE - (bufferPos - bufferPtr)))
{
/* enough room in buffer - write sample and return call */
write_sample_to_buffer(this_x, this_y, this_z, this_average, this_size);
return SUCCESS;
} else {
/* not enough room - send page to FIFO */
call FIFOBufferManager.putFIFO(bufferPtr);
/* post write task if not already posted */
if (!writeTaskInProgress)
{
writeTaskInProgress = TRUE;
post writeFifoToFlash();
}
}
}
/* currently not holding a buffer page - so get one */
bufferPtr = call FIFOBufferManager.getFreeBuffer();
/* was buffer allocation not successful? - then panic */
if (bufferPtr == 0)
{
/* no more space to store samples */
/* possible action: stop sampling */
/* possible action: raise alarm */
/* possible action: keep spamming */
/* post write task if not already posted */
// if (!writeTaskInProgress)
// {
// writeTaskInProgress = TRUE;
// post writeFifoToFlash();
// }
return FAIL;
} else {
/* buffer allocated - initialize new page - insert timestamp */
bufferPos = bufferPtr;
*bufferPos++ = stamp >> 24;
*bufferPos++ = stamp >> 16;
*bufferPos++ = stamp >> 8;
*bufferPos++ = stamp;
/* force first data sample to be written fully to buffer */
this_size = 5;
/* write data to buffer */
write_sample_to_buffer(this_x, this_y, this_z, this_average, this_size);
return SUCCESS;
}
}
task void writeFifoToFlash()
{
result_t res;
uint8_t * pagePtr;
/* get next page from FIFO */
pagePtr = call FIFOBufferManager.getFIFO();
/* page available? */
if (pagePtr == 0)
{
/* no more pages in FIFO - do not repost write task */
writeTaskInProgress = FALSE;
return;
}
/* write page to flash */
res = call FlashManagerWriter.writePage(pagePtr);
/* write failed? - flash either full or already writing */
if (res == FAIL)
{
/* set task to be reposted when either writepagedone or status is signaled */
postWriteTask = TRUE;
/* put page back in FIFO, but re-insert at old place in front */
call FIFOBufferManager.putFrontFIFO(pagePtr);
writeTaskInProgress = FALSE;
} else {
/* repost task until either flash is full or fifo is empty */
post writeFifoToFlash();
}
}
/**************************************************************************
** FlashManagerWriter
**************************************************************************/
event void FlashManagerWriter.writePageDone(uint8_t * pagePtr)
{
call StdOut.print("COMP: writepageDone: ");
call StdOut.printHexword((uint16_t) pagePtr);
call StdOut.print("\n\r");
/* buffer successfully written to flash - release buffer */
call FIFOBufferManager.releaseBuffer(pagePtr);
/* FIFO contains pages - post write task */
if (postWriteTask && !writeTaskInProgress)
{
postWriteTask = FALSE;
writeTaskInProgress = TRUE;
post writeFifoToFlash();
}
return;
}
event void FlashManagerWriter.status(uint16_t pages_used, uint16_t pages_left)
{
call StdOut.print("COMP: status: ");
call StdOut.printHexword(pages_used);
call StdOut.print(" ");
call StdOut.printHexword(pages_left);
call StdOut.print("\n\r");
/* determing from the flash status if lossy compression is needed */
if (pages_left < COMPRESSION_LOSSY_LIMIT)
lossyCompression = TRUE;
else
lossyCompression = FALSE;
/* if FIFO contains pages and there are free space in flash - post write task */
if (pages_left > 0 && postWriteTask && !writeTaskInProgress)
{
postWriteTask = FALSE;
writeTaskInProgress = TRUE;
post writeFifoToFlash();
}
return;
}
/**************************************************************************
** Helper functions
**************************************************************************/
uint8_t find_incommon_bits(uint16_t x, uint16_t y, uint16_t z)
{
uint8_t res;
int16_t diff_x, diff_y, diff_z;
/* calculate difference between this dataset and the previous */
diff_x = last_x - x;
diff_y = last_y - y;
diff_z = last_z - z;
/* 4 bit signed => [-8;7] */
if ( ((-8 <= diff_x) && (diff_x <= 7))
&& ((-8 <= diff_y) && (diff_y <= 7))
&& ((-8 <= diff_z) && (diff_z <= 7)) )
res = 2;
/* 7 bit signed => [-64;63] */
else if ( ((-64 <= diff_x) && (diff_x <= 63))
&& ((-64 <= diff_y) && (diff_y <= 63))
&& ((-64 <= diff_z) && (diff_z <= 63)) )
res = 3;
/* 9 bit signed => [-256;255] */
else if ( ((-256 <= diff_x) && (diff_x <= 255))
&& ((-256 <= diff_y) && (diff_y <= 255))
&& ((-256 <= diff_z) && (diff_z <= 255)) )
res = 4;
/* 12 bit - default */
else
res = 5;
return res;
}
void write_sample_to_buffer(uint16_t x, uint16_t y, uint16_t z, uint8_t flag, uint8_t size)
{
int16_t diff_x, diff_y, diff_z;
/* calculate difference between this dataset and the previous */
diff_x = last_x - x;
diff_y = last_y - y;
diff_z = last_z - z;
/* switch/case between the four different compression modes */
switch(size)
{
/* difference less than 4 bits - store difference */
case 2:
*bufferPos++ = 0xC0
| (flag << 5)
| (diff_x & 0x000F) << 1
| (diff_y & 0x000F) >> 3;
*bufferPos++ = (diff_y & 0x000F) << 5
| (diff_z & 0x000F) << 1;
break;
/* difference less than 7 bits - store difference */
case 3:
*bufferPos++ = 0x80
| (flag << 5)
| (diff_x & 0x007F) >> 2;
*bufferPos++ = (diff_x & 0x007F) << 6
| (diff_y & 0x007F) >> 1;
*bufferPos++ = (diff_y & 0x007F) << 7
| (diff_z & 0x007F);
break;
/* difference less than 9 bits - store difference */
case 4:
*bufferPos++ = 0x40
| (flag << 5)
| (diff_x & 0x01FF) >> 4;
*bufferPos++ = (diff_x & 0x01FF) << 4
| (diff_y & 0x01FF) >> 5;
*bufferPos++ = (diff_y & 0x01FF) << 3
| (diff_z & 0x01FF) >> 6;
*bufferPos++ = (diff_z & 0x01FF) << 2;
break;
/* difference more than 9 bits - store original */
case 5:
*bufferPos++ = 0x00
| (flag << 5)
| (x & 0x0FFF) >> 7;
*bufferPos++ = (x & 0x0FFF) << 1
| (y & 0x0FFF) >> 11;
*bufferPos++ = (y & 0x0FFF) >> 3;
*bufferPos++ = (y & 0x0FFF) << 5
| (z & 0x0FFF) >> 7;
*bufferPos++ = (z & 0x0FFF) << 1;
break;
default:
break;
}
/* update values for next pass-through */
last_x = x;
last_y = y;
last_z = z;
}
/**************************************************************************
** StdOut
**************************************************************************/
async event result_t StdOut.get(uint8_t data)
{
return SUCCESS;
}
}
--- NEW FILE: FIFOBufferManager.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
/*
*
*
*/
interface FIFOBufferManager {
command result_t init();
command uint8_t * getFreeBuffer();
command result_t releaseBuffer(uint8_t * buffer);
command result_t putFIFO(uint8_t * buffer);
command result_t putFrontFIFO(uint8_t * buffer);
command uint8_t * getFIFO();
}
--- NEW FILE: ConnectionM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module ConnectionM {
provides {
interface StdControl;
interface Connection;
}
uses {
interface StdControl as SimpleMacControl;
interface SimpleMac;
interface Timer;
interface LCG;
interface LocalTime;
interface StdOut;
}
}
implementation {
#include "cc2420.h"
#define BROADCAST_ADDRESS 0xFFFF
#define ROLE_NONE 0x00
#define ROLE_CLIENT 0x01
#define ROLE_SERVER 0x02
/* Timeouts based on these defines: */
#define TIME_DELAY_RTT 250
#define TIME_DELAY_CCA 10
#define TIME_DELAY_DT 10
#define TIME_DELAY_RESPONSE_MIN 5
#define TIME_DELAY_TIMEOUT 5000
#define TIME_DELAY_T1 65
/* t0: 205 ms */ //0x0186
/* t1: 30 ms */ //0x0041
/* t2: 70 ms */ //0x0069
/* t3: 770 ms */ //0x057d
/* t4: 170 ms */ //0x0140
/* t5: 780 ms */ //0x0587
/* Number of retries */
#define RETRY_CCA 3
#define RETRY_PROTOCOL_DISCOVERY 5
#define RETRY_PROTOCOL_ACCEPT 3
enum states {
STATE_OFF = 0x00,
STATE_IDLE = 0x10,
STATE_CONNECTION_ESTABLISHED = 0x20,
STATE_CONNECTION_CLOSING = 0x30,
STATE_CLIENT_DISCOVERY_SENT = 0x40,
STATE_CLIENT_DISCOVERY_RETRY = 0x50,
STATE_CLIENT_OFFER_RECEIVED = 0x60,
STATE_CLIENT_OFFER_ACCEPTED = 0x70,
STATE_SERVER_DISCOVERY_ACCEPT = 0x80,
STATE_SERVER_DISCOVERY_RECEIVED = 0x90,
STATE_SERVER_OFFER_SENT = 0xA0,
};
enum packet_types {
PACKET_TYPE_DISCOVERY = 0x0100,
PACKET_TYPE_OFFER = 0x0200,
PACKET_TYPE_ACCEPT = 0x0300,
PACKET_TYPE_ACKNOWLEDGE = 0x0400,
PACKET_TYPE_DATA = 0xFF00,
};
/********************/
/* Server variables */
/********************/
uint8_t publicChannel, privateChannel;
int8_t lastRSSI;
uint8_t lastSerial;
uint16_t lastClient;
/********************/
/* Client variables */
/********************/
int8_t bestServerRSSI, bestClientRSSI;
uint8_t bestSerial, bestChannel;
uint16_t bestServer;
/********************/
/* Common variables */
/********************/
bool activity;
uint8_t ccaRetry, discoveryRetry, acceptRetry;
uint16_t connectionAddress;
uint16_t TIME_DELAY_T0, TIME_DELAY_T2, TIME_DELAY_T3, TIME_DELAY_T4, TIME_DELAY_T5;
norace uint8_t currentState, role;
const mac_addr_t * shortAddress;
packet_t connectionPacket;
void connection_transmit_discovery();
void connection_transmit(uint16_t type, uint16_t receiver, uint8_t serial, uint8_t channel, int8_t rssi);
/*************************************************************************************************
*** StdControl
**************************************************************************************************/
task void initTask();
/**********************************************************************
* Init
*********************************************************************/
command result_t StdControl.init()
{
call SimpleMacControl.init();
// publicChannel = CC2420_DEFAULT_CHANNEL;
// privateChannel = (*shortAddress) % 15 + publicChannel + 1;
// privateChannel = (privateChannel > 26) ? privateChannel - 16 : privateChannel;
//publicChannel = 25;
//privateChannel = 26;
publicChannel = 26;
switch(TOS_LOCAL_ADDRESS)
{
case 0x4B7C:
case 0x3BF7:
privateChannel = 11;
break;
case 0x85F6:
case 0x82FD:
privateChannel = 14;
break;
case 0xA7B2:
case 0x9645:
privateChannel = 17;
break;
case 0x705B:
case 0x645B:
privateChannel = 20;
break;
default:
privateChannel = 23;
break;
}
call SimpleMac.setChannel(publicChannel);
// call SimpleMac.setTransmitPower(CC2420_DEFAULT_POWER);
call SimpleMac.setTransmitPower(100);
call SimpleMac.addressFilterEnable();
call LCG.seed(call LocalTime.read());
role = ROLE_NONE;
currentState = STATE_IDLE;
TIME_DELAY_T4 = TIME_DELAY_RTT + 2 * RETRY_CCA * TIME_DELAY_CCA + TIME_DELAY_DT;
TIME_DELAY_T2 = TIME_DELAY_T1 + RETRY_CCA * TIME_DELAY_CCA + TIME_DELAY_DT;
TIME_DELAY_T3 = TIME_DELAY_T2 + RETRY_PROTOCOL_ACCEPT * TIME_DELAY_T4 +
TIME_DELAY_RTT + 3 * RETRY_CCA * TIME_DELAY_CCA + TIME_DELAY_DT;
TIME_DELAY_T0 = TIME_DELAY_T1 + TIME_DELAY_RESPONSE_MIN +
TIME_DELAY_RTT + 2 * RETRY_CCA * TIME_DELAY_CCA + TIME_DELAY_DT;
TIME_DELAY_T5 = TIME_DELAY_T3 + TIME_DELAY_DT;
/*
call StdOut.print("TIME_DELAY_T0:");
call StdOut.printHexword(TIME_DELAY_T0);
call StdOut.print("\r\n");
call StdOut.print("TIME_DELAY_T1:");
call StdOut.printHexword(TIME_DELAY_T1);
call StdOut.print("\r\n");
call StdOut.print("TIME_DELAY_T2:");
call StdOut.printHexword(TIME_DELAY_T2);
call StdOut.print("\r\n");
call StdOut.print("TIME_DELAY_T3:");
call StdOut.printHexword(TIME_DELAY_T3);
call StdOut.print("\r\n");
call StdOut.print("TIME_DELAY_T4:");
call StdOut.printHexword(TIME_DELAY_T4);
call StdOut.print("\r\n");
call StdOut.print("TIME_DELAY_T5:");
call StdOut.printHexword(TIME_DELAY_T5);
call StdOut.print("\r\n");
*/
post initTask();
return SUCCESS;
}
task void initTask()
{
shortAddress = call SimpleMac.getAddress();
}
/**********************************************************************
* Start/Stop
*********************************************************************/
command result_t StdControl.start()
{
return SUCCESS;
}
command result_t StdControl.stop()
{
return SUCCESS;
}
/*************************************************************************************************
*** Connection related
**************************************************************************************************/
/**********************************************************************
* open
*********************************************************************/
command result_t Connection.open()
{
call SimpleMacControl.start();
call SimpleMac.setChannel(publicChannel);
role = ROLE_CLIENT;
currentState = STATE_CLIENT_DISCOVERY_SENT;
discoveryRetry = 0;
connection_transmit_discovery();
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T0);
return SUCCESS;
}
/**********************************************************************
* close
*********************************************************************/
command result_t Connection.close()
{
call Timer.stop();
/* regress */
if (role == ROLE_CLIENT)
{
call SimpleMacControl.stop();
role = ROLE_NONE;
currentState = STATE_IDLE;
}
else
{
currentState = STATE_SERVER_DISCOVERY_ACCEPT;
}
call SimpleMac.setChannel(publicChannel);
return SUCCESS;
}
/**********************************************************************
* accept
*********************************************************************/
command result_t Connection.accept()
{
call SimpleMacControl.start();
call SimpleMac.setChannel(publicChannel);
role = ROLE_SERVER;
currentState = STATE_SERVER_DISCOVERY_ACCEPT;
return SUCCESS;
}
/**********************************************************************
* reject
*********************************************************************/
command result_t Connection.reject()
{
call Timer.stop();
call SimpleMacControl.stop();
role = ROLE_NONE;
currentState = STATE_IDLE;
return SUCCESS;
}
/**********************************************************************
* sendPacket
*********************************************************************/
command result_t Connection.sendPacket(packet_t * packet)
{
if (currentState == STATE_CONNECTION_ESTABLISHED)
{
packet->fcf = PACKET_TYPE_DATA;
packet->dest = connectionAddress;
return call SimpleMac.sendPacket(packet);
} else
{
return FAIL;
}
}
/**********************************************************************
* setPublicChannel
*********************************************************************/
command result_t Connection.setPublicChannel(uint8_t channel)
{
publicChannel = channel;
privateChannel = (*shortAddress) % 15 + publicChannel + 1;
privateChannel = (privateChannel > 26) ? privateChannel - 16 : privateChannel;
call SimpleMac.setChannel(publicChannel);
return SUCCESS;
}
/**********************************************************************
* setPrivateChannel
*********************************************************************/
command result_t Connection.setPrivateChannel(uint8_t channel)
{
privateChannel = channel;
return SUCCESS;
}
/**********************************************************************
* getShortAddress
*********************************************************************/
command uint16_t Connection.getShortAddress()
{
return *shortAddress;
}
/*************************************************************************************************
*** Timer related
**************************************************************************************************/
event result_t Timer.fired()
{
switch(currentState)
{
case STATE_IDLE:
call StdOut.print("CON: Error - timer fired in idle state\r\n");
break;
/******************************************************************
** Client related
******************************************************************/
case STATE_CLIENT_DISCOVERY_SENT:
call StdOut.print("CON: Timeout: No reply from discovery\r\n");
call SimpleMacControl.stop();
currentState = STATE_CLIENT_DISCOVERY_RETRY;
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T5);
break;
case STATE_CLIENT_DISCOVERY_RETRY:
if (++discoveryRetry < RETRY_PROTOCOL_DISCOVERY)
{
call SimpleMacControl.start();
currentState = STATE_CLIENT_DISCOVERY_SENT;
connection_transmit_discovery();
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T0);
}
else
{
call StdOut.print("CON: Discovery failed\r\n");
/* restart */
call SimpleMacControl.stop();
role = ROLE_NONE;
currentState = STATE_IDLE;
signal Connection.openDone(STATE_CLIENT_DISCOVERY_SENT);
}
break;
case STATE_CLIENT_OFFER_RECEIVED:
call StdOut.print("CON: Timeout: Finished waiting for offers\r\n");
call StdOut.print("CON: Transmitting accept\r\n");
acceptRetry = 0;
connection_transmit(PACKET_TYPE_ACCEPT, bestServer, bestSerial + 1, privateChannel, bestServerRSSI);
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T4);
/* progress */
currentState = STATE_CLIENT_OFFER_ACCEPTED;
break;
case STATE_CLIENT_OFFER_ACCEPTED:
call StdOut.print("CON: Timeout: No acknowledgement for accept\r\n");
if (++acceptRetry < RETRY_PROTOCOL_ACCEPT)
{
connection_transmit(PACKET_TYPE_ACCEPT, bestServer, bestSerial + 1, privateChannel, bestServerRSSI);
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T4);
}
else
{
/* restart */
call SimpleMacControl.stop();
role = ROLE_NONE;
currentState = STATE_IDLE;
signal Connection.openDone(STATE_CLIENT_OFFER_ACCEPTED);
}
break;
/******************************************************************
** Server related
******************************************************************/
case STATE_SERVER_DISCOVERY_RECEIVED:
call StdOut.print("CON: Timeout: Ready to reply to discovery\r\n");
call StdOut.print("CON: Transmitting offer\r\n");
connection_transmit(PACKET_TYPE_OFFER, lastClient, lastSerial + 1, privateChannel, lastRSSI);
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T3);
/* progress */
currentState = STATE_SERVER_OFFER_SENT;
break;
case STATE_SERVER_OFFER_SENT:
call StdOut.print("CON: Timeout: No response to offer\r\n");
/* regress */
call StdOut.print("CON: Regress to discovery accept\r\n");
currentState = STATE_SERVER_DISCOVERY_ACCEPT;
break;
/******************************************************************
** Common
******************************************************************/
case STATE_CONNECTION_ESTABLISHED:
// call StdOut.print("CON: Timeout: Check for inactivity\r\n");
if (activity) {
activity = FALSE;
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_TIMEOUT);
} else {
call StdOut.print("CON: Connection lost due to inactivity\r\n");
/* regress */
if (role == ROLE_CLIENT)
{
call SimpleMacControl.stop();
role = ROLE_NONE;
currentState = STATE_IDLE;
}
else
{
currentState = STATE_SERVER_DISCOVERY_ACCEPT;
}
call SimpleMac.setChannel(publicChannel);
signal Connection.lost();
}
break;
default:
call StdOut.print("CON: Error - unhandled state:");
call StdOut.printHex(currentState);
call StdOut.print("\r\n");
break;
}
return SUCCESS;
}
/*************************************************************************************************
*** MAC related
*************************************************************************************************/
event packet_t * SimpleMac.receivedPacket(packet_t * packet)
{
packet_t * tmp = packet;
uint8_t randomDelay;
switch(currentState)
{
/******************************************************************
** Client related
******************************************************************/
case STATE_CLIENT_DISCOVERY_SENT:
if (packet->fcf == PACKET_TYPE_OFFER)
{
call Timer.stop();
/* first offer received best by default */
bestSerial = packet->data_seq_no;
bestServer = packet->src;
bestClientRSSI = packet->data[0];
bestChannel = packet->data[1];
bestServerRSSI = packet->fcs.rssi;
call StdOut.print("CON: Received offer from: ");
call StdOut.printHexword(packet->src);
call StdOut.print(" ");
call StdOut.printHex(packet->data[0]);
call StdOut.print(" ");
call StdOut.printHex(packet->fcs.rssi);
call StdOut.print("\r\n");
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_T2);
/* progress */
currentState = STATE_CLIENT_OFFER_RECEIVED;
} else
{
call StdOut.print("CON: Wrong packet type - expected offer\r\n");
}
break;
case STATE_CLIENT_OFFER_RECEIVED:
if (packet->fcf == PACKET_TYPE_OFFER)
{
call StdOut.print("CON: Received offer from: ");
call StdOut.printHexword(packet->src);
call StdOut.print(" ");
call StdOut.printHex(packet->data[0]);
call StdOut.print(" ");
call StdOut.printHex(packet->fcs.rssi);
call StdOut.print("\r\n");
/* check if offer is better than previous */
if (bestClientRSSI < (int8_t) packet->data[0])
{
bestSerial = packet->data_seq_no;
bestServer = packet->src;
bestClientRSSI = packet->data[0];
bestChannel = packet->data[1];
bestServerRSSI = packet->fcs.rssi;
}
} else
{
call StdOut.print("CON: Wrong packet type - expected offer\r\n");
}
break;
case STATE_CLIENT_OFFER_ACCEPTED:
if (packet->fcf == PACKET_TYPE_ACKNOWLEDGE)
{
call Timer.stop();
call StdOut.print("CON: Received acknowledge\r\n");
connectionAddress = bestServer;
call SimpleMac.setChannel(bestChannel);
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_TIMEOUT);
currentState = STATE_CONNECTION_ESTABLISHED;
signal Connection.openDone(SUCCESS);
} else
{
call StdOut.print("CON: Wrong packet type - expected accept\r\n");
}
break;
/******************************************************************
** Server related
******************************************************************/
case STATE_SERVER_DISCOVERY_ACCEPT:
if (packet->fcf == PACKET_TYPE_DISCOVERY)
{
call StdOut.print("CON: Discovery packet received\r\n");
lastSerial = packet->data_seq_no;
lastClient = packet->src;
lastRSSI = packet->fcs.rssi;
randomDelay = TIME_DELAY_RESPONSE_MIN + 5 * (call LCG.next() % 16);
call StdOut.print("CON: Random: ");
call StdOut.printHex(randomDelay);
call StdOut.print("\r\n");
call Timer.start(TIMER_ONE_SHOT, randomDelay);
currentState = STATE_SERVER_DISCOVERY_RECEIVED;
} else
{
call StdOut.print("CON: Wrong packet type - expected discovery\r\n");
}
break;
case STATE_SERVER_OFFER_SENT:
if (packet->fcf == PACKET_TYPE_ACCEPT)
{
call Timer.stop();
call StdOut.print("CON: Accept packet received\r\n");
lastSerial = packet->data_seq_no;
lastClient = packet->src;
lastRSSI = packet->fcs.rssi;
connectionAddress = lastClient;
connection_transmit(PACKET_TYPE_ACKNOWLEDGE, lastClient, lastSerial + 1, privateChannel, lastRSSI);
call SimpleMac.setChannel(privateChannel);
call Timer.start(TIMER_ONE_SHOT, TIME_DELAY_TIMEOUT);
currentState = STATE_CONNECTION_ESTABLISHED;
signal Connection.established();
} else
{
call StdOut.print("CON: Wrong packet type - expected accept\r\n");
}
break;
/******************************************************************
** Common
******************************************************************/
case STATE_CONNECTION_ESTABLISHED:
if (packet->fcf == PACKET_TYPE_DATA)
{
// call StdOut.print("CON: Received data packet\r\n");
activity = TRUE;
tmp = signal Connection.receivedPacket(packet);
}
break;
default:
call StdOut.print("CON: Error - unhandled state:");
call StdOut.printHex(currentState);
call StdOut.print("\r\n");
break;
}
return tmp;
}
event void SimpleMac.sendPacketDone(packet_t * packet, result_t result)
{
if (currentState == STATE_CONNECTION_ESTABLISHED)
{
activity = TRUE;
signal Connection.sendPacketDone(packet, result);
}
else if (result != SUCCESS)
{
if (++ccaRetry < RETRY_CCA)
{
call StdOut.print("CON: Error - retry: ");
call StdOut.printHex(ccaRetry);
call StdOut.print("\r\n");
call SimpleMac.sendPacket(&connectionPacket);
}
// else
// {
// signal Connection.openDone(currentState);
// }
}
}
/*************************************************************************************************
** Packet utility functions
*************************************************************************************************/
void connection_transmit_discovery()
{
ccaRetry = 0;
connectionPacket.length = 9; // 7 + 0 + 2;
connectionPacket.fcf = PACKET_TYPE_DISCOVERY;
connectionPacket.data_seq_no = (call LCG.next() & 0x7F);
connectionPacket.dest = BROADCAST_ADDRESS;
// connectionPacket.src = *shortAddress;
// connectionPacket.fcs.rssi = 0;
// connectionPacket.fcs.correlation = 0;
call SimpleMac.sendPacket(&connectionPacket);
}
void connection_transmit(uint16_t type, uint16_t receiver, uint8_t serial, uint8_t channel, int8_t rssi)
{
ccaRetry = 0;
connectionPacket.length = 11; // 7 + 2 + 2;
connectionPacket.fcf = type;
connectionPacket.data_seq_no = serial;
connectionPacket.dest = receiver;
connectionPacket.data[0] = rssi;
connectionPacket.data[1] = channel;
// connectionPacket.src = *shortAddress;
// connectionPacket.data[2] = distanceToGateway;
// connectionPacket.data[3] = successRate;
// connectionPacket.data[4] = batteryStatus;
// connectionPacket.fcs.rssi = 0;
// connectionPacket.fcs.correlation = 0;
call SimpleMac.sendPacket(&connectionPacket);
}
/*************************************************************************************************
** StdOut
*************************************************************************************************/
async event result_t StdOut.get(uint8_t data) {
return SUCCESS;
}
}
--- NEW FILE: BufferManager.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
/*
*
*
*/
includes BufferManager;
interface BufferManager {
command void clear();
/**
* Locates a free packet in the buffer-pool, and returns it. If
* there is no free packets NULL is returned, and getFailure is
* signaled.
*
* @return A free packet, or NULL if no free packets exists
*/
command page_t * get(uint16_t page);
/**
* Returns a packet to the buffer-pool. If successful, the function
* will return SUCCESS. Otherwise it returns FAIL, and putFailure is
* signalled.
*
* @return SUCCESS, if the packet could be returned.
*/
command result_t free(uint16_t page);
command uint8_t freeBuffers();
}
--- NEW FILE: Connection.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
includes packet;
interface Connection
{
command result_t accept();
command result_t reject();
event void established();
event void lost();
command result_t open();
event void openDone(uint8_t result);
command result_t close();
command result_t setPublicChannel(uint8_t channel);
command result_t setPrivateChannel(uint8_t channel);
command uint16_t getShortAddress();
/**
* sendPacket will perform a CCA, put the device into transmit mode,
* send the packet and return. If the SPI bus is not free or CCA
* fails, the sending of the packet is delayed. The contents
* of packet_t must not be changed after the call to sendPacket.
*
* @param packet_t * packet The packet that should be sent.
* @return result_t If the packet was queued for sending successfully.
*/
command result_t sendPacket(packet_t *packet);
/**
* sendPacketDone is signaled when a packet have been sent successfully.
*
* @param packet_t *packet The packet that have been sent.
* @param result_t result If the packet was sent successfully.
*/
event void sendPacketDone(packet_t *packet, result_t result);
/**
* receivedPacket is signalled when the radio have received a full
* packet. The function must return a free packet_t to the radio
* stack. This can be the same packet that have been signaled
*
* @param packet_t *packet The received packet
* @return packet_t* A free packet
*/
event packet_t *receivedPacket(packet_t *packet);
}
--- NEW FILE: FlashManagerC.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
configuration FlashManagerC {
provides {
interface StdControl as FlashManagerControl;
interface FlashManagerWriter;
interface FlashManagerReader;
}
uses {
interface ProtocolStarter;
interface Timer;
interface StdOut;
}
}
implementation {
components FlashManagerM,
FlashAccessC as FlashDriverM, StatisticsC;
FlashManagerControl = FlashManagerM;
FlashManagerWriter = FlashManagerM;
FlashManagerReader = FlashManagerM;
ProtocolStarter = FlashManagerM;
Timer = FlashManagerM;
StdOut = FlashManagerM;
FlashManagerM.FlashControl -> FlashDriverM.FlashControl;
FlashManagerM.FlashAccess -> FlashDriverM.FlashAccess;
}
--- NEW FILE: DatasetManager.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
/*
*
*
*/
includes DatasetManager;
interface DatasetManager {
command void clear();
command void insertFragment(dataset_t * set, fragment_t * frag);
command void checkDataset(dataset_t * set, intervals_t * list, uint8_t * statistics);
}
--- NEW FILE: Statistics.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
interface Statistics
{
/////////////////////////////////////////////////////////////////////////
// Initialize the counter inside the statistical module. The counter
// starts at zero.
//
// @param const char * name The name of the counter
/////////////////////////////////////////////////////////////////////////
command void init(const char *name, const bool public);
command void load();
command void save();
/////////////////////////////////////////////////////////////////////////
// Set the counter to a specific value.
//
// @param uint32_t value The value for the counter
/////////////////////////////////////////////////////////////////////////
command void set(uint32_t value);
/////////////////////////////////////////////////////////////////////////
// Get value of counter.
//
// @return uint32_t The counter's value
/////////////////////////////////////////////////////////////////////////
command uint32_t getValue();
/////////////////////////////////////////////////////////////////////////
// Get name of counter.
//
// @return const char * The counter name
/////////////////////////////////////////////////////////////////////////
command const char * getName();
/////////////////////////////////////////////////////////////////////////
// Increment counter by 1.
/////////////////////////////////////////////////////////////////////////
async command void increment();
/////////////////////////////////////////////////////////////////////////
// Decrement counter by 1.
/////////////////////////////////////////////////////////////////////////
async command void decrement();
/////////////////////////////////////////////////////////////////////////
// Change counter by a variable value.
//
// @param int32_t value The (pos/neg)value to be added to the counter
/////////////////////////////////////////////////////////////////////////
async command void add(int32_t value);
}
--- NEW FILE: config.h ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
//#define DISABLE_FLASH
// Used in CompressionM, FlashManagerM
//#define MEMBUFSIZE 256
#define FLASH_PAGE_SIZE 256
/******************************************************************************
* Module: FlashManagerM
* Initiate offload when the number of pages with _data_ is more than this
* Note: flash pages are either: free, with data or need to be deleted
******************************************************************************/
#define CRITICAL_PAGE_LIMIT_STARTUP 7
#define CRITICAL_PAGE_LIMIT 1023
// Used in SamplingM
#define ACCEL_PERIOD 250 // 1/4th second
/******************************************************************************
* Module: CompressionM
* Do lossy compression when number of _free_ pages is _less_ than LOSSY_LIMIT
******************************************************************************/
#define COMPRESSION_SAMPLES_IN_AVERAGE 4
#define COMPRESSION_LOSSY_LIMIT 256
#define COMPRESSION_BUFFERS 18
#define CONTROLLER_LOOKBACK_SIZE 40
#define CONTROLLER_ERROR_THRESHOLD 10
--- NEW FILE: FlashManagerM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module FlashManagerM {
provides {
interface StdControl as FlashManagerControl;
interface FlashManagerWriter;
interface FlashManagerReader;
}
uses {
interface StdControl as FlashControl;
interface FlashAccess;
interface ProtocolStarter;
interface Timer;
interface StdOut;
}
}
implementation {
#include "config.h"
#define TIME_OFFLOAD_RETRY 2*60*1000UL
// Flash state. This needs to be kept during reboots.
int16_t flash_head;
uint16_t flash_tail;
// flash-boundries
uint16_t flash_start, flash_end;
uint16_t flash_size;
bool writePageInProgress = FALSE;
bool readPageInProgress = FALSE;
bool clearSectorInProgress = FALSE;
task void pageReadyTask();
task void writePageTask();
task void readPageTask();
uint16_t clearSectorStart, clearSectorEnd;
task void clearSectorTask();
bool inc_head();
void inc_tail(uint16_t acked_pages);
uint16_t used_pages();
uint16_t free_pages();
uint16_t threshold_used_pages, threshold_previous_increment, threshold_flash_pages;
/**************************************************************************
** FlashManagerControl
**************************************************************************/
command result_t FlashManagerControl.init() {
/* set flash-boundries */
flash_start = call FlashAccess.firstUsablePage();
flash_end = call FlashAccess.lastUsablePage();
// Set flash_head = -1 to indicate empty flash
flash_head = -1;
flash_tail = flash_start;
flash_size = flash_end - flash_start + 1;
/* initiate offload when this threshold has been reached */
/* use a different value at startup to facilitate deployment */
threshold_used_pages = CRITICAL_PAGE_LIMIT_STARTUP;
threshold_previous_increment = CRITICAL_PAGE_LIMIT_STARTUP;
threshold_flash_pages = flash_end - flash_start + 1;
return SUCCESS;
}
command result_t FlashManagerControl.start()
{
/* cascading erase of all sectors */
clearSectorStart = flash_start & 0xFF00;
clearSectorEnd = clearSectorStart;
clearSectorInProgress = TRUE;
post clearSectorTask();
return SUCCESS;
}
command result_t FlashManagerControl.stop() {
return SUCCESS;
}
/**************************************************************************
** FlashManagerWriter
**************************************************************************/
command result_t FlashManagerWriter.writePage(uint8_t * pagePtr) {
if (writePageInProgress || clearSectorInProgress)
{
call StdOut.print("FLASH: Error - flash is busy!\n\r");
return FAIL;
}
/* Find next available page in flash */
if (inc_head()) {
call StdOut.print("FLASH: Writing Page: ");
call StdOut.printHexword(flash_head);
call StdOut.print("\r\n");
/* block other calls */
writePageInProgress = TRUE;
/* Save data in flash */
call FlashAccess.write(flash_head, pagePtr);
} else {
/* Flash memory full - cannot write page */
call StdOut.print("FLASH: Error! - flash full\r\n");
return FAIL;
}
return SUCCESS;
}
event void FlashAccess.writeDone(uint16_t page_no, void *page)
{
// If there are less than the specified free pages - start offload
if (free_pages() < (threshold_flash_pages - threshold_used_pages) )
{
// Check if protocol is already at work
if (call ProtocolStarter.startOffload() == SUCCESS)
{
call StdOut.print("FLASH: Start offloading\n\r");
call StdOut.print("FLASH: head: ");
call StdOut.printHexword(flash_head);
call StdOut.print("\r\n");
call StdOut.print("FLASH: tail: ");
call StdOut.printHexword(flash_tail);
call StdOut.print("\r\n");
} else {
call StdOut.print("FLASH: Offloading in progress\n\r");
}
}
/* unblock for other write calls */
writePageInProgress = FALSE;
if (clearSectorInProgress)
post clearSectorTask();
signal FlashManagerWriter.writePageDone(page);
/* notify module writing to flash about the status of free/full pages */
signal FlashManagerWriter.status(used_pages(), free_pages());
}
/**************************************************************************
** FlashManagerReader
**************************************************************************/
command uint16_t FlashManagerReader.getPagesInUse()
{
return used_pages();
}
command result_t FlashManagerReader.getPage(uint16_t page_no, uint8_t *output_buf)
{
uint16_t tmp;
// Already reading page from flash?
// Consistency check - is flash full?
// Consistency check - is index within bounds?
if (readPageInProgress || (flash_head == -1) || (page_no + 1 > used_pages() )) {
call StdOut.print("FLASH: Error! - cannot read page\n\r");
return FAIL;
}
/* Set flag to block other getPages from queueing up */
readPageInProgress = TRUE;
/* Check if flash has wrapped */
tmp = flash_tail + page_no;
if (tmp > flash_end)
tmp = tmp - flash_end + flash_start - 1;
call StdOut.print("FLASH: Getting page: ");
call StdOut.printHexword(tmp);
call StdOut.print("\n\r");
/* Read flash page into buffer */
call FlashAccess.read(tmp, output_buf);
return SUCCESS;
}
/**************************************************************************
** FlashAccess
**************************************************************************/
event void FlashAccess.readReady(uint16_t page_no, void *page, uint16_t length)
{
/* Release hold on flash */
readPageInProgress = FALSE;
signal FlashManagerReader.pageReady(page_no);
}
/**************************************************************************
** ProtocolStarter
**************************************************************************/
event void ProtocolStarter.offloadLater()
{
/* half the last increment and add it to the threshold */
threshold_previous_increment >>= 1;
threshold_used_pages += threshold_previous_increment;
call StdOut.print("FLASH: Offloading later: ");
call StdOut.printHexword(threshold_used_pages);
call StdOut.print("\r\n");
/* no more free pages i.e. flash is full - use timer */
if (free_pages() == 0)
{
call StdOut.print("FLASH: Flash full - using timer\r\n");
call Timer.start(TIMER_ONE_SHOT, TIME_OFFLOAD_RETRY);
}
}
event void ProtocolStarter.offloadFinished(uint16_t acked_pages)
{
/* consistency check */
if ( acked_pages > used_pages() )
return;
/* reset number of pages to initiate offload */
threshold_used_pages = CRITICAL_PAGE_LIMIT;
threshold_previous_increment = CRITICAL_PAGE_LIMIT;
clearSectorStart = flash_tail & 0xFF00;
inc_tail(acked_pages);
clearSectorEnd = flash_tail & 0xFF00;
if ( (clearSectorStart != clearSectorEnd) || (used_pages() == 0) )
{
clearSectorInProgress = TRUE;
post clearSectorTask();
} else {
/* notify module writing to flash about the status of free/full pages */
signal FlashManagerWriter.status(used_pages(), free_pages());
}
call StdOut.print("FLASH: head: ");
call StdOut.printHexword(flash_head);
call StdOut.print("\r\n");
call StdOut.print("FLASH: tail: ");
call StdOut.printHexword(flash_tail);
call StdOut.print("\r\n");
call StdOut.print("FLASH: Free pages: ");
call StdOut.printHexword(free_pages());
call StdOut.print("\r\n");
call StdOut.print("FLASH: Used pages: ");
call StdOut.printHexword(used_pages());
call StdOut.print("\r\n");
call StdOut.print("FLASH: Offload finished\n\r\n\r");
}
task void clearSectorTask()
{
call StdOut.print("FLASH: Erasing sector: ");
call StdOut.printHexword(clearSectorStart);
call StdOut.print("\r\n");
/* erase sector */
call FlashAccess.erase(clearSectorStart);
/* update sector pointers */
if (clearSectorStart == (flash_end & 0xFF00) )
{
clearSectorStart = flash_start & 0xFF00;
}
else
{
clearSectorStart += 0x0100;
}
}
/**************************************************************************
** Timer
**************************************************************************/
event result_t Timer.fired()
{
/* panic - initate offload */
call ProtocolStarter.startOffload();
return SUCCESS;
}
/**************************************************************************
** FlashAccess
**************************************************************************/
event void FlashAccess.eraseDone(uint16_t page_no)
{
/* repost task if there are still sectors that need to be cleared */
if (clearSectorStart != clearSectorEnd)
{
if (!writePageInProgress)
post clearSectorTask();
}
else
{
/* all free sectors have been cleared */
clearSectorInProgress = FALSE;
/* notify module writing to flash about the status of free/full pages */
signal FlashManagerWriter.status(used_pages(), free_pages());
}
}
event void FlashAccess.eraseAllDone()
{
;
}
/**************************************************************************
** Cyclic flash_buffer management
**************************************************************************/
/* Increment head pointer */
bool inc_head() {
uint16_t tmp;
/* Special case - cyclic buffer is empty */
if (flash_head == -1) {
/* Initialize head pointer */
flash_head = flash_tail;
return TRUE;
} else {
/* Buffer is not empty - increment head pointer */
tmp = flash_head + 1;
/* Check for buffer wrapping */
if (tmp > flash_end)
tmp = flash_start;
/* Check if head pointer is on same sector as tail pointer */
if ( (tmp <= flash_tail) && ((tmp & 0xFF00) == (flash_tail & 0xFF00)) ) {
return FALSE;
} else {
/* Return new head pointer */
flash_head = tmp;
return TRUE;
}
}
}
/* Calculate the number of used pages */
uint16_t used_pages()
{
if (flash_head == -1) {
// Head pointer not set - flash is empty
return 0;
} else if (flash_head < flash_tail) {
// Flash wrapped
return flash_end - flash_tail + flash_head - flash_start + 2;
} else {
// Linear flash
return flash_head - flash_tail + 1;
}
}
/* Calculate the number of free pages */
uint16_t free_pages()
{
uint16_t locked_by_sector;
/* check if tail pointer is on same sector as start */
if ( (flash_tail & 0xFF00) == (flash_start & 0xFF00) )
{
locked_by_sector = flash_tail - flash_start;
}else
{
locked_by_sector = flash_tail & 0x00FF;
}
return flash_size - used_pages() - locked_by_sector;
}
/* Increment a tail-pointer */
void inc_tail(uint16_t acked_pages) {
atomic
{
/* reset head pointer if buffer is empty */
if (used_pages() == acked_pages)
flash_head = -1;
/* increment tail pointer */
flash_tail += acked_pages;
/* wrap around if necessary */
if (flash_tail > flash_end)
flash_tail = flash_tail - flash_end + flash_start - 1;
}
return;
}
/**************************************************************************
** StdOut
**************************************************************************/
async event result_t StdOut.get(uint8_t data) {
return SUCCESS;
}
}
--- NEW FILE: ProtocolC.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
includes protocol;
configuration ProtocolC {
provides {
interface StdControl;
interface ProtocolStarter;
}
uses {
interface FlashManagerReader;
interface Timer;
interface StdOut;
}
}
implementation {
components ProtocolM, BufferManagerM, DatasetManagerM, ConnectionC, StatisticsC;
StdControl = ProtocolM;
ProtocolStarter = ProtocolM;
FlashManagerReader = ProtocolM;
Timer = ProtocolM;
StdOut = ProtocolM;
StdControl = ConnectionC;
StdOut = ConnectionC;
ProtocolM.Connection -> ConnectionC.Connection;
ProtocolM.DatasetManager -> DatasetManagerM.DatasetManager;
ProtocolM.StatNoConnection -> StatisticsC.Statistics[unique("Statistic")];
ProtocolM.StatLostConnection -> StatisticsC.Statistics[unique("Statistic")];
ProtocolM.StatGotConnection -> StatisticsC.Statistics[unique("Statistic")];
ProtocolM.StatisticsReader -> StatisticsC.StatisticsReader;
ProtocolM.StatControl -> StatisticsC.StdControl;
StdOut = DatasetManagerM;
DatasetManagerM.BufferManager -> BufferManagerM.BufferManager;
}
--- NEW FILE: SamplingC.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
configuration SamplingC {
provides {
interface StdControl as SamplingControl;
interface ThreeAxisAccel as SamplingRaw;
}
uses {
interface Timer;
interface StdOut;
interface Compression;
}
}
implementation {
components SamplingM, StatisticsC, AccelerometerC;
SamplingControl = SamplingM;
Compression = SamplingM;
Timer = SamplingM;
StdOut = SamplingM;
StdOut = AccelerometerC;
SamplingRaw = AccelerometerC;
SamplingM.SampleCounter -> StatisticsC.Statistics[unique("Statistic")];
SamplingM.SampleError -> StatisticsC.Statistics[unique("Statistic")];
SamplingM.ThreeAxisAccel -> AccelerometerC;
}
--- NEW FILE: BufferManager.h ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
struct page
{
uint16_t pageNumber;
uint8_t page[256];
uint8_t status;
uint32_t crc;
};
typedef struct page page_t;
--- NEW FILE: FlashManagerWriter.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
interface FlashManagerWriter
{
///////////////////////////////////////////////////////////////////////
// Write page to flash
//
// @param pagepointer Pointer to memory buffer containing page
// @return pagepointer Pointer to free memory buffer
///////////////////////////////////////////////////////////////////////
command result_t writePage(uint8_t * pagepointer);
///////////////////////////////////////////////////////////////////////
// Write page to flash completed
//
///////////////////////////////////////////////////////////////////////
event void writePageDone(uint8_t * pagepointer);
event void status(uint16_t pages_used, uint16_t pages_left);
}
--- NEW FILE: StatisticsC.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
configuration StatisticsC {
provides {
interface StdControl;
interface Statistics[uint8_t id];
interface StatisticsReader;
}
uses {
interface StdOut;
}
}
implementation {
components StatisticsM, InternalFlashC;
StdControl = StatisticsM;
Statistics = StatisticsM;
StatisticsReader = StatisticsM;
StdOut = StatisticsM;
StatisticsM.SelfCounter -> StatisticsM.Statistics[unique("Statistic")];
StatisticsM.InternalFlash -> InternalFlashC;
}
--- NEW FILE: ProtocolM.nc ---
/* Copyright (c) 2007, Marcus Chang, Klaus Madsen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dept. of Computer Science, University of
Copenhagen nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Author: Marcus Chang <marcus at diku.dk>
Klaus S. Madsen <klaussm at diku.dk>
Last modified: March, 2007
*/
module ProtocolM {
provides {
interface StdControl;
interface ProtocolStarter;
}
uses {
interface Connection;
interface FlashManagerReader;
interface StatisticsReader;
interface BufferManager;
interface DatasetManager;
interface Statistics as StatNoConnection;
interface Statistics as StatLostConnection;
interface Statistics as StatGotConnection;
interface Timer;
interface StdOut;
interface StdControl as StatControl;
}
}
implementation {
#include "config.h"
#define RETRY_CCA 3
#define TIME_DELAY_RTT 100
#define NUMBER_OF_INTERVALS 10
/* PACKETS_PER_PAGE * DEFAULT_PAYLOAD > PAGE_SIZE (256) */
//#define PACKETS_PER_PAGE 3
#define PACKET_PAYLOAD 90
enum packet_types {
PACKET_TYPE_SET_INIT = 0x01,
PACKET_TYPE_PAGE_REQ = 0x02,
PACKET_TYPE_SET_COMPLETE = 0x03,
PACKET_TYPE_PAGE_FRAGMENT = 0x04,
PACKET_TYPE_END = 0x05,
};
enum states {
STATE_OFF = 0x00,
STATE_IDLE = 0x10,
STATE_CLIENT_OPEN_CONNECTION = 0x20,
STATE_CLIENT_DATASET_BEGIN = 0x30,
STATE_CLIENT_DATASET_TRANSMIT = 0x40,
STATE_CLIENT_DATASET_END = 0x50,
STATE_SERVER = 0x60,
};
default event void ProtocolStarter.offloadFinished(uint16_t acked_pages) {;}
void calculate_panic_degree();
void protocol_transmit_set_init(dataset_t * set, uint8_t * statistics);
void protocol_transmit_page_req(dataset_t * set, intervals_t * list);
void protocol_transmit_page_fragment(dataset_t * set, fragment_t * part);
void protocol_transmit_set_complete(dataset_t * set);
void protocol_transmit_end(dataset_t * set);
task void serverPacketHandlerTask();
task void clientPacketHandlerTask();
task void clientOffloadTask();
/* variables used in client mode */
uint8_t pageBuffer[FLASH_PAGE_SIZE]