[Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/rwth/mobnets/ULLA
AMTypes.h, NONE, 1.1 Attribute.h, NONE, 1.1 CommandInf.nc,
NONE, 1.1 CommandProcessorC.nc, NONE, 1.1 CommandProcessorM.nc,
NONE, 1.1 Condition.nc, NONE, 1.1 ConditionM.nc, NONE,
1.1 EventProcessorC.nc, NONE, 1.1 EventProcessorM.nc, NONE,
1.1 GetInfoIf.nc, NONE, 1.1 InfoRequest.nc, NONE, 1.1 LLAC.nc,
NONE, 1.1 LLAM.nc, NONE, 1.1 LinkEstimation.nc, NONE,
1.1 LinkProviderIf.nc, NONE, 1.1 Lu.h, NONE, 1.1 MemAlloc.h,
NONE, 1.1 MemAlloc.nc, NONE, 1.1 NotificationTimerC.nc, NONE,
1.1 NotificationTimerM.nc, NONE, 1.1 ProcessCmd.nc, NONE,
1.1 ProcessData.nc, NONE, 1.1 QauAdapterC.nc, NONE,
1.1 QauAdapterM.nc, NONE, 1.1 Query.nc, NONE,
1.1 QueryAssemblerC.nc, NONE, 1.1 QueryAssemblerM.nc, NONE,
1.1 QueryM.nc, NONE, 1.1 QueryProcessor.h, NONE,
1.1 QueryProcessorC.nc, NONE, 1.1 QueryProcessorM.nc, NONE,
1.1 RNTimer.nc, NONE, 1.1 ReadFromStorage.nc, NONE,
1.1 ReceivePacket.nc, NONE, 1.1 RequestUpdate.nc, NONE,
1.1 ScanLinks.h, NONE, 1.1 ScanMsg.h, NONE, 1.1 Sensing.nc,
NONE, 1.1 SensorMeterC.nc, NONE, 1.1 SensorMeterM.nc, NONE,
1.1 StorageIf.nc, NONE, 1.1 TestLinkUser.nc, NONE,
1.1 Transceiver.nc, NONE, 1.1 TransceiverM.nc, NONE,
1.1 ULLAStorageC.nc, NONE, 1.1 ULLAStorageM.nc, NONE,
1.1 UQLCmdMsg.h, NONE, 1.1 UcpIf.nc, NONE, 1.1 UllaAllocC.nc,
NONE, 1.1 UllaAllocM.nc, NONE, 1.1 UllaCoreC.nc, NONE,
1.1 UllaCoreM.nc, NONE, 1.1 UllaLinkProviderC.nc, NONE,
1.1 UllaLinkProviderM.nc, NONE, 1.1 UllaQuery.h, NONE,
1.1 UllaStorage.h, NONE, 1.1 UqpIf.nc, NONE,
1.1 WriteToStorage.nc, NONE, 1.1 msg_type.h, NONE, 1.1 ulla.h,
NONE, 1.1
Krisakorn Rerkrai
krerkrai at users.sourceforge.net
Wed Jan 16 13:51:50 PST 2008
Update of /cvsroot/tinyos/tinyos-1.x/contrib/rwth/mobnets/ULLA
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv30224
Added Files:
AMTypes.h Attribute.h CommandInf.nc CommandProcessorC.nc
CommandProcessorM.nc Condition.nc ConditionM.nc
EventProcessorC.nc EventProcessorM.nc GetInfoIf.nc
InfoRequest.nc LLAC.nc LLAM.nc LinkEstimation.nc
LinkProviderIf.nc Lu.h MemAlloc.h MemAlloc.nc
NotificationTimerC.nc NotificationTimerM.nc ProcessCmd.nc
ProcessData.nc QauAdapterC.nc QauAdapterM.nc Query.nc
QueryAssemblerC.nc QueryAssemblerM.nc QueryM.nc
QueryProcessor.h QueryProcessorC.nc QueryProcessorM.nc
RNTimer.nc ReadFromStorage.nc ReceivePacket.nc
RequestUpdate.nc ScanLinks.h ScanMsg.h Sensing.nc
SensorMeterC.nc SensorMeterM.nc StorageIf.nc TestLinkUser.nc
Transceiver.nc TransceiverM.nc ULLAStorageC.nc ULLAStorageM.nc
UQLCmdMsg.h UcpIf.nc UllaAllocC.nc UllaAllocM.nc UllaCoreC.nc
UllaCoreM.nc UllaLinkProviderC.nc UllaLinkProviderM.nc
UllaQuery.h UllaStorage.h UqpIf.nc WriteToStorage.nc
msg_type.h ulla.h
Log Message:
--- NEW FILE: AMTypes.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
#ifndef _AM_TYPES_H
#define _AM_TYPES_H
enum {
IEEE_802_15_4_TYPE = 222,
CC1000_TYPE = 223,
};
typedef struct ScanLinkMsg {
uint16_t parent;
uint16_t linkid;
uint8_t msg_type;
} ScanLinkMsg;
typedef struct GetInfoMsg {
uint8_t type; // send or receive
uint8_t attribute;
uint8_t numFields;
uint8_t fieldIdx;
uint16_t qid;
uint16_t linkid;
uint16_t seq;
uint16_t src_address;
uint16_t dst_address;
uint16_t data;
uint8_t lqi;
uint8_t rssi;
uint8_t txPower;
uint8_t state;
//uint16_t data2[9];
} GetInfoMsg;
typedef struct ProbingMsg {
uint8_t id;
uint8_t lp_id;
uint8_t type;
uint8_t state;
uint8_t lqi;
uint8_t rssi;
uint8_t txPower;
} ProbingMsg;
typedef struct FixedAttrMsg {
uint16_t node_id;
uint16_t source;
uint8_t type;
uint8_t rssi;
uint8_t lqi;
} FixedAttrMsg;
// ScanLinkMsg->msg_type
enum {
SCAN_FORWARD_MSG = 1,
SCAN_REPLY_MSG = 2,
};
enum {
SCAN_AVAILABLE_LINKS = 30,
READ_AVAILABLE_LINKS = 31,
AM_SCAN_LINKS = 108,
AM_GETINFO_MESSAGE = 109,
AM_RESULT_GETINFO_MESSAGE = 110,
AM_FIXEDATTR = 111,
};
#endif /* _AM_TYPES_H */
--- NEW FILE: Attribute.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Header file for Attribute list
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
// attribute 8 bits
enum {
TUNE_PRESET = 31,
TUNE_MANUAL,
GET_FREQ,
};
--- NEW FILE: CommandInf.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Interface for UCP - Process commands from a local link user
*
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface CommandInf {
//command bool processCommandInf(ResultTuplePtr trp, Cond *c, char idx);
command bool control(CommandMsgPtr cmp, Cond *c, char idx);
command result_t setAttribute8(CommandMsgPtr cmp, uint8_t mode, uint8_t param);
command result_t setAttribute16(CommandMsgPtr cmp, uint8_t mode, uint16_t param);
command result_t setAttribute32(CommandMsgPtr cmp, uint8_t mode, uint32_t param);
//event bool processCommandInfDone(ResultTuplePtr rtp, bool success);
}
--- NEW FILE: CommandProcessorC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Ulla Command Processing - transforms the received binary commands
* into the appropriate requests (understandable by the link provider).
* Afterwards, it forwards this request to the appropriate underlying
* link provider.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
configuration CommandProcessorC {
provides {
interface StdControl;
interface ProcessCmd as ProcessCommand;
interface ProcessData as ProcessScanLinks;
interface CommandInf;
interface UcpIf;
}
}
implementation {
components
CommandProcessorM
, LedsC
, ULLAStorageC
, LLAC
;
StdControl = CommandProcessorM;
CommandInf = CommandProcessorM;
UcpIf = CommandProcessorM;
ProcessScanLinks = CommandProcessorM;
CommandProcessorM.Leds -> LedsC;
CommandProcessorM.LinkProviderIf -> LLAC;
CommandProcessorM.TransControl -> LLAC;
CommandProcessorM.Control -> LLAC;
CommandProcessorM.StorageIf -> ULLAStorageC;
ProcessCommand = CommandProcessorM;
}
--- NEW FILE: CommandProcessorM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* UCP implementation
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes AMTypes;
module CommandProcessorM {
provides {
interface StdControl;
interface ProcessCmd as ProcessCommand; // assemble commands from a remote user
interface CommandInf; // commands from a local user
interface UcpIf;
interface ProcessData as ProcessScanLinks;
}
uses {
interface Leds;
interface StdControl as TransControl;
interface ProcessCmd as Control;
interface LinkProviderIf[uint8_t id];
interface StorageIf;
}
}
/*
* Module Implementation
*/
implementation
{
typedef struct {
void **next;
struct CommandMsg uq;
} CommandList, *CommandListPtr, **CommandListHandle;
typedef struct {
uint8_t cid;
uint16_t interval;
uint16_t ntimes;
} SleepRadioUnit, *SleepRadioUnitPtr;
TOS_MsgPtr msg;
CommandMsgPtr cmsg;
uint8_t mStatus;
bool is_processing_command;
SleepRadioUnit sleepUnit, *sleepUnitPtr;
bool sleepNow;
SleepRadioUnit blinkUnit, *blinkUnitPtr;
CommandListHandle cListHead;
CommandListHandle cListTail;
struct CommandMsg **gCurCommand;
Handle gCurHandle;
bool allocateCommand();
void addCommand(HandlePtr memory);
void SleepRadio();
void WakeUpRadio();
/* task declaration */
// task void deleteCommand();
task void modifyCommand();
task void continueProcessCommand();
task void RadioTask();
command result_t StdControl.init() {
atomic {
sleepUnitPtr = &sleepUnit;
blinkUnitPtr = &blinkUnit;
cListHead = NULL;
cListTail = NULL;
sleepNow = FALSE;
is_processing_command = 0;
}
call Leds.init();
return (SUCCESS);
}
/* start generic communication interface */
command result_t StdControl.start(){
return (SUCCESS);
}
/* stop generic communication interface */
command result_t StdControl.stop(){
return (SUCCESS);
}
/*new from ULLA */
command uint8_t UcpIf.doCmd(LuId_t luId, CmdDescrPtr cmddescr) {
uint8_t numLinks;
uint8_t links[10];
dbg(DBG_USR1,"UCP: doCmd\n");
switch (cmddescr->cmd) {
case READ_AVAILABLE_LINKS:
dbg(DBG_USR1, "LLAM: ReadAvailableLinks\n");
call StorageIf.readAvailableLinks(&numLinks, &links[0]);
break;
default:
call LinkProviderIf.execCmd[/*cmd type?*/1](cmddescr);
//return COMMAND_NOT_SUPPORTED
break;
} //*/
return 1;
}
command uint8_t UcpIf.requestCmd(LuId_t luId, CmdDescr_t* cmddescr, RcDescr_t *rcdescr, CmdId_t *cmdId) {
return 1;
}
command uint8_t UcpIf.cancelCmd(LuId_t luId, CmdId_t cmdId) {
return 1;
}
command uint8_t UcpIf.setParam(LuId_t luId, AttrDescr_t paramDescr) {
return 1;
}
command result_t ProcessCommand.execute(TOS_MsgPtr pmsg) {
atomic {
cmsg = (struct CommandMsg *) pmsg->data;
msg = pmsg;
}
dbg(DBG_USR1,"ProcessCommand execute\n");
//check message data type: add, modify, delete
if (cmsg->msgType == DEL_MSG) { // delete a command
dbg(DBG_USR1,"ProcessCommand DEL_MSG\n");
if (is_processing_command) return FAIL;
// modify a previous command (given a command ID)
} else if (cmsg->msgType == MOD_MSG) {
dbg(DBG_USR1,"ProcessCommand MOD_MSG\n");
if (is_processing_command) return FAIL;
is_processing_command = 1;
post modifyCommand();
is_processing_command = 0;
// add a command
} else if (cmsg->msgType == ADD_MSG) {
dbg(DBG_USR1,"ProcessCommand ADD_MSG\n");
if (is_processing_command) return FAIL;
}
return SUCCESS;
}
/*
task void deleteCommand() {
dbg(DBG_USR1, "deleteCommand\n");
} */
task void modifyCommand() {
dbg(DBG_USR1, "modifyCommand\n");
}
inline void setSleepUnit() {
sleepUnitPtr->cid = (**gCurCommand).cid;
sleepUnitPtr->interval = (**gCurCommand).interval;
sleepUnitPtr->ntimes = (**gCurCommand).ntimes;
}
inline void setBlinkUnit() {
blinkUnitPtr->cid = (**gCurCommand).cid;
blinkUnitPtr->interval = (**gCurCommand).interval;
blinkUnitPtr->ntimes = (**gCurCommand).ntimes;
}
task void scanAvailableLinks() {
//struct ScanLinks scan;
//scan.
/////call SendInf.send[AM_SCAN_LINKS](msg, sizeof(struct ScanLinkMsg));
}
task void continueProcessCommand() {
dbg(DBG_USR1, "continueProcessCommand %p %d\n",*gCurCommand, (**gCurCommand).cid);
switch ((**gCurCommand).action){
case LED_TOGGLE :
dbg(DBG_USR1, "Yellow Toggle\n");
//call Leds.yellowToggle();
break;
case LED_BLINK :
// blink commands can stay here
setBlinkUnit();
//call BlinkTimer.start( TIMER_REPEAT, blinkUnitPtr->interval);
break;
case SLEEP_MODE :
// needs to be changed. Use LLA to do so.
setSleepUnit();
//call RadioTimer.start( TIMER_ONE_SHOT, 10);
break;
case SET_RFPOWER :
/*power = 31 => full power (0dbm)
* 3 => lowest power (-25dbm) */
/* platform dependence should be removed.
* UCP will be connected to LLA with ProcessCmd interface.
* setAttribute commands will be translated here to put in
* CommandMsg and send to LLA via ProcessCmd.
*/
atomic {
*gCurCommand = (struct CommandMsg *) msg->data;
}
call Control.execute(msg);
///call CommandInf.setAttribute8(RF_POWER, (**gCurCommand).param);
//call CC2420Control.SetRFPower((**gCurCommand).param);
break;
case SCAN_AVAILABLE_LINKS :
// send polling message to the neighbours
post scanAvailableLinks();
default:
break;
}
}
command bool CommandInf.control(CommandMsgPtr cmp, Cond *c, char idx) {
dbg(DBG_USR1,"ULLA Core: CommandInf.control \n");
return TRUE;
}
command result_t CommandInf.setAttribute8(CommandMsgPtr cmp, uint8_t mode, uint8_t param) {
return SUCCESS;
}
command result_t CommandInf.setAttribute16(CommandMsgPtr cmp, uint8_t mode, uint16_t param) {
return SUCCESS;
}
command result_t CommandInf.setAttribute32(CommandMsgPtr cmp, uint8_t mode, uint32_t param) {
return SUCCESS;
}
command result_t ProcessScanLinks.perform(void *pdata, uint8_t length) {
struct ScanLinkMsg *scanlink = (struct ScanLinkMsg *) pdata;
dbg(DBG_USR1, "UCP: ProcessScanLinks.perform\n");
// FIXME update the storage
call StorageIf.addLink(scanlink->linkid);
return SUCCESS;
}
/*---------------------------------- Transceiver ----------------------------*/
/*
event result_t SendInf.sendDone[uint8_t id](TOS_MsgPtr pmsg, result_t success) {
return SUCCESS;
}*/
/*--------------------------------- LinkProvider ---------------------------*/
event result_t LinkProviderIf.getAttributeDone[uint8_t id](AttrDescr_t* attDescr, uint8_t *result) {
return SUCCESS;
}
event result_t Control.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
/*--------------------------------- Radio ------------------------------------*/
inline void SleepRadio() {
call TransControl.stop();
}
inline void WakeUpRadio() {
call TransControl.start();
}
task void RadioTask() {
}
/*---------------------------- Command Allocation ---------------------------*/
#ifdef MULTIPLE_COMMANDS
inline bool allocateCommand() {
dbg(DBG_USR1, "allocateCommand \n");
atomic mStatus = ALLOC_QUERY_STATUS;
if (call MemAlloc.allocate(&gCurHandle, sizeof(struct CommandMsg)) == SUCCESS)
return TRUE;
return FALSE;
}
inline void addCommand(HandlePtr memory) {
gCurCommand = (struct CommandMsg **)*memory;
dbg(DBG_USR1, "addCommand %p %p\n",*memory, *gCurCommand);
memcpy(&(**gCurCommand), cmsg, sizeof(struct CommandMsg));
post continueProcessCommand();
}
/*--------------------------- MemAlloc Events -------------------------------*/
event result_t MemAlloc.allocComplete(Handle *handle, result_t complete) {
CommandListHandle clh = (CommandListHandle)*handle;
if (mStatus == NOT_ALLOCING_STATUS) return SUCCESS; //not our allocation
if (complete) {
dbg(DBG_USR1,"Allocated command\n");
switch (mStatus) {
case ALLOC_QUERY_STATUS:
// put a new command to the list
(**clh).next = NULL;
atomic {
if (cListTail == NULL) {
dbg(DBG_USR1,"--** start cListTail **--\n");
cListTail = clh;
cListHead = clh;
} else {
dbg(DBG_USR1,"--** next cListTail **--\n");
(**cListTail).next = (void **)clh;
cListTail = clh;
}
}
// then add the information
//call Query.addQuery(qmsg, *gCurCommand);
addCommand((HandlePtr)&cListTail);
break; //
}
} else {
dbg(DBG_USR1,"Error: Out of Memory!\n");
}
mStatus = NOT_ALLOCING_STATUS; //not allocating any more
return SUCCESS;
}
event result_t MemAlloc.reallocComplete(Handle handle, result_t complete) {
dbg(DBG_USR1,"MemAlloc.realloc complete\n");
return SUCCESS;
}
event result_t MemAlloc.compactComplete() {
dbg(DBG_USR1,"MemAlloc.compact complete\n");
return SUCCESS;
}
#endif
} // end of implementation
--- NEW FILE: Condition.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Interface for condition operator
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UllaQuery;
interface Condition {
/**
* Verify a condition to see whether it is satisfied or not
* @param rtp The result tuple
* @param c The condition to verify
* @return A result true or false
**/
command bool processCondition(ResultTuplePtr trp, Cond *c, char idx);
event bool processConditionDone(ResultTuplePtr rtp, bool success);
}
--- NEW FILE: ConditionM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
*/
/**
*
* Condition Operator
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UllaQuery;
module ConditionM {
provides {
interface Condition;
}
}
implementation {
void getIndexOfSelectedAttribute(ResultTuplePtr rtp, Cond *c, int8_t *attrIndex)
{
uint8_t i;
*attrIndex = -1; // not found
for (i=0; i<MAX_ATTR; i++)
{
if (c->field == rtp->fields[i])
*attrIndex = i;
}
return;
}
command bool Condition.processCondition(ResultTuplePtr rtp, Cond *c, char idx) {
bool result = FALSE;
uint16_t fieldValue;
int8_t attrIndex;
// check which attribute is being processed. Map attribute in the condition to rtp index.
getIndexOfSelectedAttribute(rtp, c, &attrIndex);
if (attrIndex>=0) {
fieldValue = rtp->data[attrIndex];
dbg(DBG_USR1, "FieldVal = %d\n", fieldValue);
//switch (c->opval.op) {
switch (c->op) {
case OP_EQ:
//result = (fieldValue == c->opval.value);
result = (fieldValue == c->value);
break;
case OP_NEQ:
//result = (fieldValue != c->opval.value);
result = (fieldValue != c->value);
break;
case OP_GT:
//result = (fieldValue > c->opval.value);
result = (fieldValue > c->value);
break;
case OP_GE:
//result = (fieldValue >= c->opval.value);
result = (fieldValue >= c->value);
break;
case OP_LT:
//result = (fieldValue < c->opval.value);
result = (fieldValue < c->value);
break;
case OP_LE:
//result = (fieldValue <= c->opval.value);
result = (fieldValue <= c->value);
break;
}
}
else {
result = TRUE; // not found in the condition
}
return result;
}
}
--- NEW FILE: EventProcessorC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Ulla Event Processing - in charge of collecting the various
* events from their sources (i.e. the link providers), delivering
* them to the corresponding link users or applications.
<p>
* There are different sorts of events considered so far:
* - attribute events: correspond to a certain circumstance (e.g.
* crossing some threshold level)
* - link events: used to notify the ULLA core about the status of
* the different link providers, allowing it to track them.
* - command completion events: used by the link providers to deliver
* the information generated after the completion of a particular
* command, as requested by the application through the Ulla
* Command Processing.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
configuration EventProcessorC {
provides {
interface StdControl;
interface ProcessCmd as ProcessEvent[uint8_t channel];
}
}
implementation {
components
EventProcessorM
, LedsC
;
StdControl = EventProcessorM;
EventProcessorM.Leds -> LedsC;
ProcessEvent = EventProcessorM;
//AttributeEvent = EventProcessorM;
//LinkEvent = EventProcessorM;
//CompleteCmdEvent = EventProcessorM;
//EventProcessorM.RequestUpdate-> LLAC;
}
--- NEW FILE: EventProcessorM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Ulla Event Processing implementation
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
module EventProcessorM {
provides {
interface StdControl;
interface ProcessCmd as ProcessEvent[uint8_t channel];
}
uses {
interface Leds;
}
}
/*
* Module Implementation
*/
implementation
{
TOS_MsgPtr msg;
TOS_Msg buf;
command result_t StdControl.init() {
msg = &buf;
call Leds.init();
return (SUCCESS);
}
/* start generic communication interface */
command result_t StdControl.start(){
return (SUCCESS);
}
/* stop generic communication interface */
command result_t StdControl.stop(){
return (SUCCESS);
}
command result_t ProcessEvent.execute[uint8_t channel](TOS_MsgPtr pmsg) {
//call RequestUpdate.execute(pmsg);
return SUCCESS;
}
/*
command result_t AttributeEvent.execute(TOS_MsgPtr pmsg) {
//call RequestUpdate.execute(pmsg);
return SUCCESS;
}
command result_t LinkEvent.execute(TOS_MsgPtr pmsg) {
//call RequestUpdate.execute(pmsg);
return SUCCESS;
}
command result_t CompleteCmdEvent.execute(TOS_MsgPtr pmsg) {
//call RequestUpdate.execute(pmsg);
return SUCCESS;
} */
/*
event result_t ProcessQuery.done(TOS_MsgPtr pmsg, result_t status) {
msg = pmsg;
//call Leds.redToggle();
if (status) {
post forwarder();
} else {
bcast_pending = 0;
}
return SUCCESS;
} */
} // end of implementation
--- NEW FILE: GetInfoIf.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface GetInfoIf {
command uint8_t getAttribute(TOS_Msg *tmsg);
event result_t getAttributeDone(TOS_Msg *tmsg);
}
--- NEW FILE: InfoRequest.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Interface for UQP
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface InfoRequest {
/**
* Process a request from the Link User
* @param q query message
* @param c conditions
* @param idx
* @return false if the query message is known before
**/
command bool processInfoRequest(Query *q, Cond *c, char idx);
event bool processInfoRequestDone(ResultTuplePtr rtp, bool success);
}
--- NEW FILE: LLAC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* WSN Link Layer Adapter - a proxy interface on the existing driver that
* implements an interface known by the ULLA (methods and queries), enabling
* the ULLA to forward queries and method calls to the driver through the LLA.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
includes MultiHop;
includes AMTypes;
configuration LLAC {
provides {
//interface ProcessCmd as RequestUpdate;
//interface RequestUpdate;
interface LinkProviderIf[uint8_t id]; // replacement of RequestUpdate
interface StdControl;
///interface CC2420Control;
interface ProcessCmd as Control;
// for TransceiverM
//interface StdControl as TransControl;
interface Send as SendInf[uint8_t id];
///interface Receive as ReceiveInf[uint8_t id];
}
}
implementation {
components
Main
, LLAM
, UllaCoreC
, EventProcessorC
#ifdef ULLA_STORAGE
, StorageC
#endif
, TimerC
, LedsC
#ifndef MAKE_PC_PLATFORM
, CC2420ControlM
, CC2420RadioC
#endif
#ifdef OSCOPE
, OscopeC
#endif
, GenericComm as Comm
, TransceiverM
, ULLAStorageC
//, SensorMeterM
//, GenericCommPromiscuous as Comm
, RandomLFSR
//, LQIMultiHopRouter as multihop
//, QueuedSend
;
Main.StdControl -> LLAM;
Main.StdControl -> TimerC;
//Main.StdControl -> multihop;
//Main.StdControl -> Comm;
//Main.StdControl -> QueuedSend;
StdControl = LLAM;
LLAM.Timer -> TimerC.Timer[unique("Timer")];
LLAM.Leds -> LedsC;
TransceiverM.Leds -> LedsC;
//RequestUpdate = LLAM;
LinkProviderIf = LLAM;
LLAM.AttributeEvent -> EventProcessorC.ProcessEvent[0];
LLAM.LinkEvent -> EventProcessorC.ProcessEvent[1];
LLAM.CompleteCmdEvent -> EventProcessorC.ProcessEvent[2];
#ifdef ULLA_STORAGE
LLAM.WriteToStorage -> StorageC;
#endif
Control = LLAM;
#if defined(TELOS_PLATFORM) || defined(SIM_TELOS_PLATFORM)
LLAM.CC2420Control -> CC2420ControlM;
#endif
#ifdef OSCOPE
LLAM.ORFPower -> OscopeC.Oscope[6];
LLAM.OLQI -> OscopeC.Oscope[7];
LLAM.ORSSI -> OscopeC.Oscope[8];
#endif
StdControl = TransceiverM;
TransceiverM.LinkEstimation -> LLAM;
//TransceiverM.CommControl -> Comm;
TransceiverM.CommStdControl -> Comm;
TransceiverM.MacControl -> CC2420RadioC;
TransceiverM.GetLinkInfo -> LLAM; // 2006/03/14
//TransceiverM.GetSensorInfo -> SensorMeterM; // 2006/03/14
TransceiverM.Random -> RandomLFSR;
SendInf = TransceiverM;
//ReceiveInf = TransceiverM;
TransceiverM.ReceivePacket -> UllaCoreC;
LLAM.StorageIf -> ULLAStorageC;
LLAM.SendScanLinks -> TransceiverM.SendInf[AM_SCAN_LINKS];
LLAM.SendGetInfo -> TransceiverM.SendInf[AM_GETINFO_MESSAGE];
LLAM.SendProbingMsg -> TransceiverM.SendInf[AM_PROBING];
/////LLAM.Receive -> TransceiverM.ReceiveInf; //2006/03/07 avoid pan-out
//LLAM.SendMsg -> Comm.SendMsg[AM_GETINFO_MESSAGE];
TransceiverM.SendMsg -> Comm;
TransceiverM.ReceiveMsg -> Comm;
}
--- NEW FILE: LLAM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* LLA implementation
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
includes Attribute;
includes AMTypes;
module LLAM {
provides {
interface StdControl;
interface LinkProviderIf[uint8_t id]; // replacement of RequestUpdate
interface ProcessCmd as Control;
interface LinkEstimation;
interface GetInfoIf as GetLinkInfo;
}
uses {
interface Timer;
interface Leds;
interface ProcessCmd as AttributeEvent;
interface ProcessCmd as LinkEvent;
interface ProcessCmd as CompleteCmdEvent;
interface Send as SendScanLinks;
interface Send as SendGetInfo;
interface Send as SendProbingMsg;
interface Receive[uint8_t id];
interface StdControl as RadioControl;
interface RouteControl;
interface StorageIf;
interface CC2420Control;
#ifdef ULLA_STORAGE
interface WriteToStorage;
#endif
#ifdef OSCOPE
interface Oscope as ORFPower;
interface Oscope as OLQI;
interface Oscope as ORSSI;
#endif
}
}
/*
* Module Implementation
*/
implementation
{
enum {
OSCOPE_DELAY = 10,
};
norace uint16_t rfpower, lqi, rssi /*, per */;
norace uint8_t state;
norace uint16_t numSamples;
norace uint16_t timeInterval;
norace uint8_t actionIndex;
uint16_t count;
uint32_t period;
// module scoped variables
TOS_MsgPtr msg;
TOS_Msg buf;
int8_t pending;
QueryPtr query;
ResultTuple rt;
ResultTuplePtr rtp;
/* task declaration */
task void getRFPower();
task void getLQI();
task void getRSSI();
//task void getPER();
/* function declaration */
//result_t addToResultTuple(ResultTuplePtr result);
task void SimDataReady();
//void CheckCounter();
command result_t StdControl.init() {
atomic {
//state = HUMIDITY;
rtp = &rt;
actionIndex = 0;
msg = &buf;
count = 0;
period = 0;
}
return (SUCCESS);
}
/* start the sensorcontrol component */
command result_t StdControl.start() {
#if defined(ENABLE_ACK)
//call CC2420Control.enableAutoAck();
#endif
call CC2420Control.SetRFPower(10);
return SUCCESS;
}
/* stop the sensorcontrol component */
command result_t StdControl.stop() {
call Timer.stop();
return SUCCESS;
}
#if 0
// fill in the result tuple when dataReady, and signal receiveTuple
// request from UQP
command result_t RequestUpdate.execute(QueryPtr pq) {
dbg(DBG_USR1, "Request update starts\n");
atomic {
query = pq;
actionIndex = 0;
state = pq->fields[actionIndex];
numSamples = pq->nsamples;
timeInterval = pq->interval;
//rtp->qid = pq->qid;
rtp->numFields = pq->numFields;
rtp->numConds = pq->numConds;
}
call Timer.start( TIMER_ONE_SHOT, OSCOPE_DELAY );
return SUCCESS;
}
#endif
task void getAttributeTask() {
switch(state) {
case RF_POWER:
post getRFPower();
break;
case LQI:
post getLQI();
break;
case RSSI:
post getRSSI();
break;
/*
case PER:
post getPER();
break; */
case LED_ON:
call Leds.yellowOn();
break;
case LED_OFF:
call Leds.yellowOff();
break;
//default:
// call Timer.start(TIMER_ONE_SHOT, 10);
} // switch case
}
task void processNextAttribute() {
dbg(DBG_USR1, "LLAM: processNextAttribute\n");
}
event result_t Timer.fired() {
dbg(DBG_USR1, "Timer fired\n");
// set a timeout in case a task post fails (rare)
//call Timer.start(TIMER_ONE_SHOT, 100);
post getAttributeTask();
return SUCCESS;
}
// commands from UCP
command result_t Control.execute(TOS_MsgPtr pmsg) {
CommandMsgPtr cmd = (struct CommandMsg *) pmsg->data;
switch (cmd->action) {
case RF_POWER:
#ifndef MAKE_PC_PLATFORM
call CC2420Control.SetRFPower(cmd->param);
#endif
break;
case TUNE_PRESET:
#ifndef MAKE_PC_PLATFORM
call CC2420Control.TunePreset(cmd->param);
#endif
break;
case TUNE_MANUAL:
#ifndef MAKE_PC_PLATFORM
call CC2420Control.TuneManual(cmd->param);
#endif
break;
}
return SUCCESS;
}
#if 0
default event ResultTuplePtr RequestUpdate.receiveTuple(ResultTuplePtr rtr) {
return rtr;
}
#endif
event result_t AttributeEvent.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
event result_t LinkEvent.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
event result_t CompleteCmdEvent.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
/*------------------------------- Put data ------------------------------------*/
task void putRFPower() {
#ifdef OSCOPE
call ORFPower.put(rfpower);
#endif
rtp->fields[actionIndex] = RF_POWER;
rtp->data[actionIndex] = rfpower;
//CheckCounter();
post processNextAttribute();
}
task void putLQI() {
#ifdef OSCOPE
call OLQI.put(lqi);
#endif
rtp->fields[actionIndex] = LQI;
rtp->data[actionIndex] = lqi;
//CheckCounter();
post processNextAttribute();
}
task void putRSSI() {
#ifdef OSCOPE
call ORSSI.put(rssi);
#endif
rtp->fields[actionIndex] = RSSI;
rtp->data[actionIndex] = rssi;
//CheckCounter();
post processNextAttribute();
}
task void getRFPower() {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
#ifndef MAKE_PC_PLATFORM
//rfpower = call CC2420Control.GetRFPower();
//state = query->fields[actionIndex];
//addToResultTuple(rtp);
post putRFPower();
#else
post SimDataReady();
#endif
}
task void getLQI() {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
#ifndef MAKE_PC_PLATFORM
lqi = msg->lqi; // LQI
post putLQI();
#else
post SimDataReady();
#endif
}
task void getRSSI() {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
#ifndef MAKE_PC_PLATFORM
rssi = msg->strength; // RSSI
post putRSSI();
#else
post SimDataReady();
#endif
}
command uint16_t LinkEstimation.calculatePER(TOS_MsgPtr pmsg) {
uint16_t PER = 0;
return PER;
}
/*---------------------------- Link Provider Interface ------------------------*/
task void continueUpdate() {
call Timer.start(TIMER_REPEAT, period);
}
task void cancelUpdate() {
call Timer.stop();
}
command uint8_t LinkProviderIf.execCmd[uint8_t id](CmdDescr_t* cmddescr) {
struct ScanLinkMsg *scanlink;
dbg(DBG_USR1, "LLAM: LP.execCmd\n");
switch (cmddescr->cmd) {
case SCAN_AVAILABLE_LINKS:
dbg(DBG_USR1, "LLAM: ScanAvailableLinks\n");
scanlink = (struct ScanLinkMsg *) buf.data;
scanlink->parent = TOS_LOCAL_ADDRESS;
scanlink->msg_type = SCAN_FORWARD_MSG;
call SendScanLinks.send(msg, sizeof(struct ScanLinkMsg));
break;
default:
//return COMMAND_NOT_SUPPORTED
break;
}
return 1;
}
command uint8_t LinkProviderIf.requestUpdate[uint8_t id](RuId_t ruId, RuDescr_t* ruDescr, AttrDescr_t* attrDescr) {
dbg(DBG_USR1, "LLAM: LPIf.requestUpdate\n");
/*
* 1. Start the timer
* 2. signal events to UQP when the data is ready
* 3. Check the counter
*/
atomic {
period = ruDescr->period;
count = ruDescr->count;
}
post continueUpdate();
return 1;
}
command uint8_t LinkProviderIf.cancelUpdate[uint8_t id](RuId_t ruId) {
dbg(DBG_USR1, "LLAM: LPIf.cancelUpdate\n");
return 1;
}
task void sendProbingMsgTask() {
//TOS_Msg beaconMsg; // can't be used locally here.
FixedAttrMsg *fixed = (FixedAttrMsg *)msg->data;
fixed->source = TOS_LOCAL_ADDRESS;
fixed->type = 0; // request;
//call Leds.redToggle();
call SendProbingMsg.send(msg, sizeof(FixedAttrMsg));
}
// should be modified in order to get the attributes from the driver or
// firmware not to probe everything. 2006/02/24
// 2 kinds of queries
// 1. remote queries - probing or reading from a firmware.
// 2. local queries - reading attributes for a local.
command uint8_t LinkProviderIf.getAttribute[uint8_t query_type](AttrDescr_t* attrDescr) {
TOS_MsgPtr p;
struct GetInfoMsg *getInfo = (struct GetInfoMsg *)buf.data;
uint8_t *val_8;
uint16_t *val_16;
dbg(DBG_USR1, "LLAM: getAttribute\n");
// 2006/03/06
// LP has 2 mechanisms to deal with getAttribute() call
// 1. Poll its neighbour because there is no update in the firmware
// from any beacon signal
// 2. Read from the firmware if there are periodic beacons sent from
// its neighbour. It can cooperate with some other mechanism that provides
// beacon, for example proactive routing agent.
// LP should provide some mechanism to get info from neighbour (beacon?)
// i.e. call SendBeacon();
switch (attrDescr->attribute) {
case LP_ID:
break;
case LINK_ID:
case LQI:
case RSSI:
post sendProbingMsgTask();
break;
default:
break;
}
return 1;
}
command uint8_t LinkProviderIf.setAttribute[uint8_t id](AttrDescr_t* attrDescr) {
return 1;
}
command void LinkProviderIf.freeAttribute[uint8_t id](AttrDescr_t* attrDescr) {
}
/*------------------------------- Transceiver ----------------------------------*/
command uint8_t GetLinkInfo.getAttribute(TOS_Msg *tmsg) {
struct GetInfoMsg *getinfo = (struct GetInfoMsg *)tmsg->data;
dbg(DBG_USR1,"LLAM: GetLinkInfo.getAttribute\n");
switch (getinfo->attribute) {
case LQI:
//call Leds.yellowToggle();
#ifndef MAKE_PC_PLATFORM
getinfo->data = msg->lqi;
#endif
break;
case RSSI:
dbg(DBG_USR1,"Get Me RSSI\n");
//call Leds.redToggle();
getinfo->attribute = RSSI;
//getinfo->src_address = ;
getinfo->data = 978;//msg->strength;
break;
case LINK_ID:
getinfo->data = TOS_LOCAL_ADDRESS;
break;
case TYPE:
getinfo->data = 9;//ULLA_MEDIATYPE_ZIGBEE;
break;
case STATE:
getinfo->data = 11;
break;
case NETWORK_NAME:
getinfo->data = 0x66;
break;
case RX_ENCRYPTION:
getinfo->data = 1;
break;
case TX_ENCRYPTION:
getinfo->data = 1;
break;
case MODE:
getinfo->data = 1;//HALF_DUPLEX;
break;
default:
dbg(DBG_USR1, "attribute not defined\n");
break;
}
getinfo->linkid = TOS_LOCAL_ADDRESS;
getinfo->type = 2;
signal GetLinkInfo.getAttributeDone(tmsg);
return 1;
}
event result_t SendScanLinks.sendDone(TOS_MsgPtr pmsg, result_t success) {
AttrDescr_t* attrDescr;
dbg(DBG_USR1, "LLAM: SendScanLinks.sendDone\n");
//signal LinkProviderIf.getAttributeDone[REMOTE_QUERY](attrDescr);
return success;
}
event result_t SendGetInfo.sendDone(TOS_MsgPtr pmsg, result_t success) {
AttrDescr_t* attrDescr;
dbg(DBG_USR1, "LLAM: SendGetInfo.sendDone\n");
//signal LinkProviderIf.getAttributeDone[REMOTE_QUERY](attrDescr);
return success;
}
event result_t SendProbingMsg.sendDone(TOS_MsgPtr pmsg, result_t success) {
AttrDescr_t attrDescr;
dbg(DBG_USR1, "LLAM: SendProbingMsg.sendDone\n");
memcpy(&attrDescr, &(pmsg->data), sizeof(AttrDescr_t));
////////signal LinkProviderIf.getAttributeDone[REMOTE_QUERY](&attrDescr);
return success;
}
event TOS_MsgPtr Receive.receive[uint8_t id](TOS_MsgPtr pmsg, void* payload, uint16_t payloadLen) {
// receive GetInfo message from remote LP
// should process and send the result back
struct GetInfoMsg *getInfo = (struct GetInfoMsg *)pmsg->data;
dbg(DBG_USR1, "LLAM: receive GetInfo message\n");
return pmsg;
}
/*------------------------------- Simulation Results ---------------------------*/
#ifdef MAKE_PC_PLATFORM
task void SimDataReady() {
dbg(DBG_USR1, "Simulate Data\n");
switch(state) {
case RF_POWER:
dbg(DBG_USR1, "Simulate RF_POWER %d\n", actionIndex);
rfpower = 16;
post putRFPower();
break;
case LQI:
dbg(DBG_USR1, "Simulate LQI %d\n", actionIndex);
lqi = 17;
post putLQI();
break;
case RSSI:
dbg(DBG_USR1, "Simulate RSSI %d\n", actionIndex);
rssi = 18;
post putRSSI();
break;
}
//post SimDataReady();
}
#endif
/*------------------------------- ULLA Storage ---------------------------------*/
#ifdef ULLA_STORAGE
event result_t WriteToStorage.writeDone(uint8_t *data, uint32_t bytes, result_t ok) {
dbg(DBG_USR1,"WriteToStorage write done\n");
return SUCCESS;
}
#endif
} // end of implementation
--- NEW FILE: LinkEstimation.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Interface for link estimation
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface LinkEstimation {
/**
* Calculate a packet error rate (PER)
* @param pmsg a received message
* @return PER
**/
command uint16_t calculatePER(TOS_MsgPtr pmsg);
//command result_t updateNbrCounter(TOS_MsgPtr);
}
--- NEW FILE: LinkProviderIf.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes ulla;
includes msg_type;
interface LinkProviderIf {
command uint8_t execCmd(CmdDescr_t* cmdDescr);
command uint8_t requestUpdate(RuId_t ruId, RuDescr_t* ruDescr, AttrDescr_t* attrDescr);
command uint8_t cancelUpdate(RuId_t ruId);
command uint8_t getAttribute (AttrDescr_t* attDescr);
event result_t getAttributeDone (AttrDescr_t* attDescr, uint8_t *result);
command uint8_t setAttribute(AttrDescr_t* attDescr);
command void freeAttribute(AttrDescr_t* attDescr);
}
--- NEW FILE: Lu.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
#ifndef LU_H
#define LU_H
/**
*
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
/**
* @ingroup type
* @brief Link User identifier returned from the ULLA core to the Link User upon call to registerLu()
*
*/
typedef uint8_t LuId_t;
/**
* @ingroup type
* @brief Notification Request identifier returned from the ULLA core to the Link User upon call to requestNotification()
*
*/
typedef uint8_t RnId_t;
/**
* @ingroup type
* @brief Command request identifier returned from the ULLA core to the Link User upon call to requestCmd()
*
*/
typedef uint8_t CmdId_t;
/**
* @ingroup type
* @brief Link User information.
*
* This is the data structure passed from the linkUser to the ullaCore upon registration with registerLu
*/
typedef struct LuDescr_t{
char* name; /**< Name of the Link User */
char* description; /**< Link User description (e.g. supplier, type of application, whatever) */
char* version; /**< Version of the ULLA we are willing to use */
uint8_t profile; /**< The requested profile type */
}LuDescr_t;
#endif
--- NEW FILE: MemAlloc.h ---
// $Id: MemAlloc.h,v 1.1 2008/01/16 21:51:47 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* Authors: Philip Levis, Sam Madden
* Date last modified: 6/25/02
* Description: Types for MemAlloc.ti.
*/
/**
* @author Philip Levis
* @author Sam Madden
*/
typedef int8_t** Handle;
typedef Handle* HandlePtr;
--- NEW FILE: MemAlloc.nc ---
// $Id: MemAlloc.nc,v 1.1 2008/01/16 21:51:47 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* Authors: Sam Madden, Philip Levis
* Date last modified: 6/25/02
*/
/**
* @author Sam Madden
* @author Philip Levis
*/
includes MemAlloc;
/**
* Interface for dynamic memory allocators.
*/
interface MemAlloc {
/**
* Allocate a memory region.
*
* @param handle Handle to memory region (to be filled in).
*
* @param size Size of region in bytes.
*
* @return SUCCESS if allocated, FAIL otherwise.
*/
command result_t allocate(HandlePtr handle, int16_t size);
/**
* Reallocate a region to a new size, copying data over.
*
* @param handle Region to resize.
*
* @param size New size.
*
* @return SUCCESS if reallocated, FAIL otherwise.
*/
command result_t reallocate(Handle handle, int16_t size);
/**
* Lock a memory region from being compacted. This is needed if
* pointers within it are passed around.
*
* @param handle Handle to region to lock.
*
* @return SUCCESS if locked successfuly, FAIL otherwise.
*/
command result_t lock(Handle handle);
/**
* Unlock a memory region to allow its compaction.
*
* @param handle Handle to region to unlock.
*
* @return SUCCESS if unlocked successfuly, FAIL otherwise.
*/
command result_t unlock(Handle handle);
/**
* Deallocate a memory region and return it to allocatable memory.
*
* @param handle Handle to region to free.
*
* @return Size of freed region.
*/
command int16_t free(Handle handle);
/**
* Compact the allocated regions to prevent fragmentation.
*
* @return Whether the request to compact was accepted.
*/
command result_t compact();
/**
* Get the size of a memory region.
*
* @param A memory region.
*
* @return The region's size.
*/
command int16_t size(Handle handle);
/**
* Get whether a region is locked from compaction.
*
* @param handle The region to check.
*
* @return Whether the region is locked.
*
*/
command bool isLocked(Handle handle);
/**
* Return the number of free bytes available in the
* heap. This is the sum of all free blocks; even
* after compaction, a single block of this size
* may not be available if there are locked handles
* in the heap.
*
* @return The number of free bytes.
*/
command uint16_t freeBytes();
/**
* Signals when an allocation request has completed.
*
* @param handle The handle to the requested region.
*
* @param success Whether the allocation was successful.
*
* @return Should always return SUCCESS.
*
*/
event result_t allocComplete(HandlePtr handle, result_t success);
/**
* Signals when an reallocation request has completed.
*
* @param handle The handle to the requested region.
*
* @param success Whether the reallocation was successful.
*
* @return Should always return SUCCESS.
*
*/
event result_t reallocComplete(Handle handle, result_t success);
/**
* Signals when a compaction request has completed.
*
* @return Should always return SUCCESS.
*
*/
event result_t compactComplete();
}
--- NEW FILE: NotificationTimerC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Notification Timer -
<p>
* There are different sorts of events considered so far:
* - attribute events: correspond to a certain circumstance (e.g.
* crossing some threshold level)
* - link events: used to notify the ULLA core about the status of
* the different link providers, allowing it to track them.
* - command completion events: used by the link providers to deliver
* the information generated after the completion of a particular
* command, as requested by the application through the Ulla
* Command Processing.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
configuration NotificationTimerC {
provides {
interface StdControl as RNControl;
interface RNTimer;
}
}
implementation {
components
NotificationTimerM
, UllaCoreC
, TimerC
;
RNTimer = NotificationTimerM;
RNControl = NotificationTimerM;
NotificationTimerM.PeriodicTimer -> TimerC.Timer[unique("Timer")];
NotificationTimerM.EventTimer -> TimerC.Timer[unique("Timer")];
NotificationTimerM.UqpIf -> UllaCoreC.UqpIf[REMOTE_LU];
}
--- NEW FILE: NotificationTimerM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Notification Timer -
<p>
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
#define MAX_RN_TABLE 10
includes UllaQuery;
module NotificationTimerM {
provides {
interface StdControl as RNControl;
interface RNTimer;
}
uses {
interface Timer as PeriodicTimer;
interface Timer as EventTimer;
interface UqpIf;
}
}
implementation {
typedef struct RNTable {
uint8_t active;
uint8_t rnId;
uint16_t max_count;
uint16_t counter;
uint16_t gcdCnt;
uint32_t interval;
} RNTable, *RNTablePtr;
RNTable rnBuffer[MAX_RN_TABLE];
//RNTablePtr rnBufferPtr;
uint32_t gcdAll;
uint32_t gcdOld;
Query testQuery;
bool hasManyRN();
uint32_t gcd(uint32_t m, uint32_t n);
void CalculateGCD();
void ResetRNTimer();
uint8_t ActiveBuffer(uint16_t count, uint32_t interval);
command result_t RNControl.init() {
atomic {
gcdAll = 0;
gcdOld = 0;
}
return SUCCESS;
}
command result_t RNControl.start() {
return SUCCESS;
}
command result_t RNControl.stop() {
return SUCCESS;
}
event result_t UqpIf.requestInfoDone(ResultTuple *result, uint8_t numBytes) {
return SUCCESS;
}
event result_t EventTimer.fired() {
uint8_t i;
if (!hasManyRN()) call EventTimer.stop();
for (i=0; i<MAX_RN_TABLE; i++) {
if (rnBuffer[i].active) {
atomic rnBuffer[i].gcdCnt--;
if (rnBuffer[i].gcdCnt == 0) {
atomic rnBuffer[i].counter++;
dbg(DBG_USR1, "counter%d = %d max_counter = %d\n",i, rnBuffer[i].counter, rnBuffer[i].max_count);
signal RNTimer.fired(rnBuffer[i].rnId);
call UqpIf.requestInfo(&testQuery, &i);
if (rnBuffer[i].counter == rnBuffer[i].max_count) {
// FIXME: remove this RN from the table without changing (again) GCD (to make this simple we only
// change when there is a new RN)
//call PeriodicTimer.stop();
rnBuffer[i].active = 0; // disable this column
memset(&rnBuffer[i], 0, sizeof(RNTable));
signal RNTimer.stop(rnBuffer[i].rnId);
dbg(DBG_USR1, "RNTimer.stop\n");
}
// Reset gcdCnt
atomic {
rnBuffer[i].gcdCnt = rnBuffer[i].interval / gcdAll;
}
dbg(DBG_USR1, "RNTimer.fired gcdCnt%d = %d\n",i, rnBuffer[i].gcdCnt);
}
}
}
return SUCCESS;
}
event result_t PeriodicTimer.fired() {
uint8_t i;
//dbg(DBG_USR1, "NotificationTimer: PeriodicTimer.fired\n");
// if
if (!hasManyRN()) call PeriodicTimer.stop();
for (i=0; i<MAX_RN_TABLE; i++) {
if (rnBuffer[i].active) {
atomic rnBuffer[i].gcdCnt--;
if (rnBuffer[i].gcdCnt == 0) {
atomic rnBuffer[i].counter++;
dbg(DBG_USR1, "counter%d = %d max_counter = %d\n",i, rnBuffer[i].counter, rnBuffer[i].max_count);
signal RNTimer.fired(rnBuffer[i].rnId);
call UqpIf.requestInfo(&testQuery, &i);
if (rnBuffer[i].counter == rnBuffer[i].max_count) {
// FIXME: remove this RN from the table without changing (again) GCD (to make this simple we only
// change when there is a new RN)
//call PeriodicTimer.stop();
rnBuffer[i].active = 0; // disable this column
memset(&rnBuffer[i], 0, sizeof(RNTable));
signal RNTimer.stop(rnBuffer[i].rnId);
dbg(DBG_USR1, "RNTimer.stop\n");
}
// Reset gcdCnt
atomic {
rnBuffer[i].gcdCnt = rnBuffer[i].interval / gcdAll;
}
dbg(DBG_USR1, "RNTimer.fired gcdCnt%d = %d\n",i, rnBuffer[i].gcdCnt);
}
}
}
return SUCCESS;
}
command result_t RNTimer.startPeriodic(RnId_t rnId, uint16_t count, uint16_t interval, QueryPtr pCurQuery) {
// FIXME: introduce a way to handle rnId here
// FIXME: check if there are more than one notification requests. If so, GCD must be calculated and
// the Timer will stop and start with a new time interval.
uint8_t activeRN;
memcpy(&testQuery, pCurQuery, sizeof(Query));
if (hasManyRN()) {
dbg(DBG_USR1, "RNTimer: hasManyRN %d %d rnId %d\n",count,interval, rnId);
dbg(DBG_USR1, "RNTimer: Calculate GCD\n");
activeRN = ActiveBuffer(count, interval);
dbg(DBG_USR1, "Buffer is actived\n");
CalculateGCD();
rnBuffer[activeRN].gcdCnt = rnBuffer[activeRN].interval / gcdAll;
rnBuffer[activeRN].rnId = rnId;
if (activeRN >= 2) {
ResetRNTimer();
}
}
else { // only one RN
dbg(DBG_USR1, "RNTimer: has only one RN with count %d interval %d\n",count,interval);
atomic {
rnBuffer[0].max_count = count;
rnBuffer[0].interval = interval;
rnBuffer[0].active = 1;
rnBuffer[0].gcdCnt = count;
rnBuffer[0].rnId = rnId;
gcdAll = interval;
}
dbg(DBG_USR1, "GCD = %d\n",gcd(10,gcd(20,50)));
call PeriodicTimer.start(TIMER_REPEAT, interval);
}
return SUCCESS;
}
command result_t RNTimer.startEvent(RnId_t rnId, uint16_t count, uint16_t fixedInterval, QueryPtr pCurQuery){
uint8_t activeRN;
memcpy(&testQuery, pCurQuery, sizeof(Query));
if (hasManyRN()) {
dbg(DBG_USR1, "RNTimer: hasManyRN %d %d rnId %d\n",count,interval, rnId);
dbg(DBG_USR1, "RNTimer: Calculate GCD\n");
activeRN = ActiveBuffer(count, fixedInterval);
dbg(DBG_USR1, "Buffer is actived\n");
CalculateGCD();
rnBuffer[activeRN].gcdCnt = rnBuffer[activeRN].interval / gcdAll;
rnBuffer[activeRN].rnId = rnId;
if (activeRN >= 2) {
ResetRNTimer();
}
}
else { // only one RN
dbg(DBG_USR1, "RNTimer: has only one RN with count %d interval %d\n",count,interval);
atomic {
rnBuffer[0].max_count = count;
rnBuffer[0].interval = fixedInterval;
rnBuffer[0].active = 1;
rnBuffer[0].gcdCnt = count;
rnBuffer[0].rnId = rnId;
gcdAll = fixedInterval;
}
dbg(DBG_USR1, "GCD = %d\n",gcd(10,gcd(20,50)));
call EventTimer.start(TIMER_REPEAT, fixedInterval);
}
return SUCCESS;
}
bool hasManyRN() {
/*
* Check if there are more than one RNs.
*/
uint8_t i, hit=0;
for (i=0; i<MAX_RN_TABLE; i++) {
if (rnBuffer[i].active == 1) {
hit++;
}
}
if (hit > 0) return TRUE;
return FALSE;
}
uint8_t ActiveBuffer(uint16_t count, uint32_t interval) {
uint8_t i;
dbg(DBG_USR1, "ActiveBuffer count %d interval %d\n",count, interval);
for (i=0; i<MAX_RN_TABLE; i++) {
if (rnBuffer[i].active == 0) {
rnBuffer[i].max_count = count;
rnBuffer[i].interval = interval;
rnBuffer[i].active = 1;
dbg(DBG_USR1, "Buffer has a free slot %d\n", i);
break;
}
}
return i;
}
/*
* This is used when more RN is registered (can't directly use this if RN is removed)
*/
void ResetRNTimer() {
/*
* 1. Recalculate gcdCnt
* 2. Restart the RNTimer
*/
uint8_t i;
for (i=0; i<MAX_RN_TABLE; i++) {
if (rnBuffer[i].active) {
dbg(DBG_USR1, "new gcdCnt111 = %d GCD old=%d new=%d\n", rnBuffer[i].gcdCnt, gcdOld, gcdAll);
rnBuffer[i].gcdCnt *= (gcdOld / gcdAll);
dbg(DBG_USR1, "new gcdCnt = %d GCD old=%d new=%d\n", rnBuffer[i].gcdCnt, gcdOld, gcdAll);
}
}
dbg(DBG_USR1, "Restart RNTimer with a new GCD %d\n",gcdAll);
call PeriodicTimer.stop();
call PeriodicTimer.start(TIMER_REPEAT, gcdAll);
}
void CalculateGCD() {
uint8_t i;
uint32_t gcd_temp;
atomic gcd_temp = rnBuffer[0].interval;
gcdOld = gcdAll;
for (i=0; i<MAX_RN_TABLE; i++) {
if (rnBuffer[i].active) {
gcd_temp = gcd(gcd_temp, rnBuffer[i].interval);
}
}
atomic {
gcdAll = gcd_temp;
}
dbg(DBG_USR1, "GCD = %d\n", gcdAll);
}
uint32_t gcd(uint32_t m, uint32_t n) {
uint32_t t, r;
if (m < n) {
t = m;
m = n;
n = t;
}
r = m % n;
if (r == 0) {
return n;
} else {
return gcd(n, r);
}
}
}
--- NEW FILE: ProcessCmd.nc ---
// $Id: ProcessCmd.nc,v 1.1 2008/01/16 21:51:47 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
includes AM;
/**
* This interface process a
* command and is capable of the hnadling of command
* led_on, led_off, radio_louder and radio_quieter
*/
interface ProcessCmd
{
/**
* This command extracts the command from the message 'pmsg' and
* executes the command.
* @return Command execution result.
*/
command result_t execute(TOS_MsgPtr pmsg);
/**
* Indicate that the command contained in 'pmsg' has finished executing.
* @param status The status of the command completion.
* @return Always returns SUCCESS.
*/
event result_t done(TOS_MsgPtr pmsg, result_t status);
}
--- NEW FILE: ProcessData.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface ProcessData
{
command result_t perform(void *pdata, uint8_t length);
event result_t done(void *pdata, result_t status);
}
--- NEW FILE: QauAdapterC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
configuration QauAdapterC {
provides {
interface StdControl;
interface ProcessCmd[uint8_t id];
}
}
implementation {
components
QauAdapterM
, QueryAssemblerC
, LedsC
;
ProcessCmd = QauAdapterM;
StdControl = QauAdapterM;
QauAdapterM.ProcessQuery -> QueryAssemblerC;
QauAdapterM.Leds -> LedsC;
}
--- NEW FILE: QauAdapterM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes hardware;
module QauAdapterM {
provides {
interface StdControl;
interface ProcessCmd[uint8_t id];
}
uses {
interface ProcessCmd as ProcessQuery[uint8_t id];
interface Leds;
}
}
implementation {
uint8_t nConds;
command result_t StdControl.init() {
atomic {
nConds = 0;
}
return SUCCESS;
}
command result_t StdControl.start() {
return SUCCESS;
}
command result_t StdControl.stop() {
return SUCCESS;
}
command result_t ProcessCmd.execute[uint8_t id](TOS_MsgPtr pmsg) {
struct QueryMsgNew *qnmsg = (struct QueryMsgNew *)pmsg->data;
TOS_Msg temp;
struct QueryMsg *qomsg = (struct QueryMsg *)(&temp)->data;
uint8_t i, cIndex=0;
uint8_t foundLpId = 0, processThisLpId = 0;
dbg(DBG_USR1, "\n\n\n\n QauAdapter \n\n\n\n");
memcpy(&temp, pmsg, 10);
if (qnmsg->dataType == COND_MSG) {
// if it is a condition message we need to extract into several messages (one condition/message)
#if 1
for (i=0; i<CONDITION_SIZE && i<nConds; i++)
{
if (qnmsg->u.cond[i].field == LP_ID)
{
foundLpId = 1;
if (qnmsg->u.cond[i].value == TOS_LOCAL_ADDRESS) processThisLpId = 1;
}
}
if (foundLpId == 1 && processThisLpId != 1)
{
return FAIL;
}
#endif
else
{
memcpy((&temp)->data,pmsg->data, 12);
for (i=0; i<CONDITION_SIZE && i<nConds; i++) {
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
TOSH_uwait(6000);
qomsg->u.cond.field = qnmsg->u.cond[i].field;
qomsg->u.cond.op = qnmsg->u.cond[i].op;
qomsg->u.cond.value = qnmsg->u.cond[i].value;
qomsg->index = cIndex;
cIndex++;
call ProcessQuery.execute[id](&temp);
}
atomic nConds -= i+1;
}
}
else {
atomic nConds = qnmsg->numConds;
call ProcessQuery.execute[id](pmsg);
} //*/
return SUCCESS;
}
event result_t ProcessQuery.done[uint8_t id](TOS_MsgPtr pmsg, result_t status) {
dbg(DBG_USR1, "ProcessQuery done: prepare to send back\n");
return SUCCESS;
}
}
--- NEW FILE: Query.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* Interface for Query Message
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UllaQuery;
interface Query {
command uint8_t getField(QueryPtr q, uint8_t idx);
command uint8_t *getFieldPtr(QueryPtr q, uint8_t idx);
command uint8_t setField(QueryPtr q, uint8_t idx, uint8_t *f);
command Cond getCondition(QueryPtr q, uint8_t idx);
command result_t setCondition(QueryPtr q, uint8_t idx, CondPtr c);
command bool gotAllConds(QueryPtr q);
command bool gotAllFields(QueryPtr q);
command bool gotCompleteQuery(QueryPtr q);
/**
* Assembles all the query messages into a single query
* @param qmsg incoming query messages
* @param q output
* @return false if the query message is known before
**/
command bool addQuery(QueryMsgPtr qmsg, QueryPtr q);
// need to be added to notify when memory is allocated 2006/02/24
//event result_t addQueryDone(QueryPtr q);
/**
* Parses the query and starts measurement
* @param q input query to parse
* @param uq parsed query known as ulla query
**/
command result_t parseQuery(QueryPtr q, UllaQueryPtr uq);
}
--- NEW FILE: QueryAssemblerC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Query Assembler - gather multiple messages sent from a remote
* Link User into a singel query
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
configuration QueryAssemblerC {
provides {
interface StdControl;
interface ProcessCmd as ProcessQuery[uint8_t id];
}
}
implementation {
components
//Main
QueryAssemblerM
, QueryProcessorC
, UllaCoreC
, QueryM
, UllaAllocC // parameterized-interface version of TinyAlloc
, LedsC
;
StdControl = QueryAssemblerM;
QueryAssemblerM.Leds -> LedsC;
QueryAssemblerM.UllaAlloc -> UllaAllocC.QauAlloc;
QueryAssemblerM.Query -> QueryM;
QueryAssemblerM.UqpIf -> UllaCoreC.UqpIf[REMOTE_LU]; // REMOTE_LU
ProcessQuery = QueryAssemblerM;
}
--- NEW FILE: QueryAssemblerM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Query Assembler implementation
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
includes MemAlloc;
includes hardware;
includes msg_type;
module QueryAssemblerM {
provides {
interface StdControl;
interface ProcessCmd as ProcessQuery[uint8_t id];
}
uses {
interface MemAlloc as UllaAlloc;
interface Leds;
interface Query;
interface UqpIf; // parameterized at UQP
}
}
/*
* Module Implementation
*/
implementation
{
enum {
ALLOC_ULLA_QUERY_STATUS,
ALLOC_QUERY_STATUS,
RESIZE_QUERY_STATUS,
NOT_ALLOCING_STATUS,
ALLOC_QUERY_RESULT_STATUS,
};
typedef struct {
void **next;
struct Query uq;
} QueryList, *QueryListPtr, **QueryListHandle;
QueryListHandle qListHead;
QueryListHandle qListTail;
TOS_MsgPtr msg;
//TOS_Msg buf;
TOS_MsgPtr rmsg;
TOS_Msg rbuf;
short nsamples; // number of samples
uint8_t packetReadingNumber;
uint16_t readingNumber;
uint8_t queryType;
QueryMsgPtr qmsg;
QueryMsg qmsg_buf;
struct Query qbuf;
/* we need a query handle for dynamic allocation (later on) */
QueryPtr pquery;
struct Query **gCurQuery; /* gCurQuery is a query handle */
UllaQueryPtr uq;
Handle gCurHandle;
Handle first;
/* global varibles */
char gCurCond;
ResultTuple *gCurTuple;
typedef void (*MemCallback)(Handle *memory);
MemCallback memCallback;
uint8_t mStatus;
uint8_t seen;
/* task declaration */
task void deleteQuery();
task void modifyQuery();
/* function declaration */
void addQuery(HandlePtr memory);
bool allocateQuery();
bool allocateUllaQuery(QueryPtr q);
bool is_processing_query;
uint8_t checkQueryComplete();
command result_t StdControl.init() {
atomic {
rmsg = &rbuf;
pquery = &qbuf;
qmsg = &qmsg_buf;
qListHead = NULL;
qListTail = NULL;
pquery->seenConds = 0;
gCurCond = -1;
is_processing_query = 0;
}
return (SUCCESS);
}
command result_t StdControl.start(){
return (SUCCESS);
}
command result_t StdControl.stop(){
return (SUCCESS);
}
#if 1
command result_t ProcessQuery.execute[uint8_t id](TOS_MsgPtr pmsg) {
uint8_t i;
atomic {
//qmsg = (struct QueryMsg *) pmsg->data;
memcpy(qmsg, &(pmsg->data), sizeof(QueryMsg));
msg = pmsg;
queryType = id; // RN or query
}
dbg(DBG_USR1,"UQP: ProcessQuery %d\n",qmsg->numFields);
//call Leds.yellowToggle();
dbg(DBG_USR1,"ProcessQuery execute\n");
//check message data type: add, modify, delete
if (qmsg->msgType == DEL_MSG) { // delete a query
if (is_processing_query) return FAIL;
is_processing_query = 1;
post deleteQuery();
is_processing_query = 0;
// modify a previous query (given a query ID)
} else if (qmsg->msgType == MOD_MSG) {
dbg(DBG_USR1,"ProcessQuery MOD_MSG\n");
if (is_processing_query) return FAIL;
is_processing_query = 1;
post modifyQuery();
is_processing_query = 0;
// add a query
}
else if (qmsg->msgType == ADD_MSG)
{
dbg(DBG_USR1,"ProcessQuery ADD_MSG\n");
if (!is_processing_query) {
is_processing_query = 1;
allocateQuery();
//call Leds.yellowToggle();
}
else
{
if (qmsg->ruId != (**gCurQuery).qid)
{
dbg(DBG_USR1,"QAU: different query -> delete old one\n");
call UllaAlloc.unlock((Handle)gCurQuery);
call UllaAlloc.free((Handle)gCurQuery);
} else // same query id
{
dbg(DBG_USR1, "QAU: ruId = qid\n");
call Query.addQuery(qmsg, *gCurQuery);
if (checkQueryComplete())
{
dbg(DBG_USR1, "QAU: adding query complete\n");
//call Leds.greenToggle();
}
}
}
}
return SUCCESS;
}
#endif
task void deleteQuery() {
}
task void modifyQuery() {
}
uint8_t checkQueryComplete() {
uint8_t i;
uint8_t complete = 0;
RnDescr_t rnDescr;
call Query.addQuery(qmsg, *gCurQuery);
//if (call Query.addQuery(qmsg, *gCurQuery) == FALSE)
if (call Query.gotCompleteQuery(*gCurQuery) == TRUE) {
dbg(DBG_USR1,"ProcessQuery gotCompleteQuery %p\n",*gCurQuery);
switch (qmsg->queryType) {
case 1: // notification
{
struct RnDescr_t rndescr;
uint8_t rnId;
memcpy(&(rnDescr.query), *gCurQuery, sizeof(struct Query));
rnDescr.count = qmsg->nsamples;
rnDescr.period = qmsg->interval;
//if (rnDescr.query.fields[0] != 0) call Leds.redToggle(); else call Leds.yellowToggle();
call UqpIf.requestNotification(&rnDescr, &i, 10);
//RnDescr_t *rndescr, RnId_t* rnId, uint16_t validity
call UllaAlloc.unlock((Handle)gCurQuery);
call UllaAlloc.free((Handle)gCurQuery);
}
break;
case 2: // query
call UqpIf.requestInfo(*gCurQuery, &i);
call UllaAlloc.unlock((Handle)gCurQuery);
call UllaAlloc.free((Handle)gCurQuery);
break;
default:
break;
}
complete = 1;
}
return complete;
}
/*----------------------------------- UQP ----------------------------------------*/
//event result_t UqpIf.requestInfoDone(ullaResult_t *result, uint8_t numBytes) {
event result_t UqpIf.requestInfoDone(ResultTuple *result, uint8_t numBytes) {
// need to reset ulla_result after getting value
call UqpIf.clearResult();
// send results back to the remote user
// send one message per one attribute or?
///call Send.send[AM_QUERY_MESSAGE](&rbuf, sizeof(struct QueryMsg));
return SUCCESS;
}
/*---------------------------------- Ulla Core ----------------------------------*/
/*
event result_t Send.sendDone[uint8_t id](TOS_MsgPtr pMsg, result_t success) {
return SUCCESS;
}*/
/*--------------------------- Memory Allocation (RAM) ------------------------*/
// FIXME: handler is wrongly used here (see ULLAStorageM)
//
void addQuery(HandlePtr memory) {
uint8_t i;
gCurQuery = (struct Query **)*memory;
dbg(DBG_USR1, "addQuery %p %p\n",*memory, *gCurQuery);
(**gCurQuery).qid = qmsg->ruId;
(**gCurQuery).numFields = qmsg->numFields;
(**gCurQuery).numConds = qmsg->numConds;
(**gCurQuery).className = qmsg->className;
//(**gCurQuery).interval = qmsg->interval;
//(**gCurQuery).nsamples = qmsg->nsamples;
(**gCurQuery).seenConds = 0;
call Query.addQuery(qmsg, *gCurQuery);
dbg(DBG_USR1, "++++++Query %d %d\n",(**gCurQuery).numFields, (**gCurQuery).numConds);
for (i=qmsg->numConds; i<8; i++)
(**gCurQuery).seenConds |= (1 << i);
call UllaAlloc.unlock((Handle)gCurQuery);
checkQueryComplete();
}
bool allocateQuery() {
dbg(DBG_USR1, "allocateQuery \n");
mStatus = ALLOC_QUERY_STATUS;
call UllaAlloc.lock((Handle) gCurHandle);
if (call UllaAlloc.allocate(&gCurHandle, sizeof(struct Query)) == SUCCESS)
return TRUE;
return FALSE;
}
/*--------------------------- MemAlloc Events -------------------------------*/
event result_t UllaAlloc.allocComplete(Handle *handle, result_t complete) {
QueryListHandle qlh = (QueryListHandle)*handle;
dbg(DBG_USR1,"UllaAlloc.alloc complete %p\n", qlh);
if (mStatus == NOT_ALLOCING_STATUS) return SUCCESS; //not our allocation
if (complete) {
dbg(DBG_USR1,"Allocated query\n"); //fflush(stdout);
//(*memCallback)(handle);
// callback function
switch (mStatus) {
case ALLOC_QUERY_STATUS:
// put a new query to the list
(**qlh).next = NULL;
atomic {
if (qListTail == NULL) {
dbg(DBG_USR1,"--** start qListTail **--\n");
qListTail = qlh;
qListHead = qlh;
} else {
dbg(DBG_USR1,"--** next qListTail **--\n");
(**qListTail).next = (void **)qlh;
qListTail = qlh;
}
}
// then add the information
//call Query.addQuery(qmsg, *gCurQuery);
addQuery((HandlePtr)&qListTail);
break; //*/
}
} else {
dbg(DBG_USR1,"Error: Out of Memory!\n");
}
mStatus = NOT_ALLOCING_STATUS; //not allocating any more
return SUCCESS;
}
//event result_t UllaAlloc.reallocComplete[uint8_t id](Handle handle, result_t complete) {
event result_t UllaAlloc.reallocComplete(Handle handle, result_t complete) {
dbg(DBG_USR1,"UllaAlloc.realloc complete\n");
return SUCCESS;
}
//event result_t UllaAlloc.compactComplete[uint8_t id]() {
event result_t UllaAlloc.compactComplete() {
dbg(DBG_USR1,"UllaAlloc.compact complete\n");
return SUCCESS;
}
}
--- NEW FILE: QueryM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* Implementation for Query interface
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
module QueryM {
provides {
interface Query;
}
}
implementation {
command uint8_t Query.getField(QueryPtr q, uint8_t idx) {
return q->fields[idx];
}
command uint8_t *Query.getFieldPtr(QueryPtr q, uint8_t idx) {
return &(q->fields[idx]);
}
command result_t Query.setField(QueryPtr q, uint8_t numFields, uint8_t *f) {
memcpy(&q->fields, f, numFields);
q->numFields = numFields;
return SUCCESS;
}
command Cond Query.getCondition(QueryPtr q, uint8_t idx) {
return q->cond[idx];
}
command result_t Query.setCondition(QueryPtr q, uint8_t idx, CondPtr c) {
//c = (Cond *)((char *)((char *)q + sizeof(struct Query) + idx * sizeof(struct Cond)));
//c = &q->cond[idx];
memcpy(&q->cond[idx], c, sizeof(struct Cond));
return SUCCESS;
}
command bool Query.gotAllConds(QueryPtr q) {
dbg(DBG_USR1, "gotAllConds %2X\n",q->seenConds);
return (q->seenConds & (0xFF)) == 0xFF;
}
command bool Query.gotAllFields(QueryPtr q) {
dbg(DBG_USR1, "gotAllFields %d\n",q->seenFields);
return (q->seenFields);
}
command bool Query.gotCompleteQuery(QueryPtr q) {
return rcombine(call Query.gotAllFields(q), call Query.gotAllConds(q));
}
command bool Query.addQuery(QueryMsgPtr qmsg, QueryPtr q) {
result_t seenBefore = FALSE;
if (qmsg->dataType == FIELD_MSG) {
dbg(DBG_USR1,"FIELD_MSG %2X\n",q->seenFields);
call Query.setField(q, qmsg->numFields, qmsg->u.fields);
//seenBefore = q->seenFields;
q->seenFields = TRUE; // only one field message
} else if (qmsg->dataType == COND_MSG) {
dbg(DBG_USR1,"COND_MSG %2X\n",q->seenConds);
call Query.setCondition(q, qmsg->index, &qmsg->u.cond);
seenBefore = (q->seenConds & (1 << qmsg->index));
q->seenConds |= (1 << qmsg->index);
}
return seenBefore;
}
command result_t Query.parseQuery(QueryPtr q, UllaQueryPtr uq) {
uq->qid = q->qid;
uq->numFields = q->numFields;
uq->numConds = q->numConds;
//uq->interval = q->interval;
//uq->nsamples = q->nsamples;
return SUCCESS;
}
}
--- NEW FILE: QueryProcessor.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Header file for Query Processor
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
/* bCheckBit - used to bitmask the state */
enum {
ADDING_QUERY_STATUS = 0x0001, // reading queries from network
PARSING_QUERY_STATUS = 0x0002, // parsing the query
ROUTING_STATUS = 0x0004, // routing tuples to queries
CHECKING_CONDITION_STATUS = 0x0008, // checking conditions
SENDING_QUERY_STATUS = 0x0010, // sending a query message
PROCESSING_QUERY_STATUS = 0x0020, // processing a query message
REMOVING_QUERY_STATUS = 0x0040, // removing a query
};
--- NEW FILE: QueryProcessorC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Ulla Query Processing - implements the direct interface with the link
* users and also handles all the requests from them. The UQP therefore
* processes requests for information or notification regarding one or
* more link attributes.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes AMTypes;
configuration QueryProcessorC {
provides {
interface StdControl;
//interface ProcessCmd as ProcessQuery;
interface UqpIf[uint8_t id];
interface ProcessData as ProcessResultGetInfo;
}
}
implementation {
components
// Main
QueryProcessorM
, QueryM
, NotificationTimerC
, UllaCoreC
, ConditionM
//, ExprEvalM
, LLAC
, UllaLinkProviderC
, SensorMeterC
//, HistoricalStorageC
, ULLAStorageC
//, TinyAlloc
//, UllaAllocM
//, GenericComm as Comm
, LedsC
;
//Main.StdControl -> QueryProcessorM;
StdControl = QueryProcessorM;
UqpIf = QueryProcessorM;
ProcessResultGetInfo = QueryProcessorM;
QueryProcessorM.Query -> QueryM;
QueryProcessorM.Condition -> ConditionM;
//ConditionM.ExprEval -> ExprEvalM;
QueryProcessorM.RNTimer -> NotificationTimerC;
QueryProcessorM.RNControl -> NotificationTimerC;
QueryProcessorM.Leds -> LedsC;
/*
QueryProcessorM.ReadFromStorage -> HistoricalStorageC;
QueryProcessorM.WriteToStorage -> HistoricalStorageC;
*/
QueryProcessorM.StorageIf -> ULLAStorageC;
//QueryProcessorM.StorageControl -> ULLAStorageC;
/////QueryProcessorM.RequestUpdate -> LLAC; // will be replaced with LinkProviderIf
QueryProcessorM.LinkProviderIf -> LLAC;
//QueryProcessorM.Receive -> LLAC.ReceiveInf[AM_RESULT_GETINFO_MESSAGE];
QueryProcessorM.UllaLinkProviderIf -> UllaLinkProviderC;
// FIXME 01.08.06
// Fix fan-out problem (ULLACore+UQP share Send interface)
////QueryProcessorM.Send -> LLAC.SendInf;
QueryProcessorM.SendResult -> UllaCoreC.Send[AM_QUERY_REPLY];
QueryProcessorM.SendTest -> UllaCoreC.Send[99];
QueryProcessorM.SendFixedAttrMsg -> UllaCoreC.Send[AM_FIXEDATTR];
///QueryProcessorM.RequestUpdate -> SensorMeterC;
QueryProcessorM.SensorIf -> SensorMeterC.LinkProviderIf;
//ProcessQuery = QueryProcessorM;
}
--- NEW FILE: QueryProcessorM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
[...1517 lines suppressed...]
event result_t ReadFromStorage.readDone(uint8_t *buffer, uint32_t bytes, result_t ok) {
dbg(DBG_USR1,"ReadFromStroage read done\n");
return SUCCESS;
}
event result_t WriteToStorage.writeDone(uint8_t *data, uint32_t bytes, result_t ok) {
dbg(DBG_USR1,"WriteToStorage write done\n");
//call Leds.redToggle();
return SUCCESS;
}
} // end of implementation
/*----------------------------- Default Event Handler ------------------------*/
/*---------------------------------------------------------------------------*/
--- NEW FILE: RNTimer.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface RNTimer {
command result_t startPeriodic(RnId_t rnId, uint16_t count, uint16_t interval, QueryPtr pCurQuery);
command result_t startEvent(RnId_t rnId, uint16_t count, uint16_t interval, QueryPtr pCurQuery);
event result_t stop(RnId_t rnId);
event result_t fired(RnId_t rnId);
}
--- NEW FILE: ReadFromStorage.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* ReadFromStorage Interface - processes a request from the ULLA
* Query Processing to access the information in the ULLA Storage.
<p>
*
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface ReadFromStorage
{
/**
* Read data.
* @param offset Offset at which to read.
* @param data Where to place read data
* @param numBytesRead number of bytes to read
* @return FAIL if the read request is refused. If the result is SUCCESS,
* the <code>readDone</code> event will be signaled.
*/
command result_t read(uint32_t offset, uint8_t* buffer, uint32_t numBytesRead);
/**
* Signal read completion
* @param data Address where read data was placed
* @param numBytesRead Number of bytes read
* @param status SUCCESS if read was successful, FAIL otherwise
* @return Ignored.
*/
event result_t readDone(uint8_t* buffer, uint32_t numBytesRead, result_t status);
}
--- NEW FILE: ReceivePacket.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes AM;
interface ReceivePacket {
command result_t receive(TOS_MsgPtr rmsg);
event result_t receiveDone(TOS_MsgPtr rmsg);
}
--- NEW FILE: RequestUpdate.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* Interface for Request Update
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UllaQuery;
interface RequestUpdate {
/**
* This command extracts the command from the message 'pq' and
* executes the command.
* @return Command execution result.
*/
command result_t execute(QueryPtr pq);
/**
* Indicate that a tuple is received
* @param rt The result tuple
* @return The result tuple
*/
event ResultTuplePtr receiveTuple(ResultTuplePtr rt);
}
--- NEW FILE: ScanLinks.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
#ifndef _SCANLINKS_H_
#define _SCANLINKS_H_
enum {
SCAN_AVAILABLE_LINKS = 31,
AM_SCAN_LINKS = 106,
};
typedef struct ScanLinks{
uint16_t id;
} ScanLinks;
#endif
--- NEW FILE: ScanMsg.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
enum {
SCAN_AVAILABLE_LINKS = 30,
AM_SCAN_LINKS = 106,
};
--- NEW FILE: Sensing.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface Sensing
{
/**
* Start sensing data.
* @param nsamples The number of samples to gather.
* @param interval_ms The interval (in msec) at which to gather samples.
*/
command result_t start(int nsamples, int interval_ms);
/**
* Signalled when sensing has completed.
*/
event result_t done();
}
--- NEW FILE: SensorMeterC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Sensor Meter - senses the physical world e.g. light, temperature, etc.
* It is used for the SmartHome Monitoring application.
*
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
/*
#ifndef OSCOPE
#define OSCOPE
#endif*/
/*
#ifndef TELOS_SENSOR
#define TELOS_SENSOR
#endif*/
includes UllaQuery;
configuration SensorMeterC {
provides {
interface StdControl;
///interface RequestUpdate;
interface LinkProviderIf[uint8_t id];
}
}
implementation {
components
Main
, SensorMeterM
, EventProcessorC
//, LLAC
#ifdef HISTORICAL_STORAGE
, HistoricalStorageC
#endif
, TimerC
, LedsC
#ifdef OSCOPE
, OscopeC
#endif
#ifdef TELOS_SENSOR
, HumidityC
, HamamatsuC
, InternalTempC
, InternalVoltageC
#endif
//, GenericComm as Comm
;
Main.StdControl -> SensorMeterM;
Main.StdControl -> TimerC;
//Main.StdControl -> Comm;
#ifdef OSCOPE
Main.StdControl -> OscopeC;
#endif
#ifdef TELOS_SENSOR
Main.StdControl -> HamamatsuC;
Main.StdControl -> InternalTempC;
Main.StdControl -> InternalVoltageC;
#endif
StdControl = SensorMeterM;
SensorMeterM.Timer -> TimerC.Timer[unique("Timer")];
SensorMeterM.Leds -> LedsC;
///RequestUpdate = SensorMeterM;
LinkProviderIf = SensorMeterM;
SensorMeterM.AttributeEvent -> EventProcessorC.ProcessEvent[0];
SensorMeterM.LinkEvent -> EventProcessorC.ProcessEvent[1];
SensorMeterM.CompleteCmdEvent -> EventProcessorC.ProcessEvent[2];
#ifdef HISTORICAL_STORAGE
SensorMeterM.WriteToStorage -> HistoricalStorageC;
#endif
/////SensorMeterM.Send -> LLAC.SendInf;
#ifdef TELOS_SENSOR
/* Sensors */
SensorMeterM.HumidityControl -> HumidityC;
SensorMeterM.Humidity -> HumidityC.Humidity;
SensorMeterM.Temperature -> HumidityC.Temperature;
SensorMeterM.TSR -> HamamatsuC.TSR;
SensorMeterM.PAR -> HamamatsuC.PAR;
SensorMeterM.InternalTemperature -> InternalTempC;
SensorMeterM.InternalVoltage -> InternalVoltageC;
SensorMeterM.HumidityError -> HumidityC.HumidityError;
SensorMeterM.TemperatureError -> HumidityC.TemperatureError;
#endif
#ifdef OSCOPE
SensorMeterM.OHumidity -> OscopeC.Oscope[0];
SensorMeterM.OTemperature -> OscopeC.Oscope[1];
SensorMeterM.OTSR -> OscopeC.Oscope[2];
SensorMeterM.OPAR -> OscopeC.Oscope[3];
SensorMeterM.OInternalTemperature -> OscopeC.Oscope[4];
SensorMeterM.OInternalVoltage -> OscopeC.Oscope[5];
#endif
}
--- NEW FILE: SensorMeterM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Implementation of SersorMeterC.nc
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
#ifndef TELOS_PLATFORM
#define TELOS_PLATFORM
#endif
module SensorMeterM {
provides {
interface StdControl;
//interface RequestUpdate;
interface LinkProviderIf[uint8_t id];
interface GetInfoIf as GetSensorInfo;
}
uses {
interface Timer;
interface Leds;
interface ProcessCmd as AttributeEvent;
interface ProcessCmd as LinkEvent;
interface ProcessCmd as CompleteCmdEvent;
////interface Send[uint8_t id];
//interface Condition;
#ifdef HISTORICAL_STORAGE
interface WriteToStorage;
#endif
#ifdef TELOS_PLATFORM
/* Sensors */
interface SplitControl as HumidityControl;
interface ADC as Humidity;
interface ADC as Temperature;
interface ADC as TSR;
interface ADC as PAR;
interface ADC as InternalTemperature;
interface ADC as InternalVoltage;
interface ADCError as HumidityError;
interface ADCError as TemperatureError;
#endif
#ifdef OSCOPE
interface Oscope as OHumidity;
interface Oscope as OTemperature;
interface Oscope as OTSR;
interface Oscope as OPAR;
interface Oscope as OInternalTemperature;
interface Oscope as OInternalVoltage;
#endif
}
}
/*
* Module Implementation
*/
implementation
{
enum {
OSCOPE_DELAY = 10,
};
norace uint16_t humidity, temperature, tsr, par, itemp, ivolt;
norace uint8_t state;
norace uint16_t numSamples;
norace uint16_t timeInterval;
norace uint8_t actionIndex;
norace uint16_t sdata;
// module scoped variables
TOS_MsgPtr msg;
TOS_Msg buf;
int8_t pending;
QueryPtr query;
ResultTuple rt;
ResultTuplePtr rtp;
uint8_t query_type;
uint8_t currentLU;
/* task declaration */
task void getHumidity();
task void getTemperature();
task void getTSR();
task void getPAR();
task void getInternalTemperature();
task void getInternalVoltage();
/* function declaration */
//result_t addToResultTuple(ResultTuplePtr result);
task void SimDataReady();
task void CheckQueryType();
////void CheckCounter();
command result_t StdControl.init() {
atomic {
//state = HUMIDITY;
rtp = &rt;
msg = &buf;
actionIndex = 0;
}
//call Leds.init();
//call Leds.set(0);
#ifdef TELOS_PLATFORM
call HumidityControl.init();
#endif
return (SUCCESS);
}
#ifdef TELOS_PLATFORM
event result_t HumidityControl.initDone() {
return SUCCESS;
}
#endif
/* start the sensorcontrol component */
command result_t StdControl.start() {
#ifdef TELOS_PLATFORM
call HumidityControl.start();
#endif
return SUCCESS;
}
#ifdef TELOS_PLATFORM
event result_t HumidityControl.startDone() {
call HumidityError.enable();
call TemperatureError.enable();
//call Timer.start( TIMER_ONE_SHOT, 250 );
return SUCCESS;
}
#endif
/* stop the sensorcontrol component */
command result_t StdControl.stop() {
#ifdef TELOS_PLATFORM
call HumidityControl.stop();
#endif
call Timer.stop();
return SUCCESS;
}
#ifdef TELOS_PLATFORM
event result_t HumidityControl.stopDone() {
call HumidityError.disable();
call TemperatureError.disable();
return SUCCESS;
}
#endif
#if 0
// fill in the result tuple when dataReady, and signal receiveTuple
command result_t RequestUpdate.execute(QueryPtr pq) {
dbg(DBG_USR1, "Request update starts\n");
atomic {
query = pq;
actionIndex = 0;
state = pq->fields[actionIndex];
numSamples = pq->nsamples;
timeInterval = pq->interval;
//rtp->qid = pq->qid;
rtp->numFields = pq->numFields;
rtp->numConds = pq->numConds;
}
call Timer.start( TIMER_ONE_SHOT, OSCOPE_DELAY );
return SUCCESS;
}
#endif
event result_t Timer.fired() {
//call Leds.yellowToggle();
dbg(DBG_USR1, "Timer fired\n");
// set a timeout in case a task post fails (rare)
//call Timer.start(TIMER_ONE_SHOT, 100);
switch(state) {
case HUMIDITY:
post getHumidity();
break;
case TEMPERATURE:
post getTemperature();
break;
case TSRSENSOR:
post getTSR();
break;
case PARSENSOR:
post getPAR();
break;
case INT_TEMP:
post getInternalTemperature();
break;
case INT_VOLT:
post getInternalVoltage();
break;
//default:
// call Timer.start(TIMER_ONE_SHOT, 10);
} // switch case
return SUCCESS;
}
/*
default event ResultTuplePtr RequestUpdate.receiveTuple(ResultTuplePtr rtr) {
return rtr;
}
*/
event result_t AttributeEvent.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
event result_t LinkEvent.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
event result_t CompleteCmdEvent.done(TOS_MsgPtr pmsg, result_t status) {
return SUCCESS;
}
void ProcessAttribute(uint8_t attr) {
switch(attr) {
case LP_ID:
state = LP_ID;
post CheckQueryType();
break;
case HUMIDITY:
post getHumidity();
call Leds.greenToggle();
break;
case TEMPERATURE:
//call Leds.yellowToggle();
post getTemperature();
break;
case TSRSENSOR:
post getTSR();
break;
case PARSENSOR:
post getPAR();
break;
case INT_TEMP:
post getInternalTemperature();
break;
case INT_VOLT:
post getInternalVoltage();
break;
}
}
/*------------------------------ Link Provider --------------------------------*/
command uint8_t LinkProviderIf.execCmd[uint8_t id](CmdDescr_t* cmdDescr) {
}
command uint8_t LinkProviderIf.requestUpdate[uint8_t id](RuId_t ruId, RuDescr_t* ruDescr, AttrDescr_t* attrDescr) {
switch (id) {
// probe or read from the firmware
case REMOTE_QUERY:
// no use here
dbg(DBG_USR1, "SensorMeter: LP.requestUpdate REMOTE_QUERY\n");
break;
// local reading
// This case we should signal LinkProviderIf.getAttributeDone back to UQP
case LOCAL_QUERY:
dbg(DBG_USR1, "SensorMeter: LP.requestUpdate LOCAL_QUERY\n");
break;
default:
dbg(DBG_USR1, "SensorMeter: LP.requestUpdate UNDEFINED TYPE\n");
break;
}
return 1;
}
command uint8_t LinkProviderIf.cancelUpdate[uint8_t id](RuId_t ruId) {
}
command uint8_t LinkProviderIf.getAttribute[uint8_t id](AttrDescr_t* attDescr) {
TOS_MsgPtr p;
struct GetInfoMsg *getInfo = (struct GetInfoMsg *)buf.data;
dbg(DBG_USR1, "SensorMeterM: getAttribute\n");
/*
atomic {
query_type = id;
currentLU = LOCAL_LU;
}
*/
call Leds.greenToggle();
dbg(DBG_USR1, "SensorMeter.getAttribute\n");
ProcessAttribute(attDescr->attribute);
return 1;
}
command uint8_t LinkProviderIf.setAttribute[uint8_t id](AttrDescr_t* attDescr) {
return 1;
}
command void LinkProviderIf.freeAttribute[uint8_t id](AttrDescr_t* attDescr) {
}
/*-------------------------------- Transceiver --------------------------------*/
command uint8_t GetSensorInfo.getAttribute(TOS_Msg *tmsg) {
struct GetInfoMsg *getinfo = (struct GetInfoMsg *)tmsg->data;
atomic {
currentLU = REMOTE_LU;
query_type = REMOTE_QUERY;
}
ProcessAttribute(getinfo->attribute);
return 1;
}
/*
event result_t Send.sendDone[uint8_t id](TOS_MsgPtr pmsg, result_t success) {
AttrDescr_t* attDescr;
dbg(DBG_USR1, "SensorMeterM: SendGetInfoMsg.sendDone\n");
//signal LinkProviderIf.getAttributeDone[REMOTE_QUERY](attDescr);
return success;
}*/
/*------------------------------- Put data ------------------------------------*/
task void putHumidity() {
#ifdef OSCOPE
call OHumidity.put(humidity);
#endif
// fill in tuple here
rtp->fields[actionIndex] = HUMIDITY;
rtp->data[actionIndex] = humidity;
//call Leds.yellowToggle();
////CheckCounter();
}
task void putTemperature() {
#ifdef OSCOPE
call OTemperature.put(temperature);
#endif
rtp->fields[actionIndex] = TEMPERATURE;
rtp->data[actionIndex] = temperature;
//call Leds.greenToggle();
////CheckCounter();
}
task void putTSR() {
#ifdef OSCOPE
call OTSR.put(tsr);
//call Leds.greenToggle();
#endif
rtp->fields[actionIndex] = TSRSENSOR;
rtp->data[actionIndex] = tsr;
////CheckCounter();
}
task void putPAR() {
#ifdef OSCOPE
call OPAR.put(par);
#endif
rtp->fields[actionIndex] = PARSENSOR;
///rtp->dummy = 0xFF;
rtp->data[actionIndex] = par;
///CheckCounter();
}
task void putIntTemp() {
#ifdef OSCOPE
call OInternalTemperature.put(itemp);
#endif
rtp->fields[actionIndex] = INT_TEMP;
rtp->data[actionIndex] = itemp;
///CheckCounter();
}
task void putIntVoltage() {
#ifdef OSCOPE
call OInternalVoltage.put(ivolt);
#endif
rtp->fields[actionIndex] = INT_VOLT;
rtp->data[actionIndex] = ivolt;
///CheckCounter();
}
task void getHumidity() {
state = HUMIDITY;
#ifdef TELOS_PLATFORM
call Humidity.getData();
#else
post SimDataReady();
#endif
}
task void getTemperature() {
state = TEMPERATURE;
//call Leds.yellowToggle();
#ifdef TELOS_PLATFORM
call Temperature.getData();
#else
post SimDataReady();
#endif
}
task void getTSR() {
state = TSRSENSOR;
#ifdef TELOS_PLATFORM
call TSR.getData();
#else
post SimDataReady();
#endif
}
task void getPAR() {
state = PARSENSOR;
#ifdef TELOS_PLATFORM
call PAR.getData();
#else
post SimDataReady();
#endif
}
task void getInternalTemperature() {
state = INT_TEMP;
#ifdef TELOS_PLATFORM
call InternalTemperature.getData();
#else
post SimDataReady();
#endif
}
task void getInternalVoltage() {
state = INT_VOLT;
#ifdef TELOS_PLATFORM
call InternalVoltage.getData();
#else
post SimDataReady();
#endif
}
//#ifdef TELOS_PLATFORM
task void CheckQueryType() {
struct GetInfoMsg *getinfo = (struct GetInfoMsg *) msg->data;
struct AttrDescr_t attDescr;
elseHorizontalTuple tuple;
uint16_t data;
//call Leds.redToggle();
switch(state) {
case LP_ID:
sdata = TOS_LOCAL_ADDRESS;
break;
case HUMIDITY:
sdata = humidity;
break;
case TEMPERATURE:
sdata = temperature;
break;
case TSRSENSOR:
//call Leds.redToggle();
sdata = tsr;
break;
case PARSENSOR:
///call Leds.yellowToggle();
sdata = par;
break;
case INT_TEMP:
call Leds.greenToggle();
sdata = itemp;
break;
case INT_VOLT:
sdata = ivolt;
break;
}
dbg(DBG_USR1, "SenserMeterM: CheckQueryType sdata=%d\n",sdata);
data = sdata;
attDescr.attribute = state;
attDescr.className = sensorMeter;
tuple.attr = state;
tuple.u.value16 = sdata;
signal LinkProviderIf.getAttributeDone[LOCAL_QUERY](&attDescr, (uint8_t *) &tuple);
#if 0
switch (currentLU) {
case LOCAL_LU:
//call Leds.yellowToggle();
switch (query_type) {
case LOCAL_QUERY:
//call Leds.yellowToggle();
signal LinkProviderIf.getAttributeDone[LOCAL_QUERY](&attDescr, &data);
break;
case REMOTE_QUERY:
//////call Send.send[AM_GETINFO_MESSAGE](msg, sizeof(struct GetInfoMsg));
signal LinkProviderIf.getAttributeDone[REMOTE_QUERY](&attDescr, &data);
break;
}
break;
case REMOTE_LU:
//call Leds.greenToggle();
switch (query_type) {
case LOCAL_QUERY:
signal LinkProviderIf.getAttributeDone[LOCAL_QUERY](&attDescr, &data);
break;
case REMOTE_QUERY:
// FIXME 04.08.06: check if this is correct (changed GetSensorInfo to LinkProvider[LOCAL_QUERY].
///signal GetSensorInfo.getAttributeDone(msg);
signal LinkProviderIf.getAttributeDone[REMOTE_QUERY](&attDescr, &data);
break;
}
break;
default:
//call Leds.greenToggle();
break;
}
#endif
}
#ifdef TELOS_PLATFORM
async event result_t Humidity.dataReady(uint16_t data) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
humidity = data;
//post putHumidity();
state = HUMIDITY;
post CheckQueryType();
return SUCCESS;
}
event result_t HumidityError.error(uint8_t token) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
humidity = 0;
//post putHumidity();
state = HUMIDITY;
post CheckQueryType();
return SUCCESS;
}
async event result_t Temperature.dataReady(uint16_t data) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
temperature = data;
//post putTemperature();
state = TEMPERATURE;
post CheckQueryType();
//state = TSRSENSOR;
return SUCCESS;
}
event result_t TemperatureError.error(uint8_t token) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
temperature = 0;
//post putTemperature();
state = TEMPERATURE;
post CheckQueryType();
return SUCCESS;
}
async event result_t TSR.dataReady(uint16_t data) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
struct GetInfoMsg *getinfo = (struct GetInfoMsg *) msg->data;
tsr = data;
state = TSRSENSOR;
post CheckQueryType();
//post putTSR();
getinfo->data = tsr;
return SUCCESS;
}
async event result_t PAR.dataReady(uint16_t data) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
struct GetInfoMsg *getinfo = (struct GetInfoMsg *) msg->data;
par = data;
//post putPAR();
/*
uint8_t type; // send or receive
uint8_t attribute;
uint8_t numFields;
uint8_t fieldIdx;
uint8_t linkid;
uint16_t seq;
uint16_t src_address;
uint16_t dst_address;*/
state = PARSENSOR;
post CheckQueryType();
//getinfo->data = par;
//call Send.send[AM_GETINFO_MESSAGE](msg, sizeof(struct GetInfoMsg));
return SUCCESS;
}
async event result_t InternalTemperature.dataReady(uint16_t data) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
itemp = data;
//post putIntTemp();
state = INT_TEMP;
post CheckQueryType();
return SUCCESS;
}
async event result_t InternalVoltage.dataReady(uint16_t data) {
//struct QueryMsg *query = (struct QueryMsg *) msg->data;
ivolt = data;
state = INT_VOLT;
post CheckQueryType();
//post putIntVoltage();
return SUCCESS;
}
#endif
/*------------------------------- Simulation Results ---------------------------*/
#ifndef TELOS_PLATFORM
task void SimDataReady() {
dbg(DBG_USR1, "Simulate Data state=%d\n",state);
switch(state) {
case HUMIDITY:
dbg(DBG_USR1, "Simulate HUMIDITY %d\n", actionIndex);
humidity = 10000;
//post putHumidity();
break;
case TEMPERATURE:
dbg(DBG_USR1, "Simulate TEMPERATURE %d\n", actionIndex);
temperature = 2000;
//post putTemperature();
break;
case TSRSENSOR:
dbg(DBG_USR1, "Simulate TSRSENSOR %d\n", actionIndex);
tsr = 3000;
//post putTSR();
break;
case PARSENSOR:
dbg(DBG_USR1, "Simulate PARSENSOR %d\n", actionIndex);
par = 4000;
//post putPAR();
break;
case INT_TEMP:
dbg(DBG_USR1, "Simulate INT_TEMP %d\n", actionIndex);
itemp = 5000;
//post putIntTemp();
break;
case INT_VOLT:
dbg(DBG_USR1, "Simulate INT_VOLT %d\n", actionIndex);
ivolt = 5500;
//post putIntVoltage();
break;
}
post CheckQueryType();
}
#endif
#if 0
void CheckCounter() {
dbg(DBG_USR1, "CheckCounter actionIndex=%d numF=%d\n", actionIndex,rtp->numFields);
actionIndex++;
if (actionIndex >= rtp->numFields) {
rtp->qid = (uint8_t)numSamples;
dbg(DBG_USR1, "QID = %d\n", numSamples);
// send results back to UQP
signal RequestUpdate.receiveTuple(rtp);
actionIndex = 0;
numSamples--;
}
state = query->fields[actionIndex];
if (numSamples > 0) {
if (actionIndex == 0) {
dbg(DBG_USR1, "***start next interval\n");
call Timer.start(TIMER_ONE_SHOT, timeInterval);
}
else {
dbg(DBG_USR1, "---go to next attribute\n");
call Timer.start(TIMER_ONE_SHOT, OSCOPE_DELAY);
}
}
}
#endif
/*------------------------------- Result Tuple ---------------------------------*/
/*------------------------------- ULLA Storage ---------------------------------*/
#ifdef HISTORICAL_STORAGE
event result_t WriteToStorage.writeDone(uint8_t *data, uint32_t bytes, result_t ok) {
dbg(DBG_USR1,"WriteToStorage write done\n");
return SUCCESS;
}
#endif
} // end of implementation
--- NEW FILE: StorageIf.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* Interface for ULLA Storage
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes ulla;
includes msg_type;
includes UllaStorage;
interface StorageIf {
/*
* Read an attribute of ullaLink class from the storage.
*/
command result_t readAttributeFromUllaLink(AttrDescr_t *attrDescr, ullaLinkHorizontalTuple *horizontal_tuple, uint8_t *attr_length, uint8_t *tuple_length);
/*
* Read an attribute of ullaLink class from the storage.
*/
command result_t readAttributeFromElse(AttrDescr_t *attrDescr, elseHorizontalTuple *horizontal_tuple, uint8_t *attr_length, uint8_t *tuple_length);
/*
* Read an attribute from the storage.
*/
command result_t readAttribute(uint16_t linkid, uint8_t attribute, void *data, uint8_t *length);
/*
* Update an attribute from the storage.
*/
//command result_t updateAttribute(uint16_t linkid, uint8_t attribute, void *data, uint8_t *length);
command result_t updateAttribute(AttrDescr_t *attrDescr);
/*
* Update an attribute from the storage.
*/
command result_t updateMessage(TOS_Msg *update);
/*
* Read available links which are present in the storage.
* @return numLinks: number of available links in the storage.
* @return linkHead: head pointer to links.
*/
command result_t readAvailableLinks(uint8_t *numLinks, uint8_t *linkHead);
/*
* Add a new link to the storage.
*/
command result_t addLink(uint8_t linkid);
/*
* Remove a link from the storage.
*/
command result_t removeLink(uint8_t linkid);
/*
* Check whether there is still an available link in the storage.
* FIXME: should check whether there is a next link (instead of returning 0)
*/
command result_t hasNextLink();
/*
* Fetch the next link in the storage if present.
*/
command uint8_t getLink();
}
--- NEW FILE: TestLinkUser.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Interface for TestLinkUserM.nc
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UllaQuery;
interface TestLinkUser {
command result_t putQuery(QueryMsgNewPtr qp, uint8_t msg_idx);
event result_t queryDone(QueryMsgNewPtr qp);
command result_t putCommand(CommandMsgPtr cp);
event result_t commandDone(CommandMsgPtr cp);
}
--- NEW FILE: Transceiver.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* Interface for Network Communication
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UllaQuery;
interface Transceiver {
/**
* Broadcast a query message containing part of a query to the neighbors
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendQuery(TOS_MsgPtr msg);
/**
* Signalled when a query message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendQueryDone(TOS_MsgPtr msg, result_t rs);
/**
* Broadcast a data message to the neighbors to reach the root node
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendData(TOS_MsgPtr msg);
/**
* Signalled when a data message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendDataDone(TOS_MsgPtr msg, result_t rs);
/**
* Broadcast a command messageto the neighbors
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendCommand(TOS_MsgPtr msg);
/**
* Signalled when a command message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendCommandDone(TOS_MsgPtr msg, result_t rs);
/**
* Broadcast a debug message to the neighbors
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendDebug(TOS_MsgPtr msg);
/**
* Signalled when a debug message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendDebugDone(TOS_MsgPtr msg, result_t rs);
/**
* Broadcast a result message to the neighbors
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendResult(TOS_MsgPtr msg);
/**
* Signalled when a result message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendResultDone(TOS_MsgPtr msg, result_t rs);
/**
* Broadcast a multihop message to the neighbors
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendMHop(TOS_MsgPtr msg);
/**
* Signalled when a multihop message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendMHopDone(TOS_MsgPtr msg, result_t rs);
/**
* Broadcast a multihop debug message to the neighbors
* @param msg The message to send
* @return errorSendFailed if message failed to transmit
**/
command UllaError sendMHopDebug(TOS_MsgPtr msg);
/**
* Signalled when a multihop debug message has been sent
* @param msg The sent message
* @param success SUCCESS if the message sent successfully, FAIL otherwise
**/
event result_t sendMHopDebugDone(TOS_MsgPtr msg, result_t rs);
/**
* Signalled when receive a query from the radio
* @param msg The received query message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveQuery(TOS_MsgPtr msg);
/**
* Signalled when receive a data from the radio
* @param msg The received data message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveData(TOS_MsgPtr msg);
/**
* Signalled when receive a command from the radio
* @param msg The received command message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveCommand(TOS_MsgPtr msg);
/**
* Signalled when receive a debug message from the radio
* @param msg The received debug message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveDebug(TOS_MsgPtr msg);
/**
* Signalled when receive a result message from the radio
* @param msg The received result message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveResult(TOS_MsgPtr msg);
/**
* Signalled when receive a multihop message from the radio
* @param msg The received result message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveMHop(TOS_MsgPtr msg);
/**
* Signalled when receive a multihop debug message from the radio
* @param msg The received result message.
* @return TOS_MsgPtr
**/
event TOS_MsgPtr receiveMHopDebug(TOS_MsgPtr msg);
}
--- NEW FILE: TransceiverM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* Implementation for Transceiver interface
* Message queue is inspired by TOSBase
*
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
#define RETRY_CNT 1
#define BUFFER_RX_LEN 10
#define ID_QUEUE_SIZE 20
includes UllaQuery;
includes MultiHop;
//includes AM;
includes AMTypes;
includes UQLCmdMsg;
includes hardware;
module TransceiverM {
provides {
interface StdControl;
///interface Transceiver;
interface Send as SendInf[uint8_t id];
///interface Receive as ReceiveInf[uint8_t id];
}
uses {
//interface CommControl;
interface StdControl as CommStdControl;
interface GetInfoIf as GetLinkInfo;
//interface GetInfoIf as GetSensorInfo;
//interface StdControl as SubControl;
interface ReceivePacket[uint8_t id];
interface SendMsg[uint8_t id];
interface ReceiveMsg[uint8_t id];
////interface Send as MultihopSend;
interface Leds;
interface Random;
#if (defined(TELOS_PLATFORM) || defined(SIM_TELOS_PLATFORM) || defined(MICAZ_PLATFORM)) && defined(ENABLE_ACK)
interface MacControl;
#endif
interface LinkEstimation;
}
}
implementation {
bool radioIsBusy, uartIsBusy;
bool isGateway;
uint16_t gwNode; // gateway node address
TOS_Msg buf;
TOS_Msg fwdBuf;
TOS_MsgPtr msg;
int8_t retryCnt;
TOS_Msg rxQueueBuffer[BUFFER_RX_LEN];
uint8_t bufIn, bufOut, bufCount;
bool ullaBusy;
/* functions */
bool checkGateway(TOS_MsgPtr rmsg);
uint32_t buf_id[ID_QUEUE_SIZE];
bool field_id[ID_QUEUE_SIZE];
bool cond_id[ID_QUEUE_SIZE];
uint8_t enqueue;
bool gfSendBusy;
ResultTuple resultTuple;
ResultTuple *pResult;
bool notSeenPacketBefore(uint32_t id, uint8_t type);
command result_t StdControl.init() {
atomic {
radioIsBusy = FALSE;
uartIsBusy = FALSE;
isGateway = FALSE;
gwNode = 0xFFFF;
msg = &buf;
retryCnt = RETRY_CNT;
bufCount = bufIn = bufOut = 0;
ullaBusy = FALSE;
enqueue = 0;
pResult = &resultTuple;
gfSendBusy = FALSE;
}
//call SubControl.init();
call Leds.init();
call Random.init();
return (call CommStdControl.init());
}
command result_t StdControl.start() {
//call CommControl.setPromiscuous(TRUE);
//call SubControl.start();
call CommStdControl.start();
#if (defined(TELOS_PLATFORM) || defined(SIM_TELOS_PLATFORM) || defined(MICAZ_PLATFORM)) && defined(ENABLE_ACK)
call MacControl.enableAck();
#endif
return (SUCCESS);
}
command result_t StdControl.stop() {
//call SubControl.stop();
return (call CommStdControl.stop());
}
/*-------------------------------- GetInfo ------------------------------------*/
event result_t GetLinkInfo.getAttributeDone(TOS_Msg *tmsg) {
struct GetInfoMsg *getinfo = (struct GetInfoMsg *) tmsg->data;
memcpy(&buf, tmsg, sizeof(TOS_Msg));
atomic retryCnt = RETRY_CNT;
dbg(DBG_USR1, "TransceiverM: GetLinkInfo.getAttributeDone\n");
//if (call SendResultGetInfoMsg.send(getinfo->src_address, sizeof(struct GetInfoMsg), &buf) == SUCCESS )
// FIXME: send a blank message
///if (call SendResultGetInfoMsg.send(0, sizeof(struct GetInfoMsg), &buf) == SUCCESS )
if (call SendMsg.send[AM_RESULT_GETINFO_MESSAGE](0, sizeof(struct GetInfoMsg), &buf) == SUCCESS )
{
dbg(DBG_USR1, "TransceiverM: GetLinkInfo: SendResultGetInfoMsg\n");
//call Leds.redToggle();
}
/* if (getinfo->type == 2) {
dbg(DBG_USR1,"TransceiverM: SendInf.sendGetInfoMsg LinkInfo\n");
call SendResultGetInfoMsg.send(getinfo->src_address, sizeof(struct GetInfoMsg), &buf);
}
else {
dbg(DBG_USR1,"TransceiverM: SendInf.sendGetInfoMsg BCAST\n");
call SendResultGetInfoMsg.send(TOS_BCAST_ADDR, sizeof(struct GetInfoMsg), &buf);
}*/
return SUCCESS;
}
/*------------------------------ Send Receive ---------------------------------*/
command result_t SendInf.send[uint8_t id](TOS_MsgPtr rmsg, uint16_t length) {
//uint16_t newLength = offsetof(TOS_Msg,data) + length;
struct GetInfoMsg *getinfo = (struct GetInfoMsg *)rmsg->data;
dbg(DBG_USR1,"TransceiverM: SendInf.send %d\n", id);
atomic retryCnt = RETRY_CNT;
if (!radioIsBusy) {
radioIsBusy = TRUE;
//call SendMsg.send[id](rmsg, length);
//call SendMsg.send[id](TOS_BCAST_ADDR, newLength, rmsg);
//call SendQueryMsg.send(TOS_BCAST_ADDR, length, rmsg);
switch (id) {
case AM_QUERY:
//call SendQueryMsg.send(TOS_BCAST_ADDR, sizeof(struct QueryMsg), rmsg);
///call SendQueryMsg.send(TOS_BCAST_ADDR, length, rmsg);
///call SendMsg.send[AM_QUERY](TOS_BCAST_ADDR, length, rmsg);
call SendMsg.send[AM_QUERY](TOS_BCAST_ADDR, length, rmsg);
break;
case AM_MULTIHOPMSG:
//call SendQueryMsg.send(TOS_BCAST_ADDR, sizeof(struct QueryMsg), rmsg);
////call SendMHopMsg.send(TOS_BCAST_ADDR, length, rmsg);
////call SendMsg.send[AM_MULTIHOPMSG](TOS_BCAST_ADDR, length, rmsg);
call SendMsg.send[AM_MULTIHOPMSG](TOS_BCAST_ADDR, length, rmsg);
break;
case 17: // Surge message
dbg(DBG_USR1,"TransceiverM: SendInf.sendSurgeMsg addr %02X\n",rmsg->addr);
///call SendSurgeMsg.send(rmsg->addr, length, rmsg);
///call SendMsg.send[17](rmsg->addr, length, rmsg);
call SendMsg.send[17](rmsg->addr, length, rmsg);
break;
case 99: // Surge message
dbg(DBG_USR1,"TransceiverM: SendInf.sendSurgeMsg addr %02X\n",rmsg->addr);
///call SendSurgeMsg.send(rmsg->addr, length, rmsg);
///call SendMsg.send[17](rmsg->addr, length, rmsg);
call SendMsg.send[99](rmsg->addr, length, rmsg);
break;
case AM_SCAN_LINKS:
dbg(DBG_USR1,"TransceiverM: SendInf.sendScanLinkMsg\n");
///call SendScanLinksMsg.send(TOS_BCAST_ADDR, length, rmsg);
////call SendMsg.send[AM_SCAN_LINKS](TOS_BCAST_ADDR, length, rmsg);
call SendMsg.send[AM_SCAN_LINKS](TOS_BCAST_ADDR, length, rmsg);
break;
case AM_GETINFO_MESSAGE:
//call Leds.redToggle();
if (getinfo->type == 2) {
dbg(DBG_USR1,"TransceiverM: SendInf.sendGetInfoMsg addr %02X\n",rmsg->addr);
///call SendGetInfoMsg.send(getinfo->src_address, length, rmsg);
////call SendMsg.send[AM_GETINFO_MESSAGE](getinfo->src_address, length, rmsg);
call SendMsg.send[AM_GETINFO_MESSAGE](getinfo->src_address, length, rmsg);
}
else {
dbg(DBG_USR1,"TransceiverM: SendInf.sendGetInfoMsg BCAST\n");
///call SendGetInfoMsg.send(TOS_BCAST_ADDR, length, rmsg);
////call SendMsg.send[AM_GETINFO_MESSAGE](TOS_BCAST_ADDR, length, rmsg);
call SendMsg.send[AM_GETINFO_MESSAGE](TOS_BCAST_ADDR, length, rmsg);
}
break;
case AM_RESULT_GETINFO_MESSAGE:
//call Leds.redToggle();
dbg(DBG_USR1,"TransceiverM: SendInf.sendGetInfoMsg addr %02X\n",rmsg->addr);
///call SendMsg.send[AM_RESULT_GETINFO_MESSAGE](getinfo->src_address, length, rmsg);
call SendMsg.send[AM_RESULT_GETINFO_MESSAGE](getinfo->src_address, length, rmsg);
break;
case AM_QUERY_REPLY:
{
uint16_t len;
ResultTuple *tempResult = (ResultTuple *)rmsg->data;
//call Leds.redToggle();
//call Leds.yellowToggle();
////call SendResultMsg.send(TOS_BCAST_ADDR, length, rmsg);
TOSH_uwait((call Random.rand() & 0x7530) + 1);
call SendMsg.send[AM_QUERY_REPLY](0, length, rmsg);
#if 0
//if ((pResult = (ResultTuple *)call MultihopSend.getBuffer(msg, &len))) {
//memcpy(pResult, &(rmsg->data), sizeof(ResultTuple));
///call MultihopSend.send(rmsg, length);
if ((pResult = (ResultTuple *)call MultihopSend.getBuffer(msg, &len))!= NULL) {
if (!gfSendBusy) {
if ((call MultihopSend.send(msg,length)) != SUCCESS)
atomic gfSendBusy = FALSE;
}
}
#endif
}
break;
case AM_FIXEDATTR:
dbg(DBG_USR1, "TransceiverM: SendInf.sendFixed %02X\n",rmsg->addr);
//call Leds.yellowToggle();
call Leds.greenToggle();
////call SendMsg.send[AM_FIXEDATTR](TOS_BCAST_ADDR, length, rmsg);
call SendMsg.send[AM_FIXEDATTR](TOS_BCAST_ADDR, length, rmsg);
dbg(DBG_USR1, "TransceiverM: SendInf.sendFixed\n");
}
}
else {
dbg(DBG_USR1,"Radio busy\n");
}
return SUCCESS;
}
#if 0
event result_t MultihopSend.sendDone(TOS_MsgPtr smsg, result_t success)
{
///call Leds.redToggle();
gfSendBusy = FALSE;
return SUCCESS;
}
#endif
task void SignalReceiveTask()
{
if (bufCount == 0)
{
dbg(DBG_USR1, "bufCount = 0\n");
ullaBusy = FALSE;
}
else
{
if (call ReceivePacket.receive[rxQueueBuffer[bufOut].type](&rxQueueBuffer[bufOut]) == SUCCESS)
{
dbg(DBG_USR1,"Transceiver: SignalReceiveTask SUCCESS\n");
}
else
{
dbg(DBG_USR1,"Transceiver: SignalReceiveTask FAIL\n");
post SignalReceiveTask();
}
}
}
task void fwdQueryTask() {
call SendMsg.send[AM_QUERY](TOS_BCAST_ADDR, sizeof(QueryMsg), &fwdBuf);
}
event TOS_MsgPtr ReceiveMsg.receive[uint8_t id](TOS_MsgPtr rmsg) {
dbg(DBG_USR1, "receive %d message\n", id);
atomic isGateway = checkGateway(rmsg);
//call Leds.redToggle();
if (!rmsg->crc)
return rmsg;
#if 1
switch (id) {
#if 0 //doesn't work correctly yet
case AM_QUERY:
//call Leds.redToggle();
{
QueryMsgPtr query = (QueryMsgPtr)rmsg->data;
if ((TOS_LOCAL_ADDRESS != 0) && (notSeenPacketBefore(query->ruId,query->dataType)))
{
if (bufCount < BUFFER_RX_LEN)
{
memcpy(&rxQueueBuffer[bufIn], rmsg, sizeof(TOS_Msg));
bufCount++;
if( ++bufIn >= BUFFER_RX_LEN ) bufIn = 0;
if (!ullaBusy)
{
if (post SignalReceiveTask())
{
ullaBusy = TRUE;
}
}
memcpy(&fwdBuf, rmsg, sizeof(struct TOS_Msg));
//post fwdQueryTask();
}
}
}
break;
#endif
case AM_SCAN_LINKS:
{
struct ScanLinkMsg *scanlink;
memcpy(&buf, rmsg, sizeof(struct TOS_Msg));
scanlink = (struct ScanLinkMsg *) msg->data;
dbg(DBG_USR1, "TransceiverM: ReceiveScanLinkMsg %d\n",scanlink->msg_type);
if (scanlink->msg_type == SCAN_FORWARD_MSG) {
scanlink->msg_type = SCAN_REPLY_MSG;
scanlink->linkid = TOS_LOCAL_ADDRESS;
dbg(DBG_USR1, "TransceiverM: ReceiveScanLinkMsg\n");
call SendMsg.send[AM_SCAN_LINKS](scanlink->parent, sizeof(struct ScanLinkMsg), msg);
}
else if (scanlink->msg_type == SCAN_REPLY_MSG) {
dbg(DBG_USR1, "TransceiverM: Receive reply ScanLinkMsg\n");
// signal to first to ULLA Core and then call ProcessData in UCP
// and update the storage FIXME
///signal ReceiveInf.receive[AM_SCAN_LINKS](&buf, buf.data, buf.length);
call ReceivePacket.receive[AM_SCAN_LINKS](&buf);
}
}
break;
case AM_GETINFO_MESSAGE:
{
struct GetInfoMsg *getinfo;
memcpy(&buf, rmsg, sizeof(struct TOS_Msg));
getinfo = (struct GetInfoMsg *)buf.data;
TOSH_uwait((call Random.rand() & 0x2710) + 1);
dbg(DBG_USR1, "TransceiverM: ReceiveGetInfoMsg att %d\n",getinfo->attribute);
//if (getinfo->type == 1) {
getinfo->dst_address = TOS_LOCAL_ADDRESS;
getinfo->linkid = TOS_LOCAL_ADDRESS;
getinfo->type = 2;
if (getinfo->attribute <= 5) {
//call GetSensorInfo.getAttribute(&buf);
}
else {
call GetLinkInfo.getAttribute(&buf);
}
/*}
else {
//call Leds.greenToggle();
//call SendGetInfoMsg.send(TOS_UART_ADDR, sizeof(struct GetInfoMsg), rmsg);
dbg(DBG_USR1,"Undefined message type\n");
}*/
}
break;
case AM_FIXEDATTR:
memcpy(&buf, rmsg, sizeof(struct TOS_Msg));
{
FixedAttrMsg *fixedMsg = (FixedAttrMsg *)msg->data;
FixedAttrMsg *fixedTmp = (FixedAttrMsg *)&rxQueueBuffer[bufIn].data;
if(fixedMsg->type == 0) { // request
dbg(DBG_USR1, "TransceiverM: AM_FIXEDATTR request msg\n");
fixedMsg->rssi = rmsg->strength;
fixedMsg->node_id = TOS_LOCAL_ADDRESS;
fixedMsg->type = 1;
call Leds.greenToggle();
TOSH_uwait((call Random.rand() & 0x7530) + 1);
call SendMsg.send[AM_FIXEDATTR](fixedMsg->source, sizeof(FixedAttrMsg),msg);
if (bufCount < BUFFER_RX_LEN)
{
memcpy(&rxQueueBuffer[bufIn], rmsg, sizeof(TOS_Msg));
fixedTmp->node_id = fixedMsg->source;
bufCount++;
call Leds.greenToggle();
if( ++bufIn >= BUFFER_RX_LEN ) bufIn = 0;
if (!ullaBusy)
{
if (post SignalReceiveTask())
{
ullaBusy = TRUE;
}
}
}
}
else if (fixedMsg->type == 1) {// reply
dbg(DBG_USR1,"TransceiverM: AM_FIXEDATTR reply msg\n");
fixedMsg->rssi = rmsg->strength;
fixedMsg->node_id = TOS_LOCAL_ADDRESS;
fixedMsg->type = 1;
if (bufCount < BUFFER_RX_LEN)
{
memcpy(&rxQueueBuffer[bufIn], rmsg, sizeof(TOS_Msg));
bufCount++;
call Leds.greenToggle();
if( ++bufIn >= BUFFER_RX_LEN ) bufIn = 0;
if (!ullaBusy)
{
if (post SignalReceiveTask())
{
ullaBusy = TRUE;
}
}
}
}
else {
dbg(DBG_USR1,"TransceiverM: AM_FIXEDATTR unknown msg\n");
}
}
break;
default:
//call Leds.redToggle();
if (bufCount < BUFFER_RX_LEN)
{
memcpy(&rxQueueBuffer[bufIn], rmsg, sizeof(TOS_Msg));
bufCount++;
if( ++bufIn >= BUFFER_RX_LEN ) bufIn = 0;
if (!ullaBusy)
{
if (post SignalReceiveTask())
{
ullaBusy = TRUE;
}
}
}
break;
}
#endif
return rmsg;
}
event result_t ReceivePacket.receiveDone[uint8_t id](TOS_MsgPtr rmsg)
{
bufCount--;
dbg(DBG_USR1, "Transceiver: ReceivePacket.receiveDone %d bufCount %d\n", id, bufCount);
if( ++bufOut >= BUFFER_RX_LEN ) bufOut = 0;
post SignalReceiveTask();
return SUCCESS;
}
task void sendResultGetInfoMsg()
{
struct GetInfoMsg *getinfo = (struct GetInfoMsg *) buf.data;
call SendMsg.send[AM_RESULT_GETINFO_MESSAGE](getinfo->src_address, sizeof(struct GetInfoMsg), &buf);
}
task void ResendQueryReply() {
if (radioIsBusy == FALSE) {
radioIsBusy = TRUE;
TOSH_uwait((call Random.rand() & 0x7530) + 1);
call SendMsg.send[AM_QUERY_REPLY](0, sizeof(ResultTuple), &buf);
}
else {
post ResendQueryReply();
}
}
event result_t SendMsg.sendDone[uint8_t id](TOS_MsgPtr sent, result_t success) {
radioIsBusy = FALSE;
dbg(DBG_USR1, "TransceiverM: SendMsg.sendDone[id=%d]\n",id);
switch (id) {
case AM_RESULT_GETINFO_MESSAGE:
#ifdef ENABLE_ACK
if ((!sent->ack) && retryCnt-- > 0)
{
call Leds.redToggle();
retryCnt--;
TOSH_uwait((call Random.rand() & 0x2710) + 1);
dbg(DBG_USR1, "TransceiverM: resend ResultGetInfoMsg\n");
post sendResultGetInfoMsg();
}
else if (retryCnt <= 0)
{
//call Leds.yellowToggle();
retryCnt = RETRY_CNT;
}//*/
#endif // ENABLE_ACK
break;
case AM_QUERY_REPLY:
#ifdef ENABLE_ACK
if ((!sent->ack) && retryCnt-- > 0)
{
call Leds.redToggle();
memcpy(&buf, sent, sizeof(TOS_Msg));
retryCnt--;
dbg(DBG_USR1, "TransceiverM: resend ResultGetInfoMsg\n");
post ResendQueryReply();
}
else if (retryCnt <= 0)
{
//call Leds.yellowToggle();
retryCnt = RETRY_CNT;
}//*/
#endif // ENABLE_ACK
break;
}
///call Leds.redToggle();
signal SendInf.sendDone[id](sent, success);
return SUCCESS;
}
command void *SendInf.getBuffer[uint8_t id](TOS_MsgPtr pMsg, uint16_t* length) {
//TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)pMsg->data;
//*length = TOSH_DATA_LENGTH - offsetof(TOS_MHopMsg,data);
//return (&pMHMsg->data[0]);
return (&pMsg->data[0]);
}
bool checkGateway(TOS_MsgPtr rmsg) {
struct QueryMsg *qmsg = (struct QueryMsg *)rmsg->data;
///if (qmsg->prevNode == TOS_UART_ADDR) {
// this is the gateway node
atomic {
gwNode = TOS_LOCAL_ADDRESS;
isGateway = TRUE;
}
return TRUE;
///}
///else return FALSE;
}
bool notSeenPacketBefore(uint32_t id, uint8_t type) {
uint8_t i;
for (i=0;i<ID_QUEUE_SIZE;i++)
{
if (buf_id[i] == id)
{
if ((field_id[i] && (type == FIELD_MSG)) || (cond_id[i] &&(type == COND_MSG))) {
if (type == FIELD_MSG)
field_id[i]=TRUE;
else if (type == COND_MSG)
cond_id[i]=TRUE;
return FALSE;
}
}
}
if (type == FIELD_MSG)
field_id[enqueue]=TRUE;
else if (type == COND_MSG)
cond_id[enqueue]=TRUE;
buf_id[enqueue]=id;
enqueue ++;
enqueue %= ID_QUEUE_SIZE;
return TRUE;
}
}
--- NEW FILE: ULLAStorageC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Ulla Storage - maintains a cached version class definitions
* (representing link definitions) as well as instances of these
* classes (representing discovered links). Cashed versions of
* known links are kept in the ULLA storage to enable applications
* to quickly access the information regarding existing links,
* without necessarily to have to talk to the underlying driver.
<p>
* The assumption is that most of the time the information returned
* for a query can be slightly out of date. For example, an application
* requesting the bandwidth of a link does not need to receive the
* bandwidth exactly at the instant of the query but can probably be
* ok with a 2-second old information. Also, timestamps are associated
* with all attributes of cached classes in order to implement a "lazy"
* update strategy.
<p>
<p>
* Technical Details - ByteEEPROM takes a buffer of arbitrary length
* and uses it to read/write data to/from a flash. This buffer is
* provided by the application, it depends on the user how much RAM
* will be allocated for flash operations.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
//includes UllaStorage;
//includes Storage;
configuration ULLAStorageC {
provides {
interface StdControl;
interface StorageIf;
//interface ReadFromStorage;
//interface WriteToStorage;
}
}
implementation {
components
//Main
ULLAStorageM
//, TinyAlloc
, UllaAllocC
, LedsC
, TimerC
;
//Main.StdControl -> ULLAStorageM;
StdControl = ULLAStorageM;
StorageIf = ULLAStorageM;
//ULLAStorageM.MemAlloc -> TinyAlloc;
ULLAStorageM.MemAlloc -> UllaAllocC.StorageAlloc;
ULLAStorageM.ValidityTimer -> TimerC.Timer[unique("Timer")];
ULLAStorageM.Leds -> LedsC;
}
--- NEW FILE: ULLAStorageM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
[...1290 lines suppressed...]
dbg(DBG_USR1,"MemAlloc.realloc complete\n");
return SUCCESS;
}
event result_t MemAlloc.compactComplete() {
dbg(DBG_USR1,"MemAlloc.compact complete\n");
return SUCCESS;
}
} // end implementation
--- NEW FILE: UQLCmdMsg.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* Ulla Query Language header file
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
enum {
AM_QUERYMSG = 8,
};
enum {
UNUSED = 0,
TEMPERATURE = 1,
TSRSENSOR = 2,
PARSENSOR = 3,
INT_TEMP = 4,
INT_VOLT = 5,
RF_POWER = 6,
LQI = 7,
RSSI = 8,
LED_ON = 10,
LED_OFF = 11,
LINK_ID = 12,
LP_ID = 13,
NETWORK_NAME = 14,
TYPE = 15,
FREQUENCY = 16,
STATE = 17,
RX_ENCRYPTION = 18,
TX_ENCRYPTION = 19,
MODE = 20,
SUPPORTEDCLASSES = 21,
HUMIDITY = 22,
ALL = 198,
NOT_DEFINED = 199,
};
enum {
LED_TOGGLE = 21,
LED_BLINK,
SLEEP_MODE,
SET_RFPOWER,
};
// UQLCmd message structure
typedef struct UQLCmdMsg {
int8_t seqno;
int8_t action;
uint16_t nodeID;
uint8_t hop_count;
uint16_t nsamples;
uint16_t interval;
} UQLCmdMsg;
--- NEW FILE: UcpIf.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @brief Modified version of ullalu.h to be used in TinyOS
* This file contains the interfaces to the ULLA Command Processing.
*
<p>
* @modified Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes Lu;
includes ulla;
includes msg_type;
interface UcpIf {
/**
* @ingroup ucp
* @brief Send synchronous commands to Link Provider through ULLA
* This method allows a linkUser to request a single command to be executed on a specific link. The command call
* is synchronous, i.e. the doCmd() function returns only on command completion.
*
* @param luId the identifier of the calling linkUser, as assigned by registerLu()
* @param cmddescr the command description
*
* @return ULLA_OK if the command has been succesfully executed.
*
*/
command uint8_t doCmd(LuId_t luId, CmdDescrPtr cmddescr);
event result_t doCmdDone(CmdDescrPtr cmddescr);
/**
*
* @ingroup ucp
* @brief Send asynchronous commands to Link Provider through ULLA.
* This method can be called by a linkUser to request a command to be executed asynchronously on a specific link.
* The command can be issued multiple times in a periodic fashion; the parameter rcdescr must be specified for this purpose.
* Periodic command remain in force until they expire or they are explicitly canceled through cancelCmd().
* Upon completion of each command execution, the callback specified within the rcdescr parameter is called.
*
* @param luId the identifier of the calling linkUser, as assigned by registerLu()
* @param cmddescr the command description
* @param rcdescr the asynchronous request parameters, containing the callback pointer and the command request count and period.
* @param cmdId the returned identifier for the current command request
*
* @return ULLA_OK if succesful,
* ULLA_OUT_OF_MEMORY_ERROR if the async command queue is full,
* ULLA_SYNTAX_ERROR if the command string is incorrect,
* ULLA_UNSUPPORTED_FEATURE_ERROR if the requested command is not supported by the linkProvider.
*
*
*/
command uint8_t requestCmd(LuId_t luId, CmdDescr_t* cmddescr, RcDescr_t *rcdescr, CmdId_t *cmdId);
/**
* @ingroup ucp
* @brief Cancel a previously requested asynchronous command.
*
* The cancelCmd() method allows an application to cancel an asynchronous command call
* previously requested with requestCmd().
*
* @param luId the identifier of the calling linkUser, as assigned by registerLu()
* @param cmdId the numeric identifier of the command to be canceled, as returned by requestCmd()
*
* @return ULLA_OK if succesful,
* ULLA_INVALID_PARAMETER_ERROR if the command with the requested cmdId does not exist, has already been canceled or
* has already expired.
*/
command uint8_t cancelCmd(LuId_t luId, CmdId_t cmdId);
/**
* @ingroup ucp
* @brief
*
*
* @param luId
* @param paramDescr the descriptor of the parameter to be set
*
* @return
*/
command uint8_t setParam(LuId_t luId, AttrDescr_t paramDescr);
}
--- NEW FILE: UllaAllocC.nc ---
// $Id: UllaAllocC.nc,v 1.1 2008/01/16 21:51:48 krerkrai Exp $
/* tab:4
* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* Authors: Sam Madden, Phil Levis
* Modification History: 10/6/2002 SRM -- added freeBytes
*
*/
// slight modification for ULLA
configuration UllaAllocC {
provides {
interface StdControl;
//interface MemAlloc[uint8_t id];
interface MemAlloc as StorageAlloc;
interface MemAlloc as QauAlloc;
// command void allocDebug();
}
}
implementation {
components
UllaAllocM
;
StdControl = UllaAllocM;
//MemAlloc = UllaAllocM;
StorageAlloc = UllaAllocM.MemAlloc[1];
QauAlloc = UllaAllocM.MemAlloc[2];
}
--- NEW FILE: UllaAllocM.nc ---
/* tab:4
* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* Authors: Sam Madden, Phil Levis
* Modification History: 10/6/2002 SRM -- added freeBytes
*
*/
/*
* TINY_ALLOC is a simple, handle-based compacting memory manager. It
* allocates bytes from a fixed size frame and returns handles
* (pointers to pointers) into that frame. Because it components handles,
* TINY_ALLOC can move memory around in the frame without changing all
* the external references. Moving memory is a good thing because it
* allows frame compacting and tends to reduce wasted space. Handles
* can be accessed via a double dereference (**), and a single
* dereference can be used wherever a pointer is needed, but if a
* single dereference is to be stored, the handle must be locked first
* as otherwise TINY_ALLOC may move the handle and make the reference
* invalid.
*
* Example:
*
* Handle foo; // A handle to 20 allocated bytes
* (*foo)[12] // The 12th byte of foo
* **foo // The 0th byte of foo
*
* Like all good TinyOS components, TINY_ALLOC is split phase with
* respect to allocation and compaction. Allocation/reallocation
* completion is signalled via a TINY_ALLOC_COMPLETE signal and
* compaction via a TINY_ALLOC_COMPACT_COMPLETE signal. All other
* operations complete and return in a single phase. Note that
* compaction may be triggered automatically from allocation; in this
* case a COMPACT_COMPLETE event is not generated.
*
* Handles are laid out in the frame as follows:
*
* [LOCKED][SIZE][user data]
*
* Where:
* LOCKED : a single bit indicating if the handle is locked
* SIZE : 7 bits representing the size of the handle
* user data : user-requested number of bytes (**h) points to
* [user data], not [LOCKED].
*
* Calling TOS_COMMAND(TINY_ALLOC_SIZE(h)) returns the size of [user
* data] (note that the internal function size() returns the size of
* the entire handle, including the header byte.)
*
*/
/**
* @author Sam Madden
* @author Phil Levis
*/
// slight modification for ULLA
module UllaAllocM {
provides {
interface StdControl;
interface MemAlloc[uint8_t id];
command void allocDebug();
}
uses {
interface Leds;
}
}
implementation {
enum {
FRAME_SIZE = 1024,//256,
FREE_SIZE = FRAME_SIZE >> 3,
MAX_SIZE = 32765,
HEADER_SIZE = 2,
MAX_HANDLES = 20
};
uint8_t mFrame[FRAME_SIZE]; //the heap
uint8_t mFree[FREE_SIZE]; //free bit map
int8_t mAllocing; //are we allocating?
int8_t mCompacting; //are we compacting?
int16_t mSize; //how many bytes are we allocing?
int16_t mLast; //where were we in the last task invocation
Handle *mHandle; //handle we are allocating
int8_t **mTmpHandle; //temporary handle for realloc
Handle mOldHandle; //old user handle for realloc
int8_t *mHandles[MAX_HANDLES]; //handles we know about
int8_t mReallocing; //are we mReallocing
int8_t mCompacted; //already mCompacted this allocation
int8_t mNeedFree; //looking for free bits in current byte?
int16_t mContig; //mContig bytes seen so far
int16_t mStartByte; //start of free section (in bytes)
uint16_t mFreeBytes;
uint8_t gCurID;
/* DEBUGGING FIELDS */
// int8_t buf[512];
//int16_t cur;
//int16_t len;
void doAlloc(int16_t startByte, int16_t endByte);
void shiftUp(Handle handle, int bytes);
int16_t start_offset(int8_t *ptr);
void setFreeBits(int16_t startByte, int16_t endByte, int8_t on);
void remapAddr(int8_t *oldAddr, int8_t *newAddr);
int8_t isValid(Handle h);
int16_t getSize(int8_t *p);
int8_t isLocked(int8_t *ptr);
int8_t finish_realloc(Handle *handle, int8_t success);
Handle getH(int8_t *p);
int16_t getNewHandleIdx();
void markHandleFree(Handle hand);
static inline Handle ToHandle(int8_t* ptr) {return (Handle)(&ptr);}
static inline int8_t* deref(Handle h) {return (int8_t*)(*h);}
task void compactTask();
task void allocTask();
task void reallocDone();
command result_t MemAlloc.compact[uint8_t id]() {
gCurID = id;
if (!mCompacting && !mAllocing) {
post compactTask();
}
return SUCCESS;
}
command result_t StdControl.init() {
int16_t i;
mAllocing = 0;
mReallocing = 0;
for (i = 0; i < FREE_SIZE >> 4; i++) {
((int32_t *)mFree)[i] = 0;
}
for (i = 0; i < MAX_HANDLES; i++) {
mHandles[i] = 0;
}
mFreeBytes = FRAME_SIZE;
return SUCCESS;
}
command result_t StdControl.start() {
return SUCCESS;
}
command result_t StdControl.stop() {
return SUCCESS;
}
command result_t MemAlloc.allocate[uint8_t id](HandlePtr handlePtr, int16_t size) {
if (size > MAX_SIZE || mAllocing) {
return FAIL;
}
gCurID = id;
mAllocing = 1;
mSize = size + HEADER_SIZE; //need extra bytes for header info
mHandle = handlePtr;
mCompacted = 0;
mNeedFree = 0;
mContig = 0;
mLast = 0;
mStartByte = 0;
mFreeBytes -= mSize;
post allocTask();
return SUCCESS;
}
task void allocTask() {
int16_t endByte;
int16_t i, j;
i = mLast++;
if (i == FREE_SIZE) {
if (mCompacted) { //try to compact if can't allocate
//already mCompacted -- signal failure
mAllocing = 0;
if (mReallocing) {
finish_realloc(mHandle, 0);
}
else {
signal MemAlloc.allocComplete[gCurID](mHandle, FAIL);
}
}
else {
mCompacted = 1;
//CLR_RED_LED_PIN();
//try compacting
post compactTask();
}
return;
}
if (mNeedFree && mFree[i] != 0xFF) { //some free space
mStartByte = i << 3;
for (j = 0; j < 8; j++) {
if (mFree[i] & (1 << j)) {
if (mContig >= mSize) { //is enough free space
//alloc it and return
endByte = mStartByte + mSize;
doAlloc(mStartByte, endByte);
return;
}
else {
mStartByte += (mContig + 1);
mContig = 0;
}
}
else {
mContig++;
}
}
if (mContig >= mSize) {
endByte = mStartByte + mSize;
doAlloc(mStartByte,endByte);
//alloc it and return
return;
}
else {
//some free space at end of byte, but need more
mNeedFree = 0;
}
}
else if (mNeedFree == 0) { //mNeedFree sez there are free bits
//in the current byte, and we should scan to find them on
//the next pass
if (mFree[i] == 0) {
mContig += 8;
}
else {
for (j = 0; j < 8; j++) {
if ((mFree[i] & (1 << j)) == 0) {
mContig++;
}
else {
break;
}
}
}
if (mContig >= mSize) {
endByte = mStartByte + mSize;
doAlloc(mStartByte, endByte);
//alloc it and return
return;
}
else if (mFree[i] != 0) {
mContig = 0; //didn't find the needed amount of space
mNeedFree = 1;
mLast--; //retry this byte
}
}
post allocTask();
}
void doAlloc(int16_t startByte, int16_t endByte) {
int16_t newIdx = getNewHandleIdx();
if (newIdx == -1) {
mAllocing = 0;
signal MemAlloc.allocComplete[gCurID](mHandle, FAIL); //signal failure
return;
}
*(int16_t *)(&mFrame[startByte]) = (endByte - startByte) & 0x7FFF;
//WARNING -- not going through standard accessors
mHandles[newIdx] = (int8_t *)((&mFrame[startByte]) + HEADER_SIZE);
*mHandle = &mHandles[newIdx];
//mark bits
setFreeBits(startByte,endByte, 1);
mAllocing = 0;
if (mReallocing) {
finish_realloc(mHandle,1);
}
else {
signal MemAlloc.allocComplete[gCurID](mHandle, SUCCESS);
}
}
task void compactTask() {
int16_t i;
uint8_t c;
int8_t *p;
int8_t endFree = 0;
if (mCompacting == 0) {
mContig = 0;
mLast = 0;
mCompacting = 1;
mStartByte = 0;
}
c = mFree[mLast++];
if (mLast == FREE_SIZE)
goto done_compact;
//call Leds.yellowToggle();
//process: scan forward in free bitmap, looking for runs of free space
//at end of run, move bytes up
if (c == 0) { //byte not used at all
mContig += 8;
}
else {
if (c != 0xFF){ //byte not fully used
for (i = 0; i < 8; i++) {
if ((c & (1 << i)) == 0) {
mContig++;
endFree = 1; //endFree sez the last bit of this byte was free
}
else if (mContig == 0) { //bit not free, no compaction to do
mStartByte++;
endFree = 0;
}
else { //bit not free, but need to compact
endFree = 0;
break;
}
}
}
if (mContig > 0 && !endFree) { //need to compact?
p = (int8_t *)&(mFrame[mStartByte + mContig + HEADER_SIZE]); //get the handle
if (!isLocked(p)) {
Handle h = getH(p);
if (h == NULL) {
dbg(DBG_USR1, "BAD NEWS -- INVALID HANDLE START IN COMPACT.\n");
goto done_compact;
}
dbg(DBG_USR1,"compacting, from %d, %d bytes\n", mStartByte + mContig + HEADER_SIZE, mContig);
shiftUp((Handle)h, mContig);
mStartByte += (getSize(*h) >> 3) << 3;
} else {
//printf ("SOMETHING LOCKED, at %d", VAR(startByte) +
//VAR(mContig) + 1);
mStartByte += ((getSize(p) + mContig) >> 3) << 3;
//make sure we don't retry the same byte again if this
//handle is locked note that this can lead to holes of fewer
//than 8 bytes at the end of allocations which occupy fewer
//than 8 bytes
if (mStartByte >> 3 == mLast -1) {
mStartByte += 8;
}
}
mLast = (mStartByte >> 3);
mStartByte = mLast << 3;
//printf("\nlast = %d, startByte = %d\n", mLast, mStartByte);
mContig = 0;
}
else if (!endFree) { //not compacting, move to next byte
mStartByte += 8;
mContig = 0;
}
}
done_compact:
//scanned the whole thing
if (mLast >= FREE_SIZE) {
mCompacting = 0;
mLast = 0;
mContig = 0;
mNeedFree = 0;
mStartByte = 0;
if (mAllocing) {
post allocTask();
}
else {
signal MemAlloc.compactComplete[gCurID]();
}
}
else {
//call Leds.redToggle();
post compactTask(); //keep compacting
}
}
void shiftUp(Handle hand, int bytes) {
int16_t start = start_offset(deref(hand));
int16_t end = start + getSize(deref(hand));
int16_t newstart;
int16_t newend;
int8_t *p = deref(hand) - HEADER_SIZE;
int8_t *startp= deref(hand) - HEADER_SIZE - bytes, *q;
int cnt = getSize(deref(hand));
q = startp;
while(cnt--) {
*q++ = *p++;
}
remapAddr(*hand, startp + HEADER_SIZE);
*hand = startp + HEADER_SIZE;
newstart = start_offset(deref(hand));
newend = newstart + getSize(deref(hand));
//now, have to offset free bytes
//do it by unsetting old bits, setting new ones
setFreeBits(start,end,0);
setFreeBits(newstart,newend,1);
}
command int16_t MemAlloc.free[uint8_t id](Handle hand) {
int8_t* startPtr;
int16_t start;
int16_t end;
if (mAllocing) return FAIL; //don't do this if we're allocating right now
if (!isValid(hand)) return FAIL;
// 16 bit architecture (e.g. mote)
if (sizeof(int8_t*) == sizeof(int16_t)) {
startPtr = (deref(hand) - HEADER_SIZE);
start = (int16_t)(startPtr - (int8_t*)&mFrame);
end = start + getSize(deref(hand));
}
// 32-bit architecture (e.g. x86 simulator)
else if (sizeof(int8_t*) == sizeof(int32_t)) {
startPtr = (deref(hand) - HEADER_SIZE);
start = (int16_t)(startPtr - (int8_t*)&mFrame);
end = start + getSize(deref(hand));
//printf ("freeing from %d to %d", (int16_t)start, (int16_t)end);
}
else {
return FAIL;
}
//track free bytes
mFreeBytes += getSize(deref(hand));
setFreeBits(start,end,0);
markHandleFree(hand);
return (end - start);
}
command result_t MemAlloc.reallocate[uint8_t id](Handle hand, int16_t newSize) {
int16_t neededBytes = newSize + HEADER_SIZE;
int8_t *p = *hand;
if (mAllocing) return FAIL; //don't do this if we're allocing
if (neededBytes > MAX_SIZE) return FAIL; //error!
mOldHandle = hand;
if (neededBytes == getSize(*hand)) {
post reallocDone();
return SUCCESS; //already the right size!
}
//adjust our counter of the number of free bytes
if (neededBytes < getSize(*hand)) {
int16_t oldSize = getSize(*hand);
//change the size of the handle
((int16_t *)(p - HEADER_SIZE))[0] = neededBytes & 0x7FFF;
//unset the used bits at the end
setFreeBits(start_offset(p) + neededBytes , start_offset(p) + oldSize, 0);
mFreeBytes -= neededBytes;
mFreeBytes += getSize(*hand);
post reallocDone(); //schedule completion event
return SUCCESS;
}
else if (neededBytes > getSize(*hand) && !isLocked(*hand)) { //handle must be be bigger
//printf("MREALLOCING\n"); //fflush(stdout);
//for now, just allocate a new handle and copy the old handle over
mReallocing = 1;
mFreeBytes += getSize(*hand);
return call MemAlloc.allocate[id](&mTmpHandle, newSize);
}
return FAIL; //failure
}
//task so that quick reallocations are split phase
task void reallocDone() {
signal MemAlloc.reallocComplete[gCurID](mOldHandle, SUCCESS);
}
//second half of split phase reallocation
int8_t finish_realloc(Handle *hand, int8_t success) {
//printf ("realloced, success = %d!\n\n",success); //fflush(stdout);
if (success) {
int8_t *p = **hand;
int8_t *q = *mOldHandle;
int16_t cnt = getSize(*mOldHandle);
//printf("cnt = %d\n", cnt);//fflush(stdout);
while(cnt--) {
*p++ = *q++;
}
//clear bits the old handle used
setFreeBits(start_offset(*mOldHandle),
start_offset(*mOldHandle) + getSize(*mOldHandle), 0);
//remap old handle to the new handle
remapAddr(*mOldHandle, **hand);
//and finally free the new handle in the handles list, since
// the user still has the pointer to the old handle
markHandleFree(*hand);
mReallocing = 0;
signal MemAlloc.reallocComplete[gCurID](mOldHandle, SUCCESS);
}
else {
mReallocing = 0;
signal MemAlloc.reallocComplete[gCurID](mOldHandle, FAIL);
return FAIL;
}
return SUCCESS;
}
// ------------------------- Lock / Unlock ----------------------------- //
/* Lock the handle */
command result_t MemAlloc.lock[uint8_t id](Handle handle) {
// Would it be good to check previous lockedness?
int8_t *ptr = deref(handle);
((int16_t *)(ptr - HEADER_SIZE))[0] |= 0x8000;
return SUCCESS;
}
/* Unlock the handle */
command result_t MemAlloc.unlock[uint8_t id](Handle handle) {
// Would it be good to check whether it was locked?
int8_t *ptr = deref(handle);
((int16_t *)(ptr - HEADER_SIZE))[0] &= 0x7FFF;
return SUCCESS;
}
int8_t isLocked(int8_t* ptr);
/* Return 1 iff h is locked, 0 o.w. */
command bool MemAlloc.isLocked[uint8_t id](Handle h) {
return isLocked(*h);
}
/* Return 1 iff the handle referencing ptr is locked */
int8_t isLocked(int8_t *ptr) {
return (((int16_t *)(ptr - HEADER_SIZE))[0] & 0x8000) != 0;
}
// -------------------- Utility Functions ----------------------------- //
/* Return the size of the handle h, excluding the header */
command int16_t MemAlloc.size[uint8_t id](Handle h) {
return (getSize(*h) - HEADER_SIZE);
}
/* Return the size of the handle referencing ptr
including the header
*/
int16_t getSize(int8_t *ptr) {
return (int16_t)(((int16_t *)(ptr - HEADER_SIZE))[0] & 0x7FFF);
}
/* Return the total number of free bytes (available after compaction) */
command uint16_t MemAlloc.freeBytes[uint8_t id]() {
return mFreeBytes;
}
//return 1 iff the handle points to a valid loc, 0 o.w.
int8_t isValid(Handle h) {
//pointers on motes are different size than on PC
if (sizeof(int8_t*) == sizeof(int32_t)) { // 32 bit arch
return ((*h >= (int8_t*)(&mFrame)[0]) && (*h < (int8_t*)&(mFrame[FRAME_SIZE])));
}
else if (sizeof(int8_t*) == sizeof(int16_t)) { // 16 bit arch
return ((*h >= (int8_t*)(&mFrame)[0]) && (*h < (int8_t*)&(mFrame[FRAME_SIZE])));
}
else {
return 0;
}
}
//move all handles that used to point to oldAddr to
//point to newAddr
void remapAddr(int8_t *oldAddr, int8_t *newAddr) {
int16_t i;
for (i = 0; i < MAX_HANDLES; i++) {
if ((mHandles[i]) == oldAddr){
(mHandles[i]) = newAddr;
}
}
}
//return the handle with the address p
Handle getH(int8_t *p) {
int16_t i;
for (i = 0; i < MAX_HANDLES;i++) {
if ((mHandles[i]) == p) {
return &mHandles[i];
}
}
return 0;
}
//find an unused handle slot
int16_t getNewHandleIdx() {
int16_t i;
for (i = 0; i < MAX_HANDLES; i++) {
if ((mHandles[i]) == 0) return i;
}
return -1;
}
//set the entry in mHandles to null for this handle
//CAREFUL -- this is possibly a very dangerous thing to do
//if someone external has a reference to hand...
void markHandleFree(Handle hand) {
int i;
for (i = 0; i < MAX_HANDLES; i++) {
if (&mHandles[i] == hand) {
//note that setting to 0 here means we'll have to
//walk the handle list looking for free slots later
//we can't just keep a dense list of used handles
//since the application maintains pointers into
//the handle list
mHandles[i] = 0;
break;
}
}
}
/* Mark the free bits corresponding to the specified
range of bytes in the allocation buffer.
*/
void setFreeBits(int16_t startByte, int16_t endByte, int8_t on) {
int16_t leadInBits = (startByte - ((startByte >> 3) << 3));
int16_t leadOutBits = endByte - ((endByte >> 3) << 3);
int16_t i;
int16_t startFree = startByte >> 3;
int16_t endFree = endByte >> 3;
dbg (DBG_USR1,"Setting bits from %d to %d to %d\n", startByte, endByte, on);
if (startFree == endFree) {
leadInBits = 8; //no leadin if both in same byte
}
//unroll this for efficiency, since it is called a lot
if (on) {
for (i = leadInBits; i < 8; i++) {
mFree[startFree] |= (1 << i);
}
for (i = 0; i < leadOutBits; i++) {
mFree[endFree] |= (1 << i);
}
startFree ++;
for (i = startFree; i < endFree; i++) {
mFree[i] = 0xFF;
}
} else { //! on
for (i = leadInBits; i < 8; i++) {
mFree[startFree] &= (0xFF ^ (1 << i));
}
for (i = 0; i < leadOutBits; i++) {
mFree[endFree] &= (0xFF ^ (1 << i));
}
startFree ++;
for (i = startFree; i < endFree; i++) {
mFree[i] = 0x00;
}
}
}
//return the offset in bits into free where this starts
//include the header byte
int16_t start_offset(int8_t *ptr) {
if (sizeof(int8_t*) == sizeof(int32_t)) { // 32 bit arch
int16_t len = (int16_t)((ptr - (int8_t*)(&mFrame[0])) - HEADER_SIZE);
return (int16_t)(len);
}
else if (sizeof(int8_t*) == sizeof(int16_t)) { // 16 bit arch
int16_t len = (int16_t)((ptr - (int8_t*)(&mFrame[0])) - HEADER_SIZE);
return len;
}
else {
return -1;
}
}
/* Print out the current free bitmap */
command void allocDebug() {
#ifdef kDEBUG
short i,j;
dbg(DBG_USR1,"Debugging:");
for (i = 0; i < FREE_SIZE; i++) {
for (j = 0; j < 8; j++) {
printf("%d:",(mFree[i]&1<<j) > 0?1:0);
}
printf(",");
}
dbg(DBG_USR1,"\n\n");
for (i = 0; i < FRAME_SIZE; i++) {
printf("%c,",mFrame[i]);
}
#endif
}
default event result_t MemAlloc.reallocComplete[uint8_t id](Handle handle, result_t complete) {
return SUCCESS;
}
default event result_t MemAlloc.compactComplete[uint8_t id]() {
return SUCCESS;
}
default event result_t MemAlloc.allocComplete[uint8_t id](Handle *handle, result_t complete) {
return SUCCESS;
}
}
--- NEW FILE: UllaCoreC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* UllaCore - This application is the core of the ULLA architecture
* which consists of Ulla Query Processing (UQP), Ulla Command
* Processing (UCP), Ulla Event Processing (UEP), and Link Layer
* Adapter (LLA).
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
configuration UllaCoreC {
provides {
interface StdControl;
interface UqpIf[uint8_t id];
interface UcpIf;
interface CommandInf;
interface InfoRequest;
interface Receive[uint8_t id]; // general interface in /tos/interface
interface Send[uint8_t id]; // general interface in /tos/interface
interface ReceivePacket[uint8_t id];
}
}
implementation {
components
Main
, QueryProcessorC
, QueryAssemblerC
, QauAdapterC
, CommandProcessorC
, EventProcessorC
, ULLAStorageC
, SensorMeterC
, UllaCoreM
, LLAC
, TimerC
, LedsC
;
Main.StdControl -> UllaCoreM;
Main.StdControl -> QueryProcessorC;
Main.StdControl -> CommandProcessorC;
Main.StdControl -> EventProcessorC;
Main.StdControl -> LLAC;
Main.StdControl -> SensorMeterC;
Main.StdControl -> QueryAssemblerC;
Main.StdControl -> QauAdapterC;
Main.StdControl -> TimerC;
Main.StdControl -> ULLAStorageC;
StdControl = UllaCoreM;
CommandInf = CommandProcessorC;
InfoRequest = UllaCoreM;
Receive = UllaCoreM;
Send = UllaCoreM;
UqpIf = QueryProcessorC; // LOCAL_LU
UcpIf = CommandProcessorC;
UllaCoreM.ProcessNotification -> QauAdapterC.ProcessCmd[1];
UllaCoreM.ProcessQuery -> QauAdapterC.ProcessCmd[2];
UllaCoreM.ProcessCommand -> CommandProcessorC;
UllaCoreM.ProcessResultGetInfo -> QueryProcessorC;
UllaCoreM.ProcessScanLinks -> CommandProcessorC;
UllaCoreM.StorageIf -> ULLAStorageC;
UllaCoreM.LLAControl -> LLAC;
UllaCoreM.SendInf -> LLAC;
ReceivePacket = UllaCoreM;
UllaCoreM.Leds -> LedsC;
UllaCoreM.BeaconTimer -> TimerC.Timer[unique("Timer")];
}
--- NEW FILE: UllaCoreM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* UllaCore implementation
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
includes hardware;
includes MultiHop;
module UllaCoreM {
provides {
interface StdControl;
//interface CommandInf;
//interface UqpIf;
//interface UcpIf;
interface InfoRequest;
interface Receive[uint8_t id];
interface Send[uint8_t id];
interface ReceivePacket[uint8_t id];
}
uses {
interface StdControl as LLAControl;
interface Send as SendInf[uint8_t id];
///interface Receive as ReceiveInf[uint8_t id];
interface ProcessCmd as ProcessQuery;
interface ProcessCmd as ProcessNotification;
interface ProcessCmd as ProcessCommand;
interface ProcessData as ProcessResultGetInfo;
interface ProcessData as ProcessScanLinks;
interface StorageIf;
//interface UqpIf as QueryIf;
//interface UcpIf as CommandIf;
//interface Neighbour;
interface Leds;
interface Timer as BeaconTimer;
}
}
/*
* Module Implementation
*/
implementation
{
TOS_MsgPtr msg;
TOS_MsgPtr rmsg;
TOS_Msg buf;
short nsamples; // number of samples
uint8_t msg_index;
uint8_t user_index;
uint8_t beaconTimerStarted;
/* task declaration */
task void startSimulationTask();
task void sendSimulationTask ();
task void sendResult();
command result_t StdControl.init() {
atomic {
msg = &buf;
msg_index = 0;
beaconTimerStarted = 0;
}
dbg(DBG_USR1,"initialized\n");
call LLAControl.init();
call Leds.init();
return (SUCCESS);
}
/** start generic communication interface */
command result_t StdControl.start(){
dbg(DBG_USR1, "UllaCore starts\n");\
//call BeaconTimer.start(TIMER_ONE_SHOT, 20000);
call BeaconTimer.start(TIMER_ONE_SHOT, 2000);
return (call LLAControl.start());
}
/**
* stop generic communication interface
*/
command result_t StdControl.stop(){
return (call LLAControl.stop());
}
command bool InfoRequest.processInfoRequest(QueryPtr trp, Cond *c, char idx) {
dbg(DBG_USR1,"ULLA Core processInfoRequest\n");
return TRUE;
}
event result_t ProcessQuery.done(TOS_MsgPtr pmsg, result_t status) {
dbg(DBG_USR1, "ProcessQuery done: prepare to send back\n");
atomic {
//msg = pmsg;
rmsg = pmsg;
}
post sendResult();
return SUCCESS;
}
event result_t ProcessNotification.done(TOS_MsgPtr pmsg, result_t status) {
dbg(DBG_USR1, "ProcessNotification done: prepare to send back\n");
atomic {
//msg = pmsg;
rmsg = pmsg;
}
return SUCCESS;
}
event result_t ProcessCommand.done(TOS_MsgPtr pmsg, result_t status) {
msg = pmsg;
return SUCCESS;
}
event result_t ProcessResultGetInfo.done(void *pdata, result_t status) {
dbg(DBG_USR1, "ProcessResultGetInfo done: \n");
return status;
}
event result_t ProcessScanLinks.done(void *pdata, result_t status) {
dbg(DBG_USR1, "ProcessResultGetInfo done: \n");
return status;
}
task void sendResult() {
///call Transceiver.sendResult(rmsg);
call SendInf.send[AM_QUERY_REPLY](rmsg, sizeof(struct ResultTuple));
}
bool isCorrectLpId(QueryMsg *query) {
/*
if ((query->numConds>0) && (query->dataType == COND_MSG))
{
for (i = 0; i<query->numConds; i++)
{
if(query)
}
}*/
return FALSE;
}
/*------------------------------- Transceiver --------------------------------*/
/*
* FIXME 30.11.06: Every received messages need to update the ULLAStorage.
*/
command result_t ReceivePacket.receive[uint8_t id](TOS_MsgPtr pmsg)
{
memcpy(&buf, pmsg, sizeof(struct TOS_Msg));
dbg(DBG_USR1, "UllaCoreM: ReceivePacket.receive %d\n", id);
///call Leds.redToggle();
switch (id)
{
case AM_QUERY:
{
QueryMsg *query = (QueryMsg *)pmsg->data;
// call some query processing here
//call Leds.yellowToggle();
//if (isCorrectLpId(query))
call ProcessQuery.execute(pmsg);
//////call QueryIf.requestInfo(pmsg->luId, char* query, ullaResult_t *result);
//call QueryIf.requestInfo(pmsg->luId, char* query, ullaResult_t *result);
}
break;
case AM_NOTIFICATION:
call ProcessNotification.execute(pmsg);
//call Leds.redToggle();
// call ProcessNotification 05/03/06
break;
/*
case AM_DATA_MESSAGE:
// not implemented yet
break;
*/
case AM_COMMAND:
call ProcessCommand.execute(pmsg);
break;
case AM_DEBUG_MESSAGE:
// not implemented yet
break;
case AM_QUERY_REPLY:
// not implemented yet
// same as data msg?
break;
case AM_MULTIHOPMSG:
// must be modified. no need to signal the multihop engine.
// just update the storage.
/////signal Receive.receive[id](pmsg, payload, payloadLen);
// Update the storage here
////////krekre call Neighbour.updateNeighbourTable(pmsg);
break;
case 3: // AM_MULTIHOP_DEBUGMSG
break;
case AM_RESULT_GETINFO_MESSAGE:
{
struct GetInfoMsg *getinfo;
dbg(DBG_USR1, "UllaCoreM: ReceiveIf.receive GetInfo Message\n");
getinfo = (struct GetInfoMsg *)buf.data;
if (getinfo->type == 2) {
dbg(DBG_USR1, "UllaCoreM: ReceiveIf.receive Send Back Message\n");
call ProcessResultGetInfo.perform(getinfo, sizeof(struct GetInfoMsg));
}
//if (getinfo->fieldIdx == numFields) {
/////signal Receive.receive[AM_RESULT_GETINFO_MESSAGE](&buf, &buf.data, buf.length);
//2006/03/22
//}
//call SendInf.send[AM_QUERY_MESSAGE](&buf, sizeof(struct QueryMsg));
break;
}
case AM_FIXEDATTR:
dbg(DBG_USR1, "ULLACoreM: StorageIf.updateMessage %d\n",(uint8_t)pmsg->data[0]);
// FIXME 01.01.07: change to updateAttribute
//call Leds.redToggle();
call StorageIf.updateMessage(pmsg);
break;
default:
break;
}
signal ReceivePacket.receiveDone[id](pmsg);
return SUCCESS;
}
// received message from Transceiver
#if 0
event TOS_MsgPtr ReceiveInf.receive[uint8_t id](TOS_MsgPtr pmsg, void* payload, uint16_t payloadLen) {
struct GetInfoMsg *getinfo;
struct ScanLinkMsg *scanlink;
//signal Transceiver.receiveResult(msg);
memcpy(&buf, pmsg, sizeof(struct TOS_Msg));
dbg(DBG_USR1, "UllaCoreM: ReceiveInf.receive\n");
switch (id) {
case AM_QUERY_MESSAGE:
// call some query processing here
call ProcessQuery.execute(pmsg);
//////call QueryIf.requestInfo(pmsg->luId, char* query, ullaResult_t *result);
//call QueryIf.requestInfo(pmsg->luId, char* query, ullaResult_t *result);
break;
case AM_NOTIFICATION_MESSAGE:
call ProcessNotification.execute(pmsg);
// call ProcessNotification 05/03/06
break;
case AM_DATA_MESSAGE:
// not implemented yet
break;
case AM_COMMAND_MESSAGE:
call ProcessCommand.execute(pmsg);
break;
case AM_DEBUG_MESSAGE:
// not implemented yet
break;
case AM_RESULT_MESSAGE:
// not implemented yet
// same as data msg?
break;
case AM_MULTIHOPMSG:
// must be modified. no need to signal the multihop engine.
// just update the storage.
/////signal Receive.receive[id](pmsg, payload, payloadLen);
// Update the storage here
////////krekre call Neighbour.updateNeighbourTable(pmsg);
break;
case 3: // AM_MULTIHOP_DEBUGMSG
break;
case AM_RESULT_GETINFO_MESSAGE:
dbg(DBG_USR1, "UllaCoreM: ReceiveIf.receive GetInfo Message\n");
getinfo = (struct GetInfoMsg *)buf.data;
if (getinfo->type == 2) {
dbg(DBG_USR1, "UllaCoreM: ReceiveIf.receive Send Back Message\n");
call ProcessResultGetInfo.perform(getinfo, sizeof(struct GetInfoMsg));
}
//if (getinfo->fieldIdx == numFields) {
/////signal Receive.receive[AM_RESULT_GETINFO_MESSAGE](&buf, &buf.data, buf.length);
//2006/03/22
//}
//call SendInf.send[AM_QUERY_MESSAGE](&buf, sizeof(struct QueryMsg));
break;
case AM_SCAN_LINKS:
scanlink = (struct ScanLinkMsg *)pmsg->data;
dbg(DBG_USR1, "UllaCoreM: ReceiveIf.receive ScanAvailableLinks\n");
call ProcessScanLinks.perform((uint8_t *)scanlink, sizeof(struct ScanLinkMsg));
break;
default:
break;
}
return pmsg;
}
#endif
event result_t SendInf.sendDone[uint8_t id](TOS_MsgPtr pmsg, result_t success) {
switch (id) {
case AM_QUERY:
break;
/*
case AM_DATA_MESSAGE:
// not implemented yet
break;
*/
case AM_COMMAND:
break;
case AM_DEBUG_MESSAGE:
// not implemented yet
break;
case AM_QUERY_REPLY:
// not implemented yet
// same as data msg?
break;
case AM_MULTIHOPMSG:
break;
case 3: // AM_MULTIHOP_DEBUGMSG
break;
default:
break;
}
/*
* Signalled only if LU calls Send.send. If SendInf.sendDone is signalled from the other components (e.g. LLA),
* it goes to the default event handler (see below).
*/
signal Send.sendDone[id](pmsg, success);
// check id here
return SUCCESS;
}
// Send SendInf
// User--------->ULLA------------>Transceiver
command result_t Send.send[uint8_t id](TOS_MsgPtr pMsg, uint16_t PayloadLen) {
//uint16_t usMHLength = offsetof(TOS_MHopMsg,data) + PayloadLen;
dbg(DBG_USR1,"ULLACore: Send.send %d\n", id);
// should check id before calling Transceiver.sendMHop (core dependent)
///call Transceiver.sendMHop(pMsg); // changed to interface Send
call SendInf.send[id](pMsg, PayloadLen);
return SUCCESS;
}
command void *Send.getBuffer[uint8_t id](TOS_MsgPtr pMsg, uint16_t* length) {
TOS_MHopMsg *pMHMsg = (TOS_MHopMsg *)pMsg->data;
*length = TOSH_DATA_LENGTH - offsetof(TOS_MHopMsg,data);
return (&pMHMsg->data[0]);
}
/*
* Default event handler is called if no component is wired in.
*/
default event result_t Send.sendDone[uint8_t id](TOS_MsgPtr pMsg, result_t success) {
dbg(DBG_USR1, "UllaCoreM: Send.sendDone default\n");
return SUCCESS;
}
/*------------------------------- Beacon Timer --------------------------------*/
task void sendFixedAttrTask() {
//TOS_Msg beaconMsg; // can't be used locally here.
FixedAttrMsg *fixed = (FixedAttrMsg *)msg->data;
fixed->source = TOS_LOCAL_ADDRESS;
fixed->type = 0; // request;
//call Leds.redToggle();
call SendInf.send[AM_FIXEDATTR](&buf, sizeof(struct FixedAttrMsg));
}
event result_t BeaconTimer.fired() {
dbg(DBG_USR1, "UllaCoreM: BeaconTimer.fired\n");
///if(!beaconTimerStarted) call BeaconTimer.start(TIMER_REPEAT, 200000);
///else beaconTimerStarted = 1;
post sendFixedAttrTask();
return SUCCESS;
}
} // end of implementation
--- NEW FILE: UllaLinkProviderC.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* WSN Link Layer Adapter - a proxy interface on the existing driver that
* implements an interface known by the ULLA (methods and queries), enabling
* the ULLA to forward queries and method calls to the driver through the LLA.
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
includes MultiHop;
includes AMTypes;
configuration UllaLinkProviderC {
provides {
interface LinkProviderIf[uint8_t id]; // replacement of RequestUpdate
//interface StdControl;
}
}
implementation {
components
Main
, UllaLinkProviderM
, LedsC
#ifndef MAKE_PC_PLATFORM
, CC2420ControlM
, CC2420RadioC
#endif
;
//Main.StdControl -> UllaLinkProviderM;
//StdControl = UllaLinkProviderM;
UllaLinkProviderM.Leds -> LedsC;
LinkProviderIf = UllaLinkProviderM;
#if defined(TELOS_PLATFORM) || defined(SIM_TELOS_PLATFORM) || defined(MICAZ_PLATFORM)
UllaLinkProviderM.CC2420Control -> CC2420ControlM;
#endif
}
--- NEW FILE: UllaLinkProviderM.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes UQLCmdMsg;
includes UllaQuery;
includes Attribute;
includes AMTypes;
module UllaLinkProviderM {
provides {
//interface StdControl;
interface LinkProviderIf[uint8_t id]; // replacement of RequestUpdate
}
uses {
interface Leds;
#ifndef MAKE_PC_PLATFORM
interface CC2420Control;
//interface MacControl;
#endif
}
}
/*
* Module Implementation
*/
implementation
{
command uint8_t LinkProviderIf.execCmd[uint8_t id](CmdDescr_t* cmddescr) {
return 1;
}
command uint8_t LinkProviderIf.requestUpdate[uint8_t id](RuId_t ruId, RuDescr_t* ruDescr, AttrDescr_t* attrDescr) {
return 1;
}
command uint8_t LinkProviderIf.cancelUpdate[uint8_t id](RuId_t ruId) {
return 1;
}
command uint8_t LinkProviderIf.getAttribute[uint8_t id](AttrDescr_t* attrDescr) {
elseHorizontalTuple tuple;
switch (attrDescr->attribute) {
case TYPE:
tuple.u.value16 = IEEE_802_15_4_TYPE;
break;
case LP_ID:
tuple.u.value16 = TOS_LOCAL_ADDRESS;
break;
case RF_POWER:
tuple.u.value16 = call CC2420Control.GetRFPower();
break;
case FREQUENCY:
tuple.u.value16 = call CC2420Control.GetFrequency();
break;
default:
break;
}
tuple.attr = attrDescr->attribute;
signal LinkProviderIf.getAttributeDone[LOCAL_QUERY](attrDescr, (uint8_t *) &tuple);
return 1;
}
command uint8_t LinkProviderIf.setAttribute[uint8_t id](AttrDescr_t* attrDescr) {
return 1;
}
command void LinkProviderIf.freeAttribute[uint8_t id](AttrDescr_t* attrDescr) {
}
}
--- NEW FILE: UllaQuery.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/*
*
* Query Message header file
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
*/
#ifndef _ULLA_QUERY_H_
#define _ULLA_QUERY_H_
#ifdef TELOS_PLATFORM
#define TELOS_SENSOR
#endif
#ifdef HISTORICAL_STORAGE
#define BLOCKSTORAGE // works with TOSSIM
//#define BYTEEEPROM
#endif
#ifndef FIELD_SIZE
#define FIELD_SIZE 8
#endif
#define FIELD_CONDITION_SIZE 2
#define CONDITION_SIZE 4
#define COMMAND_SIZE 26
#define TUPLE_SIZE 25
#define MAX_ATTR 8
/* Message Type = msgType */
enum {
ADD_MSG = 10,
MOD_MSG = 11,
DEL_MSG = 12,
};
/* Data type - dataType */
enum {
FIELD_MSG = 1,
COND_MSG = 2,
};
/* SELECT types */
/* Supported classes */
enum {
ullaLink = 0x1,
ullaLinkProvider = 0x2,
sensorMeter = 0x4,
sensorDescription = 0x8,
allClasses = 0,
UNDEFINED = 0xff,
};
/* operation types */
enum {
OP_EQ = 0, /* = */
OP_NEQ = 1, /* <> */
OP_GT = 2, /* > */
OP_GE = 3, /* >= */
OP_LT = 4, /* < */
OP_LE = 5, /* <= */
};
/* bitmask */
enum {
BITMASK_ONE_BYTE = 0xFF,
BITMASK_TWO_BYTE = 0xFFFF,
};
/* AM message types */
enum {
AM_QUERY = 101,
AM_NOTIFICATION = 102,
AM_QUERY_REPLY = 103,
AM_NOTIFICATION_REPLY = 104,
AM_PROBING = 105,
AM_PROBING_REPLY = 106,
AM_COMMAND = 107,
AM_DEBUG_MESSAGE = 109,
};
/* error messages */
enum {
errorNoError,
errorSendFailed,
};
enum {
REMOTE_QUERY = 1,
LOCAL_QUERY =2,
};
enum {
REMOTE_LU = 3,
LOCAL_LU = 4,
};
enum {
NOTIFICATION = 1,
QUERY = 2,
};
typedef uint8_t UllaError;
typedef struct Cond {
uint8_t field; //1
uint8_t op; //2
short value; //4
} Cond, *CondPtr;
/*
* Query & Notification data structure
*/
typedef struct QueryMsgNew {
uint8_t ruId; //1 //notification id
uint8_t msgType; //2 type of message (e.g. add, modify, delete q)
uint8_t dataType; //3 is this a field, condition, buffer, or event msg
uint8_t queryType; //4 notification or query
uint8_t index; //5
uint8_t className; //6 ullaLink, ullaLinkProvider, sensorMeter
uint8_t numFields; //7 total number of fields
uint8_t numConds; //8 total number of conditions
uint16_t interval; //10 in millisecs
uint16_t nsamples; //12
union {
uint8_t fields[FIELD_SIZE];
Cond cond[CONDITION_SIZE]; //28+ (4*numConds+ = 16+)
} u; //28+ (Routing-upto 10Bytes, BMAC-10Bytes) //total 48+ Bytes
} QueryMsgNew, *QueryMsgNewPtr;
typedef struct TreeCond {
} TreeCond;
#if 1
typedef struct QueryMsg {
uint8_t ruId; //query id //1
uint8_t msgType; //type of message (e.g. add, modify, delete q) //2
uint8_t dataType; //is this a field, condition, buffer, or event msg -- 8
uint8_t queryType; // (remote or local query) // 21
uint8_t index; //9
uint8_t className;
uint8_t numFields; //5
uint8_t numConds; //6
uint16_t interval; //in millisecs -- 18
uint16_t nsamples; // 20
union {
uint8_t fields[FIELD_SIZE]; //(8)
Cond cond; //(8)
} u; //29 2006/03/14
} QueryMsg, *QueryMsgPtr;
#endif
typedef struct CommandMsg {
uint8_t cid; //command id //1
uint8_t msgType; //type of message //2
uint8_t cmdType; //type of command //3
uint8_t action; //command action //4
uint16_t param; //parameter
uint16_t interval;
uint16_t ntimes;
} CommandMsg, *CommandMsgPtr;
typedef struct DebugMsg {
uint8_t did; //debug id //1
} DebugMsg, *DebugMsgPtr;
typedef struct DataMsg {
uint8_t did; //debug id //1
} DataMsg, *DataMsgPtr;
typedef struct UllaQuery {
uint8_t qid; //1
uint8_t numFields; //5
uint8_t numConds; //6
uint16_t interval; //18
uint16_t nsamples; // 20
} UllaQuery, *UllaQueryPtr;
// FIXME: needs to be changed to dynamic size. 01.08.06
// FIXME: also includes a class type (e.g. ullaLinkProvider, ullaLink)
typedef struct Query {
uint8_t qid; //1
uint8_t numFields; //5
uint8_t numConds; //6
uint8_t seenFields;
uint8_t seenConds; //bitmask for conditions we have seen already
uint8_t className; // new 01.08.06
//uint16_t interval; //18
//uint16_t nsamples; // 20
uint8_t fields[FIELD_SIZE];
Cond cond[CONDITION_SIZE];
} Query, *QueryPtr, **QueryHandle;
typedef struct SubTuple {
uint8_t fields;
uint16_t data;
} SubTuple;
typedef struct ResultTuple {
uint8_t qid; //1
uint8_t replyType; //2 Query or Notification
uint8_t supportedClasses; //3 bit mask to be defined
uint8_t numTuples; //4
uint8_t index; //5
uint8_t fields[MAX_ATTR];
uint16_t data[MAX_ATTR];
//SubTuple subTuple[5];
} ResultTuple, *ResultTuplePtr, **ResultTupleHandle;
/*
typedef struct ResultTuple {
uint8_t qid;
uint8_t dummy; //for testing
uint8_t numFields;
uint8_t numConds;
uint8_t fields[FIELD_SIZE];
uint16_t data[FIELD_SIZE];
} ResultTuple, *ResultTuplePtr, **ResultTupleHandle;
*/
//----------------------------------------------------------------------------//
// Functions //
//----------------------------------------------------------------------------//
/**
*
**/
#endif
--- NEW FILE: UllaStorage.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/*
*
* Storage header file
<p>
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
*/
// validity in seconds
enum {
LINK_ID_VALIDITY = 5,
LQI_VALIDITY = 5,
RSSI_VALIDITY = 5,
TEMPERATURE_VALIDITY = 10,
TSR_VALIDITY = 2,
PAR_VALIDITY = 2,
INT_TEMP_VALIDITY = 30,
INT_VOLT_VALIDITY = 60,
RF_POWER_VALIDITY = 5,
DEFAULT_VALIDITY = 1,
};
enum {
MAX_ATTRIBUTE = 25,
MAX_LINKS = 10,
MAX_TUPLE = 1,
};
typedef struct StorageMsg {
uint16_t buffer[MAX_ATTRIBUTE];
uint16_t counter;
uint32_t timestamp;
bool result_is_old[MAX_ATTRIBUTE];
} StorageMsg;
typedef struct SingleTuple {
uint16_t linkid;
union {
uint8_t value8;
uint16_t value16;
} u;
} SingleTuple;
typedef struct ullaLinkHorizontalTuple {
uint8_t attr;
uint8_t num_links;
SingleTuple single_tuple[MAX_LINKS];
} ullaLinkHorizontalTuple;
typedef struct elseHorizontalTuple {
uint8_t attr;
union {
uint8_t value8;
uint16_t value16;
}u;
} elseHorizontalTuple;
--- NEW FILE: UqpIf.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
*
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
includes Lu;
includes ulla;
includes msg_type;
includes UllaQuery;
interface UqpIf {
command uint8_t requestInfo(QueryPtr gCurQuery, ullaResult_t *result);
event result_t requestInfoDone(ResultTuple *result, uint8_t numBytes);
command uint8_t requestNotification(/*IN*/ RnDescr_t* rndescr,
// handleNotification_t handler, // callback
/*OUT*/ RnId_t* rnId,
/*IN*/uint16_t validity);
command uint8_t cancelNotification(RnId_t rnId);
command uint8_t clearResult();
/*
* Result Tuple
*/
command ullaResultCode ullaResultNumFields(uint8_t res, uint8_t *num);
command ullaResultCode ullaResultNumTuples(ullaResult_t res, uint8_t *num);
/*
* Removed size: name is uint8_t not string.
*/
command ullaResultCode ullaResultFieldName(ullaResult_t res, uint8_t fieldNo, uint8_t *name);
command ullaResultCode ullaResultFieldNumber(ullaResult_t res, uint8_t fieldName, uint8_t *num);
command ullaResultCode ullaResultValueLength(ullaResult_t res, uint8_t fieldNo, uint8_t *size);
command ullaResultCode ullaResultValueType(ullaResult_t res, uint8_t fieldNo, BaseType_t *type);
command ullaResultCode ullaResultNextTuple(ullaResult_t res);
command ullaResultCode ullaResultIntValue(ullaResult_t res, uint8_t fieldNo, uint8_t *value);
command ullaResultCode ullaResultRawDataValue(ullaResult_t res, uint8_t fieldNo, char *buf, uint8_t *size);
}
--- NEW FILE: WriteToStorage.nc ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* WriteToStorage Interface - processes a request from the ULLA
* Query Processing to update the information in the ULLA Storage.
<p>
*
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
interface WriteToStorage
{
/** Write bytes to region (erase must be called first)
* @return FAIL if writes are not allowed.
* @param offset Offset of data written
* @param data Address of data written
* @param numBytesWrite Number of bytes written
* If the result is SUCCESS, <code>writeDone</code> will be signaled.
*/
command result_t write(uint32_t offset, uint8_t* data, uint32_t numBytesWrite);
/**
* Report write completion.
* @param data Address of data written
* @param numBytesWrite Number of bytes written
* @param status SUCCESS if write was successful, FAIL otherwise
* @return Ignored.
*/
event result_t writeDone(uint8_t* data, uint32_t numBytes, result_t status);
}
--- NEW FILE: msg_type.h ---
/*
* Copyright (c) 2007, RWTH Aachen University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL RWTH AACHEN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RWTH AACHEN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* RWTH AACHEN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND RWTH AACHEN UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
/**
* @author Krisakorn Rerkrai <kre at mobnets.rwth-aachen.de>
**/
#ifndef MSG_TYPE_H
#define MSG_TYPE_H
/**
* @ingroup type
* @brief notification parameters to be passed to ULLA through requestNotification()
*
*/
typedef struct RnDescr_t {
uint16_t count; /**< max number of notification to be reported by calling the handler. If zero,
the notification remains in force until explicitly canceled by cancelNotification().
Otherwise the notification is automatically canceled after "count" reports */
uint16_t period; /**< If this parameter is nonzero, the notification is periodic, and the value
of the parameter represents the time interval in milliseconds between two periodic
notifications. If the parameter is zero, the notification is event-driven. */
///handleNotification_t handler; /**< callback function provided by the application to be called by ULLA when
/// reporting events */
void* privdata; /**< private data that the application wants to be returned within the callback function */
struct Query query;
} RnDescr_t, *RnDescrPtr;
/**
* @ingroup type
* @brief Parameters for asynchronous command call
*
* This structure contains parameter which are specific to the asynchronous command call through
* requestCmd()
*
*/
typedef struct RcDescr_t
{
///handleAsyncCmd_t handler; /**< callback function privided by the Link User to be called upon
// command completion */
uint16_t count; /**< The number of times the command must be issued. If zero,
the command call is repeated until explicitly canceled by cancelCmd().
Otherwise the command is automatically canceled after "count" reports */
uint16_t period; /**< The time interval in milliseconds between two commands. The first comand is
executed after the first period has elapsed. */
} RcDescr_t, *RcDescrPtr;
/**
* @ingroup ucp
* @brief Command Description
*
* This structure contains the name and parameters of the command to be issued by the link user
* through requestCmd() or doCmd()
*/
typedef struct CmdDescr_t
{
Id_t id; /**< identifier of the link or link provider on which the command is to be executed */
uint8_t class; /**< the class (e.g. ullaLink, linkProvider, dot11Link) the command belongs to */
uint8_t cmd; /**< null-terminated string containing the command to be executed */
uint8_t cmdArgLen; /**< length of the cmdArg field in bytes */
uint8_t* cmdArg; /**< structure containing command arguments. How this is interpreted is command specific. */
} CmdDescr_t, *CmdDescrPtr;
typedef struct LpIf_t LpIf_t;
/**
* @ingroup type
* @brief Identified an update request made through requestUpdate()
*
*/
typedef uint8_t RuId_t;
/**
* @ingroup type
* @brief Link Provider information and methods
*
* This structure provides general information on the link provider, and also contains the
* interface that the link provider must export to the ullaCore.
*
* @todo The method to load dynamically LP/Link attribute and command definitions
* is still to be defined. It is still under discussion whether it can be enough to pass them
* as a sequence of names and types in a string within the structure LpDescr_t (probably sufficient for attributes),
* or whether a more complex representation should be used (which might be better to define command names and parameters).
*
*/
typedef struct LpDescr_t{
char* version; /**< Version of the ULLA this Link provider is compatible with */
LpIf_t* lpIf; /**< Pointer to link Provider interface struct */
} LpDescr_t;
/**
* @ingroup type
* @brief Request Update descriptor.
*
* Conveys information for issuing an update request through requestUpdate()
*
* @todo There is currently no way to specify the notification condition,
* e.g. if the notification must be reported only on attribute change or also on exceeding some threshold.
*/
typedef struct RuDescr_t{
uint16_t count; /**< The maxumum numner of times the request update notification fires. If set to zero
the request will stay in force until it is canceled by a cancelUpdate() call */
uint32_t period; /**< if a periodic notification was requested, this parameter indicates the reporting interval in ms. */
} RuDescr_t;
// for testing
typedef struct ullaLink_t {
uint16_t link_id;
uint16_t lp_id;
uint8_t type;
uint8_t state;
uint8_t mode;
uint8_t network_name;
uint8_t rssi;
uint8_t lqi;
} ullaLink_t;
typedef struct ullaLinkProvider_t {
uint16_t lp_id;
uint8_t foobar1;
uint8_t foobar2;
uint8_t foobar3;
} ullaLinkProvider_t;
typedef struct sensorMeter_t {
uint16_t humidity;
uint16_t temperature;
uint16_t tsr;
uint16_t par;
uint16_t int_temperature;
uint16_t int_voltage;
uint16_t rf_power;
} sensorMeter_t;
typedef struct classList_t {
ullaLink_t ulla;
ullaLinkProvider_t lp;
sensorMeter_t sm;
} classList_t;
typedef struct ResultTuple_t {
uint8_t status;
uint8_t attribute;
uint8_t size;
void *data;
} ResultTuple_t;
/*
* @rt: pointer to the headlist of ResultTuple_t of one link.
*/
typedef struct UllaResultTuple_t {
ResultTuple_t *rt;
struct UllaResultTuple_t *next;
} UllaResultTuple_t;
#endif
--- NEW FILE: ulla.h ---
#ifndef ULLA_H
#define ULLA_H
/**
* @file ulla.h
* @author Nicola Baldo
*
* @brief General definitions for the ULLA API
*
* This header files contains definitions which are common
* to both the Link User interface and the Link Provider interface.
* This header file is automatically included when ullalu.h or
* ullalp.h are included.
*
*/
/**
* @modified Krisakorn Rerkrai
* @brief Modified version to work with TinyOS
*/
//#define IN
//#define OUT
//#define INOUT
/**
* @defgroup ucp ULLA Command Processing
*/
/**
* @defgroup uqp ULLA Query Processing
*/
/**
* @defgroup lu Link User
*/
/**
* @defgroup lpfunc Link Provider
*/
/**
* @defgroup uepfunc ULLA Event Processing
*/
/**
* @defgroup type Type Definitions
*/
/**
* @defgroup error Error Handling
*/
/**
* @ingroup type
* @name Media Types
*
* @{
*/
#define ULLA_MEDIATYPE_UNKNOWN 1
#define ULLA_MEDIATYPE_80211 2
#define ULLA_MEDIATYPE_80211b 3
#define ULLA_MEDIATYPE_80211a 4
#define ULLA_MEDIATYPE_80211g 5
#define ULLA_MEDIATYPE_GPRS 6
#define ULLA_MEDIATYPE_UMTS 7
#define ULLA_MEDIATYPE_BLUETOOTH 8
#define ULLA_MEDIATYPE_ZIGBEE 9
#define ULLA_MEDIATYPE_IRDA 10
/** @} */
/**
* @ingroup type
* @name Profiles
*
* @{
*/
#define ULLA_PROFILE_UNSPECIFIED 0
#define ULLA_PROFILE_BASE 1
#define ULLA_PROFILE_EXTENDED 2
#define ULLA_PROFILE_HIGH_END 3
/** @} */
/**
* @ingroup type
* @brief Unique identifier used for links and link providers
*
* This identifier is determined by the ullaCore and is unique for both links and link providers.
*
*/
typedef uint16_t Id_t;
typedef uint8_t ullaResult_t;
typedef enum BaseType_t {
ULLA_TYPE_UINT8 = 1, /**< Unsigned char */
ULLA_TYPE_INT8, /**< Char */
ULLA_TYPE_UINT16, /**< Unsigned short */
ULLA_TYPE_INT16, /**< Short */
ULLA_TYPE_UINT32, /**< Unsigned integer */
ULLA_TYPE_INT32, /**< Integer */
ULLA_TYPE_RAWDATA, /**< Raw data bytes */
} BaseType_t;
/**
* @ingroup type
* @name Link Provider Attribute Qualifiers
*/
typedef enum AttrQual_t{
ULLA_QUAL_HARDCODED, /**< Hard-coded value */
ULLA_QUAL_THEORETICAL, /**< Theoretical value */
ULLA_QUAL_ESTIMATED, /**< Estimated value */
ULLA_QUAL_MEASURED, /**< Measured value */
ULLA_QUAL_EXACT /**< Exact value */
} AttrQual_t;
/**
* @ingroup type
* @brief data structure for attribute value request/retrieval between the UEP and the LP
*
* This data structure is used in two cases:
* - for the request and the retrieval of Link and Link Provider attributes
* between the UEP and the LP, through getAttribute(), freeAttribute(), requestUpdate() and handleEvent()
* - for the setting of link or link provider parameters through setParameter()
*
* Depending on which method the structure is passed to, the structure members act as an IN or as an OUT parameter.
*/
typedef struct AttrDescr_t{
Id_t id; /**< id of the Link or Link Provider for which the attribute is requested or reported. */
uint8_t className; /**< the name of the class the requested/reported attribute belongs to
* (e.g. ullaLink, linkProvider, dot11Link, etc.)
*/ //kre_modified
uint8_t attribute; /**< the name of the attribute */ //kre_modified
////AttrQual_t qualifier; /**< the requested/reported qualifier of the attribute */
uint8_t type; /**< the reported type of the attribute (ULLATYPE_INT, ULLATYPE_STRING...) */
uint8_t length; /**< the length of the attribute in bytes. Used for types whose length is not known (e.g. ULLATYPE_STRING)
*
* @note the length field is mainly useful for strings which cannot be null-terminated,
* for instance security keys, MAC addressed, LinkSignatures, etc.
* Since the length field itself is unique, if multiple values are reported they must be
* of the same length. This is OK when the attribute has a well-defined length
* (e.g. a MAC address, or a MD5 hash), but problems may arise if a multiple-valued attribute needs
* a different length for each value.
*/
uint8_t numValues; /**< how many values the attribute is composed of (this is to support multivalued attributes) */
uint16_t *data;
//void* data;
/**< the pointer to the attribute value(s).
* This pointer is supposed to be an array of the type indicated in the apposite field
* (in other words, a pointer to data of the indicated type).
* The receiver of this data structure (the UC for getAttribute and handleNotification,
* the LP for setAttribute() ) must explicitly cast the pointer to the appropriate type,
* e.g.
* @code
switch(attr->type) {
case ULLATYPE_INT:
{ int* value = (int*) attr->data;
for (i=0; i<attr->numValues; i++)
printf("Value = %d",value[i]);
} break;
case ULLATYPE_STRING:
{ char** value = (char**) attr->data;
sprintf(format,"Value = \%.%ds",attr->length);
for (i=0; i<attr->numValues; i++)
printf(format,value[i]);
} break;
case ULLATYPE_WHATEVER:
...
}
* @endcode
*/
} AttrDescr_t;
/*
* @ingroup error
* @name ULLA Core Error Codes
*
* All functions in the ULLA return an ullaResultCode indicating
* the result of the function call. If the function succeeded, ULLA_OK is returned
* otherwise the appropriate error code, defined hereafter.
*/
typedef enum ullaResultCode
{
/** Operation succesful */
ULLA_OK = 0,
/** Operation failed, general failure, no specific reason */
ULLA_ERROR_FAILED,
ULLA_ERROR_UNDEFINED,
ULLA_ERROR_OUT_OF_MEMORY,
/** generic error in ULLA library, e.g. due to a bug */
ULLA_ERROR_LIB,
/** generic error in ULLA Core, e.g. due to a bug */
ULLA_ERROR_CORE,
/** generic error in ulla Storage system, e.g. in the internal database or in the external
* database implementation
*/
ULLA_ERROR_STORAGE,
/** ULLA API version mismatch */
ULLA_ERROR_API_VERSION_MISMATCH,
/** Syntax error e.g. in the query string or in the commmand string */
ULLA_ERROR_SYNTAX_ERROR,
/** Invlaid class in the query string or in the commmand string */
ULLA_ERROR_INVALID_CLASS,
/** Invalid attribute in the query string or in the commmand string */
ULLA_ERROR_INVALID_ATTRIBUTE,
/** e.g. command not supported */
ULLA_ERROR_UNSUPPORTED_FEATURE,
/** one or more of the function arameters is invalid */
ULLA_ERROR_INVALID_PARAMETER,
/** the ullaResult_t identifier does not exist or has been already deallocated */
ULLA_ERROR_INVALID_ULLARESULT,
/** non-existing field number or field name */
ULLA_ERROR_INVALID_FIELD,
/** The link user has not registered yet */
ULLA_ERROR_NOTREGISTERED,
/** an error has occurred in the link provider while executing the function call */
ULLA_ERROR_LP_ERROR,
/** e.g. the buffer space allocated by the linkUser was not sufficient */
ULLA_ERROR_BUFFER_TOO_SMALL,
/** all tuples in a result set have already been processed */
ULLA_ERROR_NO_MORE_TUPLES,
/** this is returned when the linkUser is trying to access data within a result set without
* having called ullaNextTuple() at least once, or if the last call to ullaNextTuple() returned
* ULLA_NO_MORE_TUPLES but the linkUser is trying to access data anyway.
*/
ULLA_ERROR_NO_CURRENT_TUPLE,
/**
* the requested field cannot be converted to the requested value.
* E.g. ullaResultIntValue() is called on a string field.
*/
ULLA_ERROR_TYPE_MISMATCH,
/**
* No more values are available for the current field.
* For an attribute field which contains N values, this error code is returned when
* a data access function (ullaResultIntValue(), ullaResultStringValue(), etc..)
* is called more than N times.
*/
ULLA_ERROR_NO_MORE_VALUES,
/** The link provider ID does not exist or has already been unregistered */
ULLA_ERROR_UNKNOWN_ID,
/** The link user ID does not exist or has already been unregistered */
ULLA_ERROR_INVALID_LUID,
/** Returned upon a call to registerLu(), if the Link User requested support for a profile the
* ULLA Core does not support.
*/
ULLA_ERROR_UNSUPPORTED_PROFILE,
/** Returned upon a call to registerLu(), if the Link User requested a role the
* ULLA Core does not support.
*/
ULLA_ERROR_UNSUPPORTED_ROLE,
/** Returned upon a call to registerLu(), if the ULLA Core denies the requested role
*/
ULLA_ERROR_ROLE_DENIED,
/** Returned upon ullaRegisterLm from an ULLA core that does not support external LM */
ULLA_ERROR_LM_NOT_SUPPORTED,
/** LM specific error codes: LM authorizes the operation */
ULLA_AUTHORIZATION_OK,
/** LM specific error codes: LM does not authorize the operation */
ULLA_AUTHORIZATION_FAILED,
/** LM specific error codes: LM authorizes has perfomed the requested operation */
ULLA_OPERATION_PERFORMED,
/** command can not be executed by link or linkprovider */
ULLA_ERROR_INVALID_COMMAND,
/** user is not allowed to execute the command */
ULLA_ERROR_CMD_NOT_ALLOWED,
/** user is not allowed to set the attribute */
ULLA_ERROR_SETATTR_NOT_ALLOWED,
/** user is not allowed to set the attribute */
ULLA_ERROR_QUERY_NOT_ALLOWED,
/** there is already a lock on the link or LP */
ULLA_ERROR_ALREADY_LOCKED,
/** ULLA Core or Link provider can not handle the requested period */
ULLA_ERROR_PERIOD_TOO_SHORT,
/** Invalid pointer to handler used */
ULLA_ERROR_INVALID_HANDLER,
/** Invalid notification ID */
ULLA_ERROR_INVALID_NOTIFICATION,
/** There is no known error to return the error string */
ULLA_ERROR_NO_KNOWN_ERROR,
/** Indicates that the LU is already registered when a subsequent request is made*/
ULLA_ERROR_ALREADY_REGISTERED,
/** Used in unmapChannel to indicate that there is no mapping set up for this relationship */
ULLA_ERROR_NO_MAPPING,
/** Used to indicate that a command (or other operation) has been timed out */
ULLA_ERROR_TIMEOUT,
/** The provided address can not be reached */
ULLA_ERROR_DESTINATION_NOT_REACHABLE,
/** Invalid qualifier being used */
ULLA_ERROR_INVALID_QUALIFIER,
/** Trying to set an invalid value */
ULLA_ERROR_INVALID_VALUE,
/** Trying to set multiple values for a single value attribute */
ULLA_ERROR_SETATTR_NOTMULTIPLE,
/** Trying to set a read only value */
ULLA_ERROR_SETATTR_READONLY,
ULLA_ERROR_MAX = 0x7fffffff
} ullaResultCode;
/**
* @ingroup error
* @name Link Provider Error Codes
*
* @{
*/
/** A generic error descriptor. May signal
* an error in the link provider implementation
*/
#define LP_GENERIC_ERROR -101
/** An error occured in the netowrk adpater's driver */
#define LP_DRIVER_ERROR -102
/** Out of memory */
#define LP_OUT_OF_MEMORY_ERROR -103
/** The specified attribute has not been recognised by the link provider */
#define LP_BAD_ATTRIBUTE_ERROR -104
/** The specified ID does not exist */
#define LP_UNKNOWN_ID_ERROR -106
/** The supplied Request Update ID already exists */
#define LP_BAD_REQUEST_ID_ERROR -107
/** The ULLA version is not compatible to the one requested by the link provider */
#define LP_VERSION_MISMATCH_ERROR -108
/** The requested command has not been recognized by the link provider */
#define LP_BAD_COMMAND_ERROR -109
/** E.g. attribute or command known but unsupported */
#define LP_UNSUPPORTED_FEATURE_ERROR -110
/** The LP is busy and cannot perform the requested operation*/
#define LP_BUSY_ERROR -112
/** No error */
#define LP_OK 0
/** @} */
/**
* @ingroup type
* @name Attribute types
*
* @{
*/
/**
* This type code refers to data of type "int"
*/
#define ULLA_TYPE_INT 1
/**
* This type code refers to data of type "double"
*/
#define ULLA_TYPE_DOUBLE 2
/**
* This type code refers to data of type "char*"
*/
#define ULLA_TYPE_STRING 3
/** @} */
#endif /* ULLA_H */
More information about the Tinyos-contrib-commits
mailing list