Merge remote-tracking branch 'sf/master' into rpl-patch
Conflicts: core/net/tcpip.c
This commit is contained in:
commit
d0ebeb409e
4
apps/antelope/Makefile.antelope
Normal file
4
apps/antelope/Makefile.antelope
Normal 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
156
apps/antelope/antelope.c
Normal 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;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
* Copyright (c) 2010, Swedish Institute of Computer Science
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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
|
* \file
|
||||||
* A brief description of what this file is.
|
* Declarations of the main Antelope functions.
|
||||||
* \author
|
* \author
|
||||||
* Adam Dunkels <adam@sics.se>
|
* Nicolas Tsiftes <nvt@sics.se>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ETHERNODE_RIME_H__
|
#ifndef DB_H
|
||||||
#define __ETHERNODE_RIME_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
149
apps/antelope/aql-adt.c
Normal 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
240
apps/antelope/aql-exec.c
Normal 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
274
apps/antelope/aql-lexer.c
Normal 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
877
apps/antelope/aql-parser.c
Normal 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
221
apps/antelope/aql.h
Normal 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 */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
* Copyright (c) 2010, Swedish Institute of Computer Science
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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
|
* \file
|
||||||
* A brief description of what this file is.
|
* Definitions for attributes.
|
||||||
* \author
|
* \author
|
||||||
* Adam Dunkels <adam@sics.se>
|
* Nicolas Tsiftes <nvt@sics.se>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONTIKI_ESB_H__
|
#ifndef ATTRIBUTE_H
|
||||||
#define __CONTIKI_ESB_H__
|
#define ATTRIBUTE_H
|
||||||
|
|
||||||
#include "contiki.h"
|
#include <stdint.h>
|
||||||
#include "contiki-net.h"
|
#include <stdlib.h>
|
||||||
#include "contiki-lib.h"
|
|
||||||
#include "dev/leds.h"
|
|
||||||
|
|
||||||
#include "dev/vib-sensor.h"
|
#include "lib/list.h"
|
||||||
#include "dev/radio-sensor.h"
|
|
||||||
#include "dev/pir-sensor.h"
|
|
||||||
#include "dev/temperature-sensor.h"
|
|
||||||
#include "dev/button-sensor.h"
|
|
||||||
|
|
||||||
#include "dev/lpm.h"
|
#include "db-options.h"
|
||||||
#include "dev/radio.h"
|
|
||||||
|
|
||||||
#include "dev/tr1001.h"
|
typedef enum {
|
||||||
#include "dev/tr1001-drv.h"
|
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
173
apps/antelope/db-options.h
Normal 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 */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, Swedish Institute of Computer Science.
|
* Copyright (c) 2010, Swedish Institute of Computer Science
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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
|
* \file
|
||||||
* Loader definitions for the netsim target
|
* .
|
||||||
* \author
|
* \author
|
||||||
* Adam Dunkels <adam@sics.se>
|
* Nicolas Tsiftes <nvt@sics.se>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __LOADER_ARCH_H__
|
#ifndef DB_TYPES_H
|
||||||
#define __LOADER_ARCH_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 */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
* Copyright (c) 2010, Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -28,28 +28,37 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* 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
|
* \file
|
||||||
* A brief description of what this file is.
|
* A set of debugging macros.
|
||||||
* \author
|
*
|
||||||
* Adam Dunkels <adam@sics.se>
|
* \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>
|
#include <stdio.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
#define ANNOTATE(...) printf(__VA_ARGS__)
|
||||||
void
|
#else
|
||||||
lpm_on(void)
|
#define ANNOTATE(...)
|
||||||
{
|
#endif /* (DEBUG) & DEBUG_ANNOTATE */
|
||||||
printf("lpm_on()\n");
|
|
||||||
}
|
#if (DEBUG) & DEBUG_PRINT
|
||||||
/*---------------------------------------------------------------------------*/
|
#include <stdio.h>
|
||||||
void
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
lpm_off(void)
|
#else
|
||||||
{
|
#define PRINTF(...)
|
||||||
printf("lpm_off()\n");
|
#endif /* (DEBUG) & DEBUG_PRINT */
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
#endif
|
231
apps/antelope/index-inline.c
Normal file
231
apps/antelope/index-inline.c
Normal 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(¢er, 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;
|
||||||
|
}
|
747
apps/antelope/index-maxheap.c
Normal file
747
apps/antelope/index-maxheap.c
Normal 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);
|
||||||
|
}
|
194
apps/antelope/index-memhash.c
Normal file
194
apps/antelope/index-memhash.c
Normal 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
424
apps/antelope/index.c
Normal 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
113
apps/antelope/index.h
Normal 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
976
apps/antelope/lvm.c
Normal 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
144
apps/antelope/lvm.h
Normal 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
1222
apps/antelope/relation.c
Normal file
File diff suppressed because it is too large
Load diff
102
apps/antelope/relation.h
Normal file
102
apps/antelope/relation.h
Normal 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
185
apps/antelope/result.c
Normal 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;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
* Copyright (c) 2010, Swedish Institute of Computer Science
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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
|
* \file
|
||||||
* A brief description of what this file is.
|
* Declarations for the result acquisition API.
|
||||||
* \author
|
* \author
|
||||||
* Adam Dunkels <adam@sics.se>
|
* Nicolas Tsiftes <nvt@sics.se>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TR1001_H__
|
#ifndef RESULT_H
|
||||||
#define __TR1001_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);
|
typedef unsigned char *tuple_t;
|
||||||
u8_t tr1001_send(u8_t *packet, u16_t len);
|
|
||||||
unsigned short tr1001_poll(void);
|
|
||||||
|
|
||||||
void tr1001_set_txpower(unsigned char p);
|
#define DB_HANDLE_FLAG_INDEX_STEP 0x01
|
||||||
#define TR1001_TXPOWER_HIGHEST 100
|
#define DB_HANDLE_FLAG_SEARCH_INDEX 0x02
|
||||||
#define TR1001_TXPOWER_LOWEST 1
|
#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
|
db_result_t db_get_value(attribute_value_t *value,
|
||||||
#define TR1001_SSTRENGTH_MAX 2
|
db_handle_t *handle, unsigned col);
|
||||||
#define TR1001_SSTRENGTH_MIN 3
|
db_result_t db_phy_to_value(attribute_value_t *value,
|
||||||
unsigned short tr1001_packets_ok(void);
|
attribute_t *attr, unsigned char *ptr);
|
||||||
unsigned short tr1001_packets_dropped(void);
|
db_result_t db_value_to_phy(unsigned char *ptr,
|
||||||
void tr1001_clear_packets(void);
|
attribute_t *attr, attribute_value_t *value);
|
||||||
unsigned short tr1001_sstrength_value(unsigned int type);
|
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
583
apps/antelope/storage-cfs.c
Normal 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
76
apps/antelope/storage.h
Normal 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 */
|
|
@ -123,9 +123,9 @@ int
|
||||||
uint32_2_bytes(uint8_t *bytes, uint32_t var)
|
uint32_2_bytes(uint8_t *bytes, uint32_t var)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (0xFF000000 & var) bytes[i++] = var>>24;
|
if (0xFF000000 & var) bytes[i++] = (0xFF & var>>24);
|
||||||
if (0xFF0000 & var) bytes[i++] = var>>16;
|
if (0xFFFF0000 & var) bytes[i++] = (0xFF & var>>16);
|
||||||
if (0xFF00 & var) bytes[i++] = var>>8;
|
if (0xFFFFFF00 & var) bytes[i++] = (0xFF & var>>8);
|
||||||
bytes[i++] = 0xFF & var;
|
bytes[i++] = 0xFF & var;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
|
@ -136,10 +136,10 @@ serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t v
|
||||||
|
|
||||||
uint8_t *option = &buffer[i];
|
uint8_t *option = &buffer[i];
|
||||||
|
|
||||||
if (0xFF000000 & value) buffer[++i] = (uint8_t) (value>>24);
|
if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24);
|
||||||
if (0x00FF0000 & value) buffer[++i] = (uint8_t) (value>>16);
|
if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16);
|
||||||
if (0x0000FF00 & value) buffer[++i] = (uint8_t) (value>>8);
|
if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8);
|
||||||
if (0x000000FF & value) buffer[++i] = (uint8_t) value;
|
if ( value) buffer[++i] = (uint8_t) (0xFF & value);
|
||||||
|
|
||||||
i += set_option_header(number - current_number, i-start_i, option);
|
i += set_option_header(number - current_number, i-start_i, option);
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,7 @@ handle_incoming_data(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
block_size = REST_MAX_CHUNK_SIZE;
|
||||||
new_offset = 0;
|
new_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +305,7 @@ coap_set_rest_status(void *packet, unsigned int code)
|
||||||
/*- Server part ---------------------------------------------------------------------*/
|
/*- Server part ---------------------------------------------------------------------*/
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* The discover resource is automatically included for CoAP. */
|
/* 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
|
void
|
||||||
well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,10 +137,10 @@ serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t v
|
||||||
|
|
||||||
uint8_t *option = &buffer[i];
|
uint8_t *option = &buffer[i];
|
||||||
|
|
||||||
if (0xFF000000 & value) buffer[++i] = (uint8_t) (value>>24);
|
if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24);
|
||||||
if (0x00FF0000 & value) buffer[++i] = (uint8_t) (value>>16);
|
if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16);
|
||||||
if (0x0000FF00 & value) buffer[++i] = (uint8_t) (value>>8);
|
if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8);
|
||||||
if (0x000000FF & value) buffer[++i] = (uint8_t) value;
|
if (0xFFFFFFFF & value) buffer[++i] = (uint8_t) (0xFF & value);
|
||||||
|
|
||||||
i += set_option_header(number - current_number, i-start_i, option);
|
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_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_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_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;
|
((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);
|
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;
|
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;
|
if (num>0x0FFFFF) return 0;
|
||||||
|
|
||||||
((coap_packet_t *)packet)->block2_num = num;
|
((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;
|
((coap_packet_t *)packet)->block2_size = size;
|
||||||
|
|
||||||
SET_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK2);
|
SET_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK2);
|
||||||
|
|
|
@ -88,7 +88,7 @@ typedef struct unit_test {
|
||||||
*
|
*
|
||||||
* \param name The name of the 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.
|
* Mark the starting point of the unit test function.
|
||||||
|
@ -103,8 +103,7 @@ typedef struct unit_test {
|
||||||
*/
|
*/
|
||||||
#define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \
|
#define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \
|
||||||
unit_test_end: \
|
unit_test_end: \
|
||||||
utp->end = RTIMER_NOW(); \
|
utp->end = RTIMER_NOW()
|
||||||
return utp->result;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The test result is printed with a function that is selected by
|
* The test result is printed with a function that is selected by
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* 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);
|
e = find_neighbor(list, neighbor);
|
||||||
if(e != NULL) {
|
if(e != NULL) {
|
||||||
if(mac_status == MAC_TX_OK) {
|
if(mac_status == MAC_TX_OK) {
|
||||||
|
#if PHASE_DRIFT_CORRECT
|
||||||
|
e->drift = time-e->time;
|
||||||
|
#endif
|
||||||
e->time = time;
|
e->time = time;
|
||||||
}
|
}
|
||||||
/* If the neighbor didn't reply to us, it may have switched
|
/* 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);
|
rimeaddr_copy(&e->neighbor, neighbor);
|
||||||
e->time = time;
|
e->time = time;
|
||||||
|
#if PHASE_DRIFT_CORRECT
|
||||||
|
e->drift = 0;
|
||||||
|
#endif
|
||||||
e->noacks = 0;
|
e->noacks = 0;
|
||||||
list_push(*list->list, e);
|
list_push(*list->list, e);
|
||||||
}
|
}
|
||||||
|
@ -197,8 +202,27 @@ phase_wait(struct phase_list *list,
|
||||||
now = RTIMER_NOW();
|
now = RTIMER_NOW();
|
||||||
|
|
||||||
sync = (e == NULL) ? now : e->time;
|
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) {
|
if(wait < guard_time) {
|
||||||
wait += cycle_time;
|
wait += cycle_time;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +250,7 @@ phase_wait(struct phase_list *list,
|
||||||
expected = now + wait - guard_time;
|
expected = now + wait - guard_time;
|
||||||
if(!RTIMER_CLOCK_LT(expected, now)) {
|
if(!RTIMER_CLOCK_LT(expected, now)) {
|
||||||
/* Wait until the receiver is expected to be awake */
|
/* Wait until the receiver is expected to be awake */
|
||||||
|
// printf("%d ",expected%cycle_time); //for spreadsheet export
|
||||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected));
|
while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected));
|
||||||
}
|
}
|
||||||
return PHASE_SEND_NOW;
|
return PHASE_SEND_NOW;
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* 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 "lib/memb.h"
|
||||||
#include "net/netstack.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 {
|
||||||
struct phase *next;
|
struct phase *next;
|
||||||
rimeaddr_t neighbor;
|
rimeaddr_t neighbor;
|
||||||
rtimer_clock_t time;
|
rtimer_clock_t time;
|
||||||
|
#if PHASE_DRIFT_CORRECT
|
||||||
|
rtimer_clock_t drift;
|
||||||
|
#endif
|
||||||
uint8_t noacks;
|
uint8_t noacks;
|
||||||
struct timer noacks_timer;
|
struct timer noacks_timer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -630,8 +630,8 @@ tcpip_ipv6_output(void)
|
||||||
memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
|
memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
|
||||||
uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
|
uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
|
||||||
}
|
}
|
||||||
uip_len = 0;
|
|
||||||
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
|
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
|
||||||
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Send in parallel if we are running NUD (nbc state is either STALE,
|
/* Send in parallel if we are running NUD (nbc state is either STALE,
|
||||||
|
|
|
@ -825,13 +825,13 @@ CCIF void uip_send(const void *data, int len);
|
||||||
*
|
*
|
||||||
* \param rport The remote port number in network byte order.
|
* \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.
|
* if no connection could be allocated.
|
||||||
*/
|
*/
|
||||||
struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
|
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.
|
* \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)
|
} 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.
|
* 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.
|
* 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);
|
uip_ipaddr(&ipaddr1, 192,16,1,2);
|
||||||
if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
|
if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
|
||||||
printf("They are the same");
|
printf("They are the same");
|
||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
*
|
*
|
||||||
|
@ -1201,7 +1201,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
|
||||||
#endif /* UIP_HTONS */
|
#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
|
* This function is primarily used for converting variables from host
|
||||||
* byte order to network byte order. For converting constants to
|
* byte order to network byte order. For converting constants to
|
||||||
|
@ -1407,11 +1407,11 @@ struct uip_stats {
|
||||||
IP length, high byte. */
|
IP length, high byte. */
|
||||||
uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
|
uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
|
||||||
IP length, low byte. */
|
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. */
|
were IP fragments. */
|
||||||
uip_stats_t chkerr; /**< Number of packets dropped due to IP
|
uip_stats_t chkerr; /**< Number of packets dropped due to IP
|
||||||
checksum errors. */
|
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. */
|
were neither ICMP, UDP nor TCP. */
|
||||||
} ip; /**< IP statistics. */
|
} ip; /**< IP statistics. */
|
||||||
struct {
|
struct {
|
||||||
|
@ -1432,10 +1432,10 @@ struct uip_stats {
|
||||||
checksum. */
|
checksum. */
|
||||||
uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
|
uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
|
||||||
number. */
|
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 rexmit; /**< Number of retransmitted TCP segments. */
|
||||||
uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
|
uip_stats_t syndrop; /**< Number of dropped SYNs because too few
|
||||||
connections was avaliable. */
|
connections were available. */
|
||||||
uip_stats_t synrst; /**< Number of SYNs for closed ports,
|
uip_stats_t synrst; /**< Number of SYNs for closed ports,
|
||||||
triggering a RST. */
|
triggering a RST. */
|
||||||
} tcp; /**< TCP statistics. */
|
} tcp; /**< TCP statistics. */
|
||||||
|
|
|
@ -221,7 +221,7 @@ typedef unsigned char process_num_events_t;
|
||||||
*/
|
*/
|
||||||
#define PROCESS_PAUSE() do { \
|
#define PROCESS_PAUSE() do { \
|
||||||
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \
|
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \
|
||||||
PROCESS_WAIT_EVENT(); \
|
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/** @} end of protothread functions */
|
/** @} end of protothread functions */
|
||||||
|
|
|
@ -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.
|
/* 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) {
|
void clock_adjust_ticks(uint16_t howmany) {
|
||||||
|
// uint8_t sreg = SREG;cli();
|
||||||
count += howmany;
|
count += howmany;
|
||||||
scount += howmany;
|
howmany+= scount;
|
||||||
while(scount >= CLOCK_SECOND) {
|
while(howmany >= CLOCK_SECOND) {
|
||||||
scount -= CLOCK_SECOND;
|
howmany -= CLOCK_SECOND;
|
||||||
seconds++;
|
seconds++;
|
||||||
sleepseconds++;
|
sleepseconds++;
|
||||||
#if RADIOSTATS
|
#if RADIOSTATS
|
||||||
if (RF230_receive_on) radioontime += 1;
|
if (RF230_receive_on) radioontime += 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
scount = howmany;
|
||||||
|
// SREG=sreg;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
//SIGNAL(SIG_OUTPUT_COMPARE0)
|
//SIGNAL(SIG_OUTPUT_COMPARE0)
|
||||||
ISR(AVR_OUTPUT_COMPARE_INT)
|
ISR(AVR_OUTPUT_COMPARE_INT)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if(++scount == CLOCK_SECOND) {
|
if(++scount >= CLOCK_SECOND) {
|
||||||
scount = 0;
|
scount = 0;
|
||||||
seconds++;
|
seconds++;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +100,7 @@ ISR(AVR_OUTPUT_COMPARE_INT)
|
||||||
#endif
|
#endif
|
||||||
#if RADIOSTATS
|
#if RADIOSTATS
|
||||||
if (RF230_receive_on) {
|
if (RF230_receive_on) {
|
||||||
if (++rcount == CLOCK_SECOND) {
|
if (++rcount >= CLOCK_SECOND) {
|
||||||
rcount=0;
|
rcount=0;
|
||||||
radioontime++;
|
radioontime++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
static void *main_fiber;
|
static void *main_fiber;
|
||||||
|
|
||||||
#else /* _WIN32 || __CYGWIN__ */
|
#elif defined(__linux)
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -54,7 +54,7 @@ struct mtarch_t {
|
||||||
static ucontext_t main_context;
|
static ucontext_t main_context;
|
||||||
static ucontext_t *running_context;
|
static ucontext_t *running_context;
|
||||||
|
|
||||||
#endif /* _WIN32 || __CYGWIN__ */
|
#endif /* _WIN32 || __CYGWIN__ || __linux */
|
||||||
|
|
||||||
#include "mtarch.h"
|
#include "mtarch.h"
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ mtarch_start(struct mtarch_thread *thread,
|
||||||
|
|
||||||
thread->mt_thread = CreateFiber(0, (LPFIBER_START_ROUTINE)function, data);
|
thread->mt_thread = CreateFiber(0, (LPFIBER_START_ROUTINE)function, data);
|
||||||
|
|
||||||
#else /* _WIN32 || __CYGWIN__ */
|
#elif defined(__linux)
|
||||||
|
|
||||||
thread->mt_thread = malloc(sizeof(struct mtarch_t));
|
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,
|
makecontext(&((struct mtarch_t *)thread->mt_thread)->context,
|
||||||
(void (*)(void))function, 1, data);
|
(void (*)(void))function, 1, data);
|
||||||
|
|
||||||
#endif /* _WIN32 || __CYGWIN__ */
|
#endif /* _WIN32 || __CYGWIN__ || __linux */
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -128,11 +128,11 @@ mtarch_yield(void)
|
||||||
|
|
||||||
SwitchToFiber(main_fiber);
|
SwitchToFiber(main_fiber);
|
||||||
|
|
||||||
#else /* _WIN32 || __CYGWIN__ */
|
#elif defined(__linux)
|
||||||
|
|
||||||
swapcontext(running_context, &main_context);
|
swapcontext(running_context, &main_context);
|
||||||
|
|
||||||
#endif /* _WIN32 || __CYGWIN__ */
|
#endif /* _WIN32 || __CYGWIN__ || __linux */
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -142,13 +142,13 @@ mtarch_exec(struct mtarch_thread *thread)
|
||||||
|
|
||||||
SwitchToFiber(thread->mt_thread);
|
SwitchToFiber(thread->mt_thread);
|
||||||
|
|
||||||
#else /* _WIN32 || __CYGWIN__ */
|
#elif defined(__linux)
|
||||||
|
|
||||||
running_context = &((struct mtarch_t *)thread->mt_thread)->context;
|
running_context = &((struct mtarch_t *)thread->mt_thread)->context;
|
||||||
swapcontext(&main_context, running_context);
|
swapcontext(&main_context, running_context);
|
||||||
running_context = NULL;
|
running_context = NULL;
|
||||||
|
|
||||||
#endif /* _WIN32 || __CYGWIN__ */
|
#endif /* _WIN32 || __CYGWIN__ || __linux */
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -158,11 +158,11 @@ mtarch_stop(struct mtarch_thread *thread)
|
||||||
|
|
||||||
DeleteFiber(thread->mt_thread);
|
DeleteFiber(thread->mt_thread);
|
||||||
|
|
||||||
#else /* _WIN32 || __CYGWIN__ */
|
#elif defined(linux) || defined(__linux)
|
||||||
|
|
||||||
free(thread->mt_thread);
|
free(thread->mt_thread);
|
||||||
|
|
||||||
#endif /* _WIN32 || __CYGWIN__ */
|
#endif /* _WIN32 || __CYGWIN__ || __linux */
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
|
6
examples/antelope/netdb/Makefile
Normal file
6
examples/antelope/netdb/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
CONTIKI = ../../../
|
||||||
|
APPS += antelope
|
||||||
|
CFLAGS += -Wall -g -DPROJECT_CONF_H=\"project-conf.h\"
|
||||||
|
SMALL = 1
|
||||||
|
|
||||||
|
include $(CONTIKI)/Makefile.include
|
133
examples/antelope/netdb/netdb-client.c
Normal file
133
examples/antelope/netdb/netdb-client.c
Normal 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();
|
||||||
|
}
|
300
examples/antelope/netdb/netdb-server.c
Normal file
300
examples/antelope/netdb/netdb-server.c
Normal 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
271
examples/antelope/netdb/netdb.csc
Executable 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>
|
||||||
|
|
20
examples/antelope/netdb/project-conf.h
Normal file
20
examples/antelope/netdb/project-conf.h
Normal 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
|
8
examples/antelope/shell/Makefile
Normal file
8
examples/antelope/shell/Makefile
Normal 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
|
5
examples/antelope/shell/project-conf.h
Normal file
5
examples/antelope/shell/project-conf.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#undef QUEUEBUF_CONF_NUM
|
||||||
|
#define QUEUEBUF_CONF_NUM 4
|
||||||
|
|
||||||
|
#undef NETSTACK_CONF_RDC
|
||||||
|
#define NETSTACK_CONF_RDC nullrdc_driver
|
109
examples/antelope/shell/shell-db.c
Normal file
109
examples/antelope/shell/shell-db.c
Normal 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();
|
||||||
|
}
|
|
@ -34,23 +34,28 @@
|
||||||
|
|
||||||
#define SICSLOWPAN_CONF_FRAG 1
|
#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
|
#undef UIP_CONF_DS6_NBR_NBU
|
||||||
#define UIP_CONF_DS6_NBR_NBU 10
|
#define UIP_CONF_DS6_NBR_NBU 10
|
||||||
#undef UIP_CONF_DS6_ROUTE_NBU
|
#undef UIP_CONF_DS6_ROUTE_NBU
|
||||||
#define UIP_CONF_DS6_ROUTE_NBU 10
|
#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
|
#ifndef REST_MAX_CHUNK_SIZE
|
||||||
#define REST_MAX_CHUNK_SIZE 64
|
#define REST_MAX_CHUNK_SIZE 64
|
||||||
#endif
|
#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
|
#ifndef COAP_MAX_OPEN_TRANSACTIONS
|
||||||
#define COAP_MAX_OPEN_TRANSACTIONS 4
|
#define COAP_MAX_OPEN_TRANSACTIONS 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Must be <= open transaction number */
|
/* Must be <= open transaction number. */
|
||||||
#ifndef COAP_MAX_OBSERVERS
|
#ifndef COAP_MAX_OBSERVERS
|
||||||
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS
|
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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. */
|
/* 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
|
void
|
||||||
mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
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.
|
* 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.)
|
* (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
|
#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().
|
* 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.
|
* 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
|
void
|
||||||
polling_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
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().
|
* 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.
|
* 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
|
void
|
||||||
event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
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)
|
#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*/
|
/*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
|
void
|
||||||
led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
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 */
|
/* 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
|
void
|
||||||
toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
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)
|
#if defined (PLATFORM_HAS_LIGHT)
|
||||||
/* A simple getter example. Returns the reading from light sensor with a simple etag */
|
/* 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
|
void
|
||||||
light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
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)
|
#if defined (PLATFORM_HAS_BATTERY)
|
||||||
/* A simple getter example. Returns the reading from light sensor with a simple etag */
|
/* 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
|
void
|
||||||
battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -161,6 +161,10 @@ PROCESS_THREAD(udp_client_process, ev, data)
|
||||||
|
|
||||||
/* new connection with remote host */
|
/* new connection with remote host */
|
||||||
client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL);
|
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));
|
udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT));
|
||||||
|
|
||||||
PRINTF("Created a connection with the server ");
|
PRINTF("Created a connection with the server ");
|
||||||
|
|
|
@ -151,6 +151,10 @@ PROCESS_THREAD(udp_server_process, ev, data)
|
||||||
NETSTACK_MAC.off(1);
|
NETSTACK_MAC.off(1);
|
||||||
|
|
||||||
server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
|
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));
|
udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));
|
||||||
|
|
||||||
PRINTF("Created a server connection with remote address ");
|
PRINTF("Created a server connection with remote address ");
|
||||||
|
|
|
@ -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
|
|
|
@ -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 */
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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:$<
|
|
|
@ -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__ */
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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__ */
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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__ */
|
|
|
@ -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;
|
|
|
@ -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__ */
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -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__ */
|
|
|
@ -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);
|
|
|
@ -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__ */
|
|
|
@ -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);
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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__ */
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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__ */
|
|
|
@ -1,5 +0,0 @@
|
||||||
void
|
|
||||||
irq_init(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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__ */
|
|
|
@ -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);
|
|
|
@ -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__ */
|
|
|
@ -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);
|
|
|
@ -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__ */
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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__ */
|
|
|
@ -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__ */
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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__ */
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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);
|
|
|
@ -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__ */
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
|
@ -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__ */
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
|
@ -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__ */
|
|
|
@ -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);*/
|
|
||||||
}
|
|
|
@ -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__ */
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}*/
|
|
|
@ -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
Loading…
Reference in a new issue