Merge remote-tracking branch 'sf/master' into rpl-patch

Conflicts:
	core/net/tcpip.c
This commit is contained in:
Nicolas Tsiftes 2011-12-08 15:26:11 +01:00
commit d0ebeb409e
117 changed files with 8260 additions and 6932 deletions

View file

@ -0,0 +1,4 @@
antelope_src = antelope.c aql-adt.c aql-exec.c aql-lexer.c aql-parser.c \
index.c index-inline.c index-maxheap.c lvm.c relation.c \
result.c storage-cfs.c
antelope_dsc =

156
apps/antelope/antelope.c Normal file
View file

@ -0,0 +1,156 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Main functions for Antelope.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdio.h>
#include "antelope.h"
static db_output_function_t output = printf;
void
db_init(void)
{
relation_init();
index_init();
}
void
db_set_output_function(db_output_function_t f)
{
output = f;
}
const char *
db_get_result_message(db_result_t code)
{
switch(code) {
case DB_FINISHED:
return "Iteration finished";
case DB_OK:
return "Operation succeeded";
case DB_LIMIT_ERROR:
return "Limit reached";
case DB_ALLOCATION_ERROR:
return "Allocation error";
case DB_STORAGE_ERROR:
return "Storage error";
case DB_PARSING_ERROR:
return "Parsing error";
case DB_NAME_ERROR:
return "Invalid name";
case DB_RELATIONAL_ERROR:
return "Semantic error";
case DB_TYPE_ERROR:
return "Type error";
case DB_IMPLEMENTATION_ERROR:
return "Implementation error";
case DB_INDEX_ERROR:
return "Index error";
case DB_BUSY_ERROR:
return "Busy with processing";
case DB_INCONSISTENCY_ERROR:
return "Inconsistent handle";
case DB_ARGUMENT_ERROR:
return "Invalid argument";
default:
return "Unknown result code";
};
}
db_result_t
db_print_header(db_handle_t *handle)
{
int column;
attribute_t *attr;
output("[relation = %s, attributes = (", handle->result_rel->name);
attr = list_head(handle->result_rel->attributes);
for(column = 0; column < handle->ncolumns; column++) {
if(attr == NULL) {
return DB_IMPLEMENTATION_ERROR;
} else if(attr->flags & ATTRIBUTE_FLAG_NO_STORE) {
continue;
}
output("%s%s", column > 0 ? ", " : "", attr->name);
attr = attr->next;
}
output(")]\n");
return DB_OK;
}
db_result_t
db_print_tuple(db_handle_t *handle)
{
int column;
attribute_value_t value;
db_result_t result;
output("Row %lu:\t", (unsigned long)handle->current_row);
for(column = 0; column < handle->ncolumns; column++) {
result = db_get_value(&value, handle, column);
if(DB_ERROR(result)) {
output("Unable to get the value for row %lu, column %u: %s\n",
(unsigned long)handle->current_row, column,
db_get_result_message(result));
break;
}
switch(value.domain) {
case DOMAIN_STRING:
output("\"%s\"\t", VALUE_STRING(&value));
break;
case DOMAIN_INT:
output("%d\t", (int)VALUE_INT(&value));
break;
case DOMAIN_LONG:
output("%ld\t", (long)VALUE_LONG(&value));
break;
default:
output("\nUnrecognized domain: %d\n", value.domain);
return DB_IMPLEMENTATION_ERROR;
}
}
output("\n");
return DB_OK;
}
int
db_processing(db_handle_t *handle)
{
return handle->flags & DB_HANDLE_FLAG_PROCESSING;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,24 +25,29 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: ethernode-rime.h,v 1.1 2007/03/13 13:07:48 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* Declarations of the main Antelope functions.
* \author
* Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef __ETHERNODE_RIME_H__
#define __ETHERNODE_RIME_H__
#ifndef DB_H
#define DB_H
#include "contiki.h"
#include "db-types.h"
#include "result.h"
#include "aql.h"
PROCESS_NAME(ethernode_rime_process);
typedef int (*db_output_function_t)(const char *, ...);
#endif /* __ETHERNODE_RIME_H__ */
void db_init(void);
void db_set_output_function(db_output_function_t f);
const char *db_get_result_message(db_result_t code);
db_result_t db_print_header(db_handle_t *handle);
db_result_t db_print_tuple(db_handle_t *handle);
int db_processing(db_handle_t *handle);
#endif /* DB_H */

149
apps/antelope/aql-adt.c Normal file
View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Utilities for building the internal representation of an AQL command.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <string.h>
#include "aql.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
static unsigned char char_buf[DB_MAX_CHAR_SIZE_PER_ROW];
static uint8_t next_free_offset;
static aql_attribute_t *
get_attribute(aql_adt_t *adt, char *name)
{
int i;
for(i = 0; i < AQL_ATTRIBUTE_COUNT(adt); i++) {
if(strcmp(adt->attributes[i].name, name) == 0) {
return &adt->attributes[i];
}
}
return NULL;
}
static unsigned char *
save_char(unsigned char *ptr, size_t length)
{
unsigned char *start_ptr;
if(length + next_free_offset > DB_MAX_CHAR_SIZE_PER_ROW) {
return NULL;
}
start_ptr = char_buf + next_free_offset;
memcpy(start_ptr, ptr, length);
next_free_offset += length;
return start_ptr;
}
void
aql_clear(aql_adt_t *adt)
{
char_buf[0] = 0;
next_free_offset = 0;
adt->optype = AQL_TYPE_NONE;
adt->relation_count = 0;
adt->attribute_count = 0;
adt->value_count = 0;
adt->flags = 0;
memset(adt->aggregators, 0, sizeof(adt->aggregators));
}
db_result_t
aql_add_attribute(aql_adt_t *adt, char *name, domain_t domain,
unsigned element_size, int processed_only)
{
aql_attribute_t *attr;
if(adt->attribute_count == AQL_ATTRIBUTE_LIMIT) {
return DB_LIMIT_ERROR;
}
if(processed_only && get_attribute(adt, name)) {
/* No need to have multiple instances of attributes that are only
used for processing in the PLE. */
return DB_OK;
}
attr = &adt->attributes[adt->attribute_count++];
if(strlen(name) + 1 > sizeof(attr->name)) {
return DB_LIMIT_ERROR;
}
strcpy(attr->name, name);
attr->domain = domain;
attr->element_size = element_size;
attr->flags = processed_only ? ATTRIBUTE_FLAG_NO_STORE : 0;
return DB_OK;
}
db_result_t
aql_add_value(aql_adt_t *adt, domain_t domain, void *value_ptr)
{
attribute_value_t *value;
if(adt->value_count == AQL_ATTRIBUTE_LIMIT) {
return DB_LIMIT_ERROR;
}
value = &adt->values[adt->value_count++];
value->domain = domain;
switch(domain) {
case DOMAIN_INT:
VALUE_LONG(value) = *(long *)value_ptr;
break;
case DOMAIN_STRING:
VALUE_STRING(value) = save_char(value_ptr, strlen(value_ptr) + 1);
if(VALUE_STRING(value) != NULL) {
break;
}
default:
return DB_TYPE_ERROR;
}
return DB_OK;
}

240
apps/antelope/aql-exec.c Normal file
View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Query execution functions for AQL.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#include "index.h"
#include "relation.h"
#include "result.h"
#include "aql.h"
static aql_adt_t adt;
static void
clear_handle(db_handle_t *handle)
{
memset(handle, 0, sizeof(*handle));
handle->result_rel = NULL;
handle->left_rel = NULL;
handle->right_rel = NULL;
handle->join_rel = NULL;
}
static db_result_t
aql_execute(db_handle_t *handle, aql_adt_t *adt)
{
uint8_t optype;
int first_rel_arg;
db_result_t result;
relation_t *rel;
aql_attribute_t *attr;
attribute_t *relattr;
optype = AQL_GET_TYPE(adt);
if(optype == AQL_TYPE_NONE) {
/* No-ops always succeed. These can be generated by
empty lines or comments in the query language. */
return DB_OK;
}
/* If the ASSIGN flag is set, the first relation in the array is
the desired result relation. */
first_rel_arg = !!(adt->flags & AQL_FLAG_ASSIGN);
if(optype != AQL_TYPE_CREATE_RELATION &&
optype != AQL_TYPE_REMOVE_RELATION &&
optype != AQL_TYPE_JOIN) {
rel = relation_load(adt->relations[first_rel_arg]);
if(rel == NULL) {
return DB_NAME_ERROR;
}
} else {
rel = NULL;
}
result = DB_RELATIONAL_ERROR;
switch(optype) {
case AQL_TYPE_CREATE_ATTRIBUTE:
attr = &adt->attributes[0];
if(relation_attribute_add(rel, DB_STORAGE, attr->name, attr->domain,
attr->element_size) != NULL) {
result = DB_OK;
}
break;
case AQL_TYPE_CREATE_INDEX:
relattr = relation_attribute_get(rel, adt->attributes[0].name);
if(relattr == NULL) {
result = DB_NAME_ERROR;
break;
}
result = index_create(AQL_GET_INDEX_TYPE(adt), rel, relattr);
break;
case AQL_TYPE_CREATE_RELATION:
if(relation_create(adt->relations[0], DB_STORAGE) != NULL) {
result = DB_OK;
}
break;
case AQL_TYPE_REMOVE_ATTRIBUTE:
result = relation_attribute_remove(rel, adt->attributes[0].name);
break;
case AQL_TYPE_REMOVE_INDEX:
relattr = relation_attribute_get(rel, adt->attributes[0].name);
if(relattr != NULL) {
if(relattr->index != NULL) {
result = index_destroy(relattr->index);
} else {
result = DB_OK;
}
} else {
result = DB_NAME_ERROR;
}
break;
case AQL_TYPE_REMOVE_RELATION:
result = relation_remove(adt->relations[0], 1);
break;
#if DB_FEATURE_REMOVE
case AQL_TYPE_REMOVE_TUPLES:
/* Overwrite the attribute array with a full copy of the original
relation's attributes. */
adt->attribute_count = 0;
for(relattr = list_head(rel->attributes);
relattr != NULL;
relattr = relattr->next) {
AQL_ADD_ATTRIBUTE(adt, relattr->name, DOMAIN_UNSPECIFIED, 0);
}
AQL_SET_FLAG(adt, AQL_FLAG_INVERSE_LOGIC);
#endif /* DB_FEATURE_REMOVE */
case AQL_TYPE_SELECT:
if(handle == NULL) {
result = DB_ARGUMENT_ERROR;
break;
}
result = relation_select(handle, rel, adt);
break;
case AQL_TYPE_INSERT:
result = relation_insert(rel, adt->values);
break;
#if DB_FEATURE_JOIN
case AQL_TYPE_JOIN:
if(handle == NULL) {
result = DB_ARGUMENT_ERROR;
break;
}
handle->left_rel = relation_load(adt->relations[first_rel_arg]);
if(handle->left_rel == NULL) {
break;
}
handle->right_rel = relation_load(adt->relations[first_rel_arg + 1]);
if(handle->right_rel == NULL) {
relation_release(handle->left_rel);
break;
}
result = relation_join(handle, adt);
break;
#endif /* DB_FEATURE_JOIN */
default:
break;
}
if(rel != NULL) {
if(handle == NULL || !(handle->flags & DB_HANDLE_FLAG_PROCESSING)) {
relation_release(rel);
}
}
return result;
}
db_result_t
db_query(db_handle_t *handle, const char *format, ...)
{
va_list ap;
char query_string[AQL_MAX_QUERY_LENGTH];
va_start(ap, format);
vsnprintf(query_string, sizeof(query_string), format, ap);
va_end(ap);
if(handle != NULL) {
clear_handle(handle);
}
if(AQL_ERROR(aql_parse(&adt, query_string))) {
return DB_PARSING_ERROR;
}
/*aql_optimize(&adt);*/
return aql_execute(handle, &adt);
}
db_result_t
db_process(db_handle_t *handle)
{
uint8_t optype;
optype = ((aql_adt_t *)handle->adt)->optype;
switch(optype) {
#if DB_FEATURE_REMOVE
case AQL_TYPE_REMOVE_TUPLES:
return relation_process_remove(handle);
break;
#endif
case AQL_TYPE_SELECT:
return relation_process_select(handle);
break;
#if DB_FEATURE_JOIN
case AQL_TYPE_JOIN:
return relation_process_join(handle);
#endif /* DB_FEATURE_JOIN */
default:
break;
}
PRINTF("DB: Invalid operation type: %d\n", optype);
return DB_INCONSISTENCY_ERROR;
}

274
apps/antelope/aql-lexer.c Normal file
View file

@ -0,0 +1,274 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Lexical analyzer for AQL, the Antelope Query Language.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include "aql.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct keyword {
char *string;
token_t token;
};
/* The keywords are arranged primarily by length and
secondarily by expected lookup frequency. */
static struct keyword keywords[] = {
{";", END},
{"(", LEFT_PAREN},
{")", RIGHT_PAREN},
{",", COMMA},
{"=", EQUAL},
{">", GT},
{"<", LT},
{".", DOT},
{"+", ADD},
{"-", SUB},
{"*", MUL},
{"/", DIV},
{"#", COMMENT},
{">=", GEQ},
{"<=", LEQ},
{"<>", NOT_EQUAL},
{"<-", ASSIGN},
{"OR", OR},
{"IS", IS},
{"ON", ON},
{"IN", IN},
{"AND", AND},
{"NOT", NOT},
{"SUM", SUM},
{"MAX", MAX},
{"MIN", MIN},
{"INT", INT},
{"INTO", INTO},
{"FROM", FROM},
{"MEAN", MEAN},
{"JOIN", JOIN},
{"LONG", LONG},
{"TYPE", TYPE},
{"WHERE", WHERE},
{"COUNT", COUNT},
{"INDEX", INDEX},
{"INSERT", INSERT},
{"SELECT", SELECT},
{"REMOVE", REMOVE},
{"CREATE", CREATE},
{"MEDIAN", MEDIAN},
{"DOMAIN", DOMAIN},
{"STRING", STRING},
{"INLINE", INLINE},
{"PROJECT", PROJECT},
{"MAXHEAP", MAXHEAP},
{"MEMHASH", MEMHASH},
{"RELATION", RELATION},
{"ATTRIBUTE", ATTRIBUTE}
};
/* Provides a pointer to the first keyword of a specific length. */
static const int8_t skip_hint[] = {0, 13, 21, 27, 33, 36, 44, 47, 48};
static char separators[] = "#.;,() \t\n";
int
lexer_start(lexer_t *lexer, char *input, token_t *token, value_t *value)
{
lexer->input = input;
lexer->prev_pos = input;
lexer->token = token;
lexer->value = value;
return 0;
}
static token_t
get_token_id(const char *string, const size_t length)
{
int start, end;
int i;
if(sizeof(skip_hint) < length || length < 1) {
return NONE;
}
start = skip_hint[length - 1];
if(sizeof(skip_hint) == length) {
end = sizeof(keywords) / sizeof(keywords[0]);
} else {
end = skip_hint[length];
}
for(i = start; i < end; i++) {
if(strncasecmp(keywords[i].string, string, length) == 0) {
return keywords[i].token;
}
}
return NONE;
}
static int
next_real(lexer_t *lexer, const char *s)
{
char *end;
long long_value;
#if DB_FEATURE_FLOATS
float float_value;
#endif /* DB_FEATURE_FLOATS */
errno = 0;
long_value = strtol(s, &end, 10);
#if DB_FEATURE_FLOATS
if(*end == '.') {
/* Process a float value. */
float_value = strtof(s, &end);
if(float_value == 0 && s == end) {
return -1;
}
memcpy(lexer->value, &float_value, sizeof(float_value));
*lexer->token = FLOAT_VALUE;
lexer->input = end;
return 1;
}
#endif /* DB_FEATURE_FLOATS */
/* Process an integer value. */
if(long_value == 0 && errno != 0) {
return -1;
}
memcpy(lexer->value, &long_value, sizeof(long_value));
*lexer->token = INTEGER_VALUE;
lexer->input = end;
return 1;
}
static int
next_string(lexer_t *lexer, const char *s)
{
char *end;
size_t length;
end = strchr(s, '\'');
if(end == NULL) {
return -1;
}
length = end - s;
*lexer->token = STRING_VALUE;
lexer->input = end + 1; /* Skip the closing delimiter. */
memcpy(lexer->value, s, length);
(*lexer->value)[length] = '\0';
return 1;
}
static int
next_token(lexer_t *lexer, const char *s)
{
size_t length;
length = strcspn(s, separators);
if(length == 0) {
/* We encountered a separator, so we try to get a token of
precisely 1 byte. */
length = 1;
}
*lexer->token = get_token_id(s, length);
lexer->input = s + length;
if(*lexer->token != NONE) {
return 1;
}
/* The input did not constitute a valid token,
so we regard it as an identifier. */
*lexer->token = IDENTIFIER;
memcpy(lexer->value, s, length);
(*lexer->value)[length] = '\0';
return 1;
}
int
lexer_next(lexer_t *lexer)
{
const char *s;
*lexer->token = NONE;
s = lexer->input;
s += strspn(s, " \t\n");
lexer->prev_pos = s;
switch(*s) {
case '\'':
/* Process the string that follows the delimiter. */
return next_string(lexer, s + 1);
case '\0':
return 0;
default:
if(isdigit((int)*s) || (*s == '-' && isdigit((int)s[1]))) {
return next_real(lexer, s);
}
/* Process a token. */
return next_token(lexer, s);
}
}
void
lexer_rewind(lexer_t *lexer)
{
lexer->input = lexer->prev_pos;
}

877
apps/antelope/aql-parser.c Normal file
View file

@ -0,0 +1,877 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A recursive parser for AQL, the Antelope Query Language.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include "attribute.h"
#include "db-options.h"
#include "index.h"
#include "aql.h"
#include "lvm.h"
#include <limits.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define DEBUG DEBUG_NONE
#include "debug.h"
#if DEBUG
static char error_message[DB_ERROR_BUF_SIZE];
static int error_line;
static const char *error_function;
#define RETURN(value) \
do { \
if(error_message[0] == '\0') { \
strncpy(error_message, lexer->input, sizeof(error_message) - 1); \
error_line = __LINE__; \
error_function = __func__; \
} \
} while(0); \
return (value)
#define RESET_ERROR() \
do { \
error_message[0] = '\0'; \
error_line = 0; \
error_function = NULL; \
} while(0)
#else
#define RETURN(value) return (value)
#define RESET_ERROR()
#endif
#define PARSER(name) \
static aql_status_t \
parse_##name(lexer_t *lexer)
#define PARSER_ARG(name, arg) \
static aql_status_t \
parse_##name(lexer_t *lexer, arg)
#define PARSER_TOKEN(name) \
static token_t \
parse_##name(lexer_t *lexer)
#define PARSE(name) \
!AQL_ERROR(parse_##name(lexer))
#define PARSE_TOKEN(name) \
parse_##name(lexer)
#define NEXT lexer_next(lexer)
#define REWIND lexer_rewind(lexer); RESET_ERROR()
#define TOKEN *lexer->token
#define VALUE *lexer->value
#define CONSUME(token) \
do { \
NEXT; \
if(TOKEN != (token)) { \
RETURN(SYNTAX_ERROR); \
} \
} while(0)
/*
* The grammar of this language is defined in Extended Backus-Naur Form,
* where capitalized strings correspond to lexical tokens defined in
* aql.h and interpreted in lexer.c.
*
* operand = LEFT_PAREN, expr, RIGHT_PAREN | INTEGER | FLOAT |
* IDENTIFIER | STRING ;
* operator = ADD | SUB | MUL | DIV ;
* expr = operand, operator, operand ;
*
* comparison-operator = GE | GEQ | LE | LEQ | EQ | NEQ ;
* comparison = expr, comparison-operator, expr ;
* condition = comparison, [(AND | OR), comparison] ;
* relation-list = IDENTIFIER, {COMMA, relation-list} ;
* attribute-list = IDENTIFIER, {COMMA, attribute-list} ;
* select = SELECT, attribute-list, FROM, relation-list, WHERE, condition, END ;
*
* value = INTEGER | FLOAT | STRING ;
* value-list = value, {COMMA, value} ;
* insert = INSERT, LEFT_PAREN, value-list, RIGHT_PAREN, INTO, IDENTIFIER, END ;
*
* sqrl = select | insert ;
*/
static aql_adt_t *adt;
static lvm_instance_t p;
static unsigned char vmcode[128];
PARSER_TOKEN(cmp)
{
NEXT;
switch(TOKEN) {
case EQUAL:
case NOT_EQUAL:
case GT:
case LT:
case GEQ:
case LEQ:
return TOKEN;
default:
return NONE;
}
}
PARSER_TOKEN(op)
{
NEXT;
switch(TOKEN) {
case ADD:
case SUB:
case MUL:
case DIV:
case RIGHT_PAREN:
return TOKEN;
default:
return NONE;
}
}
PARSER_TOKEN(aggregator)
{
NEXT;
switch(TOKEN) {
case COUNT:
case SUM:
case MEAN:
case MEDIAN:
case MAX:
case MIN:
return TOKEN;
default:
return NONE;
}
}
PARSER(attributes)
{
token_t token;
aql_aggregator_t function;
token = PARSE_TOKEN(aggregator);
if(token != NONE) {
switch(TOKEN) {
case COUNT:
function = AQL_COUNT;
break;
case SUM:
function = AQL_SUM;
break;
case MEAN:
function = AQL_MEAN;
break;
case MEDIAN:
function = AQL_MEDIAN;
break;
case MAX:
function = AQL_MAX;
break;
case MIN:
function = AQL_MIN;
break;
default:
RETURN(SYNTAX_ERROR);
}
AQL_SET_FLAG(adt, AQL_FLAG_AGGREGATE);
PRINTF("aggregator: %d\n", TOKEN);
/* Parse the attribute to aggregate. */
CONSUME(LEFT_PAREN);
CONSUME(IDENTIFIER);
AQL_ADD_AGGREGATE(adt, function, VALUE);
PRINTF("aggregated attribute: %s\n", VALUE);
CONSUME(RIGHT_PAREN);
goto check_more_attributes;
} else {
REWIND;
}
/* Plain identifier. */
CONSUME(IDENTIFIER);
AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
check_more_attributes:
NEXT;
if(TOKEN == COMMA) {
if(!PARSE(attributes)) {
RETURN(SYNTAX_ERROR);
}
} else {
REWIND;
}
RETURN(OK);
}
PARSER(relations)
{
/* Parse comma-separated identifiers for relations. */
CONSUME(IDENTIFIER);
AQL_ADD_RELATION(adt, VALUE);
NEXT;
if(TOKEN == COMMA) {
if(!PARSE(relations)) {
RETURN(SYNTAX_ERROR);
}
} else {
REWIND;
}
RETURN(OK);
}
PARSER(values)
{
/* Parse comma-separated attribute values. */
NEXT;
switch(TOKEN) {
case STRING_VALUE:
AQL_ADD_VALUE(adt, DOMAIN_STRING, VALUE);
break;
case INTEGER_VALUE:
AQL_ADD_VALUE(adt, DOMAIN_INT, VALUE);
break;
default:
RETURN(SYNTAX_ERROR);
}
NEXT;
if(TOKEN == COMMA) {
return PARSE(values);
} else {
REWIND;
}
RETURN(OK);
}
PARSER(operand)
{
NEXT;
switch(TOKEN) {
case IDENTIFIER:
lvm_register_variable(VALUE, LVM_LONG);
lvm_set_variable(&p, VALUE);
AQL_ADD_PROCESSING_ATTRIBUTE(adt, VALUE);
break;
case STRING_VALUE:
break;
case FLOAT_VALUE:
break;
case INTEGER_VALUE:
lvm_set_long(&p, *(long *)lexer->value);
break;
default:
RETURN(SYNTAX_ERROR);
}
RETURN(OK);
}
PARSER(expr)
{
token_t token;
size_t saved_end;
operator_t op;
saved_end = lvm_get_end(&p);
NEXT;
if(TOKEN == LEFT_PAREN) {
if(!PARSE(expr)) {
RETURN(SYNTAX_ERROR);
}
CONSUME(RIGHT_PAREN);
} else {
REWIND;
if(!PARSE(operand)) {
RETURN(SYNTAX_ERROR);
}
}
while(1) {
token = PARSE_TOKEN(op);
if(token == NONE) {
saved_end = lvm_get_end(&p);
REWIND;
break;
} else if (token == RIGHT_PAREN) {
break;
}
if(!PARSE(operand) && !PARSE(expr)) {
RETURN(SYNTAX_ERROR);
}
saved_end = lvm_shift_for_operator(&p, saved_end);
switch(token) {
case ADD:
op = LVM_ADD;
break;
case SUB:
op = LVM_SUB;
break;
case MUL:
op = LVM_MUL;
break;
case DIV:
op = LVM_DIV;
break;
default:
RETURN(SYNTAX_ERROR);
}
lvm_set_op(&p, op);
lvm_set_end(&p, saved_end);
}
return OK;
}
PARSER(comparison)
{
token_t token;
size_t saved_end;
operator_t rel;
saved_end = lvm_jump_to_operand(&p);
if(!PARSE(expr)) {
RETURN(SYNTAX_ERROR);
}
saved_end = lvm_set_end(&p, saved_end);
token = PARSE_TOKEN(cmp);
if(token == NONE) {
RETURN(SYNTAX_ERROR);
}
switch(token) {
case GT:
rel = LVM_GE;
break;
case GEQ:
rel = LVM_GEQ;
break;
case LT:
rel = LVM_LE;
break;
case LEQ:
rel = LVM_LEQ;
break;
case EQUAL:
rel = LVM_EQ;
break;
case NOT_EQUAL:
rel = LVM_NEQ;
break;
default:
RETURN(SYNTAX_ERROR);
}
lvm_set_relation(&p, rel);
lvm_set_end(&p, saved_end);
if(!PARSE(expr)) {
RETURN(SYNTAX_ERROR);
}
RETURN(OK);
}
PARSER(where)
{
int r;
operator_t connective;
size_t saved_end;
if(!PARSE(comparison)) {
RETURN(SYNTAX_ERROR);
}
saved_end = 0;
/* The WHERE clause can consist of multiple prepositions. */
for(;;) {
NEXT;
if(TOKEN != AND && TOKEN != OR) {
REWIND;
break;
}
connective = TOKEN == AND ? LVM_AND : LVM_OR;
saved_end = lvm_shift_for_operator(&p, saved_end);
lvm_set_relation(&p, connective);
lvm_set_end(&p, saved_end);
NEXT;
if(TOKEN == LEFT_PAREN) {
r = PARSE(where);
if(!r) {
RETURN(SYNTAX_ERROR);
}
CONSUME(RIGHT_PAREN);
} else {
REWIND;
r = PARSE(comparison);
if(!r) {
RETURN(r);
}
}
}
lvm_print_code(&p);
return OK;
}
PARSER(join)
{
AQL_SET_TYPE(adt, AQL_TYPE_JOIN);
CONSUME(IDENTIFIER);
PRINTF("Left relation: %s\n", VALUE);
AQL_ADD_RELATION(adt, VALUE);
CONSUME(COMMA);
CONSUME(IDENTIFIER);
PRINTF("Right relation: %s\n", VALUE);
AQL_ADD_RELATION(adt, VALUE);
CONSUME(ON);
CONSUME(IDENTIFIER);
PRINTF("Join on attribute %s\n", VALUE);
AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
CONSUME(PROJECT);
/* projection attributes... */
if(!PARSE(attributes)) {
RETURN(SYNTAX_ERROR);
}
CONSUME(END);
RETURN(OK);
}
PARSER(select)
{
AQL_SET_TYPE(adt, AQL_TYPE_SELECT);
/* projection attributes... */
if(!PARSE(attributes)) {
RETURN(SYNTAX_ERROR);
}
CONSUME(FROM);
if(!PARSE(relations)) {
RETURN(SYNTAX_ERROR);
}
NEXT;
if(TOKEN == WHERE) {
lvm_reset(&p, vmcode, sizeof(vmcode));
if(!PARSE(where)) {
RETURN(SYNTAX_ERROR);
}
AQL_SET_CONDITION(adt, &p);
} else {
REWIND;
RETURN(OK);
}
CONSUME(END);
return OK;
}
PARSER(insert)
{
AQL_SET_TYPE(adt, AQL_TYPE_INSERT);
CONSUME(LEFT_PAREN);
if(!PARSE(values)) {
RETURN(SYNTAX_ERROR);
}
CONSUME(RIGHT_PAREN);
CONSUME(INTO);
if(!PARSE(relations)) {
RETURN(SYNTAX_ERROR);
}
RETURN(OK);
}
PARSER(remove_attribute)
{
AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_ATTRIBUTE);
CONSUME(IDENTIFIER);
AQL_ADD_RELATION(adt, VALUE);
CONSUME(DOT);
CONSUME(IDENTIFIER);
PRINTF("Removing the index for the attribute %s\n", VALUE);
AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
RETURN(OK);
}
#if DB_FEATURE_REMOVE
PARSER(remove_from)
{
AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_TUPLES);
/* Use a temporary persistent relation to assign the query result to. */
AQL_SET_FLAG(adt, AQL_FLAG_ASSIGN);
AQL_ADD_RELATION(adt, TEMP_RELATION);
CONSUME(IDENTIFIER);
AQL_ADD_RELATION(adt, VALUE);
CONSUME(WHERE);
lvm_reset(&p, vmcode, sizeof(vmcode));
AQL_SET_CONDITION(adt, &p);
return PARSE(where);
}
#endif /* DB_FEATURE_REMOVE */
PARSER(remove_index)
{
AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_INDEX);
CONSUME(IDENTIFIER);
AQL_ADD_RELATION(adt, VALUE);
CONSUME(DOT);
CONSUME(IDENTIFIER);
PRINTF("remove index: %s\n", VALUE);
AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
RETURN(OK);
}
PARSER(remove_relation)
{
AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_RELATION);
CONSUME(IDENTIFIER);
PRINTF("remove relation: %s\n", VALUE);
AQL_ADD_RELATION(adt, VALUE);
RETURN(OK);
}
PARSER(remove)
{
aql_status_t r;
NEXT;
switch(TOKEN) {
case ATTRIBUTE:
r = PARSE(remove_attribute);
break;
#if DB_FEATURE_REMOVE
case FROM:
r = PARSE(remove_from);
break;
#endif
case INDEX:
r = PARSE(remove_index);
break;
case RELATION:
r = PARSE(remove_relation);
break;
default:
RETURN(SYNTAX_ERROR);
}
if(!r) {
RETURN(SYNTAX_ERROR);
}
CONSUME(END);
RETURN(OK);
}
PARSER_TOKEN(index_type)
{
index_type_t type;
NEXT;
switch(TOKEN) {
case INLINE:
type = INDEX_INLINE;
break;
case MAXHEAP:
type = INDEX_MAXHEAP;
break;
case MEMHASH:
type = INDEX_MEMHASH;
break;
default:
return NONE;
};
AQL_SET_INDEX_TYPE(adt, type);
return TOKEN;
}
PARSER(create_index)
{
AQL_SET_TYPE(adt, AQL_TYPE_CREATE_INDEX);
CONSUME(IDENTIFIER);
AQL_ADD_RELATION(adt, VALUE);
CONSUME(DOT);
CONSUME(IDENTIFIER);
PRINTF("Creating an index for the attribute %s\n", VALUE);
AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
CONSUME(TYPE);
if(PARSE_TOKEN(index_type) == NONE) {
RETURN(SYNTAX_ERROR);
}
RETURN(OK);
}
PARSER(create_relation)
{
CONSUME(IDENTIFIER);
AQL_SET_TYPE(adt, AQL_TYPE_CREATE_RELATION);
AQL_ADD_RELATION(adt, VALUE);
RETURN(OK);
}
PARSER_ARG(domain, char *name)
{
domain_t domain;
unsigned element_size;
NEXT;
switch(TOKEN) {
case STRING:
domain = DOMAIN_STRING;
/* Parse the amount of characters for this domain. */
CONSUME(LEFT_PAREN);
CONSUME(INTEGER_VALUE);
element_size = *(long *)lexer->value;
CONSUME(RIGHT_PAREN);
break;
case LONG:
domain = DOMAIN_LONG;
element_size = 4;
break;
case INT:
domain = DOMAIN_INT;
element_size = 2;
break;
default:
return NONE;
}
AQL_ADD_ATTRIBUTE(adt, name, domain, element_size);
return OK;
}
PARSER(create_attributes)
{
aql_status_t r;
char name[ATTRIBUTE_NAME_LENGTH];
AQL_SET_TYPE(adt, AQL_TYPE_CREATE_ATTRIBUTE);
CONSUME(IDENTIFIER);
strncpy(name, VALUE, sizeof(name) - 1);
name[sizeof(name) - 1] = '\0';
CONSUME(DOMAIN);
r = parse_domain(lexer, name);
if(AQL_ERROR(r)) {
RETURN(r);
}
CONSUME(IN);
CONSUME(IDENTIFIER);
AQL_ADD_RELATION(adt, VALUE);
RETURN(OK);
}
PARSER(create)
{
aql_status_t r;
NEXT;
switch(TOKEN) {
case ATTRIBUTE:
r = PARSE(create_attributes);
break;
case INDEX:
r = PARSE(create_index);
break;
case RELATION:
r = PARSE(create_relation);
break;
default:
RETURN(SYNTAX_ERROR);
}
if(!r) {
RETURN(SYNTAX_ERROR);
}
CONSUME(END);
RETURN(OK);
}
aql_status_t
aql_parse(aql_adt_t *external_adt, char *input_string)
{
lexer_t lex;
token_t token = NONE;
value_t value;
aql_status_t result;
RESET_ERROR();
PRINTF("Parsing \"%s\"\n", input_string);
adt = external_adt;
AQL_CLEAR(adt);
AQL_SET_CONDITION(adt, NULL);
lexer_start(&lex, input_string, &token, &value);
result = lexer_next(&lex);
if(!AQL_ERROR(result)) {
switch(token) {
case IDENTIFIER:
PRINTF("Assign the result to relation %s\n", *lex.value);
AQL_ADD_RELATION(adt, *lex.value);
AQL_SET_FLAG(adt, AQL_FLAG_ASSIGN);
if(AQL_ERROR(lexer_next(&lex))) {
result = SYNTAX_ERROR;
break;
}
if(*lex.token != ASSIGN) {
result = SYNTAX_ERROR;
break;
}
if(AQL_ERROR(lexer_next(&lex))) {
result = SYNTAX_ERROR;
break;
}
switch(*lex.token) {
case SELECT:
result = parse_select(&lex);
break;
case JOIN:
result = parse_join(&lex);
break;
default:
result = SYNTAX_ERROR;
}
break;
case JOIN:
result = parse_join(&lex);
break;
case CREATE:
result = parse_create(&lex);
break;
case REMOVE:
result = parse_remove(&lex);
break;
case INSERT:
result = parse_insert(&lex);
break;
case SELECT:
result = parse_select(&lex);
break;
case NONE:
case COMMENT:
result = OK;
case END:
break;
default:
result = SYNTAX_ERROR;
}
}
if(AQL_ERROR(result)) {
PRINTF("Error in function %s, line %d: input \"%s\"\n",
error_function, error_line, error_message);
}
return result;
}

221
apps/antelope/aql.h Normal file
View file

@ -0,0 +1,221 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Definitions and declarations for AQL, the Antelope Query Language.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef AQL_H
#define AQL_H
#include "db-options.h"
#include "index.h"
#include "relation.h"
#include "result.h"
enum aql_status {
OK = 2,
SYNTAX_ERROR = 3,
INVALID_TOKEN = 9,
PLE_ERROR = 12
};
typedef enum aql_status aql_status_t;
#define AQL_ERROR(x) ((x) >= 3)
enum token {
END = 0,
LEFT_PAREN = 1,
RIGHT_PAREN = 2,
COMMA = 3,
EQUAL = 4,
GT = 5,
LT = 6,
DOT = 7,
ADD = 8,
SUB = 9,
MUL = 10,
DIV = 11,
COMMENT = 12,
GEQ = 13,
LEQ = 14,
NOT_EQUAL = 15,
ASSIGN = 16,
OR = 17,
IS = 18,
ON = 19,
IN = 20,
AND = 21,
NOT = 22,
SUM = 23,
MAX = 24,
MIN = 25,
INT = 26,
INTO = 27,
FROM = 28,
MEAN = 29,
JOIN = 30,
LONG = 31,
TYPE = 32,
WHERE = 33,
COUNT = 34,
INDEX = 35,
INSERT = 36,
SELECT = 37,
REMOVE = 38,
CREATE = 39,
MEDIAN = 40,
DOMAIN = 41,
STRING = 42,
INLINE = 43,
PROJECT = 44,
MAXHEAP = 45,
MEMHASH = 46,
RELATION = 47,
ATTRIBUTE = 48,
INTEGER_VALUE = 251,
FLOAT_VALUE = 252,
STRING_VALUE = 253,
IDENTIFIER = 254,
NONE = 255
};
typedef enum token token_t;
typedef char value_t[DB_MAX_ELEMENT_SIZE];
struct lexer {
const char *input;
const char *prev_pos;
token_t *token;
value_t *value;
};
typedef struct lexer lexer_t;
enum aql_aggregator {
AQL_NONE = 0,
AQL_COUNT = 1,
AQL_SUM = 2,
AQL_MIN = 3,
AQL_MAX = 4,
AQL_MEAN = 5,
AQL_MEDIAN = 6
};
typedef enum aql_aggregator aql_aggregator_t;
struct aql_attribute {
domain_t domain;
uint8_t element_size;
uint8_t flags;
char name[ATTRIBUTE_NAME_LENGTH + 1];
};
typedef struct aql_attribute aql_attribute_t;
struct aql_adt {
char relations[AQL_RELATION_LIMIT][RELATION_NAME_LENGTH + 1];
aql_attribute_t attributes[AQL_ATTRIBUTE_LIMIT];
aql_aggregator_t aggregators[AQL_ATTRIBUTE_LIMIT];
attribute_value_t values[AQL_ATTRIBUTE_LIMIT];
index_type_t index_type;
uint8_t relation_count;
uint8_t attribute_count;
uint8_t value_count;
uint8_t optype;
uint8_t flags;
void *lvm_instance;
};
typedef struct aql_adt aql_adt_t;
#define AQL_TYPE_NONE 0
#define AQL_TYPE_SELECT 1
#define AQL_TYPE_INSERT 2
#define AQL_TYPE_UPDATE 3
#define AQL_TYPE_DROP 4
#define AQL_TYPE_DELETE 5
#define AQL_TYPE_RENAME 6
#define AQL_TYPE_CREATE_ATTRIBUTE 7
#define AQL_TYPE_CREATE_INDEX 8
#define AQL_TYPE_CREATE_RELATION 9
#define AQL_TYPE_REMOVE_ATTRIBUTE 10
#define AQL_TYPE_REMOVE_INDEX 11
#define AQL_TYPE_REMOVE_RELATION 12
#define AQL_TYPE_REMOVE_TUPLES 13
#define AQL_TYPE_JOIN 14
#define AQL_FLAG_AGGREGATE 1
#define AQL_FLAG_ASSIGN 2
#define AQL_FLAG_INVERSE_LOGIC 4
#define AQL_CLEAR(adt) aql_clear(adt)
#define AQL_SET_TYPE(adt, type) (((adt))->optype = (type))
#define AQL_GET_TYPE(adt) ((adt)->optype)
#define AQL_SET_INDEX_TYPE(adt, type) ((adt)->index_type = (type))
#define AQL_GET_INDEX_TYPE(adt) ((adt)->index_type)
#define AQL_SET_FLAG(adt, flag) (((adt)->flags) |= (flag))
#define AQL_GET_FLAGS(adt) ((adt)->flags)
#define AQL_ADD_RELATION(adt, rel) \
strcpy((adt)->relations[(adt)->relation_count++], (rel))
#define AQL_RELATION_COUNT(adt) ((adt)->relation_count)
#define AQL_ADD_ATTRIBUTE(adt, attr, dom, size) \
aql_add_attribute(adt, attr, dom, size, 0)
#define AQL_ADD_PROCESSING_ATTRIBUTE(adt, attr) \
aql_add_attribute((adt), (attr), DOMAIN_UNSPECIFIED, 0, 1)
#define AQL_ADD_AGGREGATE(adt, function, attr) \
do { \
(adt)->aggregators[(adt)->attribute_count] = (function); \
aql_add_attribute((adt), (attr), DOMAIN_UNSPECIFIED, 0, 0); \
} while(0)
#define AQL_ATTRIBUTE_COUNT(adt) ((adt)->attribute_count)
#define AQL_SET_CONDITION(adt, cond) ((adt)->lvm_instance = (cond))
#define AQL_ADD_VALUE(adt, domain, value) \
aql_add_value((adt), (domain), (value))
int lexer_start(lexer_t *, char *, token_t *, value_t *);
int lexer_next(lexer_t *);
void lexer_rewind(lexer_t *);
void aql_clear(aql_adt_t *adt);
aql_status_t aql_parse(aql_adt_t *adt, char *query_string);
db_result_t aql_add_attribute(aql_adt_t *adt, char *name,
domain_t domain, unsigned element_size,
int processed_only);
db_result_t aql_add_value(aql_adt_t *adt, domain_t domain, void *value);
db_result_t db_query(db_handle_t *handle, const char *format, ...);
db_result_t db_process(db_handle_t *handle);
#endif /* !AQL_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,41 +25,65 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: contiki-esb.h,v 1.2 2006/10/10 15:58:31 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* Definitions for attributes.
* \author
* Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef __CONTIKI_ESB_H__
#define __CONTIKI_ESB_H__
#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H
#include "contiki.h"
#include "contiki-net.h"
#include "contiki-lib.h"
#include "dev/leds.h"
#include <stdint.h>
#include <stdlib.h>
#include "dev/vib-sensor.h"
#include "dev/radio-sensor.h"
#include "dev/pir-sensor.h"
#include "dev/temperature-sensor.h"
#include "dev/button-sensor.h"
#include "lib/list.h"
#include "dev/lpm.h"
#include "dev/radio.h"
#include "db-options.h"
#include "dev/tr1001.h"
#include "dev/tr1001-drv.h"
typedef enum {
DOMAIN_UNSPECIFIED = 0,
DOMAIN_INT = 1,
DOMAIN_LONG = 2,
DOMAIN_STRING = 3,
DOMAIN_FLOAT = 4
} domain_t;
#include "dev/beep.h"
#define ATTRIBUTE_FLAG_NO_STORE 0x1
#define ATTRIBUTE_FLAG_INVALID 0x2
#define ATTRIBUTE_FLAG_PRIMARY_KEY 0x4
#define ATTRIBUTE_FLAG_UNIQUE 0x8
#include "node-id.h"
struct attribute {
struct attribute *next;
void *index;
long aggregation_value;
uint8_t aggregator;
uint8_t domain;
uint8_t element_size;
uint8_t flags;
char name[ATTRIBUTE_NAME_LENGTH + 1];
};
#endif /* __CONTIKI_ESB_H__ */
typedef struct attribute attribute_t;
typedef uint8_t attribute_id_t;
struct attribute_value {
union {
int int_value;
long long_value;
unsigned char *string_value;
} u;
domain_t domain;
};
typedef struct attribute_value attribute_value_t;
#define VALUE_LONG(value) (value)->u.long_value
#define VALUE_INT(value) (value)->u.int_value
#define VALUE_STRING(value) (value)->u.string_value
#endif /* ATTRIBUTES_H */

173
apps/antelope/db-options.h Normal file
View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Database configuration options.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef DB_OPTIONS_H
#define DB_OPTIONS_H
#include "contiki-conf.h"
/* Features. Include only what is needed in order to save space. */
#ifndef DB_FEATURE_JOIN
#define DB_FEATURE_JOIN 1
#endif /* DB_FEATURE_JOIN */
#ifndef DB_FEATURE_REMOVE
#define DB_FEATURE_REMOVE 1
#endif /* DB_FEATURE_REMOVE */
#ifndef DB_FEATURE_FLOATS
#define DB_FEATURE_FLOATS 0
#endif /* DB_FEATURE_FLOATS */
#ifndef DB_FEATURE_COFFEE
#define DB_FEATURE_COFFEE 1
#endif /* DB_FEATURE_COFFEE */
#ifndef DB_FEATURE_INTEGRITY
#define DB_FEATURE_INTEGRITY 0
#endif /* DB_FEATURE_INTEGRITY */
/* Configuration parameters that may be trimmed to save space. */
#ifndef DB_ERROR_BUF_SIZE
#define DB_ERROR_BUF_SIZE 50
#endif /* DB_ERROR_BUF_SIZE */
#ifndef DB_INDEX_POOL_SIZE
#define DB_INDEX_POOL_SIZE 3
#endif /* DB_INDEX_POOL_SIZE */
#ifndef DB_RELATION_POOL_SIZE
#define DB_RELATION_POOL_SIZE 5
#endif /* DB_RELATION_POOL_SIZE */
#ifndef DB_ATTRIBUTE_POOL_SIZE
#define DB_ATTRIBUTE_POOL_SIZE 16
#endif /* DB_ATTRIBUTE_POOL_SIZE */
#ifndef DB_MAX_ATTRIBUTES_PER_RELATION
#define DB_MAX_ATTRIBUTES_PER_RELATION 6
#endif /* DB_MAX_ATTRIBUTES_PER_RELATION */
#ifndef DB_MAX_ELEMENT_SIZE
#define DB_MAX_ELEMENT_SIZE 16
#endif /* DB_MAX_ELEMENT_SIZE */
/* Language options. */
#ifndef AQL_MAX_QUERY_LENGTH
#define AQL_MAX_QUERY_LENGTH 128
#endif /* AQL_MAX_QUERY_LENGTH */
#ifndef AQL_MAX_VALUE_LENGTH
#define AQL_MAX_VALUE_LENGTH DB_MAX_ELEMENT_SIZE
#endif /* AQL_MAX_VALUE_LENGTH */
#ifndef AQL_RELATION_LIMIT
#define AQL_RELATION_LIMIT 3
#endif /* AQL_RELATION_LIMIT */
#ifndef AQL_ATTRIBUTE_LIMIT
#define AQL_ATTRIBUTE_LIMIT 5
#endif /* AQL_ATTRIBUTE_LIMIT */
/* Physical storage options. Changing these may cause compatibility problems. */
#ifndef DB_COFFEE_RESERVE_SIZE
#define DB_COFFEE_RESERVE_SIZE (128 * 1024UL)
#endif /* DB_COFFEE_RESERVE_SIZE */
#ifndef DB_MAX_CHAR_SIZE_PER_ROW
#define DB_MAX_CHAR_SIZE_PER_ROW 64
#endif /* DB_MAX_CHAR_SIZE_PER_ROW */
#ifndef DB_MAX_FILENAME_LENGTH
#define DB_MAX_FILENAME_LENGTH 16
#endif /* DB_MAX_FILENAME_LENGTH */
#ifndef ATTRIBUTE_NAME_LENGTH
#define ATTRIBUTE_NAME_LENGTH 12
#endif /* ATTRIBUTE_NAME_LENGTH */
#ifndef RELATION_NAME_LENGTH
#define RELATION_NAME_LENGTH 10
#endif /* RELATION_NAME_LENGTH */
#ifndef RESULT_RELATION
#define RESULT_RELATION "db-result"
#endif /* RESULT_RELATION */
#ifndef TEMP_RELATION
#define TEMP_RELATION "db-temp"
#endif /* TEMP_RELATION */
/* Index options. */
#ifndef DB_INDEX_COST
#define DB_INDEX_COST 64
#endif /* DB_INDEX_COST */
#ifndef DB_MEMHASH_INDEX_LIMIT
#define DB_MEMHASH_INDEX_LIMIT 1
#endif /* DB_MEMHASH_INDEX_LIMIT */
#ifndef DB_MEMHASH_TABLE_SIZE
#define DB_MEMHASH_TABLE_SIZE 61
#endif /* DB_MEMHASH_TABLE_SIZE */
#ifndef DB_HEAP_INDEX_LIMIT
#define DB_HEAP_INDEX_LIMIT 1
#endif /* DB_HEAP_INDEX_LIMIT */
#ifndef DB_HEAP_CACHE_LIMIT
#define DB_HEAP_CACHE_LIMIT 1
#endif /* DB_HEAP_CACHE_LIMIT */
/* Propositional Logic Engine options. */
#ifndef PLE_MAX_NAME_LENGTH
#define PLE_MAX_NAME_LENGTH ATTRIBUTE_NAME_LENGTH
#endif /* PLE_MAX_NAME_LENGTH */
#ifndef PLE_MAX_VARIABLE_ID
#define PLE_MAX_VARIABLE_ID AQL_ATTRIBUTE_LIMIT - 1
#endif /* PLE_MAX_VARIABLE_ID */
#ifndef PLE_USE_FLOATS
#define PLE_USE_FLOATS DB_FEATURE_FLOATS
#endif /* PLE_USE_FLOATS */
#endif /* !DB_OPTIONS_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,24 +25,40 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: loader-arch.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $
*/
/**
* \file
* Loader definitions for the netsim target
* .
* \author
* Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef __LOADER_ARCH_H__
#define __LOADER_ARCH_H__
#ifndef DB_TYPES_H
#define DB_TYPES_H
#include "loader/dlloader.h"
enum db_result {
DB_FINISHED = 3,
DB_GOT_ROW = 2,
DB_OK = 1,
DB_LIMIT_ERROR = -1,
DB_ALLOCATION_ERROR = -2,
DB_STORAGE_ERROR = -3,
DB_PARSING_ERROR = -4,
DB_NAME_ERROR = -5,
DB_RELATIONAL_ERROR = -6,
DB_TYPE_ERROR = -7,
DB_IMPLEMENTATION_ERROR = -8,
DB_INDEX_ERROR = -9,
DB_BUSY_ERROR = -10,
DB_INCONSISTENCY_ERROR = -11,
DB_ARGUMENT_ERROR = -12
};
#define LOADER_LOAD(name, arg) dlloader_load(name, arg);
typedef enum db_result db_result_t;
typedef int db_storage_id_t;
#endif /* __LOADER_ARCH_H__ */
#define DB_ERROR(result_code) ((result_code) < DB_OK)
#define DB_SUCCESS(result_code) !DB_ERROR(result_code)
#endif /* !DB_TYPES_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,28 +28,37 @@
*
* This file is part of the Contiki operating system.
*
* $Id: lpm.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
* $Id: uip-debug.h,v 1.1 2010/04/30 13:20:57 joxe Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
* A set of debugging macros.
*
* \author Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "lpm.h"
#ifndef UIP_DEBUG_H
#define UIP_DEBUG_H
#define DEBUG_NONE 0
#define DEBUG_PRINT 1
#define DEBUG_ANNOTATE 2
#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT
#if (DEBUG) & DEBUG_ANNOTATE
#include <stdio.h>
/*---------------------------------------------------------------------------*/
void
lpm_on(void)
{
printf("lpm_on()\n");
}
/*---------------------------------------------------------------------------*/
void
lpm_off(void)
{
printf("lpm_off()\n");
}
/*---------------------------------------------------------------------------*/
#define ANNOTATE(...) printf(__VA_ARGS__)
#else
#define ANNOTATE(...)
#endif /* (DEBUG) & DEBUG_ANNOTATE */
#if (DEBUG) & DEBUG_PRINT
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif /* (DEBUG) & DEBUG_PRINT */
#endif

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A binary search index for attributes that are constrained to be
* monotonically increasing, which is a rather common pattern for
* time series or keys. Since this index has no storage overhead,
* it does not wear out the flash memory nor does it occupy scarce
* scarce space. Furthermore, unlike B+-trees, it has a O(1) memory
* footprint in relation to the number of data items.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdlib.h>
#include <string.h>
#include "index.h"
#include "relation.h"
#include "result.h"
#include "storage.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
struct search_handle {
index_t *index;
tuple_id_t start_row;
tuple_id_t end_row;
};
struct search_handle handle;
static db_result_t null_op(index_t *);
static db_result_t insert(index_t *, attribute_value_t *, tuple_id_t);
static db_result_t delete(index_t *, attribute_value_t *);
static tuple_id_t get_next(index_iterator_t *);
/*
* The create, destroy, load, release, insert, and delete operations
* of the index API always succeed because the index does not store
* items separately from the row file. The four former operations share
* the same signature, and are thus implemented by the null_op function
* to save space.
*/
index_api_t index_inline = {
INDEX_INLINE,
INDEX_API_EXTERNAL | INDEX_API_COMPLETE | INDEX_API_RANGE_QUERIES,
null_op,
null_op,
null_op,
null_op,
insert,
delete,
get_next
};
static attribute_value_t *
get_value(tuple_id_t *index, relation_t *rel, attribute_t *attr)
{
unsigned char *row;
static attribute_value_t value;
row = alloca(rel->row_length);
if(row == NULL) {
return NULL;
}
if(DB_ERROR(storage_get_row(rel, index, row))) {
return NULL;
}
if(DB_ERROR(relation_get_value(rel, attr, row, &value))) {
PRINTF("DB: Unable to retrieve a value from tuple %ld\n", (long)(*index));
return NULL;
}
return &value;
}
static tuple_id_t
binary_search(index_iterator_t *index_iterator,
attribute_value_t *target_value,
int exact_match)
{
relation_t *rel;
attribute_t *attr;
attribute_value_t *cmp_value;
tuple_id_t min;
tuple_id_t max;
tuple_id_t center;
rel = index_iterator->index->rel;
attr = index_iterator->index->attr;
max = relation_cardinality(rel);
if(max == INVALID_TUPLE) {
return INVALID_TUPLE;
}
max--;
min = 0;
do {
center = min + ((max - min) / 2);
cmp_value = get_value(&center, rel, attr);
if(cmp_value == NULL) {
PRINTF("DB: Failed to get the center value, index = %ld\n",
(long)center);
return INVALID_TUPLE;
}
if(db_value_to_long(target_value) > db_value_to_long(cmp_value)) {
min = center + 1;
} else {
max = center - 1;
}
} while(min <= max && db_value_to_long(target_value) != db_value_to_long(cmp_value));
if(exact_match &&
db_value_to_long(target_value) != db_value_to_long(cmp_value)) {
PRINTF("DB: Could not find value %ld in the inline index\n",
db_value_to_long(target_value));
return INVALID_TUPLE;
}
return center;
}
static tuple_id_t
range_search(index_iterator_t *index_iterator,
tuple_id_t *start, tuple_id_t *end)
{
attribute_value_t *low_target;
attribute_value_t *high_target;
int exact_match;
low_target = &index_iterator->min_value;
high_target = &index_iterator->max_value;
PRINTF("DB: Search index for value range (%ld, %ld)\n",
db_value_to_long(low_target), db_value_to_long(high_target));
exact_match = db_value_to_long(low_target) == db_value_to_long(high_target);
/* Optimize later so that the other search uses the result
from the first one. */
*start = binary_search(index_iterator, low_target, exact_match);
if(*start == INVALID_TUPLE) {
return DB_INDEX_ERROR;
}
*end = binary_search(index_iterator, high_target, exact_match);
if(*end == INVALID_TUPLE) {
return DB_INDEX_ERROR;
}
return DB_OK;
}
static db_result_t
null_op(index_t *index)
{
return DB_OK;
}
static db_result_t
insert(index_t *index, attribute_value_t *value, tuple_id_t tuple_id)
{
return DB_OK;
}
static db_result_t
delete(index_t *index, attribute_value_t *value)
{
return DB_OK;
}
static tuple_id_t
get_next(index_iterator_t *iterator)
{
static tuple_id_t cached_start;
static tuple_id_t cached_end;
if(iterator->next_item_no == 0) {
/*
* We conduct the actual index search when the caller attempts to
* access the first item in the iteration. The first and last tuple
* id:s of the result get cached for subsequent iterations.
*/
if(DB_ERROR(range_search(iterator, &cached_start, &cached_end))) {
cached_start = 0;
cached_end = 0;
return INVALID_TUPLE;
}
PRINTF("DB: Cached the tuple range (%ld,%ld)\n",
(long)cached_start, (long)cached_end);
++iterator->next_item_no;
return cached_start;
} else if(cached_start + iterator->next_item_no <= cached_end) {
return cached_start + iterator->next_item_no++;
}
return INVALID_TUPLE;
}

View file

@ -0,0 +1,747 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* An binary maximum heap for data indexing over flash memory.
*
* The idea behind this method is to write entries sequentially
* into small buckets, which are indexed in a binary maximum heap.
* Although sequential writes make the entries unsorted within a
* bucket, the time to load and scan a single bucket is small. The
* sequential write is important for flash memories, which are
* unable to handle multiple rewrites of the same page without doing
* an expensive erase operation between the rewrites.
*
* Each bucket specifies a range (a,b) of values that it accepts.
* Once a bucket fills up, two buckets are created with the ranges
* (a,mean) and (mean+1, b), respectively. The entries from the
* original bucket are then copied into the appropriate new bucket
* before the old bucket gets deleted.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cfs/cfs.h"
#include "cfs/cfs-coffee.h"
#include "lib/memb.h"
#include "lib/random.h"
#include "db-options.h"
#include "index.h"
#include "result.h"
#include "storage.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#define BRANCH_FACTOR 2
#define BUCKET_SIZE 128
#define NODE_LIMIT 511
#define NODE_DEPTH 9
#if (1 << NODE_DEPTH) != (NODE_LIMIT + 1)
#error "NODE_DEPTH is set incorrectly."
#endif
#define EMPTY_NODE(node) ((node)->min == 0 && (node)->max == 0)
#define EMPTY_PAIR(pair) ((pair)->key == 0 && (pair)->value == 0)
typedef uint16_t maxheap_key_t;
typedef uint16_t maxheap_value_t;
#define KEY_MIN 0
#define KEY_MAX 65535
struct heap_node {
maxheap_key_t min;
maxheap_key_t max;
};
typedef struct heap_node heap_node_t;
struct key_value_pair {
maxheap_key_t key;
maxheap_value_t value;
};
struct bucket {
struct key_value_pair pairs[BUCKET_SIZE];
};
typedef struct bucket bucket_t;
struct heap {
db_storage_id_t heap_storage;
db_storage_id_t bucket_storage;
/* Remember where the next free slot for each bucket is located. */
uint8_t next_free_slot[NODE_LIMIT];
};
typedef struct heap heap_t;
struct bucket_cache {
heap_t *heap;
uint16_t bucket_id;
bucket_t bucket;
};
static struct bucket_cache bucket_cache[DB_HEAP_CACHE_LIMIT];
MEMB(heaps, heap_t, DB_HEAP_INDEX_LIMIT);
static struct bucket_cache *get_cache(heap_t *, int);
static struct bucket_cache *get_cache_free(void);
static void invalidate_cache(void);
static maxheap_key_t transform_key(maxheap_key_t);
static int heap_read(heap_t *, int, heap_node_t *);
static int heap_write(heap_t *, int, heap_node_t *);
static int heap_insert(heap_t *, maxheap_key_t, maxheap_key_t);
static int heap_find(heap_t *, maxheap_key_t key, int *iterator);
#if HEAP_DEBUG
static void heap_print(heap_t *);
#endif
static int bucket_read(heap_t *, int, bucket_t *);
static struct bucket_cache *bucket_load(heap_t *, int);
static int bucket_append(heap_t *, int, struct key_value_pair *);
static int bucket_split(heap_t *, int);
static db_result_t create(index_t *);
static db_result_t destroy(index_t *);
static db_result_t load(index_t *);
static db_result_t release(index_t *);
static db_result_t insert(index_t *, attribute_value_t *, tuple_id_t);
static db_result_t delete(index_t *, attribute_value_t *);
static tuple_id_t get_next(index_iterator_t *);
index_api_t index_maxheap = {
INDEX_MAXHEAP,
INDEX_API_EXTERNAL,
create,
destroy,
load,
release,
insert,
delete,
get_next
};
static struct bucket_cache *
get_cache(heap_t *heap, int bucket_id)
{
int i;
for(i = 0; i < DB_HEAP_CACHE_LIMIT; i++) {
if(bucket_cache[i].heap == heap && bucket_cache[i].bucket_id == bucket_id) {
return &bucket_cache[i];
}
}
return NULL;
}
static struct bucket_cache *
get_cache_free(void)
{
int i;
for(i = 0; i < DB_HEAP_CACHE_LIMIT; i++) {
if(bucket_cache[i].heap == NULL) {
return &bucket_cache[i];
}
}
return NULL;
}
static void
invalidate_cache(void)
{
int i;
for(i = 0; i < DB_HEAP_CACHE_LIMIT; i++) {
if(bucket_cache[i].heap != NULL) {
bucket_cache[i].heap = NULL;
break;
}
}
}
static maxheap_key_t
transform_key(maxheap_key_t key)
{
random_init(key);
return random_rand();
}
static int
heap_read(heap_t *heap, int bucket_id, heap_node_t *node)
{
if(DB_ERROR(storage_read(heap->heap_storage, node,
DB_MAX_FILENAME_LENGTH + (unsigned long)bucket_id * sizeof(*node), sizeof(*node)))) {
return 0;
}
return 1;
}
static int
heap_write(heap_t *heap, int bucket_id, heap_node_t *node)
{
if(DB_ERROR(storage_write(heap->heap_storage, node,
DB_MAX_FILENAME_LENGTH + (unsigned long)bucket_id * sizeof(*node), sizeof(*node)))) {
return 0;
}
return 1;
}
static int
heap_insert(heap_t *heap, maxheap_key_t min, maxheap_key_t max)
{
int i;
heap_node_t node;
PRINTF("DB: Insert node (%ld,%ld) into the heap\n", (long)min, (long)max);
if(min > max) {
return -1;
}
for(i = 0; i < NODE_LIMIT;) {
if(heap_read(heap, i, &node) == 0) {
PRINTF("DB: Failed to read heap node %d\n", i);
return -1;
}
if(EMPTY_NODE(&node)) {
node.min = min;
node.max = max;
if(heap_write(heap, i, &node) == 0) {
PRINTF("DB: Failed to write heap node %d\n", i);
return -1;
}
return i;
} else if(node.min <= min && max <= node.max) {
i = BRANCH_FACTOR * i + 1;
} else {
i++;
}
}
PRINTF("DB: No more nodes available\n");
return -1;
}
static int
heap_find(heap_t *heap, maxheap_key_t key, int *iterator)
{
maxheap_key_t hashed_key;
int i;
int first_child;
static heap_node_t node;
hashed_key = transform_key(key);
for(i = *iterator; i < NODE_LIMIT;) {
if(heap_read(heap, i, &node) == 0) {
break;
}
if(EMPTY_NODE(&node)) {
break;
} else if(node.min <= hashed_key && hashed_key <= node.max) {
first_child = BRANCH_FACTOR * i + 1;
if(first_child >= NODE_LIMIT) {
break;
}
*iterator = first_child;
return i;
} else {
i++;
}
}
return -1;
}
#if HEAP_DEBUG
static void
heap_print(heap_t *heap)
{
int level_count;
int branch_count;
int branch_amount;
int i, j;
heap_node_t node;
level_count = 0;
branch_count = 0;
branch_amount = BRANCH_FACTOR;
for(i = 0;; i++) {
if(heap_read(heap, i, &node) == 0 || EMPTY_NODE(&node)) {
break;
}
for(j = 0; j < level_count; j++) {
PRINTF("\t");
}
PRINTF("(%ld,%ld)\n", (long)node.min, (long)node.max);
if(level_count == 0) {
level_count++;
} else if(branch_count + 1 == branch_amount) {
level_count++;
branch_count = 0;
branch_amount = branch_amount * BRANCH_FACTOR;
} else {
branch_count++;
}
}
}
#endif /* HEAP_DEBUG */
static int
bucket_read(heap_t *heap, int bucket_id, bucket_t *bucket)
{
size_t size;
if(heap->next_free_slot[bucket_id] == 0) {
size = BUCKET_SIZE;
} else {
size = heap->next_free_slot[bucket_id];
}
size *= sizeof(struct key_value_pair);
if(DB_ERROR(storage_read(heap->bucket_storage, bucket,
(unsigned long)bucket_id * sizeof(*bucket), size))) {
return 0;
}
return 1;
}
static struct bucket_cache *
bucket_load(heap_t *heap, int bucket_id)
{
int i;
struct bucket_cache *cache;
cache = get_cache(heap, bucket_id);
if(cache != NULL) {
return cache;
}
cache = get_cache_free();
if(cache == NULL) {
invalidate_cache();
cache = get_cache_free();
if(cache == NULL) {
return NULL;
}
}
if(bucket_read(heap, bucket_id, &cache->bucket) == 0) {
return NULL;
}
cache->heap = heap;
cache->bucket_id = bucket_id;
if(heap->next_free_slot[bucket_id] == 0) {
for(i = 0; i < BUCKET_SIZE; i++) {
if(EMPTY_PAIR(&cache->bucket.pairs[i])) {
break;
}
}
heap->next_free_slot[bucket_id] = i;
}
PRINTF("DB: Loaded bucket %d, the next free slot is %u\n", bucket_id,
(unsigned)heap->next_free_slot[bucket_id]);
return cache;
}
static int
bucket_append(heap_t *heap, int bucket_id, struct key_value_pair *pair)
{
unsigned long offset;
if(heap->next_free_slot[bucket_id] >= BUCKET_SIZE) {
PRINTF("DB: Invalid write attempt to the full bucket %d\n", bucket_id);
return 0;
}
offset = (unsigned long)bucket_id * sizeof(bucket_t);
offset += heap->next_free_slot[bucket_id] * sizeof(struct key_value_pair);
if(DB_ERROR(storage_write(heap->bucket_storage, pair, offset, sizeof(*pair)))) {
return 0;
}
heap->next_free_slot[bucket_id]++;
return 1;
}
static int
bucket_split(heap_t *heap, int bucket_id)
{
heap_node_t node;
maxheap_key_t mean;
int small_bucket_index;
int large_bucket_index;
if(heap_read(heap, bucket_id, &node) == 0) {
return 0;
}
mean = node.min + ((node.max - node.min) / 2);
PRINTF("DB: Split bucket %d (%ld, %ld) at mean value %ld\n", bucket_id,
(long)node.min, (long)node.max, (long)mean);
small_bucket_index = heap_insert(heap, node.min, mean);
if(small_bucket_index < 0) {
return 0;
}
large_bucket_index = heap_insert(heap, mean + 1, node.max);
if(large_bucket_index < 0) {
/*heap_remove(small_bucket);*/
return 0;
}
return 1;
}
int
insert_item(heap_t *heap, maxheap_key_t key, maxheap_value_t value)
{
int heap_iterator;
int bucket_id, last_good_bucket_id;
struct key_value_pair pair;
for(heap_iterator = 0, last_good_bucket_id = -1;;) {
bucket_id = heap_find(heap, key, &heap_iterator);
if(bucket_id < 0) {
break;
}
last_good_bucket_id = bucket_id;
}
bucket_id = last_good_bucket_id;
if(bucket_id < 0) {
PRINTF("DB: No bucket for key %ld\n", (long)key);
return 0;
}
pair.key = key;
pair.value = value;
if(heap->next_free_slot[bucket_id] == BUCKET_SIZE) {
PRINTF("DB: Bucket %d is full\n", bucket_id);
if(bucket_split(heap, bucket_id) == 0) {
return 0;
}
/* Select one of the newly created buckets. */
bucket_id = heap_find(heap, key, &heap_iterator);
if(bucket_id < 0) {
return 0;
}
}
if(bucket_append(heap, bucket_id, &pair) == 0) {
return 0;
}
PRINTF("DB: Inserted key %ld (hash %ld) into the heap at bucket_id %d\n",
(long)key, (long)transform_key(key), bucket_id);
return 1;
}
static db_result_t
create(index_t *index)
{
char heap_filename[DB_MAX_FILENAME_LENGTH];
char bucket_filename[DB_MAX_FILENAME_LENGTH];
char *filename;
db_result_t result;
heap_t *heap;
heap = NULL;
filename = NULL;
bucket_filename[0] = '\0';
/* Generate the heap file, which is the main index file that is
inserted into the metadata of the relation. */
filename = storage_generate_file("heap",
(unsigned long)NODE_LIMIT * sizeof(heap_node_t));
if(filename == NULL) {
PRINTF("DB: Failed to generate a heap file\n");
return DB_INDEX_ERROR;
}
memcpy(index->descriptor_file, filename,
sizeof(index->descriptor_file));
PRINTF("DB: Generated the heap file \"%s\" using %lu bytes of space\n",
index->descriptor_file, (unsigned long)NODE_LIMIT * sizeof(heap_node_t));
index->opaque_data = heap = memb_alloc(&heaps);
if(heap == NULL) {
PRINTF("DB: Failed to allocate a heap\n");
result = DB_ALLOCATION_ERROR;
goto end;
}
heap->heap_storage = -1;
heap->bucket_storage = -1;
/* Generate the bucket file, which stores the (key, value) pairs. */
filename = storage_generate_file("bucket",
(unsigned long)NODE_LIMIT * sizeof(bucket_t));
if(filename == NULL) {
PRINTF("DB: Failed to generate a bucket file\n");
result = DB_INDEX_ERROR;
goto end;
}
memcpy(bucket_filename, filename, sizeof(bucket_filename));
PRINTF("DB: Generated the bucket file \"%s\" using %lu bytes of space\n",
bucket_filename, (unsigned long)NODE_LIMIT * sizeof(bucket_t));
/* Initialize the heap. */
memset(&heap->next_free_slot, 0, sizeof(heap->next_free_slot));
heap->heap_storage = storage_open(index->descriptor_file);
heap->bucket_storage = storage_open(bucket_filename);
if(heap->heap_storage < 0 || heap->bucket_storage < 0) {
result = DB_STORAGE_ERROR;
goto end;
}
if(DB_ERROR(storage_write(heap->heap_storage, &bucket_filename, 0,
sizeof(bucket_filename)))) {
result = DB_STORAGE_ERROR;
goto end;
}
if(heap_insert(heap, KEY_MIN, KEY_MAX) < 0) {
PRINTF("DB: Heap insertion error\n");
result = DB_INDEX_ERROR;
goto end;
}
PRINTF("DB: Created a heap index\n");
result = DB_OK;
end:
if(result != DB_OK) {
if(heap != NULL) {
storage_close(heap->bucket_storage);
storage_close(heap->heap_storage);
memb_free(&heaps, heap);
}
if(index->descriptor_file[0] != '\0') {
cfs_remove(heap_filename);
index->descriptor_file[0] = '\0';
}
if(bucket_filename[0] != '\0') {
cfs_remove(bucket_filename);
}
}
return result;
}
static db_result_t
destroy(index_t *index)
{
release(index);
return DB_INDEX_ERROR;
}
static db_result_t
load(index_t *index)
{
heap_t *heap;
db_storage_id_t fd;
char bucket_file[DB_MAX_FILENAME_LENGTH];
index->opaque_data = heap = memb_alloc(&heaps);
if(heap == NULL) {
PRINTF("DB: Failed to allocate a heap\n");
return DB_ALLOCATION_ERROR;
}
fd = storage_open(index->descriptor_file);
if(fd < 0) {
return DB_STORAGE_ERROR;
}
if(storage_read(fd, bucket_file, 0, sizeof(bucket_file)) !=
sizeof(bucket_file)) {
storage_close(fd);
return DB_STORAGE_ERROR;
}
storage_close(fd);
heap->heap_storage = storage_open(index->descriptor_file);
heap->bucket_storage = storage_open(bucket_file);
memset(&heap->next_free_slot, 0, sizeof(heap->next_free_slot));
PRINTF("DB: Loaded max-heap index from file %s and bucket file %s\n",
index->descriptor_file, bucket_file);
return DB_OK;
}
static db_result_t
release(index_t *index)
{
heap_t *heap;
heap = index->opaque_data;
storage_close(heap->bucket_storage);
storage_close(heap->heap_storage);
memb_free(&heaps, index->opaque_data);
return DB_INDEX_ERROR;
}
static db_result_t
insert(index_t *index, attribute_value_t *key, tuple_id_t value)
{
heap_t *heap;
long long_key;
heap = (heap_t *)index->opaque_data;
long_key = db_value_to_long(key);
if(insert_item(heap, (maxheap_key_t)long_key,
(maxheap_value_t)value) == 0) {
PRINTF("DB: Failed to insert key %ld into a max-heap index\n", long_key);
return DB_INDEX_ERROR;
}
return DB_OK;
}
static db_result_t
delete(index_t *index, attribute_value_t *value)
{
return DB_INDEX_ERROR;
}
static tuple_id_t
get_next(index_iterator_t *iterator)
{
struct iteration_cache {
index_iterator_t *index_iterator;
int heap_iterator;
tuple_id_t found_items;
uint8_t start;
int visited_buckets[NODE_DEPTH];
int end;
};
static struct iteration_cache cache;
heap_t *heap;
maxheap_key_t key;
int bucket_id;
int tmp_heap_iterator;
int i;
struct bucket_cache *bcache;
uint8_t next_free_slot;
heap = (heap_t *)iterator->index->opaque_data;
key = *(maxheap_key_t *)&iterator->min_value;
if(cache.index_iterator != iterator || iterator->next_item_no == 0) {
/* Initialize the cache for a new search. */
cache.end = NODE_DEPTH - 1;
cache.found_items = cache.start = 0;
cache.index_iterator = iterator;
/* Find a path of heap nodes which can contain the key. */
for(i = tmp_heap_iterator = 0; i < NODE_DEPTH; i++) {
cache.visited_buckets[i] = heap_find(heap, key, &tmp_heap_iterator);
if(cache.visited_buckets[i] < 0) {
cache.end = i - 1;
break;
}
}
cache.heap_iterator = cache.end;
}
/*
* Search for the key in each heap node, starting from the bottom
* of the heap. There is a much higher chance that the key will be
* there rather than at the top.
*/
for(; cache.heap_iterator >= 0; cache.heap_iterator--) {
bucket_id = cache.visited_buckets[cache.heap_iterator];
PRINTF("DB: Find key %lu in bucket %d\n", (unsigned long)key, bucket_id);
if((bcache = bucket_load(heap, bucket_id)) == NULL) {
PRINTF("DB: Failed to load bucket %d\n", bucket_id);
return INVALID_TUPLE;
}
/* Compare the key against the bucket_ids in the bucket sequentially because
they are placed in arbitrary order. */
next_free_slot = heap->next_free_slot[bucket_id];
for(i = cache.start; i < next_free_slot; i++) {
if(bcache->bucket.pairs[i].key == key) {
if(cache.found_items++ == iterator->next_item_no) {
iterator->next_item_no++;
cache.start = i + 1;
PRINTF("DB: Found key %ld with value %lu\n", (long)key,
(unsigned long)bcache->bucket.pairs[i].value);
return (tuple_id_t)bcache->bucket.pairs[i].value;
}
}
}
}
if(VALUE_INT(&iterator->min_value) == VALUE_INT(&iterator->max_value)) {
PRINTF("DB: Could not find key %ld in the index\n", (long)key);
return INVALID_TUPLE;
}
iterator->next_item_no = 0;
VALUE_INT(&iterator->min_value)++;
return get_next(iterator);
}

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A memory-resident hash map used as a DB index.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <string.h>
#include "lib/memb.h"
#include "db-options.h"
#include "index.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
static db_result_t create(index_t *);
static db_result_t destroy(index_t *);
static db_result_t load(index_t *);
static db_result_t release(index_t *);
static db_result_t insert(index_t *, attribute_value_t *, tuple_id_t);
static db_result_t delete(index_t *, attribute_value_t *);
static tuple_id_t get_next(index_iterator_t *);
index_api_t index_memhash = {
INDEX_MEMHASH,
INDEX_API_INTERNAL,
create,
destroy,
load,
release,
insert,
delete,
get_next
};
struct hash_item {
tuple_id_t tuple_id;
attribute_value_t value;
};
typedef struct hash_item hash_item_t;
typedef hash_item_t hash_map_t[DB_MEMHASH_TABLE_SIZE];
MEMB(hash_map_memb, hash_map_t, DB_MEMHASH_INDEX_LIMIT);
static unsigned
calculate_hash(attribute_value_t *value)
{
unsigned char *cp, *end;
unsigned hash_value;
cp = (unsigned char *)value;
end = cp + sizeof(*value);
hash_value = 0;
while(cp < end) {
hash_value = hash_value * 33 + *cp++;
}
return hash_value % DB_MEMHASH_TABLE_SIZE;
}
static db_result_t
create(index_t *index)
{
int i;
hash_map_t *hash_map;
PRINTF("Creating a memory-resident hash map index\n");
hash_map = memb_alloc(&hash_map_memb);
if(hash_map == NULL) {
return DB_ALLOCATION_ERROR;
}
for(i = 0; i < DB_MEMHASH_TABLE_SIZE; i++) {
hash_map[i]->tuple_id = INVALID_TUPLE;
}
index->opaque_data = hash_map;
return DB_OK;
}
static db_result_t
destroy(index_t *index)
{
memb_free(&hash_map_memb, index->opaque_data);
return DB_OK;
}
static db_result_t
load(index_t *index)
{
return create(index);
}
static db_result_t
release(index_t *index)
{
return destroy(index);
}
static db_result_t
insert(index_t *index, attribute_value_t *value, tuple_id_t tuple_id)
{
hash_map_t *hash_map;
uint16_t hash_value;
hash_map = index->opaque_data;
hash_value = calculate_hash(value);
hash_map[hash_value]->tuple_id = tuple_id;
hash_map[hash_value]->value = *value;
PRINTF("DB: Inserted value %ld into the hash table\n", VALUE_LONG(value));
return DB_OK;
}
static db_result_t
delete(index_t *index, attribute_value_t *value)
{
hash_map_t *hash_map;
uint16_t hash_value;
hash_map = index->opaque_data;
hash_value = calculate_hash(value);
if(memcmp(&hash_map[hash_value]->value, value, sizeof(*value)) != 0) {
return DB_INDEX_ERROR;
}
hash_map[hash_value]->tuple_id = INVALID_TUPLE;
return DB_OK;
}
static tuple_id_t
get_next(index_iterator_t *iterator)
{
hash_map_t *hash_map;
uint16_t hash_value;
if(iterator->next_item_no == 1) {
/* The memhash supports only unique values at the moment. */
return INVALID_TUPLE;
}
hash_map = iterator->index->opaque_data;
hash_value = calculate_hash(&iterator->min_value);
if(memcmp(&hash_map[hash_value]->value, &iterator->min_value, sizeof(iterator->min_value)) != 0) {
return INVALID_TUPLE;
}
iterator->next_item_no++;
PRINTF("DB: Found value %ld in the hash table\n",
VALUE_LONG(&iterator->min_value));
return hash_map[hash_value]->tuple_id;
}

424
apps/antelope/index.c Normal file
View file

@ -0,0 +1,424 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* This component forwards index calls using the generic index
* API to specific implementations.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include "contiki.h"
#include "lib/memb.h"
#include "lib/list.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#include "antelope.h"
#include "attribute.h"
#include "db-options.h"
#include "index.h"
#include "storage.h"
static index_api_t *index_components[] = {&index_inline,
&index_maxheap};
LIST(indices);
MEMB(index_memb, index_t, DB_INDEX_POOL_SIZE);
static process_event_t load_request_event;
PROCESS(db_indexer, "DB Indexer");
static index_api_t *
find_index_api(index_type_t index_type)
{
int i;
for(i = 0; i < sizeof(index_components) / sizeof(index_components[0]); i++) {
if(index_components[i]->type == index_type) {
return index_components[i];
}
}
return NULL;
}
void
index_init(void)
{
list_init(indices);
memb_init(&index_memb);
process_start(&db_indexer, NULL);
}
db_result_t
index_create(index_type_t index_type, relation_t *rel, attribute_t *attr)
{
tuple_id_t cardinality;
index_t *index;
index_api_t *api;
cardinality = relation_cardinality(rel);
if(cardinality == INVALID_TUPLE) {
return DB_STORAGE_ERROR;
}
api = find_index_api(index_type);
if(api == NULL) {
PRINTF("DB: No API for index type %d\n", (int)index_type);
return DB_INDEX_ERROR;
}
if(attr->index != NULL) {
/* Refuse to overwrite the old index. */
PRINTF("DB: The attribute %s is already indexed\n", attr->name);
return DB_INDEX_ERROR;
}
index = memb_alloc(&index_memb);
if(index == NULL) {
PRINTF("DB: Failed to allocate an index\n");
return DB_ALLOCATION_ERROR;
}
index->rel = rel;
index->attr = attr;
index->api = api;
index->flags = 0;
index->opaque_data = NULL;
index->descriptor_file[0] = '\0';
index->type = index_type;
if(DB_ERROR(api->create(index))) {
memb_free(&index_memb, index);
PRINTF("DB: Index-specific creation failed for attribute %s\n", attr->name);
return DB_INDEX_ERROR;
}
attr->index = index;
list_push(indices, index);
if(index->descriptor_file[0] != '\0' &&
DB_ERROR(storage_put_index(index))) {
api->destroy(index);
memb_free(&index_memb, index);
PRINTF("DB: Failed to store index data in file \"%s\"\n",
index->descriptor_file);
return DB_INDEX_ERROR;
}
if(!(api->flags & INDEX_API_INLINE) && cardinality > 0) {
PRINTF("DB: Created an index for an old relation; issuing a load request\n");
index->flags = INDEX_LOAD_NEEDED;
process_post(&db_indexer, load_request_event, NULL);
} else {
PRINTF("DB: Index created for attribute %s\n", attr->name);
index->flags |= INDEX_READY;
}
return DB_OK;
}
db_result_t
index_destroy(index_t *index)
{
if(DB_ERROR(index_release(index)) ||
DB_ERROR(index->api->destroy(index))) {
return DB_INDEX_ERROR;
}
return DB_OK;
}
db_result_t
index_load(relation_t *rel, attribute_t *attr)
{
index_t *index;
index_api_t *api;
PRINTF("DB: Attempting to load an index over %s.%s\n", rel->name, attr->name);
index = memb_alloc(&index_memb);
if(index == NULL) {
PRINTF("DB: No more index objects available\n");
return DB_ALLOCATION_ERROR;
}
if(DB_ERROR(storage_get_index(index, rel, attr))) {
PRINTF("DB: Failed load an index descriptor from storage\n");
memb_free(&index_memb, index);
return DB_INDEX_ERROR;
}
index->rel = rel;
index->attr = attr;
index->opaque_data = NULL;
api = find_index_api(index->type);
if(api == NULL) {
PRINTF("DB: No API for index type %d\n", index->type);
return DB_INDEX_ERROR;
}
index->api = api;
if(DB_ERROR(api->load(index))) {
PRINTF("DB: Index-specific load failed\n");
return DB_INDEX_ERROR;
}
list_push(indices, index);
attr->index = index;
index->flags = INDEX_READY;
return DB_OK;
}
db_result_t
index_release(index_t *index)
{
if(DB_ERROR(index->api->release(index))) {
return DB_INDEX_ERROR;
}
index->attr->index = NULL;
list_remove(indices, index);
memb_free(&index_memb, index);
return DB_OK;
}
db_result_t
index_insert(index_t *index, attribute_value_t *value,
tuple_id_t tuple_id)
{
return index->api->insert(index, value, tuple_id);
}
db_result_t
index_delete(index_t *index, attribute_value_t *value)
{
if(index->flags != INDEX_READY) {
return DB_INDEX_ERROR;
}
return index->api->delete(index, value);
}
db_result_t
index_get_iterator(index_iterator_t *iterator, index_t *index,
attribute_value_t *min_value,
attribute_value_t *max_value)
{
tuple_id_t cardinality;
unsigned long range;
unsigned long max_range;
long max;
long min;
cardinality = relation_cardinality(index->rel);
if(cardinality == INVALID_TUPLE) {
return DB_STORAGE_ERROR;
}
if(index->flags != INDEX_READY) {
return DB_INDEX_ERROR;
}
min = db_value_to_long(min_value);
max = db_value_to_long(max_value);
range = (unsigned long)max - min;
if(range > 0) {
/*
* Index structures that do not have a natural ability to handle
* range queries (e.g., a hash index) can nevertheless emulate them.
*
* The range query emulation attempts to look up the key for each
* value in the search range. If the search range is sparse, this
* iteration will incur a considerable overhead per found key.
*
* Hence, The emulation is preferable when an external module wants
* to iterate over a narrow range of keys, for which the total
* search cost is smaller than that of an iteration over all tuples
* in the relation.
*/
if(!(index->api->flags & INDEX_API_RANGE_QUERIES)) {
PRINTF("DB: Range query requested for an index that does not support it\n");
max_range = cardinality / DB_INDEX_COST;
if(range > max_range) {
return DB_INDEX_ERROR;
}
PRINTF("DB: Using the index anyway because the range is small enough (%lu <= %lu)\n",
range, max_range);
}
}
iterator->index = index;
iterator->min_value = *min_value;
iterator->max_value = *max_value;
iterator->next_item_no = 0;
PRINTF("DB: Acquired an index iterator for %s.%s over the range (%ld,%ld)\n",
index->rel->name, index->attr->name,
min_value->u.long_value, max_value->u.long_value);
return DB_OK;
}
tuple_id_t
index_get_next(index_iterator_t *iterator)
{
long min;
long max;
if(iterator->index == NULL) {
/* This attribute is not indexed. */
return INVALID_TUPLE;
}
if((iterator->index->attr->flags & ATTRIBUTE_FLAG_UNIQUE) &&
iterator->next_item_no == 1) {
min = db_value_to_long(&iterator->min_value);
max = db_value_to_long(&iterator->max_value);
if(min == max) {
/*
* We stop if this is an equivalence search on an attribute
* whose values are unique, and we already found one item.
*/
PRINTF("DB: Equivalence search finished\n");
return INVALID_TUPLE;
}
}
return iterator->index->api->get_next(iterator);
}
int
index_exists(attribute_t *attr)
{
index_t *index;
index = (index_t *)attr->index;
if(index == NULL || index->flags != INDEX_READY) {
return 0;
}
return 1;
}
static index_t *
get_next_index_to_load(void)
{
index_t *index;
for(index = list_head(indices); index != NULL; index = index->next) {
if(index->flags & INDEX_LOAD_NEEDED) {
return index;
}
}
return NULL;
}
PROCESS_THREAD(db_indexer, ev, data)
{
static index_t *index;
static db_handle_t handle;
static tuple_id_t row;
db_result_t result;
attribute_value_t value;
int column;
PROCESS_BEGIN();
load_request_event = process_alloc_event();
for(;;) {
PROCESS_WAIT_EVENT_UNTIL(ev == load_request_event);
index = get_next_index_to_load();
if(index == NULL) {
PRINTF("DB: Request to load an index, but no index is set to be loaded\n");
continue;
}
PRINTF("DB: Loading the index for %s.%s...\n",
index->rel->name, index->attr->name);
if(DB_ERROR(db_query(&handle, "SELECT %s FROM %s;", index->attr->name, index->rel->name))) {
index->flags |= INDEX_LOAD_ERROR;
index->flags &= ~INDEX_LOAD_NEEDED;
continue;
}
for(;; row++) {
PROCESS_PAUSE();
result = db_process(&handle);
if(DB_ERROR(result)) {
PRINTF("DB: Index loading failed while processing: %s\n",
db_get_result_message(result));
index->flags |= INDEX_LOAD_ERROR;
goto cleanup;
}
if(result == DB_FINISHED) {
break;
}
for(column = 0; column < handle.ncolumns; column++) {
if(DB_ERROR(db_get_value(&value, &handle, column))) {
index->flags |= INDEX_LOAD_ERROR;
goto cleanup;
}
if(DB_ERROR(index_insert(index, &value, row))) {
index->flags |= INDEX_LOAD_ERROR;
goto cleanup;
}
}
}
PRINTF("DB: Loaded %lu rows into the index\n",
(unsigned long)handle.current_row);
cleanup:
if(index->flags & INDEX_LOAD_ERROR) {
PRINTF("DB: Failed to load the index for %s.%s\n",
index->rel->name, index->attr->name);
}
index->flags &= ~INDEX_LOAD_NEEDED;
index->flags |= INDEX_READY;
db_free(&handle);
}
PROCESS_END();
}

113
apps/antelope/index.h Normal file
View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* .
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef INDEX_H
#define INDEX_H
#include "relation.h"
typedef enum {
INDEX_NONE = 0,
INDEX_INLINE = 1,
INDEX_MEMHASH = 2,
INDEX_MAXHEAP = 3
} index_type_t;
#define INDEX_READY 0x00
#define INDEX_LOAD_NEEDED 0x01
#define INDEX_LOAD_ERROR 0x02
#define INDEX_API_INTERNAL 0x01
#define INDEX_API_EXTERNAL 0x02
#define INDEX_API_INLINE 0x04
#define INDEX_API_COMPLETE 0x08
#define INDEX_API_RANGE_QUERIES 0x10
struct index_api;
struct index {
struct index *next;
char descriptor_file[DB_MAX_FILENAME_LENGTH];
relation_t *rel;
attribute_t *attr;
struct index_api *api;
void *opaque_data;
index_type_t type;
uint8_t flags;
};
typedef struct index index_t;
struct index_iterator {
index_t *index;
attribute_value_t min_value;
attribute_value_t max_value;
tuple_id_t next_item_no;
tuple_id_t found_items;
};
typedef struct index_iterator index_iterator_t;
struct index_api {
index_type_t type;
uint8_t flags;
db_result_t (*create)(index_t *);
db_result_t (*destroy)(index_t *);
db_result_t (*load)(index_t *);
db_result_t (*release)(index_t *);
db_result_t (*insert)(index_t *, attribute_value_t *, tuple_id_t);
db_result_t (*delete)(index_t *, attribute_value_t *);
tuple_id_t (*get_next)(index_iterator_t *);
};
typedef struct index_api index_api_t;
extern index_api_t index_inline;
extern index_api_t index_maxheap;
extern index_api_t index_memhash;
void index_init(void);
db_result_t index_create(index_type_t, relation_t *, attribute_t *);
db_result_t index_destroy(index_t *);
db_result_t index_load(relation_t *, attribute_t *);
db_result_t index_release(index_t *);
db_result_t index_insert(index_t *, attribute_value_t *, tuple_id_t);
db_result_t index_delete(index_t *, attribute_value_t *);
db_result_t index_get_iterator(index_iterator_t *, index_t *,
attribute_value_t *, attribute_value_t *);
tuple_id_t index_get_next(index_iterator_t *);
int index_exists(attribute_t *);
#endif /* !INDEX_H */

976
apps/antelope/lvm.c Normal file
View file

@ -0,0 +1,976 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Logic engine used for quickly evaluating data constraints in relations.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aql.h"
#include "lvm.h"
#define DEBUG DEBUG_NONE
#include "debug.h"
/*
* The logic engine determines whether a logical predicate is true for
* each tuple in a relation. It uses a stack-based execution model of
* operations that are arranged in prefix (Polish) notation.
*/
/* Default option values. */
#ifndef LVM_MAX_NAME_LENGTH
#define LVM_MAX_NAME_LENGTH 16
#endif
#ifndef LVM_MAX_VARIABLE_ID
#define LVM_MAX_VARIABLE_ID 8
#endif
#ifndef LVM_USE_FLOATS
#define LVM_USE_FLOATS 0
#endif
#define IS_CONNECTIVE(op) ((op) & LVM_CONNECTIVE)
struct variable {
operand_type_t type;
operand_value_t value;
char name[LVM_MAX_NAME_LENGTH + 1];
};
typedef struct variable variable_t;
struct derivation {
operand_value_t max;
operand_value_t min;
uint8_t derived;
};
typedef struct derivation derivation_t;
/* Registered variables for a LVM expression. Their values may be
changed between executions of the expression. */
static variable_t variables[LVM_MAX_VARIABLE_ID - 1];
/* Range derivations of variables that are used for index searches. */
static derivation_t derivations[LVM_MAX_VARIABLE_ID - 1];
#if DEBUG
static void
print_derivations(derivation_t *d)
{
int i;
for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
if(d[i].derived) {
printf("%s is constrained to (%ld,%ld)\n", variables[i].name,
d[i].min.l, d[i].max.l);
}
}
}
#endif /* DEBUG */
static variable_id_t
lookup(char *name)
{
variable_t *var;
for(var = variables; var <= &variables[LVM_MAX_VARIABLE_ID - 1] && var->name[0] != '\0'; var++) {
if(strcmp(var->name, name) == 0) {
break;
}
}
return (variable_id_t)(var - &variables[0]);
}
static operator_t *
get_operator(lvm_instance_t *p)
{
operator_t *operator;
operator = (operator_t *)&p->code[p->ip];
p->ip += sizeof(operator_t);
return operator;
}
static void
get_operand(lvm_instance_t *p, operand_t *operand)
{
memcpy(operand, &p->code[p->ip], sizeof(*operand));
p->ip += sizeof(*operand);
}
static node_type_t
get_type(lvm_instance_t *p)
{
node_type_t node_type;
node_type = *(node_type_t *)(p->code + p->ip);
p->ip += sizeof(node_type);
return node_type;
}
static long
operand_to_long(operand_t *operand)
{
switch(operand->type) {
case LVM_LONG:
return operand->value.l;
#if LVM_USE_FLOATS
case LVM_FLOAT:
return (long)operand->value.f;
break;
#endif /* LVM_USE_FLOATS */
case LVM_VARIABLE:
return variables[operand->value.id].value.l;
default:
return 0;
}
}
static lvm_status_t
eval_expr(lvm_instance_t *p, operator_t op, operand_t *result)
{
int i;
node_type_t type;
operator_t *operator;
operand_t operand[2];
long value[2];
long result_value;
lvm_status_t r;
for(i = 0; i < 2; i++) {
type = get_type(p);
switch(type) {
case LVM_ARITH_OP:
operator = get_operator(p);
r = eval_expr(p, *operator, &operand[i]);
if(LVM_ERROR(r)) {
return r;
}
break;
case LVM_OPERAND:
get_operand(p, &operand[i]);
break;
default:
return SEMANTIC_ERROR;
}
value[i] = operand_to_long(&operand[i]);
}
switch(op) {
case LVM_ADD:
result_value = value[0] + value[1];
break;
case LVM_SUB:
result_value = value[0] - value[1];
break;
case LVM_MUL:
result_value = value[0] * value[1];
break;
case LVM_DIV:
if(value[1] == 0) {
return MATH_ERROR;
}
result_value = value[0] / value[1];
break;
default:
return EXECUTION_ERROR;
}
result->type = LVM_LONG;
result->value.l = result_value;
return TRUE;
}
static int
eval_logic(lvm_instance_t *p, operator_t *op)
{
int i;
int r;
operand_t operand;
long result[2];
node_type_t type;
operator_t *operator;
long l1, l2;
int logic_result[2];
unsigned arguments;
if(IS_CONNECTIVE(*op)) {
arguments = *op == LVM_NOT ? 1 : 2;
for(i = 0; i < arguments; i++) {
type = get_type(p);
if(type != LVM_CMP_OP) {
return SEMANTIC_ERROR;
}
operator = get_operator(p);
logic_result[i] = eval_logic(p, operator);
if(LVM_ERROR(logic_result[i])) {
return logic_result[i];
}
}
if(*op == LVM_NOT) {
return !logic_result[0];
} else if(*op == LVM_AND) {
return logic_result[0] == TRUE && logic_result[1] == TRUE;
} else {
return logic_result[0] == TRUE || logic_result[1] == TRUE;
}
}
for(i = 0; i < 2; i++) {
type = get_type(p);
switch(type) {
case LVM_ARITH_OP:
operator = get_operator(p);
r = eval_expr(p, *operator, &operand);
if(LVM_ERROR(r)) {
return r;
}
break;
case LVM_OPERAND:
get_operand(p, &operand);
break;
default:
return SEMANTIC_ERROR;
}
result[i] = operand_to_long(&operand);
}
l1 = result[0];
l2 = result[1];
PRINTF("Result1: %ld\nResult2: %ld\n", l1, l2);
switch(*op) {
case LVM_EQ:
return l1 == l2;
case LVM_NEQ:
return l1 != l2;
case LVM_GE:
return l1 > l2;
case LVM_GEQ:
return l1 >= l2;
case LVM_LE:
return l1 < l2;
case LVM_LEQ:
return l1 <= l2;
default:
break;
}
return EXECUTION_ERROR;
}
void
lvm_reset(lvm_instance_t *p, unsigned char *code, lvm_ip_t size)
{
memset(code, 0, size);
p->code = code;
p->size = size;
p->end = 0;
p->ip = 0;
p->error = 0;
memset(variables, 0, sizeof(variables));
memset(derivations, 0, sizeof(derivations));
}
lvm_ip_t
lvm_jump_to_operand(lvm_instance_t *p)
{
lvm_ip_t old_end;
old_end = p->end;
p->end += sizeof(operator_t) + sizeof(node_type_t);
if(p->end >= p->size) {
p->error = __LINE__;
p->end = old_end;
}
return old_end;
}
lvm_ip_t
lvm_shift_for_operator(lvm_instance_t *p, lvm_ip_t end)
{
unsigned char *ptr;
lvm_ip_t old_end;
old_end = p->end;
if(p->end + sizeof(operator_t) > p->size || end >= old_end) {
p->error = __LINE__;
return 0;
}
ptr = p->code + end;
memmove(ptr + sizeof(operator_t) + sizeof(node_type_t), ptr, old_end - end);
p->end = end;
return old_end + sizeof(operator_t) + sizeof(node_type_t);
}
lvm_ip_t
lvm_get_end(lvm_instance_t *p)
{
return p->end;
}
lvm_ip_t
lvm_set_end(lvm_instance_t *p, lvm_ip_t end)
{
lvm_ip_t old_end;
if(end >= p->size) {
p->error = __LINE__;
return p->end;
}
old_end = p->end;
p->end = end;
return old_end;
}
void
lvm_set_type(lvm_instance_t *p, node_type_t type)
{
*(node_type_t *)(p->code + p->end) = type;
p->end += sizeof(type);
}
lvm_status_t
lvm_execute(lvm_instance_t *p)
{
node_type_t type;
operator_t *operator;
lvm_status_t status;
p->ip = 0;
status = EXECUTION_ERROR;
type = get_type(p);
switch(type) {
case LVM_CMP_OP:
operator = get_operator(p);
status = eval_logic(p, operator);
if(!LVM_ERROR(status)) {
PRINTF("The statement is %s\n", status == TRUE ? "true" : "false");
} else {
PRINTF("Execution error: %d\n", (int)status);
}
break;
default:
PRINTF("Error: The code must start with a relational operator\n");
}
return status;
}
void
lvm_set_op(lvm_instance_t *p, operator_t op)
{
lvm_set_type(p, LVM_ARITH_OP);
memcpy(&p->code[p->end], &op, sizeof(op));
p->end += sizeof(op);
}
void
lvm_set_relation(lvm_instance_t *p, operator_t op)
{
lvm_set_type(p, LVM_CMP_OP);
memcpy(&p->code[p->end], &op, sizeof(op));
p->end += sizeof(op);
}
void
lvm_set_operand(lvm_instance_t *p, operand_t *op)
{
lvm_set_type(p, LVM_OPERAND);
memcpy(&p->code[p->end], op, sizeof(*op));
p->end += sizeof(*op);
}
void
lvm_set_long(lvm_instance_t *p, long l)
{
operand_t op;
op.type = LVM_LONG;
op.value.l = l;
lvm_set_operand(p, &op);
}
lvm_status_t
lvm_register_variable(char *name, operand_type_t type)
{
variable_id_t id;
variable_t *var;
id = lookup(name);
if(id == LVM_MAX_VARIABLE_ID) {
return VARIABLE_LIMIT_REACHED;
}
var = &variables[id];
if(var->name[0] == '\0') {
strncpy(var->name, name, sizeof(var->name) - 1);
var->name[sizeof(var->name) - 1] = '\0';
var->type = type;
}
return TRUE;
}
lvm_status_t
lvm_set_variable_value(char *name, operand_value_t value)
{
variable_id_t id;
id = lookup(name);
if(id == LVM_MAX_VARIABLE_ID) {
return INVALID_IDENTIFIER;
}
variables[id].value = value;
return TRUE;
}
void
lvm_set_variable(lvm_instance_t *p, char *name)
{
operand_t op;
variable_id_t id;
id = lookup(name);
if(id < LVM_MAX_VARIABLE_ID) {
PRINTF("var id = %d\n", id);
op.type = LVM_VARIABLE;
op.value.id = id;
lvm_set_operand(p, &op);
}
}
void
lvm_clone(lvm_instance_t *dst, lvm_instance_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
static void
create_intersection(derivation_t *result, derivation_t *d1, derivation_t *d2)
{
int i;
for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
if(!d1[i].derived && !d2[i].derived) {
continue;
} else if(d1[i].derived && !d2[i].derived) {
result[i].min.l = d1[i].min.l;
result[i].max.l = d1[i].max.l;
} else if(!d1[i].derived && d2[i].derived) {
result[i].min.l = d2[i].min.l;
result[i].max.l = d2[i].max.l;
} else {
/* Both derivations have been made; create an
intersection of the ranges. */
if(d1[i].min.l > d2[i].min.l) {
result[i].min.l = d1[i].min.l;
} else {
result[i].min.l = d2[i].min.l;
}
if(d1[i].max.l < d2[i].max.l) {
result[i].max.l = d1[i].max.l;
} else {
result[i].max.l = d2[i].max.l;
}
}
result[i].derived = 1;
}
#if DEBUG
PRINTF("Created an intersection of D1 and D2\n");
PRINTF("D1: \n");
print_derivations(d1);
PRINTF("D2: \n");
print_derivations(d2);
PRINTF("Result: \n");
print_derivations(result);
#endif /* DEBUG */
}
static void
create_union(derivation_t *result, derivation_t *d1, derivation_t *d2)
{
int i;
for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
if(!d1[i].derived && !d2[i].derived) {
continue;
} else if(d1[i].derived && !d2[i].derived) {
result[i].min.l = d1[i].min.l;
result[i].max.l = d1[i].max.l;
} else if(!d1[i].derived && d2[i].derived) {
result[i].min.l = d2[i].min.l;
result[i].max.l = d2[i].max.l;
} else {
/* Both derivations have been made; create a
union of the ranges. */
if(d1[i].min.l > d2[i].min.l) {
result[i].min.l = d2[i].min.l;
} else {
result[i].min.l = d1[i].min.l;
}
if(d1[i].max.l < d2[i].max.l) {
result[i].max.l = d2[i].max.l;
} else {
result[i].max.l = d1[i].max.l;
}
}
result[i].derived = 1;
}
#if DEBUG
PRINTF("Created a union of D1 and D2\n");
PRINTF("D1: \n");
print_derivations(d1);
PRINTF("D2: \n");
print_derivations(d2);
PRINTF("Result: \n");
print_derivations(result);
#endif /* DEBUG */
}
static int
derive_relation(lvm_instance_t *p, derivation_t *local_derivations)
{
operator_t *operator;
node_type_t type;
operand_t operand[2];
int i;
int var;
int variable_id;
operand_value_t *value;
derivation_t *derivation;
type = get_type(p);
operator = get_operator(p);
if(IS_CONNECTIVE(*operator)) {
derivation_t d1[LVM_MAX_VARIABLE_ID];
derivation_t d2[LVM_MAX_VARIABLE_ID];
if(*operator != LVM_AND && *operator != LVM_OR) {
return DERIVATION_ERROR;
}
PRINTF("Attempting to infer ranges from a logical connective\n");
memset(d1, 0, sizeof(d1));
memset(d2, 0, sizeof(d2));
if(LVM_ERROR(derive_relation(p, d1)) ||
LVM_ERROR(derive_relation(p, d2))) {
return DERIVATION_ERROR;
}
if(*operator == LVM_AND) {
create_intersection(local_derivations, d1, d2);
} else if(*operator == LVM_OR) {
create_union(local_derivations, d1, d2);
}
return TRUE;
}
for(i = 0; i < 2; i++) {
type = get_type(p);
switch(type) {
case LVM_OPERAND:
get_operand(p, &operand[i]);
break;
default:
return DERIVATION_ERROR;
}
}
if(operand[0].type == LVM_VARIABLE && operand[1].type == LVM_VARIABLE) {
return DERIVATION_ERROR;
}
/* Determine which of the operands that is the variable. */
if(operand[0].type == LVM_VARIABLE) {
if(operand[1].type == LVM_VARIABLE) {
return DERIVATION_ERROR;
}
var = 0;
variable_id = operand[0].value.id;
value = &operand[1].value;
} else {
var = 1;
variable_id = operand[1].value.id;
value = &operand[0].value;
}
if(variable_id >= LVM_MAX_VARIABLE_ID) {
return DERIVATION_ERROR;
}
PRINTF("variable id %d, value %ld\n", variable_id, *(long *)value);
derivation = local_derivations + variable_id;
/* Default values. */
derivation->max.l = LONG_MAX;
derivation->min.l = LONG_MIN;
switch(*operator) {
case LVM_EQ:
derivation->max = *value;
derivation->min = *value;
break;
case LVM_GE:
derivation->min.l = value->l + 1;
break;
case LVM_GEQ:
derivation->min.l = value->l;
break;
case LVM_LE:
derivation->max.l = value->l - 1;
break;
case LVM_LEQ:
derivation->max.l = value->l;
break;
default:
return DERIVATION_ERROR;
}
derivation->derived = 1;
return TRUE;
}
lvm_status_t
lvm_derive(lvm_instance_t *p)
{
return derive_relation(p, derivations);
}
lvm_status_t
lvm_get_derived_range(lvm_instance_t *p, char *name,
operand_value_t *min, operand_value_t *max)
{
int i;
for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
if(strcmp(name, variables[i].name) == 0) {
if(derivations[i].derived) {
*min = derivations[i].min;
*max = derivations[i].max;
return TRUE;
}
return DERIVATION_ERROR;
}
}
return INVALID_IDENTIFIER;
}
#if DEBUG
static lvm_ip_t
print_operator(lvm_instance_t *p, lvm_ip_t index)
{
operator_t operator;
struct operator_map {
operator_t op;
char *representation;
};
struct operator_map operator_map[] = {
{LVM_ADD, "+"},
{LVM_SUB, "-"},
{LVM_MUL, "*"},
{LVM_DIV, "/"},
{LVM_GE, ">"},
{LVM_GEQ, ">="},
{LVM_LE, "<"},
{LVM_LEQ, "<="},
{LVM_EQ, "="},
{LVM_NEQ, "<>"},
{LVM_AND, "/\\"},
{LVM_OR, "\\/"},
{LVM_NOT, "!"}
};
int i;
memcpy(&operator, p->code + index, sizeof(operator));
for(i = 0; i < sizeof(operator_map) / sizeof(operator_map[0]); i++) {
if(operator_map[i].op == operator) {
PRINTF("%s ", operator_map[i].representation);
break;
}
}
return index + sizeof(operator_t);
}
static lvm_ip_t
print_operand(lvm_instance_t *p, lvm_ip_t index)
{
operand_t operand;
memcpy(&operand, p->code + index, sizeof(operand));
switch(operand.type) {
case LVM_VARIABLE:
if(operand.value.id >= LVM_MAX_VARIABLE_ID || variables[operand.value.id].name == NULL) {
PRINTF("var(id:%d):?? ", operand.value.id);
} else {
PRINTF("var(%s):%ld ", variables[operand.value.id].name,
variables[operand.value.id].value.l);
}
break;
case LVM_LONG:
PRINTF("long:%ld ", operand.value.l);
break;
default:
PRINTF("?? ");
break;
}
return index + sizeof(operand_t);
}
static lvm_ip_t
print_relation(lvm_instance_t *p, lvm_ip_t index)
{
/* Relational operators are stored as ordinary operators. */
return print_operator(p, index);
}
#endif /* DEBUG */
void
lvm_print_code(lvm_instance_t *p)
{
#if DEBUG
lvm_ip_t ip;
PRINTF("Code: ");
for(ip = 0; ip < p->end;) {
switch(*(node_type_t *)(p->code + ip)) {
case LVM_CMP_OP:
ip = print_relation(p, ip + sizeof(node_type_t));
break;
case LVM_ARITH_OP:
ip = print_operator(p, ip + sizeof(node_type_t));
break;
case LVM_OPERAND:
ip = print_operand(p, ip + sizeof(node_type_t));
break;
default:
PRINTF("Invalid opcode: 0x%x ", p->code[ip]);
ip = p->end;
break;
}
}
putchar('\n');
#endif
}
void
lvm_print_derivations(lvm_instance_t *p)
{
#if DEBUG
print_derivations(derivations);
#endif /* DEBUG */
}
#ifdef TEST
int
main(void)
{
lvm_instance_t p;
unsigned char code[256];
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("z", LVM_LONG);
lvm_set_variable_value("z", (operand_value_t)15L);
lvm_register_variable("y", LVM_LONG);
lvm_set_variable_value("y", (operand_value_t)109L);
/* Infix: 109 = y /\ 20 > 70 - (6 + z * 3) => 109 = 109 /\ 20 > 19 => true */
lvm_set_relation(&p, LVM_AND);
lvm_set_relation(&p, LVM_EQ);
lvm_set_long(&p, 109);
lvm_set_variable(&p, "y");
lvm_set_relation(&p, LVM_GE);
lvm_set_long(&p, 20);
lvm_set_op(&p, LVM_SUB);
lvm_set_long(&p, 70);
lvm_set_op(&p, LVM_ADD);
lvm_set_long(&p, 6);
lvm_set_op(&p, LVM_MUL);
lvm_set_variable(&p, "z");
lvm_set_long(&p, 3);
lvm_print_code(&p);
lvm_execute(&p);
/* Infix: !(9999 + 1 < -1 + 10001) => !(10000 < 10000) => true */
lvm_reset(&p, code, sizeof(code));
lvm_set_relation(&p, LVM_NOT);
lvm_set_relation(&p, LVM_LE);
lvm_set_op(&p, LVM_ADD);
lvm_set_long(&p, 9999);
lvm_set_long(&p, 1);
lvm_set_op(&p, LVM_ADD);
lvm_set_long(&p, -1);
lvm_set_long(&p, 10001);
lvm_print_code(&p);
lvm_execute(&p);
/* Derivation tests */
/* Infix: a = 5 => a:(5,5) */
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("a", LVM_LONG);
lvm_set_relation(&p, LVM_EQ);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 5);
lvm_derive(&p);
lvm_print_derivations(&p);
/* Infix: a < 10 => a:(-oo,9) */
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("a", LVM_LONG);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 10);
lvm_derive(&p);
lvm_print_derivations(&p);
/* Infix: a < 100 /\ 10 < a => a:(11,99) */
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("a", LVM_LONG);
lvm_set_relation(&p, LVM_AND);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 100);
lvm_set_relation(&p, LVM_GE);
lvm_set_long(&p, 10);
lvm_set_variable(&p, "a");
lvm_derive(&p);
lvm_print_derivations(&p);
/* Infix: a < 100 /\ b > 100 => a:(-oo,99), b:(101,oo) */
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("a", LVM_LONG);
lvm_register_variable("b", LVM_LONG);
lvm_set_relation(&p, LVM_AND);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 100);
lvm_set_relation(&p, LVM_GE);
lvm_set_variable(&p, "b");
lvm_set_long(&p, 100);
lvm_derive(&p);
lvm_print_derivations(&p);
/* Infix: a < 100 \/ a < 1000 \/ a < 1902 => a:(-oo,1901) */
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("a", LVM_LONG);
lvm_set_relation(&p, LVM_OR);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 100);
lvm_set_relation(&p, LVM_OR);
lvm_set_relation(&p, LVM_LE);
lvm_set_long(&p, 1000);
lvm_set_variable(&p, "a");
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 1902);
lvm_derive(&p);
lvm_print_derivations(&p);
/* Infix: (a < 100 /\ a < 90 /\ a > 80 /\ a < 105) \/ b > 10000 =>
a:(81,89), b:(10001:oo) */
lvm_reset(&p, code, sizeof(code));
lvm_register_variable("a", LVM_LONG);
lvm_register_variable("b", LVM_LONG);
lvm_set_relation(&p, LVM_OR);
lvm_set_relation(&p, LVM_GE);
lvm_set_variable(&p, "b");
lvm_set_long(&p, 10000);
lvm_set_relation(&p, LVM_AND);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 100);
lvm_set_relation(&p, LVM_AND);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 90);
lvm_set_relation(&p, LVM_AND);
lvm_set_relation(&p, LVM_GE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 80);
lvm_set_relation(&p, LVM_LE);
lvm_set_variable(&p, "a");
lvm_set_long(&p, 105);
lvm_derive(&p);
lvm_print_derivations(&p);
printf("Done\n");
return 0;
}
#endif

144
apps/antelope/lvm.h Normal file
View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Definitions and declarations for the Propositional Logic Engine.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef LVM_H
#define LVM_H
#include <stdlib.h>
#include "db-options.h"
enum lvm_status {
FALSE = 0,
TRUE = 1,
INVALID_IDENTIFIER = 2,
SEMANTIC_ERROR = 3,
MATH_ERROR = 4,
STACK_OVERFLOW = 5,
TYPE_ERROR = 6,
VARIABLE_LIMIT_REACHED = 7,
EXECUTION_ERROR = 8,
DERIVATION_ERROR = 9
};
typedef enum lvm_status lvm_status_t;
#define LVM_ERROR(x) (x >= 2)
typedef int lvm_ip_t;
struct lvm_instance {
unsigned char *code;
lvm_ip_t size;
lvm_ip_t end;
lvm_ip_t ip;
unsigned error;
};
typedef struct lvm_instance lvm_instance_t;
enum node_type {
LVM_ARITH_OP = 0x10,
LVM_OPERAND = 0x20,
LVM_CMP_OP = 0x40,
LVM_CONNECTIVE = 0x80
};
typedef enum node_type node_type_t;
enum operator {
LVM_ADD = LVM_ARITH_OP | 1,
LVM_SUB = LVM_ARITH_OP | 2,
LVM_MUL = LVM_ARITH_OP | 3,
LVM_DIV = LVM_ARITH_OP | 4,
LVM_EQ = LVM_CMP_OP | 1,
LVM_NEQ = LVM_CMP_OP | 2,
LVM_GE = LVM_CMP_OP | 3,
LVM_GEQ = LVM_CMP_OP | 4,
LVM_LE = LVM_CMP_OP | 5,
LVM_LEQ = LVM_CMP_OP | 6,
LVM_AND = LVM_CONNECTIVE | 1,
LVM_OR = LVM_CONNECTIVE | 2,
LVM_NOT = LVM_CONNECTIVE | 3
};
typedef enum operator operator_t;
enum operand_type {
LVM_VARIABLE,
LVM_FLOAT,
LVM_LONG
};
typedef enum operand_type operand_type_t;
typedef unsigned char variable_id_t;
typedef union {
long l;
#if LVM_USE_FLOATS
float f;
#endif
variable_id_t id;
} operand_value_t;
struct operand {
operand_type_t type;
operand_value_t value;
};
typedef struct operand operand_t;
void lvm_reset(lvm_instance_t *p, unsigned char *code, lvm_ip_t size);
void lvm_clone(lvm_instance_t *dst, lvm_instance_t *src);
lvm_status_t lvm_derive(lvm_instance_t *p);
lvm_status_t lvm_get_derived_range(lvm_instance_t *p, char *name,
operand_value_t *min,
operand_value_t *max);
void lvm_print_derivations(lvm_instance_t *p);
lvm_status_t lvm_execute(lvm_instance_t *p);
lvm_status_t lvm_register_variable(char *name, operand_type_t type);
lvm_status_t lvm_set_variable_value(char *name, operand_value_t value);
void lvm_print_code(lvm_instance_t *p);
lvm_ip_t lvm_jump_to_operand(lvm_instance_t *p);
lvm_ip_t lvm_shift_for_operator(lvm_instance_t *p, lvm_ip_t end);
lvm_ip_t lvm_get_end(lvm_instance_t *p);
lvm_ip_t lvm_set_end(lvm_instance_t *p, lvm_ip_t end);
void lvm_set_op(lvm_instance_t *p, operator_t op);
void lvm_set_relation(lvm_instance_t *p, operator_t op);
void lvm_set_operand(lvm_instance_t *p, operand_t *op);
void lvm_set_long(lvm_instance_t *p, long l);
void lvm_set_variable(lvm_instance_t *p, char *name);
#endif /* LVM_H */

1222
apps/antelope/relation.c Normal file

File diff suppressed because it is too large Load diff

102
apps/antelope/relation.h Normal file
View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* .
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef RELATION_H
#define RELATION_H
#include <stdint.h>
#include <stdlib.h>
#include "lib/list.h"
#include "attribute.h"
#include "db-options.h"
#include "db-types.h"
typedef uint32_t tuple_id_t;
#define INVALID_TUPLE (tuple_id_t)-1
typedef enum db_direction {
DB_MEMORY = 0,
DB_STORAGE = 1
} db_direction_t;
#define RELATION_HAS_TUPLES(rel) ((rel)->tuple_storage >= 0)
/*
* A relation consists of a name, a set of domains, a set of indexes,
* and a set of keys. Each relation must have a primary key.
*/
struct relation {
struct relation *next;
LIST_STRUCT(attributes);
attribute_t *primary_key;
size_t row_length;
attribute_id_t attribute_count;
tuple_id_t cardinality;
tuple_id_t next_row;
db_storage_id_t tuple_storage;
db_direction_t dir;
uint8_t references;
char name[RELATION_NAME_LENGTH + 1];
char tuple_filename[RELATION_NAME_LENGTH + 1];
};
typedef struct relation relation_t;
/* API for relations. */
db_result_t relation_init(void);
db_result_t relation_process_remove(void *);
db_result_t relation_process_select(void *);
db_result_t relation_process_join(void *);
relation_t *relation_load(char *);
db_result_t relation_release(relation_t *);
relation_t *relation_create(char *, db_direction_t);
db_result_t relation_rename(char *, char *);
attribute_t *relation_attribute_add(relation_t *, db_direction_t, char *,
domain_t, size_t);
attribute_t *relation_attribute_get(relation_t *, char *);
db_result_t relation_get_value(relation_t *, attribute_t *,
unsigned char *, attribute_value_t *);
db_result_t relation_attribute_remove(relation_t *, char *);
db_result_t relation_set_primary_key(relation_t *, char *);
db_result_t relation_remove(char *, int);
db_result_t relation_insert(relation_t *, attribute_value_t *);
db_result_t relation_select(void *, relation_t *, void *);
db_result_t relation_join(void *, void *);
tuple_id_t relation_cardinality(relation_t *);
#endif /* RELATION_H */

185
apps/antelope/result.c Normal file
View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Result acquisition interface for AQL queries.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <string.h>
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#include "result.h"
#include "storage.h"
/* db_get_value: Retrieve the value of the specified attribute in
the current tuple. */
db_result_t
db_get_value(attribute_value_t *value, db_handle_t *handle, unsigned col)
{
attribute_t *attr;
unsigned char *buf;
if(col >= handle->ncolumns) {
PRINTF("DB: Requested value (%d) is out of bounds; max = (%d)\n",
col, handle->ncolumns);
return DB_LIMIT_ERROR;
}
buf = handle->tuple;
for(attr = list_head(handle->result_rel->attributes); attr != NULL; attr = attr->next) {
if(attr->flags & ATTRIBUTE_FLAG_NO_STORE) {
/* This attribute was used for processing only. */
continue;
}
PRINTF("Found attribute %s in the result. The element size is %d\n",
attr->name, attr->element_size);
if(col == 0) {
break;
}
--col;
buf += attr->element_size;
}
if(attr == NULL) {
return DB_NAME_ERROR;
}
return db_phy_to_value(value, attr, buf);
}
/* db_phy_to_value: Convert a value from the physical storage
representation to the internal RAM representation. */
db_result_t
db_phy_to_value(attribute_value_t *value, attribute_t *attr,
unsigned char *ptr)
{
int int_value;
long long_value;
value->domain = attr->domain;
switch(attr->domain) {
case DOMAIN_STRING:
ptr[attr->element_size - 1] = '\0';
VALUE_STRING(value) = ptr;
PRINTF("DB: %s = %s\n", attr->name, ptr);
break;
case DOMAIN_INT:
int_value = (ptr[0] << 8) | ((unsigned)ptr[1] & 0xff);
VALUE_INT(value) = int_value;
PRINTF("DB: %s = %d\n", attr->name, int_value);
break;
case DOMAIN_LONG:
long_value = (long)ptr[0] << 24 | (long)ptr[1] << 16 |
(long)ptr[2] << 8 | (long)ptr[3];
VALUE_LONG(value) = long_value;
PRINTF("DB: %s = %ld\n", attr->name, long_value);
break;
default:
return DB_TYPE_ERROR;
}
return DB_OK;
}
/* db_value_to_phy: Convert a value from the internal RAM representation
to the physical storage representation. */
db_result_t
db_value_to_phy(unsigned char *ptr, attribute_t *attr,
attribute_value_t *value)
{
int int_value;
long long_value;
switch(attr->domain) {
case DOMAIN_STRING:
memcpy(ptr, VALUE_STRING(value), attr->element_size);
ptr[attr->element_size - 1] = '\0';
break;
case DOMAIN_INT:
int_value = VALUE_INT(value);
ptr[0] = int_value >> 8;
ptr[1] = int_value & 0xff;
break;
case DOMAIN_LONG:
long_value = VALUE_LONG(value);
ptr[0] = long_value >> 24;
ptr[1] = long_value >> 16;
ptr[2] = long_value >> 8;
ptr[3] = long_value & 0xff;
break;
default:
return DB_TYPE_ERROR;
}
return DB_OK;
}
/* db_value_to_long: Convert an attribute value
to a value of the C long type. */
long
db_value_to_long(attribute_value_t *value)
{
switch(value->domain) {
case DOMAIN_INT:
return (long)VALUE_INT(value);
case DOMAIN_LONG:
return (long)VALUE_LONG(value);
default:
return 0;
}
}
/* db_free: Free all the resources that are referenced in a DB handle. */
db_result_t
db_free(db_handle_t *handle)
{
if(handle->rel != NULL) {
relation_release(handle->rel);
}
if(handle->result_rel != NULL) {
relation_release(handle->result_rel);
}
if(handle->left_rel != NULL) {
relation_release(handle->left_rel);
}
if(handle->right_rel != NULL) {
relation_release(handle->right_rel);
}
handle->flags = 0;
return DB_OK;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,41 +25,56 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: tr1001.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* Declarations for the result acquisition API.
* \author
* Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef __TR1001_H__
#define __TR1001_H__
#ifndef RESULT_H
#define RESULT_H
#include "contiki-net.h"
#include "index.h"
#include "relation.h"
#include "storage.h"
#define RESULT_TUPLE_INVALID(tuple) ((tuple) == NULL)
#define RESULT_TUPLE_SIZE(handle) (handle).rel->row_length
void tr1001_init(void);
u8_t tr1001_send(u8_t *packet, u16_t len);
unsigned short tr1001_poll(void);
typedef unsigned char *tuple_t;
void tr1001_set_txpower(unsigned char p);
#define TR1001_TXPOWER_HIGHEST 100
#define TR1001_TXPOWER_LOWEST 1
#define DB_HANDLE_FLAG_INDEX_STEP 0x01
#define DB_HANDLE_FLAG_SEARCH_INDEX 0x02
#define DB_HANDLE_FLAG_PROCESSING 0x04
unsigned short tr1001_sstrength(void);
struct db_handle {
index_iterator_t index_iterator;
tuple_id_t tuple_id;
tuple_id_t current_row;
relation_t *rel;
relation_t *left_rel;
relation_t *join_rel;
relation_t *right_rel;
relation_t *result_rel;
attribute_t *left_join_attr;
attribute_t *right_join_attr;
tuple_t tuple;
uint8_t flags;
uint8_t ncolumns;
void *adt;
};
typedef struct db_handle db_handle_t;
#define TR1001_SSTRENGTH_DROPPED 1
#define TR1001_SSTRENGTH_MAX 2
#define TR1001_SSTRENGTH_MIN 3
unsigned short tr1001_packets_ok(void);
unsigned short tr1001_packets_dropped(void);
void tr1001_clear_packets(void);
unsigned short tr1001_sstrength_value(unsigned int type);
db_result_t db_get_value(attribute_value_t *value,
db_handle_t *handle, unsigned col);
db_result_t db_phy_to_value(attribute_value_t *value,
attribute_t *attr, unsigned char *ptr);
db_result_t db_value_to_phy(unsigned char *ptr,
attribute_t *attr, attribute_value_t *value);
long db_value_to_long(attribute_value_t *value);
db_result_t db_free(db_handle_t *handle);
#endif /* __TR1001_H__ */
#endif /* !RESULT_H */

583
apps/antelope/storage-cfs.c Normal file
View file

@ -0,0 +1,583 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Contiki File System (CFS) backend for the storage abstraction
* used by the database.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdio.h>
#include <string.h>
#include "cfs/cfs.h"
#include "cfs/cfs-coffee.h"
#include "lib/random.h"
#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"
#include "db-options.h"
#include "storage.h"
struct attribute_record {
char name[ATTRIBUTE_NAME_LENGTH];
uint8_t domain;
uint8_t element_size;
};
struct index_record {
char attribute_name[ATTRIBUTE_NAME_LENGTH];
char file_name[DB_MAX_FILENAME_LENGTH];
uint8_t type;
};
#if DB_FEATURE_COFFEE
#define DB_COFFEE_CATALOG_SIZE RELATION_NAME_LENGTH + \
(DB_MAX_ATTRIBUTES_PER_RELATION * \
sizeof(struct attribute_record))
#endif
#define ROW_XOR 0xf6U
static void
merge_strings(char *dest, char *prefix, char *suffix)
{
strcpy(dest, prefix);
strcat(dest, suffix);
}
char *
storage_generate_file(char *prefix, unsigned long size)
{
static char filename[ATTRIBUTE_NAME_LENGTH + sizeof(".ffff")];
#if !DB_FEATURE_COFFEE
int fd;
#endif
snprintf(filename, sizeof(filename), "%s.%x", prefix,
(unsigned)(random_rand() & 0xffff));
#if DB_FEATURE_COFFEE
PRINTF("DB: Reserving %lu bytes in %s\n", size, filename);
if(cfs_coffee_reserve(filename, size) < 0) {
PRINTF("DB: Failed to reserve\n");
return NULL;
}
return filename;
#else
fd = cfs_open(filename, CFS_WRITE);
cfs_close(fd);
return fd < 0 ? NULL : filename;
#endif /* DB_FEATURE_COFFEE */
}
db_result_t
storage_load(relation_t *rel)
{
PRINTF("DB: Opening the tuple file %s\n", rel->tuple_filename);
rel->tuple_storage = cfs_open(rel->tuple_filename,
CFS_READ | CFS_WRITE | CFS_APPEND);
if(rel->tuple_storage < 0) {
PRINTF("DB: Failed to open the tuple file\n");
return DB_STORAGE_ERROR;
}
return DB_OK;
}
void
storage_unload(relation_t *rel)
{
if(RELATION_HAS_TUPLES(rel)) {
PRINTF("DB: Unload tuple file %s\n", rel->tuple_filename);
cfs_close(rel->tuple_storage);
rel->tuple_storage = -1;
}
}
db_result_t
storage_get_relation(relation_t *rel, char *name)
{
int fd;
int r;
int i;
struct attribute_record record;
db_result_t result;
fd = cfs_open(name, CFS_READ);
if(fd < 0) {
return DB_STORAGE_ERROR;
}
r = cfs_read(fd, rel->name, sizeof(rel->name));
if(r != sizeof(rel->name)) {
cfs_close(fd);
PRINTF("DB: Failed to read name, got %d of %d bytes\n",
r, sizeof(rel->name));
return DB_STORAGE_ERROR;
}
r = cfs_read(fd, rel->tuple_filename, sizeof(rel->tuple_filename));
if(r != sizeof(rel->name)) {
cfs_close(fd);
PRINTF("DB: Failed to read tuple filename\n");
return DB_STORAGE_ERROR;
}
rel->tuple_filename[sizeof(rel->tuple_filename) - 1] ^= ROW_XOR;
/* Read attribute records. */
result = DB_OK;
for(i = 0;; i++) {
r = cfs_read(fd, &record, sizeof(record));
if(r == 0) {
break;
}
if(r != sizeof(record)) {
PRINTF("DB: Failed to read attribute record %d (r = %d)\n", i, r);
result = DB_STORAGE_ERROR;
break;
}
if(relation_attribute_add(rel, DB_MEMORY, record.name,
record.domain, record.element_size) == NULL) {
PRINTF("DB: Failed to add the attribute %s\n", record.name);
result = DB_STORAGE_ERROR;
break;
}
}
PRINTF("DB: Read %d attributes\n", i);
cfs_close(fd);
return result;
}
db_result_t
storage_put_relation(relation_t *rel)
{
int fd;
int r;
char *str;
unsigned char *last_byte;
PRINTF("DB: put_relation(%s)\n", rel->name);
cfs_remove(rel->name);
#if DB_FEATURE_COFFEE
cfs_coffee_reserve(rel->name, DB_COFFEE_CATALOG_SIZE);
#endif
fd = cfs_open(rel->name, CFS_WRITE | CFS_READ);
if(fd < 0) {
return DB_STORAGE_ERROR;
}
r = cfs_write(fd, rel->name, sizeof(rel->name));
if(r != sizeof(rel->name)) {
cfs_close(fd);
cfs_remove(rel->name);
return DB_STORAGE_ERROR;
}
if(rel->tuple_filename[0] == '\0') {
str = storage_generate_file("tuple", DB_COFFEE_RESERVE_SIZE);
if(str == NULL) {
cfs_close(fd);
cfs_remove(rel->name);
return DB_STORAGE_ERROR;
}
strncpy(rel->tuple_filename, str, sizeof(rel->tuple_filename) - 1);
rel->tuple_filename[sizeof(rel->tuple_filename) - 1] = '\0';
}
/*
* Encode the last byte to ensure that the filename is not
* null-terminated. This will make the Coffee FS determine
* the correct length when re-opening the file.
*/
last_byte = (unsigned char *)&rel->tuple_filename[sizeof(rel->tuple_filename) - 1];
*last_byte ^= ROW_XOR;
r = cfs_write(fd, rel->tuple_filename, sizeof(rel->tuple_filename));
*last_byte ^= ROW_XOR;
if(r != sizeof(rel->tuple_filename)) {
cfs_close(fd);
cfs_remove(rel->tuple_filename);
return DB_STORAGE_ERROR;
}
PRINTF("DB: Saved relation %s\n", rel->name);
cfs_close(fd);
return DB_OK;
}
db_result_t
storage_put_attribute(relation_t *rel, attribute_t *attr)
{
int fd;
struct attribute_record record;
int r;
PRINTF("DB: put_attribute(%s, %s)\n", rel->name, attr->name);
fd = cfs_open(rel->name, CFS_WRITE | CFS_APPEND);
if(fd < 0) {
return DB_STORAGE_ERROR;
}
memset(&record.name, 0, sizeof(record.name));
memcpy(record.name, attr->name, sizeof(record.name));
record.domain = attr->domain;
record.element_size = attr->element_size;
r = cfs_write(fd, &record, sizeof(record));
if(r != sizeof(record)) {
cfs_close(fd);
cfs_remove(rel->name);
return DB_STORAGE_ERROR;
}
cfs_close(fd);
return DB_OK;
}
db_result_t
storage_drop_relation(relation_t *rel, int remove_tuples)
{
if(remove_tuples && RELATION_HAS_TUPLES(rel)) {
cfs_remove(rel->tuple_filename);
}
return cfs_remove(rel->name) < 0 ? DB_STORAGE_ERROR : DB_OK;
}
#if DB_FEATURE_REMOVE
db_result_t
storage_rename_relation(char *old_name, char *new_name)
{
db_result_t result;
int old_fd;
int new_fd;
int r;
char buf[64];
result = DB_STORAGE_ERROR;
old_fd = new_fd = -1;
old_fd = cfs_open(old_name, CFS_READ);
new_fd = cfs_open(new_name, CFS_WRITE);
if(old_fd < 0 || new_fd < 0) {
goto error;
}
for(;;) {
r = cfs_read(old_fd, buf, sizeof(buf));
if(r < 0) {
goto error;
} else if(r == 0) {
break;
}
if(cfs_write(new_fd, buf, r) != r) {
goto error;
}
};
cfs_remove(old_name);
result = DB_OK;
error:
cfs_close(old_fd);
cfs_close(new_fd);
if(result != DB_OK) {
cfs_remove(new_name);
}
return result;
}
#endif /* DB_FEATURE_REMOVE */
db_result_t
storage_get_index(index_t *index, relation_t *rel, attribute_t *attr)
{
char filename[INDEX_NAME_LENGTH];
int fd;
int r;
struct index_record record;
db_result_t result;
merge_strings(filename, rel->name, INDEX_NAME_SUFFIX);
fd = cfs_open(filename, CFS_READ);
if(fd < 0) {
return DB_STORAGE_ERROR;
}
for(result = DB_STORAGE_ERROR;;) {
r = cfs_read(fd, &record, sizeof(record));
if(r < sizeof(record)) {
break;
}
if(strcmp(attr->name, record.attribute_name) == 0) {
PRINTF("DB: Found the index record for %s.%s: type %d, filename %s\n",
rel->name, attr->name, record.type, record.file_name);
index->type = record.type;
memcpy(index->descriptor_file, record.file_name,
sizeof(index->descriptor_file));
result = DB_OK;
}
}
cfs_close(fd);
return result;
}
db_result_t
storage_put_index(index_t *index)
{
char filename[INDEX_NAME_LENGTH];
int fd;
int r;
struct index_record record;
db_result_t result;
merge_strings(filename, index->rel->name, INDEX_NAME_SUFFIX);
fd = cfs_open(filename, CFS_WRITE | CFS_APPEND);
if(fd < 0) {
return DB_STORAGE_ERROR;
}
strcpy(record.attribute_name, index->attr->name);
memcpy(record.file_name, index->descriptor_file, sizeof(record.file_name));
record.type = index->type;
result = DB_OK;
r = cfs_write(fd, &record, sizeof(record));
if(r < sizeof(record)) {
result = DB_STORAGE_ERROR;
} else {
PRINTF("DB: Wrote an index record for %s.%s, type %d\n",
index->rel->name, index->attr->name, record.type);
}
cfs_close(fd);
return result;
}
db_result_t
storage_get_row(relation_t *rel, tuple_id_t *tuple_id, storage_row_t row)
{
int r;
tuple_id_t nrows;
if(DB_ERROR(storage_get_row_amount(rel, &nrows))) {
return DB_STORAGE_ERROR;
}
if(*tuple_id >= nrows) {
return DB_FINISHED;
}
if(cfs_seek(rel->tuple_storage, *tuple_id * rel->row_length, CFS_SEEK_SET) ==
(cfs_offset_t)-1) {
return DB_STORAGE_ERROR;
}
r = cfs_read(rel->tuple_storage, row, rel->row_length);
if(r < 0) {
PRINTF("DB: Reading failed on fd %d\n", rel->tuple_storage);
return DB_STORAGE_ERROR;
} else if(r == 0) {
return DB_FINISHED;
} else if(r < rel->row_length) {
PRINTF("DB: Incomplete record: %d < %d\n", r, rel->row_length);
return DB_STORAGE_ERROR;
}
row[rel->row_length - 1] ^= ROW_XOR;
PRINTF("DB: Read %d bytes from relation %s\n", rel->row_length, rel->name);
return DB_OK;
}
db_result_t
storage_put_row(relation_t *rel, storage_row_t row)
{
cfs_offset_t end;
unsigned remaining;
int r;
unsigned char *last_byte;
#if DB_FEATURE_INTEGRITY
int missing_bytes;
char buf[rel->row_length];
#endif
end = cfs_seek(rel->tuple_storage, 0, CFS_SEEK_END);
if(end == (cfs_offset_t)-1) {
return DB_STORAGE_ERROR;
}
#if DB_FEATURE_INTEGRITY
missing_bytes = end % rel->row_length;
if(missing_bytes > 0) {
memset(buf, 0xff, sizeof(buf));
r = cfs_write(rel->tuple_storage, buf, sizeof(buf));
if(r != missing_bytes) {
return DB_STORAGE_ERROR;
}
}
#endif
/* Ensure that last written byte is separated from 0, to make file
lengths correct in Coffee. */
last_byte = row + rel->row_length - 1;
*last_byte ^= ROW_XOR;
remaining = rel->row_length;
do {
r = cfs_write(rel->tuple_storage, row, remaining);
if(r < 0) {
PRINTF("DB: Failed to store %u bytes\n", remaining);
*last_byte ^= ROW_XOR;
return DB_STORAGE_ERROR;
}
row += r;
remaining -= r;
} while(remaining > 0);
PRINTF("DB: Stored a of %d bytes\n", rel->row_length);
*last_byte ^= ROW_XOR;
return DB_OK;
}
db_result_t
storage_get_row_amount(relation_t *rel, tuple_id_t *amount)
{
cfs_offset_t offset;
if(rel->row_length == 0) {
*amount = 0;
} else {
offset = cfs_seek(rel->tuple_storage, 0, CFS_SEEK_END);
if(offset == (cfs_offset_t)-1) {
return DB_STORAGE_ERROR;
}
*amount = (tuple_id_t)(offset / rel->row_length);
}
return DB_OK;
}
db_storage_id_t
storage_open(const char *filename)
{
int fd;
fd = cfs_open(filename, CFS_WRITE | CFS_READ);
#if DB_FEATURE_COFFEE
if(fd >= 0) {
cfs_coffee_set_io_semantics(fd, CFS_COFFEE_IO_FLASH_AWARE);
}
#endif
return fd;
}
void
storage_close(db_storage_id_t fd)
{
cfs_close(fd);
}
db_result_t
storage_read(db_storage_id_t fd,
void *buffer, unsigned long offset, unsigned length)
{
char *ptr;
int r;
/* Extend the file if necessary, so that previously unwritten bytes
will be read in as zeroes. */
if(cfs_seek(fd, offset + length, CFS_SEEK_SET) == (cfs_offset_t)-1) {
return DB_STORAGE_ERROR;
}
if(cfs_seek(fd, offset, CFS_SEEK_SET) == (cfs_offset_t)-1) {
return DB_STORAGE_ERROR;
}
ptr = buffer;
while(length > 0) {
r = cfs_read(fd, ptr, length);
if(r <= 0) {
return DB_STORAGE_ERROR;
}
ptr += r;
length -= r;
}
return DB_OK;
}
db_result_t
storage_write(db_storage_id_t fd,
void *buffer, unsigned long offset, unsigned length)
{
char *ptr;
int r;
if(cfs_seek(fd, offset, CFS_SEEK_SET) == (cfs_offset_t)-1) {
return DB_STORAGE_ERROR;
}
ptr = buffer;
while(length > 0) {
r = cfs_write(fd, ptr, length);
if(r <= 0) {
return DB_STORAGE_ERROR;
}
ptr += r;
length -= r;
}
return DB_OK;
}

76
apps/antelope/storage.h Normal file
View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* The storage interface used by the database.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#ifndef STORAGE_H
#define STORAGE_H
#include "index.h"
#include "relation.h"
#define TABLE_NAME_SUFFIX ".row"
#define TABLE_NAME_LENGTH (RELATION_NAME_LENGTH + \
sizeof(TABLE_NAME_SUFFIX) - 1)
#define INDEX_NAME_SUFFIX ".idx"
#define INDEX_NAME_LENGTH (RELATION_NAME_LENGTH + \
sizeof(INDEX_NAME_SUFFIX) - 1)
typedef unsigned char * storage_row_t;
char *storage_generate_file(char *, unsigned long);
db_result_t storage_load(relation_t *);
void storage_unload(relation_t *);
db_result_t storage_get_relation(relation_t *, char *);
db_result_t storage_put_relation(relation_t *);
db_result_t storage_drop_relation(relation_t *, int);
db_result_t storage_rename_relation(char *, char *);
db_result_t storage_put_attribute(relation_t *, attribute_t *);
db_result_t storage_get_index(index_t *, relation_t *, attribute_t *);
db_result_t storage_put_index(index_t *);
db_result_t storage_get_row(relation_t *, tuple_id_t *, storage_row_t);
db_result_t storage_put_row(relation_t *, storage_row_t);
db_result_t storage_get_row_amount(relation_t *, tuple_id_t *);
db_storage_id_t storage_open(const char *);
void storage_close(db_storage_id_t);
db_result_t storage_read(db_storage_id_t, void *, unsigned long, unsigned);
db_result_t storage_write(db_storage_id_t, void *, unsigned long, unsigned);
#endif /* STORAGE_H */

View file

@ -123,9 +123,9 @@ int
uint32_2_bytes(uint8_t *bytes, uint32_t var)
{
int i = 0;
if (0xFF000000 & var) bytes[i++] = var>>24;
if (0xFF0000 & var) bytes[i++] = var>>16;
if (0xFF00 & var) bytes[i++] = var>>8;
if (0xFF000000 & var) bytes[i++] = (0xFF & var>>24);
if (0xFFFF0000 & var) bytes[i++] = (0xFF & var>>16);
if (0xFFFFFF00 & var) bytes[i++] = (0xFF & var>>8);
bytes[i++] = 0xFF & var;
return i;

View file

@ -136,10 +136,10 @@ serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t v
uint8_t *option = &buffer[i];
if (0xFF000000 & value) buffer[++i] = (uint8_t) (value>>24);
if (0x00FF0000 & value) buffer[++i] = (uint8_t) (value>>16);
if (0x0000FF00 & value) buffer[++i] = (uint8_t) (value>>8);
if (0x000000FF & value) buffer[++i] = (uint8_t) value;
if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24);
if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16);
if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8);
if ( value) buffer[++i] = (uint8_t) (0xFF & value);
i += set_option_header(number - current_number, i-start_i, option);

View file

@ -148,6 +148,7 @@ handle_incoming_data(void)
}
else
{
block_size = REST_MAX_CHUNK_SIZE;
new_offset = 0;
}
@ -304,7 +305,7 @@ coap_set_rest_status(void *packet, unsigned int code)
/*- Server part ---------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
/* The discover resource is automatically included for CoAP. */
RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "");
RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "ct=40");
void
well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{

View file

@ -137,10 +137,10 @@ serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t v
uint8_t *option = &buffer[i];
if (0xFF000000 & value) buffer[++i] = (uint8_t) (value>>24);
if (0x00FF0000 & value) buffer[++i] = (uint8_t) (value>>16);
if (0x0000FF00 & value) buffer[++i] = (uint8_t) (value>>8);
if (0x000000FF & value) buffer[++i] = (uint8_t) value;
if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24);
if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16);
if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8);
if (0xFFFFFFFF & value) buffer[++i] = (uint8_t) (0xFF & value);
i += set_option_header(number - current_number, i-start_i, option);
@ -680,7 +680,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
((coap_packet_t *)packet)->block2_num = parse_int_option(current_option, option_len);
((coap_packet_t *)packet)->block2_more = (((coap_packet_t *)packet)->block2_num & 0x08)>>3;
((coap_packet_t *)packet)->block2_size = 16 << (((coap_packet_t *)packet)->block2_num & 0x07);
((coap_packet_t *)packet)->block2_offset = (((coap_packet_t *)packet)->block2_num & ~0x0F)<<(((coap_packet_t *)packet)->block2_num & 0x07);
((coap_packet_t *)packet)->block2_offset = (((coap_packet_t *)packet)->block2_num & ~0x0000000F)<<(((coap_packet_t *)packet)->block2_num & 0x07);
((coap_packet_t *)packet)->block2_num >>= 4;
PRINTF("Block2 [%lu%s (%u B/blk)]\n", ((coap_packet_t *)packet)->block2_num, ((coap_packet_t *)packet)->block2_more ? "+" : "", ((coap_packet_t *)packet)->block2_size);
break;
@ -1035,7 +1035,7 @@ coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size)
if (num>0x0FFFFF) return 0;
((coap_packet_t *)packet)->block2_num = num;
((coap_packet_t *)packet)->block2_more = more;
((coap_packet_t *)packet)->block2_more = more ? 1 : 0;
((coap_packet_t *)packet)->block2_size = size;
SET_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK2);

View file

@ -88,7 +88,7 @@ typedef struct unit_test {
*
* \param name The name of the unit test.
*/
#define UNIT_TEST(name) unit_test_result_t unit_test_function_##name(unit_test_t *utp)
#define UNIT_TEST(name) static void unit_test_function_##name(unit_test_t *utp)
/**
* Mark the starting point of the unit test function.
@ -103,8 +103,7 @@ typedef struct unit_test {
*/
#define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \
unit_test_end: \
utp->end = RTIMER_NOW(); \
return utp->result;
utp->end = RTIMER_NOW()
/*
* The test result is printed with a function that is selected by

View file

@ -28,7 +28,6 @@
*
* This file is part of the Contiki operating system.
*
* $Id: phase.c,v 1.17 2010/12/18 22:12:53 dak664 Exp $
*/
/**
@ -108,6 +107,9 @@ phase_update(const struct phase_list *list,
e = find_neighbor(list, neighbor);
if(e != NULL) {
if(mac_status == MAC_TX_OK) {
#if PHASE_DRIFT_CORRECT
e->drift = time-e->time;
#endif
e->time = time;
}
/* If the neighbor didn't reply to us, it may have switched
@ -140,6 +142,9 @@ phase_update(const struct phase_list *list,
}
rimeaddr_copy(&e->neighbor, neighbor);
e->time = time;
#if PHASE_DRIFT_CORRECT
e->drift = 0;
#endif
e->noacks = 0;
list_push(*list->list, e);
}
@ -197,8 +202,27 @@ phase_wait(struct phase_list *list,
now = RTIMER_NOW();
sync = (e == NULL) ? now : e->time;
wait = (rtimer_clock_t)((sync - now) &
(cycle_time - 1));
#if PHASE_DRIFT_CORRECT
{
int32_t s;
if(e->drift > cycle_time) {
s = e->drift % cycle_time / (e->drift / cycle_time); /* drift per cycle */
s = s * (now - sync) / cycle_time; /* estimated drift to now */
sync += s; /* add it in */
}
}
#endif
/* Check if cycle_time is a power of two */
if(!(cycle_time & (cycle_time - 1))) {
/* Faster if cycle_time is a power of two */
wait = (rtimer_clock_t)((sync - now) & (cycle_time - 1));
} else {
/* Works generally */
wait = cycle_time - (rtimer_clock_t)((now - sync) % cycle_time);
}
if(wait < guard_time) {
wait += cycle_time;
}
@ -226,6 +250,7 @@ phase_wait(struct phase_list *list,
expected = now + wait - guard_time;
if(!RTIMER_CLOCK_LT(expected, now)) {
/* Wait until the receiver is expected to be awake */
// printf("%d ",expected%cycle_time); //for spreadsheet export
while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected));
}
return PHASE_SEND_NOW;

View file

@ -28,7 +28,6 @@
*
* This file is part of the Contiki operating system.
*
* $Id: phase.h,v 1.5 2010/09/13 13:39:05 adamdunkels Exp $
*/
/**
@ -48,10 +47,19 @@
#include "lib/memb.h"
#include "net/netstack.h"
#if PHASE_CONF_DRIFT_CORRECT
#define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT
#else
#define PHASE_DRIFT_CORRECT 0
#endif
struct phase {
struct phase *next;
rimeaddr_t neighbor;
rtimer_clock_t time;
#if PHASE_DRIFT_CORRECT
rtimer_clock_t drift;
#endif
uint8_t noacks;
struct timer noacks_timer;
};

View file

@ -630,8 +630,8 @@ tcpip_ipv6_output(void)
memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
}
uip_len = 0;
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
uip_len = 0;
return;
}
/* Send in parallel if we are running NUD (nbc state is either STALE,

View file

@ -825,13 +825,13 @@ CCIF void uip_send(const void *data, int len);
*
* \param rport The remote port number in network byte order.
*
* \return The uip_udp_conn structure for the new connection or NULL
* \return The uip_udp_conn structure for the new connection, or NULL
* if no connection could be allocated.
*/
struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
/**
* Removed a UDP connection.
* Remove a UDP connection.
*
* \param conn A pointer to the uip_udp_conn structure for the connection.
*
@ -942,7 +942,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
} while(0)
/**
* Construct an IPv6 address from eight 8-bit words.
* Construct an IPv6 address from sixteen 8-bit words.
*
* This function constructs an IPv6 address.
*
@ -969,7 +969,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
/**
* Copy an IP address to another IP address.
* Copy an IP address from one place to another.
*
* Copies an IP address from one place to another.
*
@ -1001,7 +1001,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
uip_ipaddr(&ipaddr1, 192,16,1,2);
if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
printf("They are the same");
printf("They are the same");
}
\endcode
*
@ -1201,7 +1201,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
#endif /* UIP_HTONS */
/**
* Convert 16-bit quantity from host byte order to network byte order.
* Convert a 16-bit quantity from host byte order to network byte order.
*
* This function is primarily used for converting variables from host
* byte order to network byte order. For converting constants to
@ -1407,11 +1407,11 @@ struct uip_stats {
IP length, high byte. */
uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
IP length, low byte. */
uip_stats_t fragerr; /**< Number of packets dropped since they
uip_stats_t fragerr; /**< Number of packets dropped because they
were IP fragments. */
uip_stats_t chkerr; /**< Number of packets dropped due to IP
checksum errors. */
uip_stats_t protoerr; /**< Number of packets dropped since they
uip_stats_t protoerr; /**< Number of packets dropped because they
were neither ICMP, UDP nor TCP. */
} ip; /**< IP statistics. */
struct {
@ -1432,10 +1432,10 @@ struct uip_stats {
checksum. */
uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
number. */
uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
uip_stats_t rst; /**< Number of received TCP RST (reset) segments. */
uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
connections was avaliable. */
uip_stats_t syndrop; /**< Number of dropped SYNs because too few
connections were available. */
uip_stats_t synrst; /**< Number of SYNs for closed ports,
triggering a RST. */
} tcp; /**< TCP statistics. */

View file

@ -221,7 +221,7 @@ typedef unsigned char process_num_events_t;
*/
#define PROCESS_PAUSE() do { \
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \
PROCESS_WAIT_EVENT(); \
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); \
} while(0)
/** @} end of protothread functions */

View file

@ -67,25 +67,29 @@ void clock_adjust_seconds(uint8_t howmany) {
/*---------------------------------------------------------------------------*/
/* This routine can be called to add ticks to the clock after a sleep.
* Leap ticks or seconds can (rarely) be introduced if the ISR is not blocked.
*/
void clock_adjust_ticks(uint16_t howmany) {
// uint8_t sreg = SREG;cli();
count += howmany;
scount += howmany;
while(scount >= CLOCK_SECOND) {
scount -= CLOCK_SECOND;
howmany+= scount;
while(howmany >= CLOCK_SECOND) {
howmany -= CLOCK_SECOND;
seconds++;
sleepseconds++;
#if RADIOSTATS
if (RF230_receive_on) radioontime += 1;
#endif
}
scount = howmany;
// SREG=sreg;
}
/*---------------------------------------------------------------------------*/
//SIGNAL(SIG_OUTPUT_COMPARE0)
ISR(AVR_OUTPUT_COMPARE_INT)
{
count++;
if(++scount == CLOCK_SECOND) {
if(++scount >= CLOCK_SECOND) {
scount = 0;
seconds++;
}
@ -96,7 +100,7 @@ ISR(AVR_OUTPUT_COMPARE_INT)
#endif
#if RADIOSTATS
if (RF230_receive_on) {
if (++rcount == CLOCK_SECOND) {
if (++rcount >= CLOCK_SECOND) {
rcount=0;
radioontime++;
}

View file

@ -40,7 +40,7 @@
static void *main_fiber;
#else /* _WIN32 || __CYGWIN__ */
#elif defined(__linux)
#include <stdlib.h>
#include <signal.h>
@ -54,7 +54,7 @@ struct mtarch_t {
static ucontext_t main_context;
static ucontext_t *running_context;
#endif /* _WIN32 || __CYGWIN__ */
#endif /* _WIN32 || __CYGWIN__ || __linux */
#include "mtarch.h"
@ -88,7 +88,7 @@ mtarch_start(struct mtarch_thread *thread,
thread->mt_thread = CreateFiber(0, (LPFIBER_START_ROUTINE)function, data);
#else /* _WIN32 || __CYGWIN__ */
#elif defined(__linux)
thread->mt_thread = malloc(sizeof(struct mtarch_t));
@ -118,7 +118,7 @@ mtarch_start(struct mtarch_thread *thread,
makecontext(&((struct mtarch_t *)thread->mt_thread)->context,
(void (*)(void))function, 1, data);
#endif /* _WIN32 || __CYGWIN__ */
#endif /* _WIN32 || __CYGWIN__ || __linux */
}
/*--------------------------------------------------------------------------*/
void
@ -128,11 +128,11 @@ mtarch_yield(void)
SwitchToFiber(main_fiber);
#else /* _WIN32 || __CYGWIN__ */
#elif defined(__linux)
swapcontext(running_context, &main_context);
#endif /* _WIN32 || __CYGWIN__ */
#endif /* _WIN32 || __CYGWIN__ || __linux */
}
/*--------------------------------------------------------------------------*/
void
@ -142,13 +142,13 @@ mtarch_exec(struct mtarch_thread *thread)
SwitchToFiber(thread->mt_thread);
#else /* _WIN32 || __CYGWIN__ */
#elif defined(__linux)
running_context = &((struct mtarch_t *)thread->mt_thread)->context;
swapcontext(&main_context, running_context);
running_context = NULL;
#endif /* _WIN32 || __CYGWIN__ */
#endif /* _WIN32 || __CYGWIN__ || __linux */
}
/*--------------------------------------------------------------------------*/
void
@ -158,11 +158,11 @@ mtarch_stop(struct mtarch_thread *thread)
DeleteFiber(thread->mt_thread);
#else /* _WIN32 || __CYGWIN__ */
#elif defined(linux) || defined(__linux)
free(thread->mt_thread);
#endif /* _WIN32 || __CYGWIN__ */
#endif /* _WIN32 || __CYGWIN__ || __linux */
}
/*--------------------------------------------------------------------------*/
void

View file

@ -0,0 +1,6 @@
CONTIKI = ../../../
APPS += antelope
CFLAGS += -Wall -g -DPROJECT_CONF_H=\"project-conf.h\"
SMALL = 1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A small command-line interface for the querying remote database systems.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/serial-line.h"
#include "net/rime.h"
#include "net/rime/mesh.h"
#include "antelope.h"
/*---------------------------------------------------------------------------*/
#define MAX_QUERY_SIZE 100
#define NETDB_CHANNEL 70
#ifndef SERVER_ID
#define SERVER_ID 4
#endif
/*---------------------------------------------------------------------------*/
PROCESS(netdb_process, "NetDB");
AUTOSTART_PROCESSES(&netdb_process);
static unsigned server_id = SERVER_ID;
static struct mesh_conn mesh;
/*---------------------------------------------------------------------------*/
PROCESS(shell_process, "Shell Process");
PROCESS_THREAD(shell_process, ev, data)
{
rimeaddr_t addr;
PROCESS_BEGIN();
printf("NetDB client\n");
for(;;) {
PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL);
if(strncmp(data, "server ", 7) == 0) {
server_id = atoi((char *)data + 7);
} else {
printf("%lu Transmitting query \"%s\" to node %u\n", clock_time(), (char *)data, server_id);
packetbuf_copyfrom(data, strlen(data));
addr.u8[0] = server_id;
addr.u8[1] = 0;
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,
PACKETBUF_ATTR_PACKET_TYPE_STREAM);
mesh_send(&mesh, &addr);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
sent(struct mesh_conn *c)
{
}
static void
timedout(struct mesh_conn *c)
{
printf("Failed to send packet: time out\n");
}
static void
received(struct mesh_conn *c, const rimeaddr_t *from, uint8_t hops)
{
char *data;
unsigned len;
static char reply[MAX_QUERY_SIZE + 1];
data = (char *)packetbuf_dataptr();
len = packetbuf_datalen();
if(len > MAX_QUERY_SIZE) {
printf("Too long query: %d bytes\n", len);
return;
}
memcpy(reply, data, len);
reply[len] = '\0';
printf("%lu Reply received from %d.%d (%d hops): %s",
clock_time(), from->u8[0], from->u8[1], (int)hops, reply);
}
static const struct mesh_callbacks callbacks = {received, sent, timedout};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(netdb_process, ev, data)
{
PROCESS_EXITHANDLER(mesh_close(&mesh));
PROCESS_BEGIN();
mesh_open(&mesh, NETDB_CHANNEL, &callbacks);
process_start(&shell_process, NULL);
PROCESS_END();
}

View file

@ -0,0 +1,300 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A small command-line interface for the querying remote database systems.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/serial-line.h"
#include "dev/sht11.h"
#include "lib/random.h"
#include "net/rime.h"
#include "net/rime/mesh.h"
#include "antelope.h"
/*---------------------------------------------------------------------------*/
/* Sampling interval in Hz. */
#ifndef SAMPLING_INTERVAL
#define SAMPLING_INTERVAL 60
#endif
#ifndef RESPONSE_LIMIT
#define RESPONSE_LIMIT 1000
#endif
#ifndef PREPARE_DB
#define PREPARE_DB 1
#endif
#ifndef CARDINALITY
#define CARDINALITY 1000
#endif
#define MAX_BUFFER_SIZE 80
#define NETDB_CHANNEL 70
/*---------------------------------------------------------------------------*/
PROCESS(netdb_process, "NetDB");
AUTOSTART_PROCESSES(&netdb_process);
static struct mesh_conn mesh;
static rimeaddr_t reply_addr;
static uint8_t buffer_offset;
static char buffer[MAX_BUFFER_SIZE];
/*---------------------------------------------------------------------------*/
static void
send_buffered_data(void)
{
if(buffer_offset > 0) {
packetbuf_copyfrom(buffer, buffer_offset);
mesh_send(&mesh, &reply_addr);
buffer_offset = 0;
}
}
/*---------------------------------------------------------------------------*/
static int
buffer_db_data(const char *format, ...)
{
va_list ap;
size_t len;
char tmp[MAX_BUFFER_SIZE + 1];
va_start(ap, format);
len = vsnprintf(tmp, sizeof(tmp), format, ap);
va_end(ap);
if(len < 0) {
return -1;
}
if(len + buffer_offset > sizeof(buffer)) {
send_buffered_data();
}
memcpy(&buffer[buffer_offset], tmp, len);
buffer_offset += len;
return len;
}
/*---------------------------------------------------------------------------*/
static void
take_sample(void)
{
unsigned seconds;
unsigned humidity;
seconds = clock_seconds();
humidity = /*sht11_humidity()*/ random_rand();
if(DB_ERROR(db_query(NULL, "INSERT (%u, %u) INTO samples;",
seconds, humidity))) {
printf("DB insertion failed\n");
}
}
/*---------------------------------------------------------------------------*/
static void
stop_handler(void *ptr)
{
printf("END\n");
}
/*---------------------------------------------------------------------------*/
PROCESS(query_process, "Query process");
PROCESS_THREAD(query_process, ev, data)
{
static db_handle_t handle;
db_result_t result;
static tuple_id_t matching;
static tuple_id_t processed;
#if !PREPARE_DB
static struct etimer sampling_timer;
#endif
static unsigned i, errors;
PROCESS_BEGIN();
printf("NetDB host\n");
db_init();
db_set_output_function(buffer_db_data);
db_query(NULL, "REMOVE RELATION samples;");
db_query(NULL, "CREATE RELATION samples;");
db_query(NULL, "CREATE ATTRIBUTE time DOMAIN INT IN samples;");
db_query(NULL, "CREATE ATTRIBUTE hum DOMAIN INT IN samples;");
db_query(NULL, "CREATE INDEX samples.time TYPE INLINE;");
#if PREPARE_DB
printf("Preparing the DB with %d tuples...\n", CARDINALITY);
errors = 0;
for(i = 1; i <= CARDINALITY; i++) {
PROCESS_PAUSE();
result = db_query(NULL, "INSERT (%u, %u) INTO samples;",
i, (unsigned)random_rand());
if(DB_ERROR(result)) {
errors++;
}
}
printf("Done. Insertion errors: %d\n", errors);
printf("Ready to process queries\n");
#else
etimer_set(&sampling_timer, SAMPLING_INTERVAL * CLOCK_SECOND);
#endif
for(;;) {
PROCESS_WAIT_EVENT();
if(ev == serial_line_event_message && data != NULL) {
printf("START %s\n", (char *)data);
result = db_query(&handle, data);
if(DB_ERROR(result)) {
buffer_db_data("Query error: %s\n", db_get_result_message(result));
stop_handler(NULL);
db_free(&handle);
continue;
}
if(!db_processing(&handle)) {
buffer_db_data("OK\n");
send_buffered_data();
stop_handler(NULL);
continue;
}
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,
PACKETBUF_ATTR_PACKET_TYPE_STREAM);
db_print_header(&handle);
matching = 0;
processed = 0;
while(db_processing(&handle)) {
PROCESS_PAUSE();
if(matching == RESPONSE_LIMIT) {
buffer_db_data("Response suppressed at %u tuples: limit reached\n",
RESPONSE_LIMIT);
stop_handler(NULL);
db_free(&handle);
break;
}
result = db_process(&handle);
if(result == DB_GOT_ROW) {
/* The processed tuple matched the condition in the query. */
matching++;
processed++;
db_print_tuple(&handle);
} else if(result == DB_OK) {
/* A tuple was processed, but did not match the condition. */
processed++;
continue;
} else {
if(result == DB_FINISHED) {
/* The processing has finished. Wait for a new command. */
buffer_db_data("[%ld tuples returned; %ld tuples processed]\n",
(long)matching, (long)processed);
buffer_db_data("OK\n");
} else if(DB_ERROR(result)) {
buffer_db_data("Processing error: %s\n",
db_get_result_message(result));
}
stop_handler(NULL);
db_free(&handle);
}
}
send_buffered_data();
}
#if !PREPARE_DB
if(etimer_expired(&sampling_timer)) {
take_sample();
etimer_reset(&sampling_timer);
}
#endif
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
sent(struct mesh_conn *c)
{
}
static void
timedout(struct mesh_conn *c)
{
printf("packet time out\n");
}
static void
received(struct mesh_conn *c, const rimeaddr_t *from, uint8_t hops)
{
char *data;
unsigned len;
static char query[MAX_BUFFER_SIZE + 1];
data = (char *)packetbuf_dataptr();
len = packetbuf_datalen();
if(len > MAX_BUFFER_SIZE) {
buffer_db_data("Too long query: %d bytes\n", len);
return;
}
memcpy(query, data, len);
query[len] = '\0';
printf("Query received from %d.%d: %s (%d hops)\n",
from->u8[0], from->u8[1], query, (int)hops);
rimeaddr_copy(&reply_addr, from);
process_post(&query_process, serial_line_event_message, query);
}
static const struct mesh_callbacks callbacks = {received, sent, timedout};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(netdb_process, ev, data)
{
PROCESS_EXITHANDLER(mesh_close(&mesh));
PROCESS_BEGIN();
mesh_open(&mesh, NETDB_CHANNEL, &callbacks);
process_start(&query_process, NULL);
PROCESS_END();
}

271
examples/antelope/netdb/netdb.csc Executable file
View file

@ -0,0 +1,271 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/serial_socket</project>
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/collect-view</project>
<simulation>
<title>NetDB</title>
<delaytime>0</delaytime>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
se.sics.cooja.radiomediums.UDGM
<transmitting_range>30.0</transmitting_range>
<interference_range>30.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
se.sics.cooja.mspmote.SkyMoteType
<identifier>sky1</identifier>
<description>NetDB Server</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/antelope/netdb/netdb-server.c</source>
<commands EXPORT="discard">make netdb-server.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/antelope/netdb/netdb-server.sky</firmware>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<motetype>
se.sics.cooja.mspmote.SkyMoteType
<identifier>sky2</identifier>
<description>NetDB Client</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/antelope/netdb/netdb-client.c</source>
<commands EXPORT="discard">make netdb-client.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/antelope/netdb/netdb-client.sky</firmware>
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyByteRadio</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>23.57340748739308</x>
<y>46.80222047486912</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>40.39130096157144</x>
<y>70.54634688655467</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>66.04131381969006</x>
<y>36.41113701058369</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>63.00130046120498</x>
<y>80.89331313174746</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>4</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>40.2894982777653</x>
<y>95.14334789567525</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>5</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>-13.168104050312492</x>
<y>40.250683112542255</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>6</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>80.95025965975177</x>
<y>44.99507552455861</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>7</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>6.857316697020866</x>
<y>33.24863334754029</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>8</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>35.975659895989395</x>
<y>27.42171932830696</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>9</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>13.672853648109518</x>
<y>68.2461872644317</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>10</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
se.sics.cooja.interfaces.Position
<x>44.62423029692567</x>
<y>48.53691502749644</y>
<z>0.0</z>
</interface_config>
<interface_config>
se.sics.cooja.mspmote.interfaces.MspMoteID
<id>51</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
</simulation>
<plugin>
se.sics.cooja.plugins.SimControl
<width>259</width>
<z>3</z>
<height>205</height>
<location_x>0</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
<plugin_config>
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<skin>se.sics.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<viewport>4.472125038273293 0.0 0.0 4.472125038273293 79.43486237544504 -89.06315297501011</viewport>
</plugin_config>
<width>475</width>
<z>0</z>
<height>429</height>
<location_x>644</location_x>
<location_y>9</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.LogListener
<plugin_config>
<filter>ID:4$</filter>
</plugin_config>
<width>1024</width>
<z>2</z>
<height>150</height>
<location_x>0</location_x>
<location_y>389</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.MoteInterfaceViewer
<mote_arg>10</mote_arg>
<plugin_config>
<interface>Serial port</interface>
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>588</width>
<z>1</z>
<height>399</height>
<location_x>505</location_x>
<location_y>520</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,20 @@
#undef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 4
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver
#undef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 4
#undef DCOSYNC_CONF_ENABLED
#define DCOSYNC_CONF_ENABLED 0
#undef DB_FEATURE_JOIN
#define DB_FEATURE_JOIN 0
#undef RF_CHANNEL
#define RF_CHANNEL 16
#undef ROUTE_CONF_DEFAULT_LIFETIME
#define ROUTE_CONF_DEFAULT_LIFETIME 300

View file

@ -0,0 +1,8 @@
CONTIKI = ../../../
APPS += antelope unit-test
CFLAGS += -Wall -g -DPROJECT_CONF_H=\"project-conf.h\"
SMALL = 1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,5 @@
#undef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 4
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A small command-line interface for the database system.
* \author
* Nicolas Tsiftes <nvt@sics.se>
*/
#include <stdio.h>
#include "contiki.h"
#include "dev/serial-line.h"
#include "antelope.h"
PROCESS(db_shell, "DB shell");
AUTOSTART_PROCESSES(&db_shell);
PROCESS_THREAD(db_shell, ev, data)
{
static db_handle_t handle;
db_result_t result;
static tuple_id_t matching;
static tuple_id_t processed;
PROCESS_BEGIN();
db_init();
for(;;) {
PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL);
result = db_query(&handle, data);
if(DB_ERROR(result)) {
printf("Query \"%s\" failed: %s\n",
(char *)data, db_get_result_message(result));
db_free(&handle);
continue;
}
if(!db_processing(&handle)) {
printf("OK\n");
continue;
}
db_print_header(&handle);
matching = 0;
processed = 0;
while(db_processing(&handle)) {
PROCESS_PAUSE();
result = db_process(&handle);
switch(result) {
case DB_GOT_ROW:
/* The processed tuple matched the condition in the query. */
matching++;
processed++;
db_print_tuple(&handle);
break;
case DB_OK:
/* A tuple was processed, but did not match the condition. */
processed++;
continue;
case DB_FINISHED:
/* The processing has finished. Wait for a new command. */
printf("[%ld tuples returned; %ld tuples processed]\n",
(long)matching, (long)processed);
printf("OK\n");
default:
if(DB_ERROR(result)) {
printf("Processing error: %s\n", db_get_result_message(result));
}
db_free(&handle);
break;
}
}
}
PROCESS_END();
}

View file

@ -34,23 +34,28 @@
#define SICSLOWPAN_CONF_FRAG 1
/* Save some memory for the sky platform */
/* Disabling RDC for demo purposes. Core updates often require more memory. */
/* For projects, optimize memory and enable RDC again. */
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver
/* Save some memory for the sky platform. */
#undef UIP_CONF_DS6_NBR_NBU
#define UIP_CONF_DS6_NBR_NBU 10
#undef UIP_CONF_DS6_ROUTE_NBU
#define UIP_CONF_DS6_ROUTE_NBU 10
/* Increase rpl-border-router IP-buffer when using 128 */
/* Increase rpl-border-router IP-buffer when using 128. */
#ifndef REST_MAX_CHUNK_SIZE
#define REST_MAX_CHUNK_SIZE 64
#endif
/* Decrease to 2 if no space left for stack when using 128-byte chunks */
/* Multiplies with chunk size, be aware of memory constraints. */
#ifndef COAP_MAX_OPEN_TRANSACTIONS
#define COAP_MAX_OPEN_TRANSACTIONS 4
#endif
/* Must be <= open transaction number */
/* Must be <= open transaction number. */
#ifndef COAP_MAX_OBSERVERS
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS
#endif

View file

@ -125,7 +125,7 @@ helloworld_handler(void* request, void* response, uint8_t *buffer, uint16_t pref
}
/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */
RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "mirror", "title=\"Returns your decoded message\";rt=\"Debug\"");
RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\"");
void
mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
@ -282,7 +282,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
* These chunk-wise resources must set the offset value to its new position or -1 of the end is reached.
* (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.)
*/
RESOURCE(chunks, METHOD_GET, "chunks", "title=\"Blockwise demo\";rt=\"Data\"");
RESOURCE(chunks, METHOD_GET, "debug/chunks", "title=\"Blockwise demo\";rt=\"Data\"");
#define CHUNKS_TOTAL 2050
@ -335,7 +335,7 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
* It takes an additional period parameter, which defines the interval to call [name]_periodic_handler().
* A default post_handler takes care of subscriptions by managing a list of subscribers to notify.
*/
PERIODIC_RESOURCE(polling, METHOD_GET, "poll", "title=\"Periodic demo\";rt=\"Observable\"", 5*CLOCK_SECOND);
PERIODIC_RESOURCE(polling, METHOD_GET, "debug/poll", "title=\"Periodic demo\";rt=\"Observable\"", 5*CLOCK_SECOND);
void
polling_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
@ -372,7 +372,7 @@ polling_periodic_handler(resource_t *r)
* Additionally takes a period parameter that defines the interval to call [name]_periodic_handler().
* A default post_handler takes care of subscriptions and manages a list of subscribers to notify.
*/
EVENT_RESOURCE(event, METHOD_GET, "event", "title=\"Event demo\";rt=\"Observable\"");
EVENT_RESOURCE(event, METHOD_GET, "sensors/button", "title=\"Event demo\";rt=\"Observable\"");
void
event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
@ -405,7 +405,7 @@ event_event_handler(resource_t *r)
#if defined (PLATFORM_HAS_LEDS)
/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/
RESOURCE(led, METHOD_POST | METHOD_PUT , "leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"");
RESOURCE(led, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"");
void
led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
@ -452,7 +452,7 @@ led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_s
}
/* A simple actuator example. Toggles the red led */
RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "toggle", "title=\"Red LED\";rt=\"Control\"");
RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\"");
void
toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
@ -462,7 +462,7 @@ toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
#if defined (PLATFORM_HAS_LIGHT)
/* A simple getter example. Returns the reading from light sensor with a simple etag */
RESOURCE(light, METHOD_GET, "light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\"");
RESOURCE(light, METHOD_GET, "sensors/light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\"");
void
light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
@ -503,7 +503,7 @@ light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred
#if defined (PLATFORM_HAS_BATTERY)
/* A simple getter example. Returns the reading from light sensor with a simple etag */
RESOURCE(battery, METHOD_GET, "battery", "title=\"Battery status\";rt=\"Battery\"");
RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"Battery\"");
void
battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{

View file

@ -161,6 +161,10 @@ PROCESS_THREAD(udp_client_process, ev, data)
/* new connection with remote host */
client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL);
if(client_conn == NULL) {
PRINTF("No UDP connection available, exiting the process!\n");
PROCESS_EXIT();
}
udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT));
PRINTF("Created a connection with the server ");

View file

@ -151,6 +151,10 @@ PROCESS_THREAD(udp_server_process, ev, data)
NETSTACK_MAC.off(1);
server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
if(server_conn == NULL) {
PRINTF("No UDP connection available, exiting the process!\n");
PROCESS_EXIT();
}
udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));
PRINTF("Created a server connection with remote address ");

View file

@ -1,121 +0,0 @@
# $Id: Makefile,v 1.7 2007/05/21 14:30:52 bg- Exp $
#
# This makefile requires GNU make!
LIB = libcontiki.a
KERNELS = gateway.ihex
PROGS = #loadable_prg.ko udpsend.ko udprecv.ko
TOOLS = tunslip scat codeprop
all: $(LIB) $(KERNELS) $(PROGS) $(TOOLS)
loadable_prg.ko: loadable_prg.o
udpsend.ko: udpsend.o
udprecv.ko: udprecv.o
test.ko: test.o
gateway.out: gateway.o $(LIB)
client.out: client.o $(LIB)
dhclient.out: dhclient.o $(LIB)
TOP=../..
INCDIRS = -I. -I$(TOP)/cpu/avr -I$(TOP)/core -I$(TOP)/apps
SRCDIRS = dev $(TOP)/cpu/avr $(TOP)/cpu/avr/dev ${addprefix $(TOP)/core/,sys dev net lib loader} $(TOP)/apps/codeprop
MCU=atmega128
ARCH=avr.o spi.o qleds.o rom.o xmem.o cle_avr.o
SYSTEM=process.o procinit.o service.o clock.o etimer.o timer.o \
sym.o cle.o elfloader_compat.o
UIP=uip.o uiplib.o tcpip.o uip-fw.o uip-fw-drv.o uipbuf.o \
tcpdump.o psock.o dhcpc.o uaodv.o uaodv-rt.o uip-udp-packet.o
UIPDRIVERS=slip.o slip_uart1.o \
cc2420.o cc2420_spi.o cc2420_send_ip.o cc2420_send_uaodv.o
LIBS=memb.o list.o rand.o assert.o crtk.o
SYSAPPS=tcp_loader.o
LIBFILES=$(SYSTEM) $(ARCH) $(UIP) $(UIPDRIVERS) $(LIBS) $(SYSAPPS)
MKNMLIST=awk -f $(TOP)/tools/mknmlist-ansi
CP=cp
LIBC=-lgcc -lc -lgcc
CC=avr-gcc
LD=avr-ld
AS=avr-as
NM=avr-nm
OBJCOPY=avr-objcopy
STRIP=avr-strip
AR=avr-ar
RANLIB=avr-ranlib
BSL=avrdude
CFLAGS=-mmcu=$(MCU) $(INCDIRS) -Wall -Os
LDFLAGS=-mmcu=$(MCU) -Wl,--section-start=.bootloader=$(BOOTLOADER_START)
# Check fuse high byte, bits BOOTSZ0 and BOOTSZ1.
BOOTLOADER_START=0x1fc00
# Setup directory search path for source files
vpath %.c $(SRCDIRS) ${filter-out CVS,${wildcard labs/*}}
# Set COM port if not already set.
# DOS: 1 => COM2, 2 => COM3, etc.
# Linux: /dev/ttyUSB0, /dev/ttyUSB1, etc.
# FreeBSD 6.2: /dev/cuaU0, /dev/cuaU1, etc.
ifndef COMPORT
COMPORT := /dev/ttyUSB0
endif
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $(notdir $(<:.c=.o))
# Combine several .o:s to one .ko and put COMMONs into the BSS segment
%.ko:
$(LD) -r -dc --strip-all --unresolved-symbols=ignore-in-object-files $^ -o $@
%.ihex: %.out
$(OBJCOPY) $^ -O ihex $@
#%.out:
# $(if $^,$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^,$(error "NO TARGET $@"))
# Add a namelist to the kernel
%.out: $^
: | $(MKNMLIST) > $@_tmp.c && mv $@_tmp.c $@_nm.c
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(LIBC) $@_nm.c
$(NM) $@ | $(MKNMLIST) > $@_tmp.c && mv $@_tmp.c $@_nm.c
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(LIBC) $@_nm.c
%.u: %.ihex
$(BSL) -p $(MCU) -P $(COMPORT) -c stk500 -U flash:w:$<
$(LIB): $(LIBFILES)
$(AR) rcf $@ $^
$(RANLIB) $@
codeprop: $(TOP)/tools/codeprop.c
cc -g -Wall $< -o $@
tunslip: $(TOP)/tools/tunslip.c
cc -g -Wall -DBAUDRATE="B38400" $< -o $@
scat: $(TOP)/tools/scat.c
cc -g -Wall -DBAUDRATE="B38400" $< -o $@
### TEST ###
test.out: test.o $(LIB)
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^
depend: $(LIBFILES:.o=.c)
-$(CC) $(CCDEPFLAGS) -MM $(CFLAGS) $(INCDIRS) $^ *.c >Makefile.depend
tags: $(LIBFILES:.o=.c)
etags $^
clean:
rm -f *.o *.ko *~ *.core *.out *.ihex *_nm.c
rm -f $(LIB) $(KERNELS) $(TOOLS)
.PHONY: all
-include Makefile.depend

View file

@ -1,162 +0,0 @@
/* -*- C -*- */
/* @(#)$Id: contiki-conf.h,v 1.5 2010/06/22 06:39:44 joxe Exp $ */
#ifndef CONTIKI_CONF_H
#define CONTIKI_CONF_H
#include <avr/interrupt.h>
#define HAVE_STDINT_H
#include "avrdef.h"
/* #define CB_GATEWAY */
#define CCIF
#define CLIF
#define AODV_COMPLIANCE
#define AODV_NUM_RT_ENTRIES 32
void clock_delay(unsigned int us2);
void clock_wait(int ms10);
void clock_set_seconds(unsigned long s);
unsigned long clock_seconds(void);
#define WITH_UIP 1
#define WITH_ASCII 1
#define PROCESS_CONF_FASTPOLL 4
/* Our clock resolution, this is the same as Unix HZ. */
/* Fix clock.c XXX/bg */
#define CLOCK_CONF_SECOND 62
/* CPU target speed in Hz */
#define F_CPU 8000000L
/* The +1 and divide by 2 is to achieve rounding. */
#define BAUD2UBR(baud) ((u16_t)((F_CPU/baud/8uL + 1)/2 - 1))
/* UART configs */
//#define MCU_MHZ 8
//#define MCU atmega128
//#define SLIP_PORT RS232_PORT_1
#define UIP_CONF_DHCP_LIGHT
#define UIP_CONF_LLH_LEN 0
#define UIP_CONF_BUFFER_SIZE 116
#define UIP_CONF_RECEIVE_WINDOW (UIP_CONF_BUFFER_SIZE - 40)
#define UIP_CONF_MAX_CONNECTIONS 4
#define UIP_CONF_MAX_LISTENPORTS 8
#define UIP_CONF_UDP_CONNS 12
#define UIP_CONF_FWCACHE_SIZE 30
#define UIP_CONF_BROADCAST 1
//#define UIP_ARCH_IPCHKSUM 1
#define UIP_CONF_UDP_CHECKSUMS 1
#define UIP_CONF_PINGADDRCONF 0
#define UIP_CONF_LOGGING 0
/*
* Definitions below are dictated by the hardware and not really
* changeable!
*/
#ifdef CB_GATEWAY
/* LED port E */
#define LEDS_CONF_GREEN _BV(2) /* PE.2 - Output */
#define LEDS_CONF_YELLOW _BV(3) /* PE.3 - Output */
#else
#define LEDS_ORANGE 8
/* LED port B */
#define LEDS_CONF_ORANGE _BV(4) /* PB.4 - Output */
#define LEDS_CONF_GREEN _BV(7) /* PB.7 - Output */
/* LED port E */
#define LEDS_CONF_RED _BV(3) /* PE.3 - Output */
#define LEDS_CONF_YELLOW _BV(4) /* PE.4 - Output */
#endif
typedef u16_t uip_stats_t;
typedef u16_t clock_time_t;
typedef u32_t off_t;
#define ROM_ERASE_UNIT_SIZE SPM_PAGESIZE
#define XMEM_ERASE_UNIT_SIZE 8
/* Use the first 64k of external flash for codeprop. */
#define EEPROMFS_ADDR_CODEPROP (128 * XMEM_ERASE_UNIT_SIZE)
#define CC2420_RADIO
/* LOOP count for waiting 20 symbols in the CC2420 code */
#define CC2420_CONF_SYMBOL_LOOP_COUNT 500
/*
* SPI bus configuration for the CC2420DBK.
*/
/* SPI input/output registers. */
#define SPI_TXBUF SPDR
#define SPI_RXBUF SPDR
#define BV(bitno) _BV(bitno)
#define SPI_WAITFOREOTx() do { while (!(SPSR & BV(SPIF))); } while (0)
#define SPI_WAITFOREORx() do { while (!(SPSR & BV(SPIF))); } while (0)
#define SCK 1 /* - Output: SPI Serial Clock (SCLK) */
#define MOSI 2 /* - Output: SPI Master out - slave in (MOSI) */
#define MISO 3 /* - Input: SPI Master in - slave out (MISO) */
/*
* SPI bus - CC2420 pin configuration.
*/
#define FIFO_P 0 /* - Input: FIFOP from CC2420 */
#define FIFO 1 /* - Input: FIFO from CC2420 */
#define CCA 6 /* - Input: CCA from CC2420 */
#define SFD 4 /* - Input: SFD from CC2420 */
#define CSN 0 /* - Output: SPI Chip Select (CS_N) */
#define VREG_EN 5 /* - Output: VREG_EN to CC2420 */
#define RESET_N 6 /* - Output: RESET_N to CC2420 */
/* Pin status. */
#define FIFO_IS_1 (!!(PIND & BV(FIFO)))
#define CCA_IS_1 (!!(PIND & BV(CCA) ))
#define RESET_IS_1 (!!(PINB & BV(RESET_N)))
#define VREG_IS_1 (!!(PINB & BV(VREG_EN)))
#define FIFOP_IS_1 (!!(PIND & BV(FIFO_P)))
#define SFD_IS_1 (!!(PIND & BV(SFD)))
/* The CC2420 reset pin. */
#define SET_RESET_INACTIVE() ( PORTB |= BV(RESET_N) )
#define SET_RESET_ACTIVE() ( PORTB &= ~BV(RESET_N) )
/* CC2420 voltage regulator enable pin. */
#define SET_VREG_ACTIVE() ( PORTB |= BV(VREG_EN) )
#define SET_VREG_INACTIVE() ( PORTB &= ~BV(VREG_EN) )
/* CC2420 rising edge trigger for external interrupt 0 (FIFOP). */
#define FIFOP_INT_INIT() do {\
EICRA |= 0x03; \
CLEAR_FIFOP_INT(); \
} while (0)
/* FIFOP on external interrupt 0. */
#define ENABLE_FIFOP_INT() do { EIMSK |= 0x01; } while (0)
#define DISABLE_FIFOP_INT() do { EIMSK &= ~0x01; } while (0)
#define CLEAR_FIFOP_INT() do { EIFR = 0x01; } while (0)
/* Enables/disables CC2420 access to the SPI bus (not the bus).
*
* These guys should really be renamed but are compatible with the
* original Chipcon naming.
*
* SPI_CC2420_ENABLE/SPI_CC2420_DISABLE???
* CC2420_ENABLE_SPI/CC2420_DISABLE_SPI???
*/
#define SPI_ENABLE() ( PORTB &= ~BV(CSN) ) /* ENABLE CSn (active low) */
#define SPI_DISABLE() ( PORTB |= BV(CSN) ) /* DISABLE CSn (active low) */
#endif /* CONTIKI_CONF_H */

View file

@ -1,90 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)$Id: cb_uart01.c,v 1.1 2007/02/02 14:09:06 bg- Exp $
*/
#include <stdio.h>
#include <avr/interrupt.h>
#include "contiki.h"
#include "dev/slip.h"
static int
uart0_putchar(char c, FILE *stream)
{
while (!(UCSR0A & BV(UDRE0)))
;
UDR0 = c;
return c;
}
static FILE uart0_stdout =
FDEV_SETUP_STREAM(uart0_putchar, NULL, _FDEV_SETUP_WRITE);
void
slip_arch_init(unsigned long ubr)
{
u8_t dummy;
spl_t s = splhigh();
UBRR1L = ubr;
UBRR1H = ubr >> 8;
UCSR1C = BV(UCSZ1) | BV(UCSZ0); /* 1 start bit, no parity, 1 stop bit */
UCSR1B = BV(RXEN) | BV(TXEN) | BV(RXCIE);
dummy = UDR1; /* Flush RX buffer. */
/* And now UART0. */
UBRR0L = BAUD2UBR(38400);
UBRR0H = BAUD2UBR(38400) >> 8;
UCSR0C = BV(UCSZ1) | BV(UCSZ0); /* 1 start bit, no parity, 1 stop bit */
UCSR0B = BV(TXEN); /* TX ONLY!!! */
splx(s);
stdout = &uart0_stdout;
}
void
slip_arch_writeb(unsigned char c)
{
while (!(UCSR1A & BV(UDRE1)))
;
UDR1 = c;
}
ISR(SIG_UART1_RECV)
{
/* Should deal with receive errors. */
slip_input_byte(UDR1);
}

View file

@ -1,119 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)$Id: qleds.c,v 1.1 2007/02/02 14:07:34 bg- Exp $
*/
#include "contiki.h"
#include "dev/leds.h"
#include <avr/io.h>
void
leds_init(void)
{
#ifdef CB_GATEWAY
DDRE |= LEDS_CONF_GREEN | LEDS_CONF_YELLOW;
PORTE |= LEDS_CONF_GREEN | LEDS_CONF_YELLOW; /* LEDS off */
#else
DDRB |= LEDS_CONF_ORANGE | LEDS_CONF_GREEN;
DDRE |= LEDS_CONF_RED | LEDS_CONF_YELLOW;
PORTB &= ~(LEDS_CONF_ORANGE | LEDS_CONF_GREEN);
PORTE &= ~(LEDS_CONF_RED | LEDS_CONF_YELLOW);
#endif
}
void
leds_on(unsigned char leds)
{
#ifdef CB_GATEWAY
if (leds & LEDS_GREEN)
PORTE &= ~LEDS_CONF_GREEN;
if (leds & LEDS_YELLOW)
PORTE &= ~LEDS_CONF_YELLOW;
#else
if (leds & LEDS_ORANGE)
PORTB |= LEDS_CONF_ORANGE;
if (leds & LEDS_GREEN)
PORTB |= LEDS_CONF_GREEN;
if (leds & LEDS_RED)
PORTE |= LEDS_CONF_RED;
if (leds & LEDS_YELLOW)
PORTE |= LEDS_CONF_YELLOW;
#endif
}
void
leds_off(unsigned char leds)
{
#ifdef CB_GATEWAY
if (leds & LEDS_GREEN)
PORTE |= LEDS_CONF_GREEN;
if (leds & LEDS_YELLOW)
PORTE |= LEDS_CONF_YELLOW;
#else
if (leds & LEDS_ORANGE)
PORTB &= ~LEDS_CONF_ORANGE;
if (leds & LEDS_GREEN)
PORTB &= ~LEDS_CONF_GREEN;
if (leds & LEDS_RED)
PORTE &= ~LEDS_CONF_RED;
if (leds & LEDS_YELLOW)
PORTE &= ~LEDS_CONF_YELLOW;
#endif
}
void
leds_toggle(unsigned char leds)
{
/*
* Synonym: void leds_invert(unsigned char leds);
*/
asm(".global leds_invert\nleds_invert:\n");
#ifdef CB_GATEWAY
if (leds & LEDS_GREEN)
PORTE ^= ~LEDS_CONF_GREEN;
if (leds & LEDS_YELLOW)
PORTE ^= ~LEDS_CONF_YELLOW;
#else
if (leds & LEDS_ORANGE)
PORTB ^= LEDS_CONF_ORANGE;
if (leds & LEDS_GREEN)
PORTB ^= LEDS_CONF_GREEN;
if (leds & LEDS_RED)
PORTE ^= LEDS_CONF_RED;
if (leds & LEDS_YELLOW)
PORTE ^= LEDS_CONF_YELLOW;
#endif
}

View file

@ -1,127 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)$Id: rom.c,v 1.1 2007/02/02 14:08:22 bg- Exp $
*/
#include <stdio.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
#include "contiki.h"
#include "lib/assert.h"
#include "dev/rom.h"
#if 0
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#endif
BOOTLOADER_SECTION
int
rom_erase(long nbytes, off_t offset)
{
long nb = nbytes;
if(nbytes % ROM_ERASE_UNIT_SIZE != 0) {
return -1;
}
if(offset % ROM_ERASE_UNIT_SIZE != 0) {
return -1;
}
PRINTF("rom_erase(%ld, %06lx)\n", nbytes, offset);
while (nbytes > 0) {
spl_t s = splhigh();
eeprom_busy_wait();
boot_page_erase(offset);
boot_spm_busy_wait();
boot_rww_enable(); /* Before return or intr. */
splx(s);
nbytes -= ROM_ERASE_UNIT_SIZE;
offset += ROM_ERASE_UNIT_SIZE;
}
return nb;
}
int
rom_pread(void *buf, int nbytes, off_t offset)
{
PRINTF("rom_pread(%p, %d, %06lx)\n", buf, nbytes, offset);
assert(offset == (uintptr_t)offset);
assert((offset + nbytes) == (uintptr_t)(offset + nbytes));
memcpy_P(buf, (PGM_P)(uintptr_t)offset, nbytes);
return nbytes;
}
BOOTLOADER_SECTION
int
rom_pwrite(const void *buf, int nbytes, off_t offset)
{
long nb = nbytes;
const unsigned char *from = buf;
PRINTF("rom_pwrite(%p, %d, %06lx)\n", buf, nbytes, offset);
while(nbytes > 0) {
int i, n = (nbytes > ROM_ERASE_UNIT_SIZE) ? ROM_ERASE_UNIT_SIZE : nbytes;
spl_t s = splhigh();
eeprom_busy_wait();
for (i = 0; i < n; i += 2) {
uint16_t w = *from++;
w |= (*from++) << 8;
boot_page_fill(offset + i, w);
}
boot_page_write(offset);
boot_spm_busy_wait();
boot_rww_enable(); /* Before return or intr. */
splx(s);
nbytes -= ROM_ERASE_UNIT_SIZE;
offset += ROM_ERASE_UNIT_SIZE;
}
return nb;
}

View file

@ -1,92 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)$Id: xmem.c,v 1.1 2007/02/02 14:08:22 bg- Exp $
*/
/*
* External memory built from the AVR eeprom. It is incredibly slow!
*/
#include <stdio.h>
#include <avr/eeprom.h>
#include "contiki.h"
#include "dev/xmem.h"
#if 0
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while (0)
#endif
/*
*/
void
xmem_init(void)
{
PRINTF("xmem_init\n");
}
int
xmem_pread(void *_p, int size, off_t offset)
{
PRINTF("xmem_pread(%p, %d, %06lx)\n", _p, size, offset);
spl_t s = splhigh();
eeprom_busy_wait();
eeprom_read_block(_p, (void *)(uintptr_t)offset, size);
splx(s);
return size;
}
int
xmem_pwrite(const void *_p, int size, off_t offset)
{
PRINTF("xmem_pwrite(%p, %d, %06lx)\n", _p, size, offset);
spl_t s = splhigh();
eeprom_busy_wait();
eeprom_write_block(_p, (void *)(uintptr_t)offset, size);
splx(s);
return size;
}
int
xmem_erase(long size, off_t offset)
{
/*
* AVR internal eeprom has a kind of auto erase, thus nothing is
* done here.
*/
PRINTF("xmem_erase(%ld, %06lx)\n", size, offset);
return size;
}

View file

@ -1,169 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)$Id: gateway.c,v 1.4 2010/10/19 18:29:05 adamdunkels Exp $
*/
/*
* Example gateway configuration with two IP interfaces, one SLIP over
* USB and one over 802.11.4 radio.
*
* The IP address is hardcoded to 172.16.0.1 and the 172.16/16 network
* is on the radio interface.
*
* The default route is over the SLIP interface.
*
* On the SLIP host run a standard SLIP implementation or the tunslip
* program that can also view debug printfs, example:
*
* sliphost# ./tunslip 172.16.0.1 255.255.0.0
*
*
* This kernel has no application code but new modules can be uploaded
* using the codeprop program, example:
*
* datan$ ./codeprop 172.16.0.1 loadable_prg.ko
* File successfully sent (1116 bytes)
* Reply: ok
*
*/
#include <stdio.h>
#include <avr/eeprom.h>
#include "contiki.h"
/* Also IP output. */
#include "net/uip-fw-drv.h"
#include "net/uaodv.h"
#include "dev/slip.h"
#include "dev/cc2420.h"
#include "dev/leds.h"
#include "dev/xmem.h"
#include "codeprop/codeprop.h"
/* We have two IP interfaces. */
struct uip_fw_netif cc2420if =
{UIP_FW_NETIF(172,16,0,1, 255,255,0,0, cc2420_send_uaodv)};
static struct uip_fw_netif slipif =
{UIP_FW_NETIF(0,0,0,0, 255,255,255,255, slip_send)};
/* Radio stuff in network byte order. */
static u16_t panId = UIP_HTONS(0x2024);
#ifndef RF_CHANNEL
#define RF_CHANNEL 15
#endif
unsigned char ds2411_id[8] = { 0x00, 0x12, 0x4b, 0x00, 0x00, 0x00, 0x09, 0x04};
static void
ds2411_init(void)
{
u8_t i, t;
eeprom_read_block(ds2411_id, 0, 8);
for (i = 0; i < 4; i++) {
t = ds2411_id[i];
ds2411_id[i] = ds2411_id[7 - i];
ds2411_id[7 - i] = t;
}
}
int
main(int argc, char **argv)
{
/*
* Initalize hardware.
*/
cpu_init();
clock_init();
leds_init();
leds_toggle(LEDS_ALL);
slip_arch_init(BAUD2UBR(38400)); /* Must come before first printf */
printf("Starting %s "
"($Id: gateway.c,v 1.4 2010/10/19 18:29:05 adamdunkels Exp $)\n", __FILE__);
ds2411_init();
cc2420_init();
xmem_init();
clock_wait(CLOCK_SECOND/10);
leds_toggle(LEDS_ALL);
/*
* Hardware initialization done!
*/
printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x CHANNEL %d\n",
ds2411_id[0], ds2411_id[1], ds2411_id[2], ds2411_id[3],
ds2411_id[4], ds2411_id[5], ds2411_id[6], ds2411_id[7],
RF_CHANNEL);
uip_ipaddr_copy(&uip_hostaddr, &cc2420if.ipaddr);
uip_ipaddr_copy(&uip_netmask, &cc2420if.netmask);
printf("IP %d.%d.%d.%d netmask %d.%d.%d.%d\n",
uip_ipaddr_to_quad(&uip_hostaddr),
uip_ipaddr_to_quad(&uip_netmask));
cc2420_set_chan_pan_addr(RF_CHANNEL, panId, uip_hostaddr.u16[1], ds2411_id);
/*
* Initialize Contiki and our processes.
*/
process_init();
process_start(&etimer_process, NULL);
/* Configure IP stack. */
uip_init();
uip_fw_default(&slipif); /* Point2point, no default router. */
uip_fw_register(&cc2420if);
tcpip_set_forwarding(1);
/* Start IP stack. */
process_start(&tcpip_process, NULL);
process_start(&uip_fw_process, NULL); /* Start IP output */
process_start(&slip_process, NULL);
process_start(&cc2420_process, NULL);
cc2420_on();
process_start(&uaodv_process, NULL);
//process_start(&tcp_loader_process, NULL);
/*
* This is the scheduler loop.
*/
printf("process_run()...\n");
while (1) {
do {
/* Reset watchdog. */
} while(process_run() > 0);
/* Idle! */
}
return 0;
}

View file

@ -1,17 +0,0 @@
CONTIKI_TARGET_DIRS = . dev apps net loader
CONTIKI_TARGET_MAIN = ethernut-main.o
CONTIKI_TARGET_SOURCEFILES += slip.c rs232.c ethernut-main.c \
rtl8019-drv.c rtl8019.c rtl8019dev.c debug.c delay.c
CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.
APPS+=webserver telnetd #program-handler shell
MCU=atmega128
CONTIKI_PLAT_DEFS = -DF_CPU=14745600UL -DAUTO_CRC_PADDING=2
include $(CONTIKIAVR)/Makefile.avr
%.u: %.$(TARGET)
avrdude -P /dev/cuaa0 -c stk500 -p atmega128 -v -e
avrdude -P /dev/cuaa0 -c stk500 -p atmega128 -v -U flash:w:$<

View file

@ -1,165 +0,0 @@
#ifndef __CONTIKI_CONF_H__
#define __CONTIKI_CONF_H__
#define CC_CONF_REGISTER_ARGS 1
#define CC_CONF_FUNCTION_POINTER_ARGS 1
#define CCIF
#define CLIF
typedef unsigned short clock_time_t;
#define CLOCK_CONF_SECOND 1000
void clock_delay(unsigned int us2);
void clock_wait(int ms10);
void clock_set_seconds(unsigned long s);
unsigned long clock_seconds(void);
/*
* This file is used for setting various compile time settings for the
* CTK GUI toolkit.
*/
#include "ctk/ctk-vncarch.h"
/* Defines which key that is to be used for activating the menus */
#define CTK_CONF_MENU_KEY CH_F1
/* Defines which key that is to be used for switching the frontmost
window. */
#define CTK_CONF_WINDOWSWITCH_KEY CH_ESC
/* Defines which key that is to be used for switching to the next
widget. */
#define CTK_CONF_WIDGETDOWN_KEY CH_TAB
/* Defines which key that is to be used for switching to the prevoius
widget. */
#define CTK_CONF_WIDGETUP_KEY 1
/* Toggles support for icons. */
#define CTK_CONF_ICONS 1 /* 107 bytes */
/* Toggles support for icon bitmaps. */
#define CTK_CONF_ICON_BITMAPS 1
/* Toggles support for icon textmaps. */
#define CTK_CONF_ICON_TEXTMAPS 1
/* Toggles support for windows. */
#define CTK_CONF_WINDOWS 1
/* Toggles support for movable windows. */
#define CTK_CONF_WINDOWMOVE 1 /* 333 bytes */
/* Toggles support for closable windows. */
#define CTK_CONF_WINDOWCLOSE 1 /* 14 bytes */
/* Toggles support for menus. */
#define CTK_CONF_MENUS 1 /* 1384 bytes */
/* Toggles mouse support (must have support functions in the
architecture specific files to work). */
#define CTK_CONF_MOUSE_SUPPORT 1
/* Defines the default width of a menu. */
#define CTK_CONF_MENUWIDTH 16
/* The maximum number of menu items in each menu. */
#define CTK_CONF_MAXMENUITEMS 10
/* Maximum number of clients to the telnet server */
#define CTK_TERM_CONF_MAX_TELNET_CLIENTS 3
/* Telnet server port */
#define CTK_TERM_CONF_TELNET_PORT 23
/* Serial server output buffer size */
#define CTK_TERM_CONF_SERIAL_BUFFER_SIZE 300
/* Maximum number of clients to the terminal module.
Should be set to CTK_TERM_CONF_MAX_TELNET_CLIENTS or
CTK_TERM_CONF_MAX_TELNET_CLIENTS+1 if the serial server is used too
*/
#define CTK_TERM_CONF_MAX_CLIENTS (CTK_TERM_CONF_MAX_TELNET_CLIENTS+1)
#define CTK_VNCSERVER_CONF_NUMCONNS 8
#define CTK_VNCSERVER_CONF_MAX_ICONS 8
#define EMAIL_CONF_WIDTH 48
#define EMAIL_CONF_HEIGHT 16
#define IRC_CONF_WIDTH 78
#define IRC_CONF_HEIGHT 20
#define IRC_CONF_SYSTEM_STRING "ethernut"
#define LIBCONIO_CONF_SCREEN_WIDTH 70
#define LIBCONIO_CONF_SCREEN_HEIGHT 40
#define LOG_CONF_ENABLED 0
#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10
/* COM port to be used for SLIP connection */
#define SLIP_PORT RS232_PORT_0
#define TELNETD_CONF_LINELEN 64
#define TELNETD_CONF_NUMLINES 16
#define UIP_CONF_MAX_CONNECTIONS 10
#define UIP_CONF_MAX_LISTENPORTS 10
#define UIP_CONF_BUFFER_SIZE 100
#define UIP_CONF_TCP_SPLIT 1
#define UIP_CONF_UDP_CONNS 6
#define UIP_CONF_FWCACHE_SIZE 1
#define UIP_CONF_BROADCAST 1
/* The size of the HTML viewing area. */
#define WWW_CONF_WEBPAGE_WIDTH 46
#define WWW_CONF_WEBPAGE_HEIGHT 25
/* The size of the "Back" history. */
#define WWW_CONF_HISTORY_SIZE 8
/* Defines the maximum length of an URL */
#define WWW_CONF_MAX_URLLEN 160
/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on
a page. */
#define WWW_CONF_MAX_NUMPAGEWIDGETS 30
/* Turns <center> support on or off; must be on for forms to work. */
#define WWW_CONF_RENDERSTATE 1
/* Toggles support for HTML forms. */
#define WWW_CONF_FORMS 1
/* Maximum lengths for various HTML form parameters. */
#define WWW_CONF_MAX_FORMACTIONLEN 80
#define WWW_CONF_MAX_FORMNAMELEN 40
#define WWW_CONF_MAX_INPUTNAMELEN 40
#define WWW_CONF_MAX_INPUTVALUELEN 40
#define WWW_CONF_PAGEVIEW 1
#define HAVE_STDINT_H
#include "avrdef.h"
typedef unsigned short uip_stats_t;
#endif /* __CONTIKI_CONF_H__ */

View file

@ -1,102 +0,0 @@
/* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki OS
*
* $Id: ethernut-main.c,v 1.5 2010/12/03 21:39:33 dak664 Exp $
*
*/
#include "contiki.h"
#include "contiki-net.h"
#include "dev/rs232.h"
#include "dev/rtl8019-drv.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
PROCINIT(&etimer_process, &tcpip_process, &rtl8019_process);
static const struct uip_eth_addr ethaddr = {{0x00,0x06,0x98,0x01,0x02,0x29}};
int
main(void)
{
uip_ipaddr_t addr;
/*
* GCC depends on register r1 set to 0.
*/
asm volatile ("clr r1");
/*
* No interrupts used.
*/
cli();
/*
* Enable external data and address
* bus.
*/
MCUCR = _BV(SRE) | _BV(SRW);
clock_init();
rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
sei();
process_init();
uip_ipaddr(&addr, 193,10,67,152);
uip_sethostaddr(&addr);
uip_setethaddr(ethaddr);
procinit_init();
autostart_start(autostart_processes);
rs232_print(RS232_PORT_0, "Initialized\n");
while(1) {
process_run();
}
return 0;
}
int
putchar(int c)
{
rs232_send(RS232_PORT_0, c);
return c;
}

View file

@ -1,11 +0,0 @@
CONTIKI_TARGET_DIRS = . dev apps net loader
CONTIKI_TARGET_MAIN = ethernut-main.o
CONTIKI_SOURCEFILES += slip.c rs232.c ethernut-main.c
CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.
MCU=atmega128
CONTIKI_PLAT_DEFS = -DF_CPU=14745600UL -DAUTO_CRC_PADDING=2
include $(CONTIKIAVR)/Makefile.avr

View file

@ -1,168 +0,0 @@
#ifndef __CONTIKI_CONF_H__
#define __CONTIKI_CONF_H__
#define CC_CONF_REGISTER_ARGS 1
#define CC_CONF_FUNCTION_POINTER_ARGS 1
#define CCIF
#define CLIF
typedef unsigned short clock_time_t;
#define CLOCK_CONF_SECOND 1000
#define NUT_CPU_FREQ 14745600UL
#define AVR_CLK_COUNT (NUT_CPU_FREQ / (128L * CLOCK_CONF_SECOND) + 0.5)
void clock_delay(unsigned int us2);
void clock_wait(int ms10);
void clock_set_seconds(unsigned long s);
unsigned long clock_seconds(void);
/*
* This file is used for setting various compile time settings for the
* CTK GUI toolkit.
*/
#include "ctk/ctk-vncarch.h"
/* Defines which key that is to be used for activating the menus */
#define CTK_CONF_MENU_KEY CH_F1
/* Defines which key that is to be used for switching the frontmost
window. */
#define CTK_CONF_WINDOWSWITCH_KEY CH_ESC
/* Defines which key that is to be used for switching to the next
widget. */
#define CTK_CONF_WIDGETDOWN_KEY CH_TAB
/* Defines which key that is to be used for switching to the prevoius
widget. */
#define CTK_CONF_WIDGETUP_KEY 1
/* Toggles support for icons. */
#define CTK_CONF_ICONS 1 /* 107 bytes */
/* Toggles support for icon bitmaps. */
#define CTK_CONF_ICON_BITMAPS 1
/* Toggles support for icon textmaps. */
#define CTK_CONF_ICON_TEXTMAPS 1
/* Toggles support for windows. */
#define CTK_CONF_WINDOWS 1
/* Toggles support for movable windows. */
#define CTK_CONF_WINDOWMOVE 1 /* 333 bytes */
/* Toggles support for closable windows. */
#define CTK_CONF_WINDOWCLOSE 1 /* 14 bytes */
/* Toggles support for menus. */
#define CTK_CONF_MENUS 1 /* 1384 bytes */
/* Toggles mouse support (must have support functions in the
architecture specific files to work). */
#define CTK_CONF_MOUSE_SUPPORT 1
/* Defines the default width of a menu. */
#define CTK_CONF_MENUWIDTH 16
/* The maximum number of menu items in each menu. */
#define CTK_CONF_MAXMENUITEMS 10
/* Maximum number of clients to the telnet server */
#define CTK_TERM_CONF_MAX_TELNET_CLIENTS 3
/* Telnet server port */
#define CTK_TERM_CONF_TELNET_PORT 23
/* Serial server output buffer size */
#define CTK_TERM_CONF_SERIAL_BUFFER_SIZE 300
/* Maximum number of clients to the terminal module.
Should be set to CTK_TERM_CONF_MAX_TELNET_CLIENTS or
CTK_TERM_CONF_MAX_TELNET_CLIENTS+1 if the serial server is used too
*/
#define CTK_TERM_CONF_MAX_CLIENTS (CTK_TERM_CONF_MAX_TELNET_CLIENTS+1)
#define CTK_VNCSERVER_CONF_NUMCONNS 8
#define CTK_VNCSERVER_CONF_MAX_ICONS 8
#define EMAIL_CONF_WIDTH 48
#define EMAIL_CONF_HEIGHT 16
#define IRC_CONF_WIDTH 78
#define IRC_CONF_HEIGHT 20
#define IRC_CONF_SYSTEM_STRING "ethernut"
#define LIBCONIO_CONF_SCREEN_WIDTH 70
#define LIBCONIO_CONF_SCREEN_HEIGHT 40
#define LOG_CONF_ENABLED 0
#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10
/* COM port to be used for SLIP connection */
#define SLIP_PORT RS232_PORT_0
#define TELNETD_CONF_LINELEN 32
#define TELNETD_CONF_NUMLINES 16
#define UIP_CONF_MAX_CONNECTIONS 10
#define UIP_CONF_MAX_LISTENPORTS 10
#define UIP_CONF_BUFFER_SIZE 100
#define UIP_CONF_TCP_SPLIT 1
#define UIP_CONF_UDP_CONNS 6
#define UIP_CONF_FWCACHE_SIZE 1
#define UIP_CONF_BROADCAST 1
/* The size of the HTML viewing area. */
#define WWW_CONF_WEBPAGE_WIDTH 46
#define WWW_CONF_WEBPAGE_HEIGHT 25
/* The size of the "Back" history. */
#define WWW_CONF_HISTORY_SIZE 8
/* Defines the maximum length of an URL */
#define WWW_CONF_MAX_URLLEN 160
/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on
a page. */
#define WWW_CONF_MAX_NUMPAGEWIDGETS 30
/* Turns <center> support on or off; must be on for forms to work. */
#define WWW_CONF_RENDERSTATE 1
/* Toggles support for HTML forms. */
#define WWW_CONF_FORMS 1
/* Maximum lengths for various HTML form parameters. */
#define WWW_CONF_MAX_FORMACTIONLEN 80
#define WWW_CONF_MAX_FORMNAMELEN 40
#define WWW_CONF_MAX_INPUTNAMELEN 40
#define WWW_CONF_MAX_INPUTVALUELEN 40
#define WWW_CONF_PAGEVIEW 1
#define HAVE_STDINT_H
#include "avrdef.h"
typedef unsigned short uip_stats_t;
#endif /* __CONTIKI_CONF_H__ */

View file

@ -1,99 +0,0 @@
/* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki OS
*
* $Id: ethernut-main.c,v 1.4 2010/12/03 21:39:33 dak664 Exp $
*
*/
#include "contiki.h"
#include "contiki-net.h"
#include "dev/serial-line.h"
#include "dev/slip.h"
#include "dev/rs232.h"
#include <avr/interrupt.h>
/*static void setup_xram(void) __attribute__ ((naked)) \
__attribute__ ((section (".init1")));
static void
setup_xram(void)
{
outp(BV(SRE) | BV(SRW), MCUCR);
}*/
static struct uip_fw_netif slipif =
{UIP_FW_NETIF(0,0,0,0, 0,0,0,0, slip_send)};
PROCESS(serial_test, "Serial test");
PROCESS_THREAD(serial_test, ev, data)
{
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message);
rs232_print(RS232_PORT_0, data);
}
PROCESS_END();
}
PROCINIT(&etimer_process, &serial_line_process, &slip_process,
&uip_fw_process);
int
main(void)
{
uip_ipaddr_t addr;
clock_init();
rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
rs232_set_input(RS232_PORT_0, slip_input_byte);
sei();
/* Initialize drivers and event kernal */
process_init();
uip_ipaddr(&addr, 172,16,0,2);
uip_sethostaddr(&addr);
procinit_init();
autostart_start(autostart_processes);
uip_fw_default(&slipif);
rs232_print_p(RS232_PORT_0, PSTR("Initialized\n"));
while(1) {
process_run();
}
return 0;
}

View file

@ -1,34 +0,0 @@
ifndef CONTIKI
$(error CONTIKI not defined! You must specify where CONTIKI resides!)
endif
CONTIKI_TARGET_DIRS = . dev apps net
SENSORS = sensors.c beep.c button-sensor.c pir-sensor.c vib-sensor.c \
radio-sensor.c irq.c eeprom.c \
dummy-sensors.c leds.c leds-arch.c esb-sensors.c
NETSIM = ether.c ethernode.c ethernode-uip.c lpm.c rs232.c flash.c \
node.c nodes.c sensor.c display.c random.c radio.c \
dlloader.c main.c netsim-init.c contiki-main.c symtab.c symbols.c tr1001.c tr1001-drv.c cfs-posix.c cfs-posix-dir.c
ifeq ($(OS),Windows_NT)
CONTIKI_TARGET_SOURCEFILES = $(NETSIM) $(SENSORS) wpcap-drv.c wpcap.c
else
CONTIKI_TARGET_SOURCEFILES = $(NETSIM) $(SENSORS) tapdev-drv.c tapdev.c
endif
CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)
.SUFFIXES:
### Define the CPU directory
CONTIKI_CPU=$(CONTIKI)/cpu/native
include $(CONTIKI)/cpu/native/Makefile.native
### Compiler definitions
CFLAGS += $(shell gtk-config --cflags) -DNETSIM=1
TARGET_LIBFILES = $(shell gtk-config --libs)
ifeq ($(OS),Windows_NT)
TARGET_LIBFILES += /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a
endif

View file

@ -1,139 +0,0 @@
#ifndef __CONTIKI_CONF_H__
#define __CONTIKI_CONF_H__
#define NETSTACK_CONF_RADIO ethernode_driver
#define XMAC_CONF_ON_TIME RTIMER_SECOND
#define XMAC_CONF_OFF_TIME RTIMER_SECOND * 2
/*
* Copyright (c) 2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki desktop OS
*
* $Id: contiki-conf.h,v 1.13 2010/02/18 23:10:06 adamdunkels Exp $
*
*/
#define CC_CONF_REGISTER_ARGS 1
#define CC_CONF_FUNCTION_POINTER_ARGS 1
#define CC_CONF_FASTCALL
#define CC_CONF_VA_ARGS 1
#define CCIF
#define CLIF
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipopttypedef uIP type definitions
* @{
*/
#include <inttypes.h>
/**
* The 8-bit unsigned data type.
*
* This may have to be tweaked for your particular compiler. "unsigned
* char" works for most compilers.
*/
typedef uint8_t u8_t;
/**
* The 16-bit unsigned data type.
*
* This may have to be tweaked for your particular compiler. "unsigned
* short" works for most compilers.
*/
typedef uint16_t u16_t;
/**
* The 32-bit unsigned data type.
*
* This may have to be tweaked for your particular compiler. "unsigned
* short" works for most compilers.
*/
typedef uint32_t u32_t;
/**
* The 32-bit signed data type.
*
* This may have to be tweaked for your particular compiler. "signed
* short" works for most compilers.
*/
typedef int32_t s32_t;
/**
* The statistics data type.
*
* This datatype determines how high the statistics counters are able
* to count.
*/
typedef unsigned short uip_stats_t;
/** @} */
/*------------------------------------------------------------------------------*/
typedef unsigned long clock_time_t;
#define CLOCK_CONF_SECOND 1000
/*------------------------------------------------------------------------------*/
#define PACKETBUF_CONF_SIZE 128
#define PACKETBUF_CONF_HDR_SIZE 32
#define QUEUEBUF_CONF_STATS 1
#define UIP_CONF_UIP_IP4ADDR_T_WITH_U32 1
#define UIP_CONF_ICMP_DEST_UNREACH 1
#define UIP_CONF_MAX_CONNECTIONS 40
#define UIP_CONF_MAX_LISTENPORTS 40
#define UIP_CONF_BUFFER_SIZE 120
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
#define UIP_CONF_BROADCAST 1
#define UIP_CONF_IP_FORWARD 1
/* TCP splitting does not work well with multi hop routing. */
#define UIP_CONF_TCP_SPLIT 0
#define UIP_CONF_LOGGING 1
#define UIP_CONF_UDP_CHECKSUMS 0
#define LOADER_CONF_ARCH "loader/dlloader.h"
#endif /* __CONTIKI_CONF_H__ */

View file

@ -1,183 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: contiki-main.c,v 1.37 2010/04/21 20:27:28 oliverschmidt Exp $
*/
#include "contiki.h"
#include "contiki-net.h"
#include "contiki-lib.h"
#include "dev/serial-line.h"
#include "net/rime.h"
#ifdef __CYGWIN__
#include "net/wpcap-drv.h"
#else /* __CYGWIN__ */
#include "net/tapdev-drv.h"
#endif /* __CYGWIN__ */
#include "net/ethernode-uip.h"
#include "net/ethernode-rime.h"
#include "net/ethernode.h"
#include "net/uip-over-mesh.h"
#include "net/mac/nullmac.h"
#include "net/mac/lpp.h"
#include "ether.h"
#include <stdio.h>
#ifndef HAVE_SNPRINTF
int snprintf(char *str, size_t size, const char *format, ...);
#endif /* HAVE_SNPRINTF */
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>
#include "dev/button-sensor.h"
#include "dev/pir-sensor.h"
#include "dev/vib-sensor.h"
#include "dev/radio-sensor.h"
#include "dev/leds.h"
#ifdef __CYGWIN__
static struct uip_fw_netif extif =
{UIP_FW_NETIF(0,0,0,0, 0,0,0,0, wpcap_output)};
#else /* __CYGWIN__ */
static struct uip_fw_netif extif =
{UIP_FW_NETIF(0,0,0,0, 0,0,0,0, tapdev_output)};
#endif /* __CYGWIN__ */
static struct uip_fw_netif meshif =
{UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
/*static struct uip_fw_netif ethernodeif =
{UIP_FW_NETIF(172,16,0,0, 255,255,0,0, ethernode_drv_send)};*/
static const struct uip_eth_addr ethaddr = {{0x00,0x06,0x98,0x01,0x02,0x12}};
SENSORS(&button_sensor, &pir_sensor, &vib_sensor, &radio_sensor);
PROCINIT(&sensors_process, &etimer_process, &tcpip_process);
/*---------------------------------------------------------------------------*/
#ifdef __CYGWIN__
static void
remove_route(int s)
{
char buf[1024];
snprintf(buf, sizeof(buf), "route delete %d.%d.%d.%d",
uip_ipaddr_to_quad(&meshif.ipaddr));
printf("%s\n", buf);
system(buf);
_exit(0);
}
#endif /* __CYGWIN__ */
/*---------------------------------------------------------------------------*/
void
contiki_main(int flag)
{
random_init(getpid());
srand(getpid());
leds_init();
process_init();
procinit_init();
serial_line_init();
uip_init();
ctimer_init();
NETSTACK_MAC.init();
NETSTACK_RDC.init();
uip_over_mesh_init(2);
uip_over_mesh_set_net(&meshif.ipaddr, &meshif.netmask);
if(flag == 1) {
#ifdef __CYGWIN__
process_start(&wpcap_process, NULL);
{
char buf[1024];
uip_ipaddr_t ifaddr;
extern uip_ipaddr_t winifaddr;
uip_ipaddr_copy(&ifaddr, &winifaddr);
snprintf(buf, sizeof(buf), "route add %d.%d.%d.%d mask %d.%d.%d.%d %d.%d.%d.%d",
uip_ipaddr_to_quad(&meshif.ipaddr),
uip_ipaddr_to_quad(&meshif.netmask),
uip_ipaddr_to_quad(&ifaddr));
printf("%s\n", buf);
system(buf);
signal(SIGTERM, remove_route);
}
#else /* __CYGWIN__ */
process_start(&tapdev_process, NULL);
#endif /* __CYGWIN__ */
process_start(&uip_fw_process, NULL);
uip_fw_register(&meshif);
uip_fw_default(&extif);
printf("uip_hostaddr %d.%d.%d.%d\n", uip_ipaddr_to_quad(&uip_hostaddr));
uip_over_mesh_make_announced_gateway();
} else {
process_start(&uip_fw_process, NULL);
uip_fw_default(&meshif);
}
leds_on(LEDS_GREEN);
rtimer_init();
autostart_start(autostart_processes);
while(1) {
int n;
struct timeval tv;
n = process_run();
/* if(n > 0) {
printf("%d processes in queue\n", n);
}*/
tv.tv_sec = 0;
tv.tv_usec = 1;
select(0, NULL, NULL, NULL, &tv);
etimer_request_poll();
}
}
/*---------------------------------------------------------------------------*/
process_event_t codeprop_event_quit;

View file

@ -1,40 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: contiki-main.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $
*/
#ifndef __CONTIKI_MAIN_H__
#define __CONTIKI_MAIN_H__
void contiki_main(int b);
#endif /* __CONTIKI_MAIN_H__ */

View file

@ -1,88 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: beep.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $
*/
#include <stdio.h>
#include "dev/beep.h"
void
beep_down(int n)
{
printf("beep_down(%d)\n", n);
}
void
beep_beep(int n)
{
printf("beep_beep(%d)\n", n);
}
void
beep_alarm(int alarmmode, int len)
{
printf("beep_alarm(%d,%d)\n", alarmmode, len);
}
void
beep_spinup(void)
{
}
void beep(void)
{
printf("%cbeep\n", 7); /*fflush(NULL);*/
}
void
beep_off(void)
{
}
void
beep_on(void)
{
}
void
beep_long(clock_time_t len)
{
}
void
beep_quick(int n)
{
}

View file

@ -1,163 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: beep.h,v 1.2 2006/07/07 06:40:05 nifi Exp $
*/
/**
* \addtogroup esb
* @{
*/
/**
* \defgroup beeper Beeper interface
* @{
*/
/**
* \file
* Interface to the beeper.
* \author Adam Dunkels <adam@sics.se>
*
*/
#ifndef __BEEP_H__
#define __BEEP_H__
#define BEEP_ALARM1 1
#define BEEP_ALARM2 2
#include "sys/clock.h"
/**
* Beep for a specified time.
*
* This function causes the beeper to beep for the specified time. The
* time is measured in the same units as for the clock_delay()
* function.
*
* \note This function will hang the CPU during the beep.
*
* \note This function will stop any beep that was on previously when this
* function ends.
*
* \note If the beeper is turned off with beep_off() this call will still
* take the same time, though it will be silent.
*
* \param len The length of the beep.
*
*/
void beep_beep(int len);
/**
* Beep an alarm for a specified time.
*
* This function causes the beeper to beep for the specified time. The
* time is measured in the same units as for the clock_delay()
* function.
*
* \note This function will hang the CPU during the beep.
*
* \note This function will stop any beep that was on previously when this
* function ends.
*
* \note If the beeper is turned off with beep_off() this call will still
* take the same time, though it will be silent.
*
* \param alarmmode The alarm mode (BEEP_ALARM1,BEEP_ALARM2)
* \param len The length of the beep.
*
*/
void beep_alarm(int alarmmode, int len);
/**
* Produces a quick click-like beep.
*
* This function produces a short beep that sounds like a click.
*
*/
void beep(void);
/**
* A beep with a pitch-bend down.
*
* This function produces a pitch-bend sound with deecreasing
* frequency.
*
* \param len The length of the pitch-bend.
*
*/
void beep_down(int len);
/**
* Turn the beeper on.
*
* This function turns on the beeper. The beeper is turned off with
* the beep_off() function.
*/
void beep_on(void);
/**
* Turn the beeper off.
*
* This function turns the beeper off after it has been turned on with
* beep_on().
*/
void beep_off(void);
/**
* Produce a sound similar to a hard-drive spinup.
*
* This function produces a sound that is intended to be similar to
* the sound a hard-drive makes when it starts.
*
*/
void beep_spinup(void);
/**
* Beep for a long time (seconds)
*
* This function produces a beep with the specified length and will
* not return until the beep is complete. The length of the beep is
* specified using CLOCK_SECOND: a two second beep is CLOCK_SECOND *
* 2, and a quarter second beep is CLOCK_SECOND / 4.
*
* \note If the beeper is turned off with beep_off() this call will still
* take the same time, though it will be silent.
*
* \param len The length of the beep, measured in units of CLOCK_SECOND
*/
void beep_long(clock_time_t len);
void beep_quick(int num);
/** @} */
/** @} */
#endif /* __BEEP_H__ */

View file

@ -1,32 +0,0 @@
#include "dev/button-sensor.h"
const struct sensors_sensor button_sensor;
/*---------------------------------------------------------------------------*/
void
button_press(void)
{
sensors_changed(&button_sensor);
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int value)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(button_sensor, BUTTON_SENSOR,
value, configure, status);

View file

@ -1,12 +0,0 @@
#ifndef __BUTTON_SENSOR_H__
#define __BUTTON_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor button_sensor;
#define BUTTON_SENSOR "Button"
void button_press(void);
#endif /* __BUTTON_SENSOR_H__ */

View file

@ -1,64 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Configurable Sensor Network Application
* Architecture for sensor nodes running the Contiki operating system.
*
* $Id: dummy-sensors.c,v 1.4 2010/01/15 10:34:36 nifi Exp $
*
* -----------------------------------------------------------------
*
* Author : Adam Dunkels, Joakim Eriksson, Niclas Finne
* Created : 2005-11-01
* Updated : $Date: 2010/01/15 10:34:36 $
* $Revision: 1.4 $
*/
#include "dev/temperature-sensor.h"
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR,
value, configure, status);

View file

@ -1,67 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: eeprom.c,v 1.2 2007/11/17 18:09:18 adamdunkels Exp $
*/
#include "dev/eeprom.h"
#include "node.h"
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
static unsigned char eeprom[65536];
void
eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size)
{
int f;
char name[400];
sprintf(name, "eeprom.%d.%d", node_x(), node_y());
f = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644);
lseek(f, addr, SEEK_SET);
write(f, buf, size);
close(f);
printf("eeprom_write(addr 0x%02x, buf %p, size %d);\n", addr, buf, size);
memcpy(&eeprom[addr], buf, size);
}
void
eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size)
{
/* printf("eeprom_read(addr 0x%02x, buf %p, size %d);\n", addr, buf, size);*/
memcpy(buf, &eeprom[addr], size);
}

View file

@ -1,55 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: esb-sensors.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "esb-sensors.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/
void
esb_sensors_on(void)
{
printf("esb_sensors_on()\n");
}
/*---------------------------------------------------------------------------*/
void
esb_sensors_off(void)
{
printf("esb_sensors_off()\n");
}
/*---------------------------------------------------------------------------*/

View file

@ -1,47 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: esb-sensors.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __ESB_SENSORS_H__
#define __ESB_SENSORS_H__
void esb_sensors_on(void);
void esb_sensors_off(void);
#endif /* __ESB_SENSORS_H__ */

View file

@ -1,61 +0,0 @@
/**
* \file
* Functions for reading and writing flash ROM.
* \author Adam Dunkels <adam@sics.se>
*/
/* Copyright (c) 2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: flash.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*---------------------------------------------------------------------------*/
void
flash_setup(void)
{
}
/*---------------------------------------------------------------------------*/
void
flash_done(void)
{
}
/*---------------------------------------------------------------------------*/
void
flash_clear(unsigned short *ptr)
{
}
/*---------------------------------------------------------------------------*/
void
flash_write(unsigned short *ptr, unsigned short word)
{
}
/*---------------------------------------------------------------------------*/

View file

@ -1,78 +0,0 @@
/**
* \file
* Functions for reading and writing MSP430 flash ROM.
* \author Adam Dunkels <adam@sics.se>
*/
/* Copyright (c) 2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: flash.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __FLASH_H__
#define __FLASH_H__
/**
* Setup function to be called before any of the flash programming functions.
*
*/
void flash_setup(void);
/**
* Function that is to be called after flashing is done.
*/
void flash_done(void);
/**
* Write a 16-bit word to flash ROM.
*
* This function writes a 16-bit word to flash ROM. The function
* flash_setup() must have been called first.
*
* \param addr A pointer to the address in flash ROM which is to be
* written.
*
* \param word The 16-bit word that is to be written.
*/
void flash_write(unsigned short *addr, unsigned short word);
/**
* Clear a 16-bit word in flash ROM.
*
* This function clears a 16-bit word in flash ROM. The function
* flash_setup() must have been called first.
*
* \param addr A pointer to the address in flash ROM which is to be
* cleared.
*/
void flash_clear(unsigned short *addr);
#endif /* __FLASH_H__ */

View file

@ -1,5 +0,0 @@
void
irq_init(void)
{
}

View file

@ -1,60 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Configurable Sensor Network Application
* Architecture for sensor nodes running the Contiki operating system.
*
* $Id: leds-arch.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*
* -----------------------------------------------------------------
*
* Author : Adam Dunkels, Joakim Eriksson, Niclas Finne
* Created : 2005-11-03
* Updated : $Date: 2006/06/17 22:41:36 $
* $Revision: 1.1 $
*/
#include "dev/leds.h"
#include "ether.h"
static int cleds;
void leds_arch_init() {
cleds = 0;
}
unsigned char leds_arch_get() {
return cleds;
}
void leds_arch_set(unsigned char leds) {
if(leds != cleds) {
cleds = leds;
ether_set_leds(cleds);
}
}

View file

@ -1,40 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: lpm.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
#ifndef __LPM_H__
#define __LPM_H__
void lpm_on(void);
void lpm_off(void);
#endif /* __LPM_H__ */

View file

@ -1,35 +0,0 @@
#include "dev/pir-sensor.h"
const struct sensors_sensor pir_sensor;
static int pir_value;
/*---------------------------------------------------------------------------*/
void
pir_sensor_changed(int strength)
{
pir_value += strength;
sensors_changed(&pir_sensor);
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return pir_value;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(pir_sensor, PIR_SENSOR,
value, configure, status);

View file

@ -1,14 +0,0 @@
#ifndef __PIR_SENSOR_H__
#define __PIR_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor pir_sensor;
#define PIR_SENSOR "PIR"
void pir_sensor_changed(int strength);
#define PIR_ENABLE_EVENT 1
#endif /* __PIR_SENSOR_H__ */

View file

@ -1,61 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: radio-sensor.c,v 1.3 2010/02/23 18:43:43 adamdunkels Exp $
*/
#include "lib/sensors.h"
#include "dev/radio-sensor.h"
const struct sensors_sensor radio_sensor;
unsigned int radio_sensor_signal = 0;
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return radio_sensor_signal;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(radio_sensor, RADIO_SENSOR,
value, configure, status);

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: radio-sensor.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
#ifndef __RADIO_SENSOR_H__
#define __RADIO_SENSOR_H__
#include "contiki-esb.h"
extern const struct sensors_sensor radio_sensor;
#define RADIO_SENSOR "Radio"
extern unsigned int radio_sensor_signal;
#endif /* __RADIO_SENSOR_H__ */

View file

@ -1,52 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: radio.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "radio.h"
/*---------------------------------------------------------------------------*/
void
radio_on(void)
{
}
/*---------------------------------------------------------------------------*/
void
radio_off(void)
{
}
/*---------------------------------------------------------------------------*/

View file

@ -1,55 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: rs232.c,v 1.2 2006/10/10 15:58:31 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "rs232.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/
void
rs232_set_input(int (* f)(unsigned char))
{
/* printf("rs232_set_input(%p)\n", f);*/
}
/*---------------------------------------------------------------------------*/
void
slip_arch_writeb(unsigned char c)
{
printf("%c", c);
}
/*---------------------------------------------------------------------------*/

View file

@ -1,46 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: rs232.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __RS232_H__
#define __RS232_H__
void rs232_set_input(int (* f)(unsigned char));
#endif /* __RS232_H__ */

View file

@ -1,51 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Configurable Sensor Network Application
* Architecture for sensor nodes running the Contiki operating system.
*
* $Id: temperature-sensor.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*
* -----------------------------------------------------------------
*
* Author : Adam Dunkels, Joakim Eriksson, Niclas Finne
* Created : 2005-11-01
* Updated : $Date: 2006/06/17 22:41:36 $
* $Revision: 1.1 $
*/
#ifndef __TEMPERATURE_SENSOR_H__
#define __TEMPERATURE_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor temperature_sensor;
#define TEMPERATURE_SENSOR "Temperature"
#endif /* __TEMPERATURE_SENSOR_H__ */

View file

@ -1,84 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: tr1001-drv.c,v 1.2 2006/10/10 15:58:31 adamdunkels Exp $
*/
#include "contiki-esb.h"
#include "net/hc.h"
#include <string.h>
#include <stdio.h>
PROCESS(tr1001_drv_process, "TR1001 driver");
static unsigned char slip_dump;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(tr1001_drv_process, ev, data)
{
PROCESS_BEGIN();
tr1001_init();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_POLL);
uip_len = tr1001_poll();
if(uip_len > 0) {
uip_len = hc_inflate(&uip_buf[UIP_LLH_LEN], uip_len);
tcpip_input();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
tr1001_drv_request_poll(void)
{
process_poll(&tr1001_drv_process);
}
/*---------------------------------------------------------------------------*/
u8_t
tr1001_drv_send(void)
{
uip_len = hc_compress(&uip_buf[UIP_LLH_LEN], uip_len);
return tr1001_send(&uip_buf[UIP_LLH_LEN], uip_len);
}
/*---------------------------------------------------------------------------*/
void
tr1001_drv_set_slip_dump(int dump)
{
slip_dump = dump;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: tr1001-drv.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $
*/
#ifndef __TR1001_DRV_H__
#define __TR1001_DRV_H__
PROCESS_NAME(tr1001_drv_process);
void tr1001_drv_set_slip_dump(int dump);
u8_t tr1001_drv_send(void);
void tr1001_drv_request_poll(void);
#endif /* __TR1001_DRV_H__ */

View file

@ -1,112 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: tr1001.c,v 1.2 2006/10/10 15:58:31 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include <stdio.h>
#include "tr1001.h"
/*---------------------------------------------------------------------------*/
void
tr1001_init(void)
{
printf("tr1001_init()\n");
}
/*---------------------------------------------------------------------------*/
unsigned short
tr1001_poll(void)
{
printf("tr1001_poll()\n");
return 0;
}
/*---------------------------------------------------------------------------*/
u8_t
tr1001_send(u8_t *packet, u16_t len)
{
printf("tr1001_send(%p, %d)\n", packet, len);
return 0;
}
/*---------------------------------------------------------------------------*/
void
tr1001_set_txpower(unsigned char p)
{
printf("tr1001_set_txpower(%d)\n", p);
}
/*---------------------------------------------------------------------------*/
unsigned short
tr1001_sstrength(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static unsigned short packets_ok, packets_err;
unsigned short
tr1001_packets_ok(void)
{
return packets_ok;
}
/*---------------------------------------------------------------------------*/
unsigned short
tr1001_packets_dropped(void)
{
return packets_err;
}
/*---------------------------------------------------------------------------*/
void
tr1001_clear_packets(void)
{
packets_ok = packets_err = 0;
}
/*---------------------------------------------------------------------------*/
void
tr1001_clear_active(void)
{
}
/*---------------------------------------------------------------------------*/
int
tr1001_active(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
unsigned short
tr1001_sstrength_value(unsigned int type)
{
printf("tr1001_sstrength_value(%d)\n", type);
return 0;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,72 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Configurable Sensor Network Application
* Architecture for sensor nodes running the Contiki operating system.
*
* $Id: vib-sensor.c,v 1.3 2010/02/23 18:43:43 adamdunkels Exp $
*
* -----------------------------------------------------------------
*
* Author : Adam Dunkels, Joakim Eriksson, Niclas Finne
* Created : 2005-11-01
* Updated : $Date: 2010/02/23 18:43:43 $
* $Revision: 1.3 $
*/
#include "dev/vib-sensor.h"
const struct sensors_sensor vib_sensor;
/*---------------------------------------------------------------------------*/
void
vib_sensor_changed(void)
{
sensors_changed(&vib_sensor);
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(vib_sensor, VIB_SENSOR,
value, configure, status);

View file

@ -1,55 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Configurable Sensor Network Application
* Architecture for sensor nodes running the Contiki operating system.
*
* $Id: vib-sensor.h,v 1.2 2006/10/10 15:58:31 adamdunkels Exp $
*
* -----------------------------------------------------------------
*
* Author : Adam Dunkels, Joakim Eriksson, Niclas Finne
* Created : 2005-11-01
* Updated : $Date: 2006/10/10 15:58:31 $
* $Revision: 1.2 $
*/
#ifndef __VIB_SENSOR_H__
#define __VIB_SENSOR_H__
#include "lib/sensors.h"
extern const struct sensors_sensor vib_sensor;
#define VIB_SENSOR "Vibration"
void vib_sensor_changed(void);
#define VIB_ENABLE_EVENT 1
#endif /* __VIB_SENSOR_H__ */

View file

@ -1,738 +0,0 @@
/*
* Copyright (c) 2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $Id: display.c,v 1.10 2010/02/23 18:44:08 adamdunkels Exp $
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "dev/leds.h"
#include "display.h"
#include "nodes.h"
#include "node.h"
#include "ether.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "sensor.h"
#include <gtk/gtk.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
static GdkPixmap *pixmap = NULL;
static GtkWidget *drawing_area;
static GdkFont *font;
#define DISPLAY_WIDTH 400
#define DISPLAY_HEIGHT 400
#define BASESTATION_SIZE 4
#define MAPSCALE 20
#define SCALE 2
#define MARK_SIZE 8
#define RADIO_SIZE 20
#define DOT_SIZE ether_strength()
#define DOT_INTENSITY 3
struct dot {
struct dot *next;
int x, y;
int destx, desty;
int size;
int intensity;
};
MEMB(dotsmem, struct dot, 20000);
LIST(dots);
LIST(tempdots);
static int window_is_open;
static GdkGC *intensity_gcs[DOT_INTENSITY];
static GdkGC *intensity_clusterhead;
static GdkGC *intensity_clusterhead_lightgray;
static GdkGC *intensity_clusterhead_red;
static GdkGC *green, *red, *yellow, *black, *white;
static struct nodes_node *marked_node;
/*-----------------------------------------------------------------------------------*/
void
display_redraw(void)
{
int i;
struct nodes_node *n;
int x, y;
struct dot *d;
if(!window_is_open) {
return;
}
gdk_draw_rectangle(pixmap,
white,
TRUE,
0, 0,
drawing_area->allocation.width,
drawing_area->allocation.height);
for(i = 0; i < nodes_num(); ++i) {
n = nodes_node(i);
x = n->x;
y = n->y;
/* if(n->type == NODE_TYPE_CLUSTERHEAD) {
gdk_draw_arc(pixmap,
intensity_clusterhead_lightgray,
TRUE,
x * SCALE - DOT_SIZE * SCALE,
y * SCALE - DOT_SIZE * SCALE,
DOT_SIZE * 2 * SCALE, DOT_SIZE * 2 * SCALE,
0, 360 * 64);
}*/
if(n == marked_node) {
gdk_draw_arc(pixmap,
red,
FALSE,
x * SCALE - MARK_SIZE * SCALE,
y * SCALE - MARK_SIZE * SCALE,
MARK_SIZE * 2 * SCALE, MARK_SIZE * 2 * SCALE,
0, 360 * 64);
}
}
for(i = 0; i < nodes_num(); ++i) {
n = nodes_node(i);
x = n->x;
y = n->y;
/* if(n->type == NODE_TYPE_CLUSTERHEAD) {
gdk_draw_rectangle(pixmap,
intensity_clusterhead_red,
TRUE,
x * SCALE,
y * SCALE,
3, 3);
for(j = 0; j < nodes_num(); ++j) {
m = nodes_node(j);
if(m->type == NODE_TYPE_CLUSTERHEAD &&
((x - m->x) * (x - m->x) +
(y - m->y) * (y - m->y) < ether_strength() * ether_strength())) {
gdk_draw_line(pixmap,
intensity_clusterhead,
x * SCALE,
y * SCALE,
m->x * SCALE,
m->y * SCALE);
}
}
} else */ {
if(strlen(n->text) > 0) {
gdk_draw_string(pixmap,
font,
black,
x * SCALE + 10,
y * SCALE + 7,
n->text);
}
gdk_draw_rectangle(pixmap,
black,
TRUE,
x * SCALE,
y * SCALE,
2, 2);
/* gdk_draw_rectangle(pixmap,
drawing_area->style->white_gc,
TRUE,
x * SCALE,
y * SCALE,
2, 2);*/
if(n->leds & LEDS_GREEN) {
gdk_draw_rectangle(pixmap,
green,
TRUE,
x * SCALE + 2,
y * SCALE,
4, 4);
}
if(n->leds & LEDS_YELLOW) {
gdk_draw_rectangle(pixmap,
yellow,
TRUE,
x * SCALE,
y * SCALE + 2,
4, 4);
}
if(n->leds & LEDS_RED) {
gdk_draw_rectangle(pixmap,
red,
TRUE,
x * SCALE + 2,
y * SCALE + 2,
4, 4);
}
if(n->linex != 0 && n->liney != 0) {
gdk_draw_line(pixmap,
green,
x * SCALE,
y * SCALE,
n->linex * SCALE,
n->liney * SCALE);
gdk_draw_rectangle(pixmap,
green,
TRUE,
n->linex * SCALE - 2,
n->liney * SCALE - 2,
4, 4);
}
if(n->radio_status) {
gdk_draw_arc(pixmap,
green,
FALSE,
x * SCALE - RADIO_SIZE * SCALE,
y * SCALE - RADIO_SIZE * SCALE,
RADIO_SIZE * 2 * SCALE, RADIO_SIZE * 2 * SCALE,
0, 360 * 64);
}
}
}
for(d = list_head(dots); d != NULL; d = d->next) {
gdk_draw_arc(pixmap,
intensity_gcs[d->intensity - 1],
FALSE,
d->x * SCALE - d->size * SCALE,
d->y * SCALE - d->size * SCALE,
d->size * 2 * SCALE, d->size * 2 * SCALE,
0, 360 * 64);
}
gtk_widget_draw(drawing_area, NULL);
}
/*-----------------------------------------------------------------------------------*/
void
display_tick(void)
{
struct dot *d, *e;
struct ether_packet *p;
if(!window_is_open) {
return;
}
/* Fade out active dots. The intensity value of each dot is counted
downwards, and those dots that still have an intensity are placed
in a temporary list. The temporary list is then copied into the
list of all dots. */
list_init(tempdots);
for(d = list_head(dots);
d != NULL;
d = e) {
if(d != NULL) {
e = d->next;
} else {
e = NULL;
}
if(d->size > 20) {
d->size /= 2;
} else {
d->size -= 4;
}
/* --(d->intensity);*/
if(d->size > 0) {
list_push(tempdots, d);
} else {
memb_free(&dotsmem, (void *)d);
}
}
list_copy(dots, tempdots);
/* Check if there are any new dots that should be placed in the list. */
for(p = ether_packets(); p != NULL; p = p->next) {
d = (struct dot *)memb_alloc(&dotsmem);
if(d != NULL) {
d->x = p->x;
d->y = p->y;
d->size = DOT_SIZE;
d->intensity = DOT_INTENSITY;
list_push(dots, d);
}
}
}
/*-----------------------------------------------------------------------------------*/
static gint
configure_event(GtkWidget *widget, GdkEventConfigure *event)
{
if(pixmap != NULL) {
gdk_pixmap_unref(pixmap);
}
pixmap = gdk_pixmap_new(widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
if(pixmap == NULL) {
printf("gdk_pixmap_new == NULL\n");
exit(1);
}
gdk_draw_rectangle(pixmap,
widget->style->black_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
/* draw_screen();*/
return TRUE;
}
/* Redraw the screen from the backing pixmap */
static gint
expose_event (GtkWidget * widget, GdkEventExpose * event)
{
/* draw_screen();*/
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
static gint
key_press_event (GtkWidget * widget, GdkEventKey * event)
{
/* if(event->keyval == GDK_Shift_L ||
event->keyval == GDK_Shift_R) {
return TRUE;
}
keys[lastkey] = event->keyval;
++lastkey;
if(lastkey >= NUMKEYS) {
lastkey = 0;
}*/
if(event->keyval == 'q') {
gtk_exit(0);
/* exit(0);*/
}
if(event->keyval == 'p') {
display_output_fig();
}
return TRUE;
}
static gint
key_release_event (GtkWidget * widget, GdkEventKey * event)
{
return TRUE;
}
static gint
button_press_event (GtkWidget * widget, GdkEventKey * event)
{
struct dot *d;
struct sensor_data s;
GdkModifierType state;
int x, y;
gdk_window_get_pointer (event->window, &x, &y, &state);
x = ((GdkEventButton*)event)->x / SCALE;
y = ((GdkEventButton*)event)->y / SCALE;
if(state & GDK_BUTTON1_MASK) {
d = (struct dot *)memb_alloc(&dotsmem);
if(d != NULL) {
d->x = x;
d->y = y;
d->size = sensor_strength();
d->intensity = DOT_INTENSITY - 2;
list_push(dots, d);
}
sensor_data_init(&s);
s.pir = 1;
s.button = 0;
s.vib = 0;
ether_send_sensor_data(&s, x, y, sensor_strength());
} else if(state & GDK_BUTTON2_MASK) {
sensor_data_init(&s);
s.pir = 0;
s.button = 1;
s.vib = 0;
if(marked_node != NULL) {
ether_send_sensor_data(&s, marked_node->x, marked_node->y, 1);
}
} else if(state & GDK_BUTTON3_MASK) {
sensor_data_init(&s);
s.pir = 0;
s.button = 0;
s.vib = 1;
if(marked_node != NULL) {
ether_send_sensor_data(&s, marked_node->x, marked_node->y, 1);
}
}
return TRUE;
}
static gint
pointer_motion_event (GtkWidget * widget, GdkEventMotion * event)
{
struct dot *d;
struct sensor_data s;
GdkModifierType state;
int x, y;
struct nodes_node *node, *closest;
int nodex, nodey;
unsigned long dist;
int i;
if(event->is_hint) {
return TRUE;
}
gdk_window_get_pointer (event->window, &x, &y, &state);
x /= SCALE;
y /= SCALE;
if(state & GDK_BUTTON1_MASK) {
d = (struct dot *)memb_alloc(&dotsmem);
if(d != NULL) {
d->x = x;
d->y = y;
d->size = sensor_strength();
d->intensity = DOT_INTENSITY - 2;
list_push(dots, d);
}
sensor_data_init(&s);
s.pir = 1;
ether_send_sensor_data(&s, x, y, sensor_strength());
} else {
/* Find the closest node and mark it. */
closest = NULL;
dist = 0;
for(i = 0; i < nodes_num(); ++i) {
node = nodes_node(i);
nodex = node->x;
nodey = node->y;
if(closest == NULL ||
(x - nodex) * (x - nodex) + (y - nodey) * (y - nodey) < dist) {
dist = (x - nodex) * (x - nodex) + (y - nodey) * (y - nodey);
closest = node;
}
}
marked_node = closest;
}
return TRUE;
}
static void
quit(void)
{
gtk_exit(0);
}
/*-----------------------------------------------------------------------------------*/
static void (* idle)(void);
static gint
idle_callback(gpointer data)
{
idle();
return TRUE;
}
/*-----------------------------------------------------------------------------------*/
static GdkGC *
get_color(unsigned short r, unsigned short g, unsigned short b)
{
GdkGCValues values;
GdkColor color;
color.pixel = 0;
color.red = r;
color.green = g;
color.blue = b;
if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
&color, FALSE, TRUE)) {
}
values.foreground = color;
return gdk_gc_new_with_values(drawing_area->window,
&values,
GDK_GC_FOREGROUND);
}
/*-----------------------------------------------------------------------------------*/
static void
stdin_callback(gpointer data, gint source, GdkInputCondition condition)
{
char buf[1000];
int len;
len = read(STDIN_FILENO, &buf, sizeof(buf));
printf("read len %d\n", len);
buf[len] = 0;
ether_send_serial(buf);
}
/*-----------------------------------------------------------------------------------*/
void
display_init(void (* idlefunc)(void), int time, int with_gui)
{
int i;
GtkWidget *window;
GtkWidget *vbox;
GdkGCValues values;
GdkColor color;
memb_init(&dotsmem);
list_init(dots);
list_init(tempdots);
gtk_init(NULL, NULL);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Contiki simulation display");
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER (window), vbox);
gtk_widget_show(vbox);
gtk_signal_connect(GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (quit), NULL);
font = gdk_font_load("-*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1");
/* Create the drawing area */
drawing_area = gtk_drawing_area_new();
gtk_drawing_area_size(GTK_DRAWING_AREA (drawing_area),
DISPLAY_WIDTH,
DISPLAY_HEIGHT);
gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
gtk_widget_show(drawing_area);
/* Signals used to handle backing pixmap */
gtk_signal_connect(GTK_OBJECT (drawing_area), "expose_event",
(GtkSignalFunc) expose_event, NULL);
gtk_signal_connect(GTK_OBJECT (drawing_area), "configure_event",
(GtkSignalFunc) configure_event, NULL);
/* Event signals */
gtk_signal_connect(GTK_OBJECT (window), "key_press_event",
(GtkSignalFunc) key_press_event, NULL);
gtk_signal_connect(GTK_OBJECT (window), "key_release_event",
(GtkSignalFunc) key_release_event, NULL);
gtk_signal_connect(GTK_OBJECT (window), "button_press_event",
(GtkSignalFunc) button_press_event, NULL);
gtk_signal_connect(GTK_OBJECT (window), "motion_notify_event",
(GtkSignalFunc) pointer_motion_event, NULL);
gtk_widget_set_events(drawing_area,GDK_KEY_PRESS_MASK
| GDK_KEY_RELEASE_MASK | GDK_BUTTON_PRESS_MASK
| GDK_POINTER_MOTION_MASK);
/* gtk_window_iconify(window);*/
if(with_gui) {
gtk_widget_show(window);
window_is_open = with_gui;
}
idle = idlefunc;
gtk_timeout_add(time, idle_callback, NULL);
if(with_gui) {
for(i = 0; i < DOT_INTENSITY; ++i) {
color.pixel = 0;
color.red = 0;
color.green = ((DOT_INTENSITY + 1) * 0xffff) / (i + 1);
color.blue = ((DOT_INTENSITY + 1) * 0xffff) / (i + 1);
if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
&color, FALSE, TRUE)) {
}
values.foreground = color;
intensity_gcs[i] = gdk_gc_new_with_values(drawing_area->window, &values,
GDK_GC_FOREGROUND);
}
color.pixel = 0;
color.red = 0xbfff;
color.green = 0xbfff;
color.blue = 0xbfff;
if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
&color, FALSE, TRUE)) {
}
values.foreground = color;
intensity_clusterhead = gdk_gc_new_with_values(drawing_area->window, &values,
GDK_GC_FOREGROUND);
color.pixel = 0;
color.red = 0xefff;
color.green = 0xefff;
color.blue = 0xefff;
if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
&color, FALSE, TRUE)) {
}
values.foreground = color;
intensity_clusterhead_lightgray = gdk_gc_new_with_values(drawing_area->window, &values,
GDK_GC_FOREGROUND);
color.pixel = 0;
color.red = 0xffff;
color.green = 0;
color.blue = 0;
if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
&color, FALSE, TRUE)) {
}
values.foreground = color;
intensity_clusterhead_red = gdk_gc_new_with_values(drawing_area->window, &values,
GDK_GC_FOREGROUND);
red = get_color(0xffff, 0, 0);
green = get_color(0, 0xffff, 0);
yellow = get_color(0xffff, 0xffff, 0);
black = get_color(0, 0, 0);
white = get_color(0xffff, 0xffff, 0xffff);
}
gdk_input_add(STDIN_FILENO, GDK_INPUT_READ, stdin_callback, NULL);
}
/*-----------------------------------------------------------------------------------*/
void
display_run(void)
{
gtk_main();
}
/*-----------------------------------------------------------------------------------*/
void
display_output_fig(void)
{
int i;
struct nodes_node *n;
int x, y;
int dot_radius = 75;
int scale = 50;
FILE *fp;
char name[40];
struct timeval tv;
gettimeofday(&tv, NULL);
snprintf(name, sizeof(name), "network-%lu.fig", tv.tv_sec);
fp = fopen(name, "w");
fprintf(fp, "#FIG 3.2\n"
"Landscape\n"
"Center\n"
"Inches\n"
"Letter\n"
"100.00\n"
"Single\n"
"-2\n"
"1200 2\n"
);
for(i = 0; i < nodes_num(); ++i) {
n = nodes_node(i);
x = n->x * scale;
y = n->y * scale;
fprintf(fp, "1 3 1 1 0 7 50 -1 0 4.000 1 0.0000 %d %d %d %d %d %d %d %d\n",
x, y,
dot_radius, dot_radius,
x, y,
x + dot_radius, y + dot_radius);
if(strlen(n->text) > 0) {
fprintf(fp, "4 0 0 50 -1 16 18 0.0000 4 135 720 %d %d %s\\001\n",
x + 2 * scale, y, n->text);
}
if(n->linex != 0 && n->liney != 0) {
fprintf(fp, "2 1 1 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2\n"
"1 1 4.00 60.00 120.00\n"
"%d %d %d %d\n",
x, y,
n->linex * scale, n->liney * scale);
}
}
fclose(fp);
}
/*-----------------------------------------------------------------------------------*/

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $Id: display.h,v 1.2 2008/05/14 19:22:57 adamdunkels Exp $
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
void display_redraw(void);
void display_init(void (* idle)(void), int time, int with_gui);
void display_run(void);
void display_tick(void);
void display_output_fig(void);
#endif /* __DISPLAY_H__ */

View file

@ -1,698 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ether.c,v 1.17 2010/10/19 18:29:05 adamdunkels Exp $
*/
/**
* \file
* This module implements a simple "ether", into which datapackets can
* be injected. The packets are delivered to all nodes that are in
* transmission range.
*
* \author Adam Dunkels <adam@sics.se>
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include "ether.h"
#include "lib/memb.h"
#include "lib/list.h"
#include "nodes.h"
#include "dev/radio-sensor.h"
#include "dev/serial-line.h"
#include "sensor.h"
#include "node.h"
#include "net/uip.h"
#include "net/uip-fw.h"
#ifndef NULL
#define NULL 0
#endif /* NULL */
MEMB(packets, struct ether_packet, 20000);
LIST(active_packets);
static u8_t rxbuffer[2048];
static clock_time_t timer;
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define PRINTF(...)
/*#define PRINTF(x) printf x*/
static int s, sc;
#define PTYPE_NONE 0
#define PTYPE_CLOCK 1
#define PTYPE_DATA 2
#define PTYPE_SENSOR 3
#define PTYPE_LEDS 4
#define PTYPE_TEXT 5
#define PTYPE_DONE 6
#define PTYPE_SERIAL 7
#define PTYPE_RADIO_STATUS 8
#define SERIAL_LEN 80
struct ether_hdr {
int type;
struct sensor_data sensor_data;
clock_time_t clock;
int linex, liney;
int signal;
int srcx, srcy;
int srcpid;
int srcid;
int srcnodetype;
int leds;
int radio_status;
char text[NODES_TEXTLEN + SERIAL_LEN];
};
static int strength;
static int collisions = 1;
static int num_collisions = 0;
static int num_sent = 0;
static int num_received = 0;
static int drop_probability = 0;
static int num_drops = 0;
#include <sys/time.h>
static struct timeval t1;
static int linex, liney;
/*-----------------------------------------------------------------------------------*/
void
ether_print_stats(void)
{
unsigned long time;
struct timeval t2;
gettimeofday(&t2, NULL);
time = (t2.tv_sec * 1000 + t2.tv_usec / 1000) -
(t1.tv_sec * 1000 + t1.tv_usec / 1000);
/* printf("%d, %d, %f\n", num_packets, num_collisions, time/1000.0);*/
printf("Time: %f\n", time/1000.0);
printf("Total packets sent: %d\n", num_sent);
printf("Total collisions: %d\n", num_collisions);
printf("Total packets receptions: %d\n", num_received);
printf("Total randomly dropped packets: %d\n", num_drops);
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_drop_probability(double p)
{
drop_probability = p * 65536;
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_collisions(int c)
{
collisions = c;
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_strength(int s)
{
strength = s;
}
/*-----------------------------------------------------------------------------------*/
int
ether_strength(void)
{
return strength;
}
/*-----------------------------------------------------------------------------------*/
void
ether_server_init(void)
{
struct sockaddr_in sa;
gettimeofday(&t1, NULL);
memb_init(&packets);
list_init(active_packets);
timer = 0;
s = socket(AF_INET,SOCK_DGRAM,0);
if(s < 0) {
perror("ether_server_init: socket");
}
memset((char *)&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");/*uip_htonl(INADDR_ANY);*/
sa.sin_port = uip_htons(ETHER_PORT);
/* printf("Binding to port %d\n", ETHER_PORT);*/
if(bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
printf("Bind to port %d\n", ETHER_PORT);
perror("bind");
exit(1);
}
}
/*-----------------------------------------------------------------------------------*/
void
ether_client_init(int port)
{
struct sockaddr_in sa;
sc = socket(AF_INET,SOCK_DGRAM,0);
if(sc < 0) {
perror("socket");
}
memset((char *)&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");/*uip_htonl(INADDR_ANY);*/
sa.sin_port = uip_htons(port);
/* printf("ether_client_init: binding to port %d\n", port);*/
if(bind(sc, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
printf("Bind to port %d\n", port);
perror("bind");
exit(1);
}
}
/*-----------------------------------------------------------------------------------*/
int
ether_client_poll(void)
{
fd_set fdset;
struct timeval tv;
int ret;
FD_ZERO(&fdset);
FD_SET(sc, &fdset);
tv.tv_sec = 0;
tv.tv_usec = 1000;
ret = select(sc + 1, &fdset, NULL, NULL, &tv);
if(ret < 0) {
perror("ether_client_poll: select");
}
return ret == 1;
}
/*-----------------------------------------------------------------------------------*/
u16_t
ether_client_read(u8_t *buf, int bufsize)
{
int ret, len;
fd_set fdset;
struct timeval tv;
struct ether_hdr *hdr = (struct ether_hdr *)rxbuffer;
FD_ZERO(&fdset);
FD_SET(sc, &fdset);
tv.tv_sec = 0;
tv.tv_usec = 10000;
ret = select(sc + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
/* printf("ret 0\n");*/
return 0;
}
if(FD_ISSET(sc, &fdset)) {
ret = recv(sc, &rxbuffer[0], sizeof(rxbuffer), 0);
if(ret == -1) {
perror("ether_client_poll: recv");
return 0;
}
len = ret;
if(len > bufsize) {
PRINTF("ether_client_read: packet truncated from %d to %d\n",
len, bufsize);
len = bufsize;
}
/* printf("Incoming len %d\n", len);*/
memcpy(buf, &rxbuffer[sizeof(struct ether_hdr)], len);
radio_sensor_signal = hdr->signal;
if(hdr->type == PTYPE_DATA && hdr->srcid != node.id) {
return len - sizeof(struct ether_hdr);
} else if(hdr->type == PTYPE_CLOCK) {
node_set_time(hdr->clock);
} else if(hdr->type == PTYPE_SENSOR) {
int strength = sensor_strength() -
((hdr->srcx - node_x()) * (hdr->srcx - node_x()) +
(hdr->srcy - node_y()) * (hdr->srcy - node_y())) / sensor_strength();
/* printf("Dist %d \n", strength);*/
if(strength > 0) {
sensor_input(&hdr->sensor_data, strength);
}
} else if(hdr->type == PTYPE_SERIAL) {
char *ptr = hdr->text;
printf("serial input %s\n", ptr);
for(ptr = hdr->text; *ptr != 0; ++ptr) {
serial_line_input_byte(*ptr);
}
}
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
ether_server_poll(void)
{
int ret;
fd_set fdset;
struct timeval tv;
struct ether_hdr *hdr = (struct ether_hdr *)rxbuffer;
/* struct timeval rtime1, rtime2;
struct timespec ts;
struct timezone tz;*/
tv.tv_sec = 0;
tv.tv_usec = 100;
do {
FD_ZERO(&fdset);
FD_SET(s, &fdset);
ret = select(s + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
return;
}
if(FD_ISSET(s, &fdset)) {
ret = recv(s, &rxbuffer[0], sizeof(rxbuffer), 0);
if(ret == -1) {
perror("ether_poll: read");
return;
}
nodes_set_line(hdr->srcx, hdr->srcy, hdr->linex, hdr->liney);
switch(hdr->type) {
case PTYPE_DATA:
PRINTF("ether_poll: read %d bytes from (%d, %d)\n",
ret, hdr->srcx, hdr->srcy);
ether_put((char *)rxbuffer, ret, hdr->srcx, hdr->srcy);
break;
case PTYPE_LEDS:
nodes_set_leds(hdr->srcx, hdr->srcy, hdr->leds);
break;
case PTYPE_TEXT:
nodes_set_text(hdr->srcx, hdr->srcy, hdr->text);
break;
case PTYPE_DONE:
nodes_done(hdr->srcid);
break;
case PTYPE_SERIAL:
break;
case PTYPE_RADIO_STATUS:
nodes_set_radio_status(hdr->srcx, hdr->srcy, hdr->radio_status);
break;
}
}
/* tv.tv_sec = 0;
tv.tv_usec = 1;*/
} while(1/*ret > 0*/);
}
/*-----------------------------------------------------------------------------------*/
void
ether_put(char *data, int len, int x, int y)
{
struct ether_packet *p;
/* printf("ether_put: packet len %d at (%d, %d)\n", len, x, y);*/
p = (struct ether_packet *)memb_alloc(&packets);
if(p != NULL) {
if(len > 1500) {
len = 1500;
}
memcpy(p->data, data, len);
p->len = len;
p->x = x;
p->y = y;
list_push(active_packets, p);
}
}
/*-----------------------------------------------------------------------------------*/
static void
send_packet(char *data, int len, int port)
{
struct sockaddr_in sa;
memset((char *)&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
sa.sin_port = uip_htons(port);
if(sendto(s, data, len, 0, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
perror("ether: send_packet: sendto");
}
}
/*-----------------------------------------------------------------------------------*/
void
ether_tick(void)
{
struct ether_packet *p, *q;
struct ether_hdr *hdr;
int port;
int x, y;
int i;
int interference;
/* Go through every node and see if there are any packets destined
to them. If two or more packets are sent in the vicinity of the
node, they interfere with each otehr and none reaches the
node. */
for(i = 0; i < nodes_num(); ++i) {
x = nodes_node(i)->x;
y = nodes_node(i)->y;
port = nodes_node(i)->port;
/* Go through all active packets to see if anyone is sent within
range of this node. */
for(p = list_head(active_packets); p != NULL; p = p->next) {
num_sent++;
/* Update the node type. */
hdr = (struct ether_hdr *)p->data;
/* nodes_node(hdr->srcid)->type = hdr->srcnodetype;*/
if(!(p->x == x && p->y == y) && /* Don't send packets back to
the sender. */
(p->x - x) * (p->x - x) +
(p->y - y) * (p->y - y) <=
ether_strength() * ether_strength()) {
hdr->signal = ether_strength() * ether_strength() -
(p->x - x) * (p->x - x) -
(p->y - y) * (p->y - y);
/* This packet was sent in the reception range of this node,
so we check against all other packets to see if there is
more than one packet sent towards this node. If so, we have
interference and the node will not be able to receive any
data. */
interference = 0;
if(collisions) {
for(q = list_head(active_packets); q != NULL; q = q->next) {
/* Compute the distance^2 and check against signal strength. */
if(p != q &&
((q->x - x) * (q->x - x) +
(q->y - y) * (q->y - y) <=
ether_strength() * ether_strength())) {
/* If the potentially interfering packets were sent from
the same node, then they don't interfere with each
other. Otherwise they interfere and we sent the
interference flag to 1. */
if(p->x != q->x ||
p->y != q->y) {
interference = 1;
}
break;
}
}
}
if(interference) {
num_collisions++;
/* printf("Collisions %d\n", num_collisions);*/
}
if(!interference) {
/* printf("ether: delivering packet from %d to %d\n",
hdr->srcid, port);*/
if((unsigned int)((rand() * 17) % 65536) >= drop_probability) {
send_packet(p->data, p->len, port);
num_received++;
} else {
num_drops++;
}
}
}
}
}
/* Remove all packets from the active packets list. */
while((p = list_pop(active_packets)) != NULL) {
memb_free(&packets, (void *) p);
}
++timer;
}
/*-----------------------------------------------------------------------------------*/
struct ether_packet *
ether_packets(void)
{
return list_head(active_packets);
}
/*-----------------------------------------------------------------------------------*/
clock_time_t
ether_time(void)
{
return timer;
}
/*-----------------------------------------------------------------------------------*/
static void
node_send_packet(char *data, int len)
{
struct sockaddr_in sa;
memset((char *)&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
sa.sin_port = uip_htons(ETHER_PORT);
if(sendto(sc, data, len, 0,
(struct sockaddr *)&sa, sizeof(sa)) == -1) {
perror("ether.c node_send_packet: sendto");
}
}
/*-----------------------------------------------------------------------------------*/
u8_t
ether_send(char *data, int len)
{
char tmpbuf[2048];
struct ether_hdr *hdr = (struct ether_hdr *)tmpbuf;
memcpy(&tmpbuf[sizeof(struct ether_hdr)], data, len);
hdr->srcx = node.x;
hdr->srcy = node.y;
hdr->type = PTYPE_DATA;
/* hdr->srcnodetype = node.type;*/
hdr->srcid = node.id;
hdr->linex = linex;
hdr->liney = liney;
node_send_packet(tmpbuf, len + sizeof(struct ether_hdr));
return UIP_FW_OK;
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_leds(int leds)
{
struct ether_hdr hdr;
memset(&hdr, 0, sizeof (hdr));
hdr.srcx = node.x;
hdr.srcy = node.y;
hdr.type = PTYPE_LEDS;
hdr.leds = leds;
/* hdr.srcnodetype = node.type;*/
hdr.srcid = node.id;
hdr.linex = linex;
hdr.liney = liney;
node_send_packet((char *)&hdr, sizeof(struct ether_hdr));
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_text(char *text)
{
struct ether_hdr hdr;
hdr.srcx = node.x;
hdr.srcy = node.y;
hdr.type = PTYPE_TEXT;
strncpy(hdr.text, text, NODES_TEXTLEN);
/* hdr.srcnodetype = node.type;*/
hdr.srcid = node.id;
hdr.linex = linex;
hdr.liney = liney;
node_send_packet((char *)&hdr, sizeof(struct ether_hdr));
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_radio_status(int onoroff)
{
struct ether_hdr hdr;
hdr.srcx = node.x;
hdr.srcy = node.y;
hdr.type = PTYPE_RADIO_STATUS;
hdr.radio_status = onoroff;
hdr.srcid = node.id;
hdr.linex = linex;
hdr.liney = liney;
node_send_packet((char *)&hdr, sizeof(struct ether_hdr));
}
/*-----------------------------------------------------------------------------------*/
void
ether_send_sensor_data(struct sensor_data *d, int srcx, int srcy, int strength)
{
int port;
int x, y;
int i;
struct ether_hdr hdr;
/* printf("Sensor data at (%d, %d)\n", srcx, srcy);*/
for(i = 0; i < nodes_num(); ++i) {
x = nodes_node(i)->x;
y = nodes_node(i)->y;
port = nodes_node(i)->port;
if((srcx - x) * (srcx - x) +
(srcy - y) * (srcy - y) <=
strength * strength) {
hdr.srcx = srcx;
hdr.srcy = srcy;
hdr.type = PTYPE_SENSOR;
hdr.sensor_data = *d;
send_packet((char *)&hdr, sizeof(hdr), port);
}
}
}
/*-----------------------------------------------------------------------------------*/
void
ether_send_done(void)
{
struct ether_hdr hdr;
hdr.srcx = node.x;
hdr.srcy = node.y;
hdr.type = PTYPE_DONE;
hdr.srcid = node.id;
node_send_packet((char *)&hdr, sizeof(struct ether_hdr));
}
/*-----------------------------------------------------------------------------------*/
void
ether_send_serial(char *str)
{
struct ether_hdr hdr;
int len;
hdr.srcx = node.x;
hdr.srcy = node.y;
hdr.type = PTYPE_SERIAL;
hdr.srcid = node.id;
len = strlen(str) + 1;
if(len > sizeof(hdr.text)) {
len = sizeof(hdr.text);
}
memcpy(&hdr.text, str, len);
hdr.text[len] = 0;
/* printf("ether_send_serial '%s' to %d len %d\n", str, nodes_base_node_port, sizeof(struct ether_hdr));*/
send_packet((char *)&hdr, sizeof(struct ether_hdr), nodes_base_node_port);
}
/*-----------------------------------------------------------------------------------*/
void
ether_set_line(int x, int y)
{
struct ether_hdr hdr;
linex = x;
liney = y;
hdr.srcx = node.x;
hdr.srcy = node.y;
hdr.type = PTYPE_NONE;
hdr.srcid = node.id;
hdr.linex = linex;
hdr.liney = liney;
node_send_packet((char *)&hdr, sizeof(struct ether_hdr));
}
/*-----------------------------------------------------------------------------------*/

View file

@ -1,92 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ether.h,v 1.9 2008/05/14 19:22:58 adamdunkels Exp $
*/
#ifndef __ETHER_H__
#define __ETHER_H__
#include "contiki.h"
#include "sensor.h"
struct ether_packet {
struct ether_packet *next;
char data[1500];
int len;
int x, y;
int destx, desty;
};
void ether_send_done(void);
u8_t ether_send(char *data, int len);
void ether_set_leds(int leds);
void ether_set_text(char *text);
void ether_set_radio_status(int onoroff);
void ether_send_serial(char *text);
void ether_poll(void);
void ether_server_init(void);
void ether_client_init(int port);
void ether_tick(void);
u16_t ether_client_read(u8_t *buf, int len);
void ether_server_poll(void);
void ether_put(char *packet, int len, int src_x, int src_y);
void ether_send_sensor_data(struct sensor_data *d, int srcx, int srcy, int strength);
int ether_client_poll(void);
struct ether_packet * ether_packets(void);
clock_time_t ether_time(void);
#define ETHER_PORT 4999
/*#define ETHER_STRENGTH 24*/
int ether_strength(void);
void ether_set_strength(int s);
void ether_set_collisions(int c);
void ether_set_drop_probability(double p);
void ether_print_stats(void);
void ether_set_line(int x, int y);
#endif /* __ETHER_H__ */

View file

@ -1,70 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: init.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $
*/
#include "init.h"
#include "random.h"
void
init(void)
{
int x, y;
ether_set_strength(21);
main_add_node(1, 1);
main_add_node(1, 20);
main_add_node(20, 1);
/*for(x = 1; x < 201; x += 20) {
for(y = 1; y < 201; y += 20) {
main_add_node(x, y);
}
}*/
/* main_add_node(10, 10);
main_add_node(11, 11);
main_add_node(12, 12);
main_add_node(13, 13);
main_add_node(14, 14);
main_add_node(15, 15);
main_add_node(16, 16); */
/* for(x = 10; x < 370; x += 20) {
for(y = 10; y < 370; y += 20) {
main_add_node(x + (random_rand() % 20) - 10,
y + (random_rand() % 20) - 10);
}
}*/
/* main_add_base(1, 1);*/
}

View file

@ -1,43 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* @(#)$Id: init.h,v 1.3 2007/11/17 18:09:18 adamdunkels Exp $
*/
#ifndef __INIT_H__
#define __INIT_H__
#include "ether.h"
void init(void);
int main_add_node(int x, int y);
void main_add_base(int x, int y);
#endif /* __INIT_H__ */

View file

@ -1,296 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: main.c,v 1.13 2008/11/09 12:30:32 adamdunkels Exp $
*/
/**
* \file
* This file implements the main function of the Contiki distributed
* sensor network simulation environment.
* \author Adam Dunkels <adam@sics.se>
*
* When starting, each sensor node is created as its own process. The
* sensor node processes communicates with the starting process using
* named pipes. These pipes carry messages such as data packets and
* configuration and statistics information requests.
*/
#include "contiki-net.h"
#include "display.h"
#include "contiki-main.h"
#include "nodes.h"
#include "ether.h"
#include "node.h"
#include "net/ethernode.h"
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <arpa/inet.h>
in_addr_t gwaddr, winifaddr;
void netsim_init(void);
static int main_process = 0;
/*---------------------------------------------------------------------------*/
static void
sigchld_handler(int sig)
{
int status;
pid_t pid;
struct nodes_node *node;
if(!main_process) {
return;
}
pid = waitpid(-1, &status, WNOHANG);
if(WIFSIGNALED(status) &&
WTERMSIG(status) == SIGSEGV) {
node = nodes_find_pid(pid);
if(node == NULL) {
printf("A Contiki node crashed, but it wasn't even started by the system. Something weird is going on!\n");
} else {
printf("Contiki node at (%d, %d) crashed - Segmentation fault\n",
node->x, node->y);
}
}
}
/*---------------------------------------------------------------------------*/
static void
idle(void)
{
int events;
do {
ether_server_poll();
display_tick();
display_redraw();
ether_tick();
events = process_run();
if(events > 0) {
printf("events %d\n", events);
}
} while(events > 0);
}
/*---------------------------------------------------------------------------*/
static int
start_node(int x, int y, int b)
{
pid_t pid;
struct timeval tv;
static unsigned short port = NODES_PORTBASE;
pid = fork();
if(pid == 0) {
/* This is the sensor process. */
main_process = 0;
/* Make standard output unbuffered. */
setvbuf(stdout, (char *)NULL, _IONBF, 0);
srand(getpid());
tv.tv_sec = 0;
tv.tv_usec = 1000 * (rand() % 1000);
select(0, NULL, NULL, NULL, &tv);
node_init(port - NODES_PORTBASE + 2, x, y, b);
ethernode_init(port);
contiki_main(b);
/* NOTREACHED */
}
if(b) {
nodes_base_node_port = port;
}
/* printf("Adding sensor %d at (%d,%d)\n", pid, x, y);*/
main_process = 1;
nodes_add(pid, x, y, port, port - NODES_PORTBASE + 2);
++port;
return port - NODES_PORTBASE + 1;
}
/*---------------------------------------------------------------------------*/
int
main_add_node(int x, int y)
{
return start_node(x, y, 0);
}
/*---------------------------------------------------------------------------*/
void
main_add_base(int x, int y)
{
start_node(x, y, 1);
}
/*---------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
#ifdef __CYGWIN__
if(argc == 3 &&
inet_addr(argv[1]) == INADDR_NONE &&
inet_addr(argv[2]) == INADDR_NONE) {
printf("usage: %s <ip addr of ethernet card to share> "
"<ip addr of netsim gateway>\n", argv[0]);
exit(1);
} else if(argc >= 2) {
gwaddr = inet_addr(argv[2]);
winifaddr = inet_addr(argv[1]);
}
#endif /* __CYGWIN__ */
/* system("ifconfig tap0 inet 192.168.250.1");*/
/* system("route delete 172.16.0.0/16");
system("route add 172.16.0.0/16 192.168.250.2");*/
nodes_init();
atexit(nodes_kill);
atexit(ether_print_stats);
netsim_init();
ether_server_init();
#if 0
while(1) {
ether_server_poll();
ether_tick();
process_run();
usleep(100);
}
#endif /* 0 */
#ifdef __CYGWIN__
if(argc > 1 && (strcmp(argv[1], "-q") ||
strcmp(argv[2], "-q") ||
strcmp(argv[3], "-q")) == 0) {
#else /* __CYGWIN__ */
if(argc > 1 && strcmp(argv[1], "-q") == 0) {
#endif /* __CYGWIN__ */
display_init(idle, 50, 0);
} else {
display_init(idle, 50, 1);
}
display_redraw();
signal(SIGCHLD, sigchld_handler);
display_run();
return 0;
argv = argv;
argc = argc;
}
/*-----------------------------------------------------------------------------------*/
char *arg_alloc(char size) {return NULL;}
void arg_init(void) {}
void arg_free(char *arg) {}
/*-----------------------------------------------------------------------------------*/
char *shell_prompt_text = "sensor-router> ";
/*-----------------------------------------------------------------------------------*/
#include <sys/time.h>
static signed long drift = 0;
void
clock_delay(unsigned int num)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100 * num;
select(0, NULL, NULL, NULL, &tv);
}
void
clock_set_time(clock_time_t time, clock_time_t ftime)
{
drift = time - node_time();
}
clock_time_t
clock_time(void)
{
return drift + node_time();
}
/*-----------------------------------------------------------------------------------*/
unsigned long
clock_seconds(void)
{
return node_seconds();
}
/*-----------------------------------------------------------------------------------*/
void
uip_log(char *m)
{
uip_ipaddr_t addr;
uip_gethostaddr(&addr);
printf("uIP log at %d.%d.%d.%d: %s\n", uip_ipaddr_to_quad(&addr), m);
fflush(NULL);
}
void
configurator_send_config(uip_ipaddr_t *addr, unsigned long seconds)
{
printf("Configurator: address %d.%d.%d.%d, seconds %lu\n",
uip_ipaddr_to_quad(addr), seconds);
}
void
system_log(char *m)
{
printf("%s", m);
}
/*void tr1001_drv_set_slip_dump(int c)
{
}*/

View file

@ -1,78 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ethernode-rime.c,v 1.7 2009/03/12 21:58:21 adamdunkels Exp $
*/
#include "contiki.h"
#include "ethernode.h"
#include "net/rime.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
static void
receiver(void)
{
u8_t len;
packetbuf_clear();
len = ethernode_read(packetbuf_dataptr(), PACKETBUF_SIZE);
if(len > 0) {
packetbuf_set_datalen(len);
rime_input();
}
}
/*---------------------------------------------------------------------------*/
void
ethernode_rime_send(void)
{
ethernode_send_buf(packetbuf_hdrptr(), packetbuf_totlen());
}
/*---------------------------------------------------------------------------*/
void
ethernode_rime_init(void)
{
ethernode_set_receiver(receiver);
rime_set_output(ethernode_rime_send);
}
/*---------------------------------------------------------------------------*/

Some files were not shown because too many files have changed in this diff Show more