diff --git a/apps/antelope/Makefile.antelope b/apps/antelope/Makefile.antelope new file mode 100644 index 000000000..a27a1f087 --- /dev/null +++ b/apps/antelope/Makefile.antelope @@ -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 = diff --git a/apps/antelope/antelope.c b/apps/antelope/antelope.c new file mode 100644 index 000000000..6a1860ccb --- /dev/null +++ b/apps/antelope/antelope.c @@ -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 + */ + +#include + +#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; +} diff --git a/platform/netsim/net/ethernode-rime.h b/apps/antelope/antelope.h similarity index 73% rename from platform/netsim/net/ethernode-rime.h rename to apps/antelope/antelope.h index 4ad34ced9..40f63303b 100644 --- a/platform/netsim/net/ethernode-rime.h +++ b/apps/antelope/antelope.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Swedish Institute of Computer Science. + * Copyright (c) 2010, Swedish Institute of Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,24 +25,29 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: ethernode-rime.h,v 1.1 2007/03/13 13:07:48 adamdunkels Exp $ */ /** * \file - * A brief description of what this file is. + * Declarations of the main Antelope functions. * \author - * Adam Dunkels + * Nicolas Tsiftes */ -#ifndef __ETHERNODE_RIME_H__ -#define __ETHERNODE_RIME_H__ +#ifndef DB_H +#define DB_H -#include "contiki.h" +#include "db-types.h" +#include "result.h" +#include "aql.h" -PROCESS_NAME(ethernode_rime_process); +typedef int (*db_output_function_t)(const char *, ...); -#endif /* __ETHERNODE_RIME_H__ */ +void db_init(void); +void db_set_output_function(db_output_function_t f); +const char *db_get_result_message(db_result_t code); +db_result_t db_print_header(db_handle_t *handle); +db_result_t db_print_tuple(db_handle_t *handle); +int db_processing(db_handle_t *handle); + +#endif /* DB_H */ diff --git a/apps/antelope/aql-adt.c b/apps/antelope/aql-adt.c new file mode 100644 index 000000000..3187f0a1c --- /dev/null +++ b/apps/antelope/aql-adt.c @@ -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 + */ + +#include + +#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; +} diff --git a/apps/antelope/aql-exec.c b/apps/antelope/aql-exec.c new file mode 100644 index 000000000..b838a720f --- /dev/null +++ b/apps/antelope/aql-exec.c @@ -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 + */ + +#include +#include +#include + +#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; +} diff --git a/apps/antelope/aql-lexer.c b/apps/antelope/aql-lexer.c new file mode 100644 index 000000000..0e98584ef --- /dev/null +++ b/apps/antelope/aql-lexer.c @@ -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 + */ + +#include "aql.h" + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/apps/antelope/aql-parser.c b/apps/antelope/aql-parser.c new file mode 100644 index 000000000..eecf31f8f --- /dev/null +++ b/apps/antelope/aql-parser.c @@ -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 + */ + +#include "attribute.h" +#include "db-options.h" +#include "index.h" +#include "aql.h" +#include "lvm.h" + +#include +#include +#include +#include +#include + +#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; +} diff --git a/apps/antelope/aql.h b/apps/antelope/aql.h new file mode 100644 index 000000000..ab29f7e5d --- /dev/null +++ b/apps/antelope/aql.h @@ -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 + */ + +#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 */ diff --git a/platform/netsim/contiki-esb.h b/apps/antelope/attribute.h similarity index 56% rename from platform/netsim/contiki-esb.h rename to apps/antelope/attribute.h index 48dd8447a..03278919e 100644 --- a/platform/netsim/contiki-esb.h +++ b/apps/antelope/attribute.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Swedish Institute of Computer Science. + * Copyright (c) 2010, Swedish Institute of Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,41 +25,65 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: contiki-esb.h,v 1.2 2006/10/10 15:58:31 adamdunkels Exp $ */ /** * \file - * A brief description of what this file is. + * Definitions for attributes. * \author - * Adam Dunkels + * Nicolas Tsiftes */ -#ifndef __CONTIKI_ESB_H__ -#define __CONTIKI_ESB_H__ +#ifndef ATTRIBUTE_H +#define ATTRIBUTE_H -#include "contiki.h" -#include "contiki-net.h" -#include "contiki-lib.h" -#include "dev/leds.h" +#include +#include -#include "dev/vib-sensor.h" -#include "dev/radio-sensor.h" -#include "dev/pir-sensor.h" -#include "dev/temperature-sensor.h" -#include "dev/button-sensor.h" +#include "lib/list.h" -#include "dev/lpm.h" -#include "dev/radio.h" +#include "db-options.h" -#include "dev/tr1001.h" -#include "dev/tr1001-drv.h" +typedef enum { + DOMAIN_UNSPECIFIED = 0, + DOMAIN_INT = 1, + DOMAIN_LONG = 2, + DOMAIN_STRING = 3, + DOMAIN_FLOAT = 4 +} domain_t; -#include "dev/beep.h" +#define ATTRIBUTE_FLAG_NO_STORE 0x1 +#define ATTRIBUTE_FLAG_INVALID 0x2 +#define ATTRIBUTE_FLAG_PRIMARY_KEY 0x4 +#define ATTRIBUTE_FLAG_UNIQUE 0x8 -#include "node-id.h" +struct attribute { + struct attribute *next; + void *index; + long aggregation_value; + uint8_t aggregator; + uint8_t domain; + uint8_t element_size; + uint8_t flags; + char name[ATTRIBUTE_NAME_LENGTH + 1]; +}; -#endif /* __CONTIKI_ESB_H__ */ +typedef struct attribute attribute_t; +typedef uint8_t attribute_id_t; + +struct attribute_value { + union { + int int_value; + long long_value; + unsigned char *string_value; + } u; + domain_t domain; +}; + +typedef struct attribute_value attribute_value_t; + +#define VALUE_LONG(value) (value)->u.long_value +#define VALUE_INT(value) (value)->u.int_value +#define VALUE_STRING(value) (value)->u.string_value + +#endif /* ATTRIBUTES_H */ diff --git a/apps/antelope/db-options.h b/apps/antelope/db-options.h new file mode 100644 index 000000000..7f4dce4cc --- /dev/null +++ b/apps/antelope/db-options.h @@ -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 + */ + +#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 */ diff --git a/platform/netsim/loader-arch.h b/apps/antelope/db-types.h similarity index 68% rename from platform/netsim/loader-arch.h rename to apps/antelope/db-types.h index 12e662cc7..bf2ad97ce 100644 --- a/platform/netsim/loader-arch.h +++ b/apps/antelope/db-types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Swedish Institute of Computer Science. + * Copyright (c) 2010, Swedish Institute of Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,24 +25,40 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: loader-arch.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ */ /** * \file - * Loader definitions for the netsim target + * . * \author - * Adam Dunkels + * Nicolas Tsiftes */ -#ifndef __LOADER_ARCH_H__ -#define __LOADER_ARCH_H__ +#ifndef DB_TYPES_H +#define DB_TYPES_H -#include "loader/dlloader.h" +enum db_result { + DB_FINISHED = 3, + DB_GOT_ROW = 2, + DB_OK = 1, + DB_LIMIT_ERROR = -1, + DB_ALLOCATION_ERROR = -2, + DB_STORAGE_ERROR = -3, + DB_PARSING_ERROR = -4, + DB_NAME_ERROR = -5, + DB_RELATIONAL_ERROR = -6, + DB_TYPE_ERROR = -7, + DB_IMPLEMENTATION_ERROR = -8, + DB_INDEX_ERROR = -9, + DB_BUSY_ERROR = -10, + DB_INCONSISTENCY_ERROR = -11, + DB_ARGUMENT_ERROR = -12 +}; -#define LOADER_LOAD(name, arg) dlloader_load(name, arg); +typedef enum db_result db_result_t; +typedef int db_storage_id_t; -#endif /* __LOADER_ARCH_H__ */ +#define DB_ERROR(result_code) ((result_code) < DB_OK) +#define DB_SUCCESS(result_code) !DB_ERROR(result_code) + +#endif /* !DB_TYPES_H */ diff --git a/platform/netsim/dev/lpm.c b/apps/antelope/debug.h similarity index 68% rename from platform/netsim/dev/lpm.c rename to apps/antelope/debug.h index 4de5f759f..edb39b8ed 100644 --- a/platform/netsim/dev/lpm.c +++ b/apps/antelope/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Swedish Institute of Computer Science. + * Copyright (c) 2010, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,28 +28,37 @@ * * This file is part of the Contiki operating system. * - * $Id: lpm.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * $Id: uip-debug.h,v 1.1 2010/04/30 13:20:57 joxe Exp $ */ - /** * \file - * A brief description of what this file is. - * \author - * Adam Dunkels + * A set of debugging macros. + * + * \author Nicolas Tsiftes + * Niclas Finne + * Joakim Eriksson */ -#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 -/*---------------------------------------------------------------------------*/ -void -lpm_on(void) -{ - printf("lpm_on()\n"); -} -/*---------------------------------------------------------------------------*/ -void -lpm_off(void) -{ - printf("lpm_off()\n"); -} -/*---------------------------------------------------------------------------*/ +#define ANNOTATE(...) printf(__VA_ARGS__) +#else +#define ANNOTATE(...) +#endif /* (DEBUG) & DEBUG_ANNOTATE */ + +#if (DEBUG) & DEBUG_PRINT +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif /* (DEBUG) & DEBUG_PRINT */ + +#endif diff --git a/apps/antelope/index-inline.c b/apps/antelope/index-inline.c new file mode 100644 index 000000000..2654ce5b5 --- /dev/null +++ b/apps/antelope/index-inline.c @@ -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 + */ + +#include +#include + +#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; +} diff --git a/apps/antelope/index-maxheap.c b/apps/antelope/index-maxheap.c new file mode 100644 index 000000000..bc1c8455a --- /dev/null +++ b/apps/antelope/index-maxheap.c @@ -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 + */ + +#include +#include +#include +#include + +#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); +} diff --git a/apps/antelope/index-memhash.c b/apps/antelope/index-memhash.c new file mode 100644 index 000000000..db3c3fbe3 --- /dev/null +++ b/apps/antelope/index-memhash.c @@ -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 + */ + +#include + +#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; +} diff --git a/apps/antelope/index.c b/apps/antelope/index.c new file mode 100644 index 000000000..be86bbbe7 --- /dev/null +++ b/apps/antelope/index.c @@ -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 + */ + +#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(); +} diff --git a/apps/antelope/index.h b/apps/antelope/index.h new file mode 100644 index 000000000..de7b28b36 --- /dev/null +++ b/apps/antelope/index.h @@ -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 + */ + +#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 */ diff --git a/apps/antelope/lvm.c b/apps/antelope/lvm.c new file mode 100644 index 000000000..4d05cc594 --- /dev/null +++ b/apps/antelope/lvm.c @@ -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 + */ + +#include +#include +#include +#include + +#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 diff --git a/apps/antelope/lvm.h b/apps/antelope/lvm.h new file mode 100644 index 000000000..0969501d9 --- /dev/null +++ b/apps/antelope/lvm.h @@ -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 + */ + +#ifndef LVM_H +#define LVM_H + +#include + +#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 */ diff --git a/apps/antelope/relation.c b/apps/antelope/relation.c new file mode 100644 index 000000000..6576f01ca --- /dev/null +++ b/apps/antelope/relation.c @@ -0,0 +1,1222 @@ +/* + * 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 for relational databases. + * \author + * Nicolas Tsiftes + */ + +#include +#include + +#include "lib/crc16.h" +#include "lib/list.h" +#include "lib/memb.h" + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +#include "db-options.h" +#include "index.h" +#include "lvm.h" +#include "relation.h" +#include "result.h" +#include "storage.h" +#include "aql.h" + +/* + * The source_dest_map structure is used for mapping the pointers to + * data in a source row and in the corresponding destination row. The + * structure is calculated just before processing a relational + * selection, and then used to improve the performance when processing + * each row. +*/ +struct source_dest_map { + attribute_t *from_attr; + attribute_t *to_attr; + unsigned from_offset; + unsigned to_offset; +}; + +static struct source_dest_map attr_map[AQL_ATTRIBUTE_LIMIT]; + +#if DB_FEATURE_JOIN +/* + * The source_map structure is used for mapping attributes to + * their offsets in rows. + */ +struct source_map { + attribute_t *attr; + unsigned char *from_ptr; +}; + +static struct source_map source_map[AQL_ATTRIBUTE_LIMIT]; +#endif /* DB_FEATURE_JOIN */ + +static unsigned char row[DB_MAX_ATTRIBUTES_PER_RELATION * DB_MAX_ELEMENT_SIZE]; +static unsigned char extra_row[DB_MAX_ATTRIBUTES_PER_RELATION * DB_MAX_ELEMENT_SIZE]; +static unsigned char result_row[AQL_ATTRIBUTE_LIMIT * DB_MAX_ELEMENT_SIZE]; +static unsigned char * const left_row = row; +static unsigned char * const right_row = extra_row; +static unsigned char * const join_row = result_row; + +LIST(relations); +MEMB(relations_memb, relation_t, DB_RELATION_POOL_SIZE); +MEMB(attributes_memb, attribute_t, DB_ATTRIBUTE_POOL_SIZE); + +static relation_t *relation_find(char *); +static attribute_t *attribute_find(relation_t *, char *); +static int get_attribute_value_offset(relation_t *, attribute_t *); +static void attribute_free(relation_t *, attribute_t *); +static void purge_relations(void); +static void relation_clear(relation_t *); +static relation_t *relation_allocate(void); +static void relation_free(relation_t *); + +static relation_t * +relation_find(char *name) +{ + relation_t *rel; + + for(rel = list_head(relations); rel != NULL; rel = rel->next) { + if(strcmp(rel->name, name) == 0) { + return rel; + } + } + + return NULL; +} + +static attribute_t * +attribute_find(relation_t *rel, char *name) +{ + attribute_t *attr; + + for(attr = list_head(rel->attributes); attr != NULL; attr = attr->next) { + if(strcmp(attr->name, name) == 0) { + return attr; + } + } + return NULL; +} + +static int +get_attribute_value_offset(relation_t *rel, attribute_t *attr) +{ + attribute_t *ptr; + int offset; + + for(offset = 0, ptr = list_head(rel->attributes); + ptr != NULL; + ptr = ptr->next) { + if(ptr == attr) { + return offset; + } + offset += ptr->element_size; + } + + return -1; +} + +static void +attribute_free(relation_t *rel, attribute_t *attr) +{ + if(attr->index != NULL) { + index_release(attr->index); + } + memb_free(&attributes_memb, attr); + rel->attribute_count--; +} + +static void +purge_relations(void) +{ + relation_t *rel; + relation_t *next; + + for(rel = list_head(relations); rel != NULL;) { + next = rel->next; + if(rel->references == 0) { + relation_free(rel); + } + rel = next; + } +} + +static void +relation_clear(relation_t *rel) +{ + memset(rel, 0, sizeof(*rel)); + rel->tuple_storage = -1; + rel->cardinality = INVALID_TUPLE; + rel->dir = DB_STORAGE; + LIST_STRUCT_INIT(rel, attributes); +} + +static relation_t * +relation_allocate(void) +{ + relation_t *rel; + + rel = memb_alloc(&relations_memb); + if(rel == NULL) { + purge_relations(); + rel = memb_alloc(&relations_memb); + if(rel == NULL) { + PRINTF("DB: Failed to allocate a relation\n"); + return NULL; + } + } + + relation_clear(rel); + return rel; +} + +static void +relation_free(relation_t *rel) +{ + attribute_t *attr; + + while((attr = list_pop(rel->attributes)) != NULL) { + attribute_free(rel, attr); + } + + list_remove(relations, rel); + memb_free(&relations_memb, rel); +} + +db_result_t +relation_init(void) +{ + list_init(relations); + memb_init(&relations_memb); + memb_init(&attributes_memb); + + return DB_OK; +} + +relation_t * +relation_load(char *name) +{ + relation_t *rel; + + rel = relation_find(name); + if(rel != NULL) { + rel->references++; + goto end; + } + + rel = relation_allocate(); + if(rel == NULL) { + return NULL; + } + + if(DB_ERROR(storage_get_relation(rel, name))) { + memb_free(&relations_memb, rel); + return NULL; + } + + memcpy(rel->name, name, sizeof(rel->name)); + rel->name[sizeof(rel->name) - 1] = '\0'; + rel->references = 1; + list_add(relations, rel); + +end: + if(rel->dir == DB_STORAGE && DB_ERROR(storage_load(rel))) { + relation_release(rel); + return NULL; + } + + return rel; +} + +db_result_t +relation_release(relation_t *rel) +{ + if(rel->references > 0) { + rel->references--; + } + + if(rel->references == 0) { + storage_unload(rel); + } + + return DB_OK; +} + +relation_t * +relation_create(char *name, db_direction_t dir) +{ + relation_t old_rel; + relation_t *rel; + + if(*name != '\0') { + relation_clear(&old_rel); + + if(storage_get_relation(&old_rel, name) == DB_OK) { + /* Reject a creation request if the relation already exists. */ + PRINTF("DB: Attempted to create a relation that already exists (%s)\n", + name); + return NULL; + } + + rel = relation_allocate(); + if(rel == NULL) { + return NULL; + } + + rel->cardinality = 0; + + strncpy(rel->name, name, sizeof(rel->name) - 1); + rel->name[sizeof(rel->name) - 1] = '\0'; + rel->dir = dir; + + if(dir == DB_STORAGE) { + storage_drop_relation(rel, 1); + + if(storage_put_relation(rel) == DB_OK) { + list_add(relations, rel); + return rel; + } + memb_free(&relations_memb, rel); + } else { + list_add(relations, rel); + return rel; + } + } + + return NULL; +} + +#if DB_FEATURE_REMOVE +db_result_t +relation_rename(char *old_name, char *new_name) +{ + if(DB_ERROR(relation_remove(new_name, 0)) || + DB_ERROR(storage_rename_relation(old_name, new_name))) { + return DB_STORAGE_ERROR; + } + + return DB_OK; +} +#endif /* DB_FEATURE_REMOVE */ + +attribute_t * +relation_attribute_add(relation_t *rel, db_direction_t dir, char *name, + domain_t domain, size_t element_size) +{ + attribute_t *attribute; + tuple_id_t cardinality; + + cardinality = relation_cardinality(rel); + if(cardinality != INVALID_TUPLE && cardinality > 0) { + PRINTF("DB: Attempt to create an attribute in a non-empty relation\n"); + return NULL; + } + + if(element_size == 0 || element_size > DB_MAX_ELEMENT_SIZE) { + PRINTF("DB: Unacceptable element size: %u\n", element_size); + return NULL; + } + + attribute = memb_alloc(&attributes_memb); + if(attribute == NULL) { + PRINTF("DB: Failed to allocate attribute \"%s\"!\n", name); + return NULL; + } + + strncpy(attribute->name, name, sizeof(attribute->name) - 1); + attribute->name[sizeof(attribute->name) - 1] = '\0'; + attribute->domain = domain; + attribute->element_size = element_size; + attribute->aggregator = 0; + attribute->index = NULL; + attribute->flags = 0 /*ATTRIBUTE_FLAG_UNIQUE*/; + + rel->row_length += element_size; + + list_add(rel->attributes, attribute); + rel->attribute_count++; + + if(dir == DB_STORAGE) { + if(DB_ERROR(storage_put_attribute(rel, attribute))) { + PRINTF("DB: Failed to store attribute %s\n", attribute->name); + memb_free(&attributes_memb, attribute); + return NULL; + } + } else { + index_load(rel, attribute); + } + + return attribute; +} + +attribute_t * +relation_attribute_get(relation_t *rel, char *name) +{ + attribute_t *attr; + + attr = attribute_find(rel, name); + if(attr != NULL && !(attr->flags & ATTRIBUTE_FLAG_INVALID)) { + return attr; + } + + return NULL; +} + +db_result_t +relation_attribute_remove(relation_t *rel, char *name) +{ + /* Not implemented completely. */ + return DB_IMPLEMENTATION_ERROR; +#if 0 + attribute_t *attr; + + if(rel->references > 1) { + return DB_BUSY_ERROR; + } + + attr = relation_attribute_get(rel, name); + if(attr == NULL) { + return DB_NAME_ERROR; + } + + list_remove(rel->attributes, attr); + attribute_free(rel, attr); + return DB_OK; +#endif +} + +db_result_t +relation_get_value(relation_t *rel, attribute_t *attr, + unsigned char *row_ptr, attribute_value_t *value) +{ + int offset; + unsigned char *from_ptr; + + offset = get_attribute_value_offset(rel, attr); + if(offset < 0) { + return DB_IMPLEMENTATION_ERROR; + } + from_ptr = row_ptr + offset; + + return db_phy_to_value(value, attr, from_ptr); +} + +db_result_t +relation_set_primary_key(relation_t *rel, char *name) +{ + attribute_t *attribute; + + attribute = relation_attribute_get(rel, name); + if(attribute == NULL) { + return DB_NAME_ERROR; + } + + attribute->flags = ATTRIBUTE_FLAG_PRIMARY_KEY; + PRINTF("DB: New primary key: %s\n", attribute->name); + + return DB_OK; +} + +db_result_t +relation_remove(char *name, int remove_tuples) +{ + relation_t *rel; + db_result_t result; + + rel = relation_load(name); + if(rel == NULL) { + /* + * Attempt to remove an inexistent relation. To allow for this + * operation to be used for setting up repeatable tests and + * experiments, we do not signal an error. + */ + return DB_OK; + } + + if(rel->references > 1) { + return DB_BUSY_ERROR; + } + + result = storage_drop_relation(rel, remove_tuples); + relation_free(rel); + return result; +} + +db_result_t +relation_insert(relation_t *rel, attribute_value_t *values) +{ + size_t size; + attribute_t *attr; + storage_row_t record; + unsigned char *ptr; + attribute_value_t *value; + db_result_t result; + + value = values; + + size = rel->row_length; + PRINTF("DB: Relation %s has a record size of %d bytes\n", + rel->name, (int)size); + ptr = record = alloca(size); + + PRINTF("DB: Insert ("); + + for(attr = list_head(rel->attributes); attr != NULL; attr = attr->next, value++) { + /* Verify that the value is in the expected domain. An exception + to this rule is that INT may be promoted to LONG. */ + if(attr->domain != value->domain && + !(attr->domain == DOMAIN_LONG && value->domain == DOMAIN_INT)) { + PRINTF("DB: The value domain %d does not match the domain %d of attribute %s\n", + value->domain, attr->domain, attr->name); + return DB_RELATIONAL_ERROR; + } + + /* Set the data area for removed attributes to 0. */ + if(attr->flags & ATTRIBUTE_FLAG_INVALID) { + memset(ptr, 0, attr->element_size); + ptr += attr->element_size; + continue; + } + + result = db_value_to_phy((unsigned char *)ptr, attr, value); + if(DB_ERROR(result)) { + return result; + } + +#if DEBUG + switch(attr->domain) { + case DOMAIN_INT: + PRINTF("%s=%d", attr->name, VALUE_INT(value)); + break; + case DOMAIN_LONG: + PRINTF("%s=%ld", attr->name, VALUE_LONG(value)); + break; + case DOMAIN_STRING: + PRINTF("%s='%s", attr->name, VALUE_STRING(value)); + break; + default: + PRINTF(")\nDB: Unhandled attribute domain: %d\n", attr->domain); + return DB_TYPE_ERROR; + } + + if(attr->next != NULL) { + PRINTF(", "); + } +#endif /* DEBUG */ + + ptr += attr->element_size; + if(attr->index != NULL) { + if(DB_ERROR(index_insert(attr->index, value, rel->next_row))) { + return DB_INDEX_ERROR; + } + } + } + + PRINTF(")\n"); + + rel->cardinality++; + rel->next_row++; + return storage_put_row(rel, record); +} + +static void +aggregate(attribute_t *attr, attribute_value_t *value) +{ + long long_value; + + switch(value->domain) { + case DOMAIN_INT: + long_value = VALUE_INT(value); + break; + case DOMAIN_LONG: + long_value = VALUE_LONG(value); + break; + default: + return; + } + + switch(attr->aggregator) { + case AQL_COUNT: + attr->aggregation_value++; + break; + case AQL_SUM: + attr->aggregation_value += long_value; + break; + case AQL_MEAN: + break; + case AQL_MEDIAN: + break; + case AQL_MAX: + if(long_value > attr->aggregation_value) { + attr->aggregation_value = long_value; + } + break; + case AQL_MIN: + if(long_value < attr->aggregation_value) { + attr->aggregation_value = long_value; + } + break; + default: + break; + } +} + +static db_result_t +generate_attribute_map(struct source_dest_map *attr_map, unsigned attribute_count, + relation_t *from_rel, relation_t *to_rel, + unsigned char *from_row, unsigned char *to_row) +{ + attribute_t *from_attr; + attribute_t *to_attr; + unsigned size_sum; + struct source_dest_map *attr_map_ptr; + int offset; + + attr_map_ptr = attr_map; + for(size_sum = 0, to_attr = list_head(to_rel->attributes); + to_attr != NULL; + to_attr = to_attr->next) { + from_attr = attribute_find(from_rel, to_attr->name); + if(from_attr == NULL) { + PRINTF("DB: Invalid attribute in the result relation: %s\n", + to_attr->name); + return DB_NAME_ERROR; + } + + attr_map_ptr->from_attr = from_attr; + attr_map_ptr->to_attr = to_attr; + offset = get_attribute_value_offset(from_rel, from_attr); + if(offset < 0) { + return DB_IMPLEMENTATION_ERROR; + } + attr_map_ptr->from_offset = offset; + attr_map_ptr->to_offset = size_sum; + + size_sum += to_attr->element_size; + attr_map_ptr++; + } + + return DB_OK; +} + +static void +select_index(db_handle_t *handle, lvm_instance_t *lvm_instance) +{ + index_t *index; + attribute_t *attr; + operand_value_t min; + operand_value_t max; + attribute_value_t av_min; + attribute_value_t av_max; + long range; + unsigned long min_range; + + index = NULL; + min_range = ULONG_MAX; + + /* Find all indexed and derived attributes, and select the index of + the attribute with the smallest range. */ + for(attr = list_head(handle->rel->attributes); + attr != NULL; + attr = attr->next) { + if(attr->index != NULL && + !LVM_ERROR(lvm_get_derived_range(lvm_instance, attr->name, &min, &max))) { + range = (unsigned long)max.l - (unsigned long)min.l; + PRINTF("DB: The search range for attribute \"%s\" comprises %ld values\n", + attr->name, range + 1); + + if(range <= min_range) { + index = attr->index; + av_min.domain = av_max.domain = DOMAIN_INT; + VALUE_LONG(&av_min) = min.l; + VALUE_LONG(&av_max) = max.l; + } + } + } + + if(index != NULL) { + /* We found a suitable index; get an iterator for it. */ + if(index_get_iterator(&handle->index_iterator, index, + &av_min, &av_max) == DB_OK) { + handle->flags |= DB_HANDLE_FLAG_SEARCH_INDEX; + } + } +} + +static db_result_t +generate_selection_result(db_handle_t *handle, relation_t *rel, aql_adt_t *adt) +{ + relation_t *result_rel; + unsigned attribute_count; + attribute_t *attr; + + result_rel = handle->result_rel; + + handle->current_row = 0; + handle->ncolumns = 0; + handle->tuple_id = 0; + for(attr = list_head(result_rel->attributes); attr != NULL; attr = attr->next) { + if(attr->flags & ATTRIBUTE_FLAG_NO_STORE) { + continue; + } + handle->ncolumns++; + } + handle->tuple = (tuple_t)result_row; + + attribute_count = result_rel->attribute_count; + if(DB_ERROR(generate_attribute_map(attr_map, attribute_count, rel, result_rel, row, result_row))) { + return DB_IMPLEMENTATION_ERROR; + } + + if(adt->lvm_instance != NULL) { + /* Try to establish acceptable ranges for the attribute values. */ + if(!LVM_ERROR(lvm_derive(adt->lvm_instance))) { + select_index(handle, adt->lvm_instance); + } + } + + handle->flags |= DB_HANDLE_FLAG_PROCESSING; + + return DB_OK; +} + +#if DB_FEATURE_REMOVE +db_result_t +relation_process_remove(void *handle_ptr) +{ + db_handle_t *handle; + aql_adt_t *adt; + db_result_t result; + + handle = (db_handle_t *)handle_ptr; + adt = handle->adt; + + result = relation_process_select(handle_ptr); + if(result == DB_FINISHED) { + PRINTF("DB: Finished removing tuples. Overwriting relation %s with the result\n", + adt->relations[1]); + relation_release(handle->rel); + relation_rename(adt->relations[0], adt->relations[1]); + } + + return result; +} +#endif + +db_result_t +relation_process_select(void *handle_ptr) +{ + db_handle_t *handle; + aql_adt_t *adt; + db_result_t result; + unsigned attribute_count; + struct source_dest_map *attr_map_ptr, *attr_map_end; + attribute_t *result_attr; + unsigned char *from_ptr; + unsigned char *to_ptr; + operand_value_t operand_value; + uint8_t intbuf[2]; + attribute_value_t value; + lvm_status_t wanted_result; + + handle = (db_handle_t *)handle_ptr; + adt = (aql_adt_t *)handle->adt; + + attribute_count = handle->result_rel->attribute_count; + attr_map_end = attr_map + attribute_count; + + if(handle->flags & DB_HANDLE_FLAG_SEARCH_INDEX) { + handle->tuple_id = index_get_next(&handle->index_iterator); + if(handle->tuple_id == INVALID_TUPLE) { + PRINTF("DB: An attribute value could not be found in the index\n"); + if(handle->index_iterator.next_item_no == 0) { + return DB_INDEX_ERROR; + } + + if(adt->flags & AQL_FLAG_AGGREGATE) { + goto end_aggregation; + } + + return DB_FINISHED; + } + } + + /* Put the tuples fulfilling the given condition into a new relation. + The tuples may be projected. */ + result = storage_get_row(handle->rel, &handle->tuple_id, row); + handle->tuple_id++; + if(DB_ERROR(result)) { + PRINTF("DB: Failed to get a row in relation %s!\n", handle->rel->name); + return result; + } else if(result == DB_FINISHED) { + if(AQL_GET_FLAGS(adt) & AQL_FLAG_AGGREGATE) { + goto end_aggregation; + } + return DB_FINISHED; + } + + /* Process the attributes in the result relation. */ + for(attr_map_ptr = attr_map; attr_map_ptr < attr_map_end; attr_map_ptr++) { + from_ptr = row + attr_map_ptr->from_offset; + result_attr = attr_map_ptr->to_attr; + + /* Update the internal state of the PLE. */ + if(result_attr->domain == DOMAIN_INT) { + operand_value.l = from_ptr[0] << 8 | from_ptr[1]; + lvm_set_variable_value(result_attr->name, operand_value); + } else if(result_attr->domain == DOMAIN_LONG) { + operand_value.l = (uint32_t)from_ptr[0] << 24 | + (uint32_t)from_ptr[1] << 16 | + (uint32_t)from_ptr[2] << 8 | + from_ptr[3]; + lvm_set_variable_value(result_attr->name, operand_value); + } + + if(result_attr->flags & ATTRIBUTE_FLAG_NO_STORE) { + /* The attribute is used just for the predicate, + so do not copy the current value into the result. */ + continue; + } + + if(!(AQL_GET_FLAGS(adt) & AQL_FLAG_AGGREGATE)) { + /* No aggregators. Copy the original value into the resulting tuple. */ + memcpy(result_row + attr_map_ptr->to_offset, from_ptr, + result_attr->element_size); + } + } + + wanted_result = TRUE; + if(AQL_GET_FLAGS(adt) & AQL_FLAG_INVERSE_LOGIC) { + wanted_result = FALSE; + } + + /* Check whether the given predicate is true for this tuple. */ + if(adt->lvm_instance == NULL || + lvm_execute(adt->lvm_instance) == wanted_result) { + if(AQL_GET_FLAGS(adt) & AQL_FLAG_AGGREGATE) { + for(attr_map_ptr = attr_map; attr_map_ptr < attr_map_end; attr_map_ptr++) { + from_ptr = row + attr_map_ptr->from_offset; + result = db_phy_to_value(&value, attr_map_ptr->to_attr, from_ptr); + if(DB_ERROR(result)) { + return result; + } + aggregate(attr_map_ptr->to_attr, &value); + } + } else { + if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) { + if(DB_ERROR(storage_put_row(handle->result_rel, result_row))) { + PRINTF("DB: Failed to store a row in the result relation!\n"); + return DB_STORAGE_ERROR; + } + } + handle->current_row++; + return DB_GOT_ROW; + } + } + + return DB_OK; + +end_aggregation: + /* Generate aggregated result if requested. */ + for(attr_map_ptr = attr_map; attr_map_ptr < attr_map_end; attr_map_ptr++) { + result_attr = attr_map_ptr->to_attr; + to_ptr = result_row + attr_map_ptr->to_offset; + + intbuf[0] = result_attr->aggregation_value >> 8; + intbuf[1] = result_attr->aggregation_value & 0xff; + from_ptr = intbuf; + memcpy(to_ptr, from_ptr, result_attr->element_size); + } + + if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) { + if(DB_ERROR(storage_put_row(handle->result_rel, result_row))) { + PRINTF("DB: Failed to store a row in the result relation!\n"); + return DB_STORAGE_ERROR; + } + } + + handle->current_row = 1; + AQL_GET_FLAGS(adt) &= ~AQL_FLAG_AGGREGATE; /* Stop the aggregation. */ + + return DB_GOT_ROW; +} + +db_result_t +relation_select(void *handle_ptr, relation_t *rel, void *adt_ptr) +{ + aql_adt_t *adt; + db_handle_t *handle; + char *name; + db_direction_t dir; + char *attribute_name; + attribute_t *attr; + int i; + int normal_attributes; + + adt = (aql_adt_t *)adt_ptr; + + handle = (db_handle_t *)handle_ptr; + handle->rel = rel; + handle->adt = adt; + + if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) { + name = adt->relations[0]; + dir = DB_STORAGE; + } else { + name = RESULT_RELATION; + dir = DB_MEMORY; + } + relation_remove(name, 1); + relation_create(name, dir); + handle->result_rel = relation_load(name); + + if(handle->result_rel == NULL) { + PRINTF("DB: Failed to load a relation for the query result\n"); + return DB_ALLOCATION_ERROR; + } + + for(i = normal_attributes = 0; i < AQL_ATTRIBUTE_COUNT(adt); i++) { + attribute_name = adt->attributes[i].name; + + attr = relation_attribute_get(rel, attribute_name); + if(attr == NULL) { + PRINTF("DB: Select for invalid attribute %s in relation %s!\n", + attribute_name, rel->name); + return DB_NAME_ERROR; + } + + PRINTF("DB: Found attribute %s in relation %s\n", + attribute_name, rel->name); + + attr = relation_attribute_add(handle->result_rel, dir, + attribute_name, + adt->aggregators[i] ? DOMAIN_INT : attr->domain, + attr->element_size); + if(attr == NULL) { + PRINTF("DB: Failed to add a result attribute\n"); + relation_release(handle->result_rel); + return DB_ALLOCATION_ERROR; + } + + attr->aggregator = adt->aggregators[i]; + switch(attr->aggregator) { + case AQL_NONE: + if(!(adt->attributes[i].flags & ATTRIBUTE_FLAG_NO_STORE)) { + /* Only count attributes projected into the result set. */ + normal_attributes++; + } + break; + case AQL_MAX: + attr->aggregation_value = LONG_MIN; + break; + case AQL_MIN: + attr->aggregation_value = LONG_MAX; + break; + default: + attr->aggregation_value = 0; + break; + } + + attr->flags = adt->attributes[i].flags; + } + + /* Preclude mixes of normal attributes and aggregated ones in + selection results. */ + if(normal_attributes > 0 && + handle->result_rel->attribute_count > normal_attributes) { + return DB_RELATIONAL_ERROR; + } + + return generate_selection_result(handle, rel, adt); +} + +#if DB_FEATURE_JOIN +db_result_t +relation_process_join(void *handle_ptr) +{ + db_handle_t *handle; + db_result_t result; + relation_t *left_rel; + relation_t *right_rel; + relation_t *join_rel; + unsigned char *join_next_attribute_ptr; + size_t element_size; + tuple_id_t right_tuple_id; + attribute_value_t value; + int i; + + handle = (db_handle_t *)handle_ptr; + left_rel = handle->left_rel; + right_rel = handle->right_rel; + join_rel = handle->join_rel; + + if(!(handle->flags & DB_HANDLE_FLAG_INDEX_STEP)) { + goto inner_loop; + } + + /* Equi-join for indexed attributes only. In the outer loop, we iterate over + each tuple in the left relation. */ + for(handle->tuple_id = 0;; handle->tuple_id++) { + result = storage_get_row(left_rel, &handle->tuple_id, left_row); + if(DB_ERROR(result)) { + PRINTF("DB: Failed to get a row in left relation %s!\n", left_rel->name); + return result; + } else if(result == DB_FINISHED) { + return DB_FINISHED; + } + + if(DB_ERROR(relation_get_value(left_rel, handle->left_join_attr, left_row, &value))) { + PRINTF("DB: Failed to get a value of the attribute \"%s\" to join on\n", + handle->left_join_attr->name); + return DB_IMPLEMENTATION_ERROR; + } + + if(DB_ERROR(index_get_iterator(&handle->index_iterator, + handle->right_join_attr->index, + &value, &value))) { + PRINTF("DB: Failed to get an index iterator\n"); + return DB_INDEX_ERROR; + } + handle->flags &= ~DB_HANDLE_FLAG_INDEX_STEP; + + /* In the inner loop, we iterate over all rows with a matching value for the + join attribute. The index component provides an iterator for this purpose. */ +inner_loop: + for(;;) { + /* Get all rows matching the attribute value in the right relation. */ + right_tuple_id = index_get_next(&handle->index_iterator); + if(right_tuple_id == INVALID_TUPLE) { + /* Exclude this row from the left relation in the result, + and step to the next value in the index iteration. */ + handle->flags |= DB_HANDLE_FLAG_INDEX_STEP; + break; + } + + result = storage_get_row(right_rel, &right_tuple_id, right_row); + if(DB_ERROR(result)) { + PRINTF("DB: Failed to get a row in right relation %s!\n", right_rel->name); + return result; + } else if(result == DB_FINISHED) { + PRINTF("DB: The index refers to an invalid row: %lu\n", + (unsigned long)right_tuple_id); + return DB_IMPLEMENTATION_ERROR; + } + + /* Use the source attribute map to fill in the physical representation + of the resulting tuple. */ + join_next_attribute_ptr = join_row; + + for(i = 0; i < join_rel->attribute_count; i++) { + element_size = source_map[i].attr->element_size; + + memcpy(join_next_attribute_ptr, source_map[i].from_ptr, element_size); + join_next_attribute_ptr += element_size; + } + + if(((aql_adt_t *)handle->adt)->flags & AQL_FLAG_ASSIGN) { + if(DB_ERROR(storage_put_row(join_rel, join_row))) { + return DB_STORAGE_ERROR; + } + } + + handle->current_row++; + return DB_GOT_ROW; + } + } + + return DB_OK; +} + +static db_result_t +generate_join_result(db_handle_t *handle) +{ + relation_t *left_rel; + relation_t *right_rel; + relation_t *join_rel; + attribute_t *attr; + attribute_t *result_attr; + struct source_map *source_pair; + int i; + int offset; + unsigned char *from_ptr; + + handle->tuple = (tuple_t)join_row; + handle->tuple_id = 0; + + left_rel = handle->left_rel; + right_rel = handle->right_rel; + join_rel = handle->join_rel; + + /* Generate a map over the source attributes for each + attribute in the join relation. */ + for(i = 0, result_attr = list_head(join_rel->attributes); + result_attr != NULL; + result_attr = result_attr->next, i++) { + source_pair = &source_map[i]; + attr = attribute_find(left_rel, result_attr->name); + if(attr != NULL) { + offset = get_attribute_value_offset(left_rel, attr); + from_ptr = left_row + offset; + } else if((attr = attribute_find(right_rel, result_attr->name)) != NULL) { + offset = get_attribute_value_offset(right_rel, attr); + from_ptr = right_row + offset; + } else { + PRINTF("DB: The attribute %s could not be found\n", result_attr->name); + return DB_NAME_ERROR; + } + + if(offset < 0) { + PRINTF("DB: Unable to retrieve attribute values for the JOIN result\n"); + return DB_IMPLEMENTATION_ERROR; + } + + source_pair->attr = attr; + source_pair->from_ptr = from_ptr; + } + + handle->flags |= DB_HANDLE_FLAG_PROCESSING; + + return DB_OK; +} + +db_result_t +relation_join(void *query_result, void *adt_ptr) +{ + aql_adt_t *adt; + db_handle_t *handle; + relation_t *left_rel; + relation_t *right_rel; + relation_t *join_rel; + char *name; + db_direction_t dir; + int i; + char *attribute_name; + attribute_t *attr; + + adt = (aql_adt_t *)adt_ptr; + + handle = (db_handle_t *)query_result; + handle->current_row = 0; + handle->ncolumns = 0; + handle->adt = adt; + handle->flags = DB_HANDLE_FLAG_INDEX_STEP; + + if(AQL_GET_FLAGS(adt) & AQL_FLAG_ASSIGN) { + name = adt->relations[0]; + dir = DB_STORAGE; + } else { + name = RESULT_RELATION; + dir = DB_MEMORY; + } + relation_remove(name, 1); + relation_create(name, dir); + join_rel = relation_load(name); + handle->result_rel = join_rel; + + if(join_rel == NULL) { + PRINTF("DB: Failed to create a join relation!\n"); + return DB_ALLOCATION_ERROR; + } + + handle->join_rel = handle->result_rel = join_rel; + left_rel = handle->left_rel; + right_rel = handle->right_rel; + + handle->left_join_attr = relation_attribute_get(left_rel, adt->attributes[0].name); + handle->right_join_attr = relation_attribute_get(right_rel, adt->attributes[0].name); + if(handle->left_join_attr == NULL || handle->right_join_attr == NULL) { + PRINTF("DB: The attribute (\"%s\") to join on does not exist in both relations\n", + adt->attributes[0].name); + return DB_RELATIONAL_ERROR; + } + + if(!index_exists(handle->right_join_attr)) { + PRINTF("DB: The attribute to join on is not indexed\n"); + return DB_INDEX_ERROR; + } + + /* + * Define the resulting relation. We start from 1 when counting attributes + * because the first attribute is only the one to join, and is not included + * by default in the projected attributes. + */ + for(i = 1; i < AQL_ATTRIBUTE_COUNT(adt); i++) { + attribute_name = adt->attributes[i].name; + attr = relation_attribute_get(left_rel, attribute_name); + if(attr == NULL) { + attr = relation_attribute_get(right_rel, attribute_name); + if(attr == NULL) { + PRINTF("DB: The projection attribute \"%s\" does not exist in any of the relations to join\n", + attribute_name); + return DB_RELATIONAL_ERROR; + } + } + + if(relation_attribute_add(join_rel, dir, attr->name, attr->domain, + attr->element_size) == NULL) { + PRINTF("DB: Failed to add an attribute to the join relation\n"); + return DB_ALLOCATION_ERROR; + } + + handle->ncolumns++; + } + + return generate_join_result(handle); +} +#endif /* DB_FEATURE_JOIN */ + +tuple_id_t +relation_cardinality(relation_t *rel) +{ + tuple_id_t tuple_id; + + + if(rel->cardinality != INVALID_TUPLE) { + return rel->cardinality; + } + + if(!RELATION_HAS_TUPLES(rel)) { + return 0; + } + + if(DB_ERROR(storage_get_row_amount(rel, &tuple_id))) { + return INVALID_TUPLE; + } + + rel->cardinality = tuple_id; + + PRINTF("DB: Relation %s has cardinality %lu\n", rel->name, + (unsigned long)tuple_id); + + return tuple_id; +} diff --git a/apps/antelope/relation.h b/apps/antelope/relation.h new file mode 100644 index 000000000..a881e6e07 --- /dev/null +++ b/apps/antelope/relation.h @@ -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 + */ + +#ifndef RELATION_H +#define RELATION_H + +#include +#include + +#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 */ diff --git a/apps/antelope/result.c b/apps/antelope/result.c new file mode 100644 index 000000000..e4e9fdf55 --- /dev/null +++ b/apps/antelope/result.c @@ -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 + */ + +#include + +#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; +} diff --git a/platform/netsim/dev/tr1001.h b/apps/antelope/result.h similarity index 53% rename from platform/netsim/dev/tr1001.h rename to apps/antelope/result.h index 2b9325bb1..0788b77f6 100644 --- a/platform/netsim/dev/tr1001.h +++ b/apps/antelope/result.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Swedish Institute of Computer Science. + * Copyright (c) 2010, Swedish Institute of Computer Science * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,41 +25,56 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: tr1001.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ */ /** * \file - * A brief description of what this file is. + * Declarations for the result acquisition API. * \author - * Adam Dunkels + * Nicolas Tsiftes */ -#ifndef __TR1001_H__ -#define __TR1001_H__ +#ifndef RESULT_H +#define RESULT_H -#include "contiki-net.h" +#include "index.h" +#include "relation.h" +#include "storage.h" +#define RESULT_TUPLE_INVALID(tuple) ((tuple) == NULL) +#define RESULT_TUPLE_SIZE(handle) (handle).rel->row_length -void tr1001_init(void); -u8_t tr1001_send(u8_t *packet, u16_t len); -unsigned short tr1001_poll(void); +typedef unsigned char *tuple_t; -void tr1001_set_txpower(unsigned char p); -#define TR1001_TXPOWER_HIGHEST 100 -#define TR1001_TXPOWER_LOWEST 1 +#define DB_HANDLE_FLAG_INDEX_STEP 0x01 +#define DB_HANDLE_FLAG_SEARCH_INDEX 0x02 +#define DB_HANDLE_FLAG_PROCESSING 0x04 -unsigned short tr1001_sstrength(void); +struct db_handle { + index_iterator_t index_iterator; + tuple_id_t tuple_id; + tuple_id_t current_row; + relation_t *rel; + relation_t *left_rel; + relation_t *join_rel; + relation_t *right_rel; + relation_t *result_rel; + attribute_t *left_join_attr; + attribute_t *right_join_attr; + tuple_t tuple; + uint8_t flags; + uint8_t ncolumns; + void *adt; +}; +typedef struct db_handle db_handle_t; -#define TR1001_SSTRENGTH_DROPPED 1 -#define TR1001_SSTRENGTH_MAX 2 -#define TR1001_SSTRENGTH_MIN 3 -unsigned short tr1001_packets_ok(void); -unsigned short tr1001_packets_dropped(void); -void tr1001_clear_packets(void); -unsigned short tr1001_sstrength_value(unsigned int type); +db_result_t db_get_value(attribute_value_t *value, + db_handle_t *handle, unsigned col); +db_result_t db_phy_to_value(attribute_value_t *value, + attribute_t *attr, unsigned char *ptr); +db_result_t db_value_to_phy(unsigned char *ptr, + attribute_t *attr, attribute_value_t *value); +long db_value_to_long(attribute_value_t *value); +db_result_t db_free(db_handle_t *handle); -#endif /* __TR1001_H__ */ +#endif /* !RESULT_H */ diff --git a/apps/antelope/storage-cfs.c b/apps/antelope/storage-cfs.c new file mode 100644 index 000000000..425873e2a --- /dev/null +++ b/apps/antelope/storage-cfs.c @@ -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 + */ + +#include +#include + +#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; +} diff --git a/apps/antelope/storage.h b/apps/antelope/storage.h new file mode 100644 index 000000000..b40496c8e --- /dev/null +++ b/apps/antelope/storage.h @@ -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 + */ + +#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 */ diff --git a/apps/er-coap-03/er-coap-03.c b/apps/er-coap-03/er-coap-03.c index 220af6be2..b02227ba2 100644 --- a/apps/er-coap-03/er-coap-03.c +++ b/apps/er-coap-03/er-coap-03.c @@ -123,9 +123,9 @@ int uint32_2_bytes(uint8_t *bytes, uint32_t var) { int i = 0; - if (0xFF000000 & var) bytes[i++] = var>>24; - if (0xFF0000 & var) bytes[i++] = var>>16; - if (0xFF00 & var) bytes[i++] = var>>8; + if (0xFF000000 & var) bytes[i++] = (0xFF & var>>24); + if (0xFFFF0000 & var) bytes[i++] = (0xFF & var>>16); + if (0xFFFFFF00 & var) bytes[i++] = (0xFF & var>>8); bytes[i++] = 0xFF & var; return i; diff --git a/apps/er-coap-06/er-coap-06.c b/apps/er-coap-06/er-coap-06.c index 3e72c48e7..013001c48 100644 --- a/apps/er-coap-06/er-coap-06.c +++ b/apps/er-coap-06/er-coap-06.c @@ -136,10 +136,10 @@ serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t v uint8_t *option = &buffer[i]; - if (0xFF000000 & value) buffer[++i] = (uint8_t) (value>>24); - if (0x00FF0000 & value) buffer[++i] = (uint8_t) (value>>16); - if (0x0000FF00 & value) buffer[++i] = (uint8_t) (value>>8); - if (0x000000FF & value) buffer[++i] = (uint8_t) value; + if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24); + if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16); + if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8); + if ( value) buffer[++i] = (uint8_t) (0xFF & value); i += set_option_header(number - current_number, i-start_i, option); diff --git a/apps/er-coap-07/er-coap-07-engine.c b/apps/er-coap-07/er-coap-07-engine.c index 6c0c44628..6a79db718 100644 --- a/apps/er-coap-07/er-coap-07-engine.c +++ b/apps/er-coap-07/er-coap-07-engine.c @@ -148,6 +148,7 @@ handle_incoming_data(void) } else { + block_size = REST_MAX_CHUNK_SIZE; new_offset = 0; } @@ -304,7 +305,7 @@ coap_set_rest_status(void *packet, unsigned int code) /*- Server part ---------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/ /* The discover resource is automatically included for CoAP. */ -RESOURCE(well_known_core, METHOD_GET, ".well-known/core", ""); +RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "ct=40"); void well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { diff --git a/apps/er-coap-07/er-coap-07.c b/apps/er-coap-07/er-coap-07.c index 34c41a387..1e3223b2e 100644 --- a/apps/er-coap-07/er-coap-07.c +++ b/apps/er-coap-07/er-coap-07.c @@ -137,10 +137,10 @@ serialize_int_option(int number, int current_number, uint8_t *buffer, uint32_t v uint8_t *option = &buffer[i]; - if (0xFF000000 & value) buffer[++i] = (uint8_t) (value>>24); - if (0x00FF0000 & value) buffer[++i] = (uint8_t) (value>>16); - if (0x0000FF00 & value) buffer[++i] = (uint8_t) (value>>8); - if (0x000000FF & value) buffer[++i] = (uint8_t) value; + if (0xFF000000 & value) buffer[++i] = (uint8_t) (0xFF & value>>24); + if (0xFFFF0000 & value) buffer[++i] = (uint8_t) (0xFF & value>>16); + if (0xFFFFFF00 & value) buffer[++i] = (uint8_t) (0xFF & value>>8); + if (0xFFFFFFFF & value) buffer[++i] = (uint8_t) (0xFF & value); i += set_option_header(number - current_number, i-start_i, option); @@ -680,7 +680,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len) ((coap_packet_t *)packet)->block2_num = parse_int_option(current_option, option_len); ((coap_packet_t *)packet)->block2_more = (((coap_packet_t *)packet)->block2_num & 0x08)>>3; ((coap_packet_t *)packet)->block2_size = 16 << (((coap_packet_t *)packet)->block2_num & 0x07); - ((coap_packet_t *)packet)->block2_offset = (((coap_packet_t *)packet)->block2_num & ~0x0F)<<(((coap_packet_t *)packet)->block2_num & 0x07); + ((coap_packet_t *)packet)->block2_offset = (((coap_packet_t *)packet)->block2_num & ~0x0000000F)<<(((coap_packet_t *)packet)->block2_num & 0x07); ((coap_packet_t *)packet)->block2_num >>= 4; PRINTF("Block2 [%lu%s (%u B/blk)]\n", ((coap_packet_t *)packet)->block2_num, ((coap_packet_t *)packet)->block2_more ? "+" : "", ((coap_packet_t *)packet)->block2_size); break; @@ -1035,7 +1035,7 @@ coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size) if (num>0x0FFFFF) return 0; ((coap_packet_t *)packet)->block2_num = num; - ((coap_packet_t *)packet)->block2_more = more; + ((coap_packet_t *)packet)->block2_more = more ? 1 : 0; ((coap_packet_t *)packet)->block2_size = size; SET_OPTION((coap_packet_t *)packet, COAP_OPTION_BLOCK2); diff --git a/apps/unit-test/unit-test.h b/apps/unit-test/unit-test.h index e12fff50d..e39025cd0 100644 --- a/apps/unit-test/unit-test.h +++ b/apps/unit-test/unit-test.h @@ -88,7 +88,7 @@ typedef struct unit_test { * * \param name The name of the unit test. */ -#define UNIT_TEST(name) unit_test_result_t unit_test_function_##name(unit_test_t *utp) +#define UNIT_TEST(name) static void unit_test_function_##name(unit_test_t *utp) /** * Mark the starting point of the unit test function. @@ -103,8 +103,7 @@ typedef struct unit_test { */ #define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \ unit_test_end: \ - utp->end = RTIMER_NOW(); \ - return utp->result; + utp->end = RTIMER_NOW() /* * The test result is printed with a function that is selected by diff --git a/core/net/mac/phase.c b/core/net/mac/phase.c index 6e29ed959..ac29c4afa 100644 --- a/core/net/mac/phase.c +++ b/core/net/mac/phase.c @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: phase.c,v 1.17 2010/12/18 22:12:53 dak664 Exp $ */ /** @@ -108,6 +107,9 @@ phase_update(const struct phase_list *list, e = find_neighbor(list, neighbor); if(e != NULL) { if(mac_status == MAC_TX_OK) { +#if PHASE_DRIFT_CORRECT + e->drift = time-e->time; +#endif e->time = time; } /* If the neighbor didn't reply to us, it may have switched @@ -140,6 +142,9 @@ phase_update(const struct phase_list *list, } rimeaddr_copy(&e->neighbor, neighbor); e->time = time; +#if PHASE_DRIFT_CORRECT + e->drift = 0; +#endif e->noacks = 0; list_push(*list->list, e); } @@ -197,8 +202,27 @@ phase_wait(struct phase_list *list, now = RTIMER_NOW(); sync = (e == NULL) ? now : e->time; - wait = (rtimer_clock_t)((sync - now) & - (cycle_time - 1)); + +#if PHASE_DRIFT_CORRECT + { + int32_t s; + if(e->drift > cycle_time) { + s = e->drift % cycle_time / (e->drift / cycle_time); /* drift per cycle */ + s = s * (now - sync) / cycle_time; /* estimated drift to now */ + sync += s; /* add it in */ + } + } +#endif + + /* Check if cycle_time is a power of two */ + if(!(cycle_time & (cycle_time - 1))) { + /* Faster if cycle_time is a power of two */ + wait = (rtimer_clock_t)((sync - now) & (cycle_time - 1)); + } else { + /* Works generally */ + wait = cycle_time - (rtimer_clock_t)((now - sync) % cycle_time); + } + if(wait < guard_time) { wait += cycle_time; } @@ -226,6 +250,7 @@ phase_wait(struct phase_list *list, expected = now + wait - guard_time; if(!RTIMER_CLOCK_LT(expected, now)) { /* Wait until the receiver is expected to be awake */ +// printf("%d ",expected%cycle_time); //for spreadsheet export while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected)); } return PHASE_SEND_NOW; diff --git a/core/net/mac/phase.h b/core/net/mac/phase.h index d74431fcc..8025d2c13 100644 --- a/core/net/mac/phase.h +++ b/core/net/mac/phase.h @@ -28,7 +28,6 @@ * * This file is part of the Contiki operating system. * - * $Id: phase.h,v 1.5 2010/09/13 13:39:05 adamdunkels Exp $ */ /** @@ -48,10 +47,19 @@ #include "lib/memb.h" #include "net/netstack.h" +#if PHASE_CONF_DRIFT_CORRECT +#define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT +#else +#define PHASE_DRIFT_CORRECT 0 +#endif + struct phase { struct phase *next; rimeaddr_t neighbor; rtimer_clock_t time; +#if PHASE_DRIFT_CORRECT + rtimer_clock_t drift; +#endif uint8_t noacks; struct timer noacks_timer; }; diff --git a/core/net/tcpip.c b/core/net/tcpip.c index 305214f35..7556b1239 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -630,8 +630,8 @@ tcpip_ipv6_output(void) memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len); uip_packetqueue_set_buflen(&nbr->packethandle, uip_len); } - uip_len = 0; #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ + uip_len = 0; return; } /* Send in parallel if we are running NUD (nbc state is either STALE, diff --git a/core/net/uip.h b/core/net/uip.h index 9b35f1de6..c39e81090 100644 --- a/core/net/uip.h +++ b/core/net/uip.h @@ -825,13 +825,13 @@ CCIF void uip_send(const void *data, int len); * * \param rport The remote port number in network byte order. * - * \return The uip_udp_conn structure for the new connection or NULL + * \return The uip_udp_conn structure for the new connection, or NULL * if no connection could be allocated. */ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport); /** - * Removed a UDP connection. + * Remove a UDP connection. * * \param conn A pointer to the uip_udp_conn structure for the connection. * @@ -942,7 +942,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport); } while(0) /** - * Construct an IPv6 address from eight 8-bit words. + * Construct an IPv6 address from sixteen 8-bit words. * * This function constructs an IPv6 address. * @@ -969,7 +969,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport); /** - * Copy an IP address to another IP address. + * Copy an IP address from one place to another. * * Copies an IP address from one place to another. * @@ -1001,7 +1001,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport); uip_ipaddr(&ipaddr1, 192,16,1,2); if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { - printf("They are the same"); + printf("They are the same"); } \endcode * @@ -1201,7 +1201,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport); #endif /* UIP_HTONS */ /** - * Convert 16-bit quantity from host byte order to network byte order. + * Convert a 16-bit quantity from host byte order to network byte order. * * This function is primarily used for converting variables from host * byte order to network byte order. For converting constants to @@ -1407,11 +1407,11 @@ struct uip_stats { IP length, high byte. */ uip_stats_t lblenerr; /**< Number of packets dropped due to wrong IP length, low byte. */ - uip_stats_t fragerr; /**< Number of packets dropped since they + uip_stats_t fragerr; /**< Number of packets dropped because they were IP fragments. */ uip_stats_t chkerr; /**< Number of packets dropped due to IP checksum errors. */ - uip_stats_t protoerr; /**< Number of packets dropped since they + uip_stats_t protoerr; /**< Number of packets dropped because they were neither ICMP, UDP nor TCP. */ } ip; /**< IP statistics. */ struct { @@ -1432,10 +1432,10 @@ struct uip_stats { checksum. */ uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK number. */ - uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */ + uip_stats_t rst; /**< Number of received TCP RST (reset) segments. */ uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ - uip_stats_t syndrop; /**< Number of dropped SYNs due to too few - connections was avaliable. */ + uip_stats_t syndrop; /**< Number of dropped SYNs because too few + connections were available. */ uip_stats_t synrst; /**< Number of SYNs for closed ports, triggering a RST. */ } tcp; /**< TCP statistics. */ diff --git a/core/sys/process.h b/core/sys/process.h index 097ac03cf..4aadf9ca7 100644 --- a/core/sys/process.h +++ b/core/sys/process.h @@ -221,7 +221,7 @@ typedef unsigned char process_num_events_t; */ #define PROCESS_PAUSE() do { \ process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \ - PROCESS_WAIT_EVENT(); \ + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); \ } while(0) /** @} end of protothread functions */ diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c index dce8e500d..1c5db991a 100644 --- a/cpu/avr/dev/clock.c +++ b/cpu/avr/dev/clock.c @@ -67,25 +67,29 @@ void clock_adjust_seconds(uint8_t howmany) { /*---------------------------------------------------------------------------*/ /* This routine can be called to add ticks to the clock after a sleep. + * Leap ticks or seconds can (rarely) be introduced if the ISR is not blocked. */ void clock_adjust_ticks(uint16_t howmany) { +// uint8_t sreg = SREG;cli(); count += howmany; - scount += howmany; - while(scount >= CLOCK_SECOND) { - scount -= CLOCK_SECOND; + howmany+= scount; + while(howmany >= CLOCK_SECOND) { + howmany -= CLOCK_SECOND; seconds++; sleepseconds++; #if RADIOSTATS if (RF230_receive_on) radioontime += 1; #endif } + scount = howmany; +// SREG=sreg; } /*---------------------------------------------------------------------------*/ //SIGNAL(SIG_OUTPUT_COMPARE0) ISR(AVR_OUTPUT_COMPARE_INT) { count++; - if(++scount == CLOCK_SECOND) { + if(++scount >= CLOCK_SECOND) { scount = 0; seconds++; } @@ -96,7 +100,7 @@ ISR(AVR_OUTPUT_COMPARE_INT) #endif #if RADIOSTATS if (RF230_receive_on) { - if (++rcount == CLOCK_SECOND) { + if (++rcount >= CLOCK_SECOND) { rcount=0; radioontime++; } diff --git a/cpu/native/mtarch.c b/cpu/native/mtarch.c index 6121ae8ba..5bb01a0cc 100644 --- a/cpu/native/mtarch.c +++ b/cpu/native/mtarch.c @@ -40,7 +40,7 @@ static void *main_fiber; -#else /* _WIN32 || __CYGWIN__ */ +#elif defined(__linux) #include #include @@ -54,7 +54,7 @@ struct mtarch_t { static ucontext_t main_context; static ucontext_t *running_context; -#endif /* _WIN32 || __CYGWIN__ */ +#endif /* _WIN32 || __CYGWIN__ || __linux */ #include "mtarch.h" @@ -88,7 +88,7 @@ mtarch_start(struct mtarch_thread *thread, thread->mt_thread = CreateFiber(0, (LPFIBER_START_ROUTINE)function, data); -#else /* _WIN32 || __CYGWIN__ */ +#elif defined(__linux) thread->mt_thread = malloc(sizeof(struct mtarch_t)); @@ -118,7 +118,7 @@ mtarch_start(struct mtarch_thread *thread, makecontext(&((struct mtarch_t *)thread->mt_thread)->context, (void (*)(void))function, 1, data); -#endif /* _WIN32 || __CYGWIN__ */ +#endif /* _WIN32 || __CYGWIN__ || __linux */ } /*--------------------------------------------------------------------------*/ void @@ -128,11 +128,11 @@ mtarch_yield(void) SwitchToFiber(main_fiber); -#else /* _WIN32 || __CYGWIN__ */ +#elif defined(__linux) swapcontext(running_context, &main_context); -#endif /* _WIN32 || __CYGWIN__ */ +#endif /* _WIN32 || __CYGWIN__ || __linux */ } /*--------------------------------------------------------------------------*/ void @@ -142,13 +142,13 @@ mtarch_exec(struct mtarch_thread *thread) SwitchToFiber(thread->mt_thread); -#else /* _WIN32 || __CYGWIN__ */ +#elif defined(__linux) running_context = &((struct mtarch_t *)thread->mt_thread)->context; swapcontext(&main_context, running_context); running_context = NULL; -#endif /* _WIN32 || __CYGWIN__ */ +#endif /* _WIN32 || __CYGWIN__ || __linux */ } /*--------------------------------------------------------------------------*/ void @@ -158,11 +158,11 @@ mtarch_stop(struct mtarch_thread *thread) DeleteFiber(thread->mt_thread); -#else /* _WIN32 || __CYGWIN__ */ +#elif defined(linux) || defined(__linux) free(thread->mt_thread); -#endif /* _WIN32 || __CYGWIN__ */ +#endif /* _WIN32 || __CYGWIN__ || __linux */ } /*--------------------------------------------------------------------------*/ void diff --git a/examples/antelope/netdb/Makefile b/examples/antelope/netdb/Makefile new file mode 100644 index 000000000..e680009ca --- /dev/null +++ b/examples/antelope/netdb/Makefile @@ -0,0 +1,6 @@ +CONTIKI = ../../../ +APPS += antelope +CFLAGS += -Wall -g -DPROJECT_CONF_H=\"project-conf.h\" +SMALL = 1 + +include $(CONTIKI)/Makefile.include diff --git a/examples/antelope/netdb/netdb-client.c b/examples/antelope/netdb/netdb-client.c new file mode 100644 index 000000000..59fdf9277 --- /dev/null +++ b/examples/antelope/netdb/netdb-client.c @@ -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 + */ + +#include + +#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(); +} diff --git a/examples/antelope/netdb/netdb-server.c b/examples/antelope/netdb/netdb-server.c new file mode 100644 index 000000000..50700a457 --- /dev/null +++ b/examples/antelope/netdb/netdb-server.c @@ -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 + */ + +#include + +#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(); +} diff --git a/examples/antelope/netdb/netdb.csc b/examples/antelope/netdb/netdb.csc new file mode 100755 index 000000000..d6d98a0dd --- /dev/null +++ b/examples/antelope/netdb/netdb.csc @@ -0,0 +1,271 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + NetDB + 0 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 30.0 + 30.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + sky1 + NetDB Server + [CONTIKI_DIR]/examples/antelope/netdb/netdb-server.c + make netdb-server.sky TARGET=sky + [CONTIKI_DIR]/examples/antelope/netdb/netdb-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + sky2 + NetDB Client + [CONTIKI_DIR]/examples/antelope/netdb/netdb-client.c + make netdb-client.sky TARGET=sky + [CONTIKI_DIR]/examples/antelope/netdb/netdb-client.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 23.57340748739308 + 46.80222047486912 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 40.39130096157144 + 70.54634688655467 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 66.04131381969006 + 36.41113701058369 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 63.00130046120498 + 80.89331313174746 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 4 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 40.2894982777653 + 95.14334789567525 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 5 + + sky1 + + + + + se.sics.cooja.interfaces.Position + -13.168104050312492 + 40.250683112542255 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 6 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 80.95025965975177 + 44.99507552455861 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 7 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 6.857316697020866 + 33.24863334754029 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 8 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 35.975659895989395 + 27.42171932830696 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 9 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 13.672853648109518 + 68.2461872644317 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 10 + + sky1 + + + + + se.sics.cooja.interfaces.Position + 44.62423029692567 + 48.53691502749644 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 51 + + sky2 + + + + se.sics.cooja.plugins.SimControl + 259 + 3 + 205 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + 4.472125038273293 0.0 0.0 4.472125038273293 79.43486237544504 -89.06315297501011 + + 475 + 0 + 429 + 644 + 9 + + + se.sics.cooja.plugins.LogListener + + ID:4$ + + 1024 + 2 + 150 + 0 + 389 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 10 + + Serial port + 0,0 + + 588 + 1 + 399 + 505 + 520 + + + diff --git a/examples/antelope/netdb/project-conf.h b/examples/antelope/netdb/project-conf.h new file mode 100644 index 000000000..9d1ed0c56 --- /dev/null +++ b/examples/antelope/netdb/project-conf.h @@ -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 diff --git a/examples/antelope/shell/Makefile b/examples/antelope/shell/Makefile new file mode 100644 index 000000000..265de76c0 --- /dev/null +++ b/examples/antelope/shell/Makefile @@ -0,0 +1,8 @@ +CONTIKI = ../../../ + +APPS += antelope unit-test + +CFLAGS += -Wall -g -DPROJECT_CONF_H=\"project-conf.h\" +SMALL = 1 + +include $(CONTIKI)/Makefile.include diff --git a/examples/antelope/shell/project-conf.h b/examples/antelope/shell/project-conf.h new file mode 100644 index 000000000..cc9fa46c1 --- /dev/null +++ b/examples/antelope/shell/project-conf.h @@ -0,0 +1,5 @@ +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 + +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver diff --git a/examples/antelope/shell/shell-db.c b/examples/antelope/shell/shell-db.c new file mode 100644 index 000000000..72583c90a --- /dev/null +++ b/examples/antelope/shell/shell-db.c @@ -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 + */ + +#include + +#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(); +} diff --git a/examples/er-rest-example/project-conf.h b/examples/er-rest-example/project-conf.h index 1672795d7..017f80701 100644 --- a/examples/er-rest-example/project-conf.h +++ b/examples/er-rest-example/project-conf.h @@ -34,23 +34,28 @@ #define SICSLOWPAN_CONF_FRAG 1 -/* Save some memory for the sky platform */ +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver + +/* Save some memory for the sky platform. */ #undef UIP_CONF_DS6_NBR_NBU #define UIP_CONF_DS6_NBR_NBU 10 #undef UIP_CONF_DS6_ROUTE_NBU #define UIP_CONF_DS6_ROUTE_NBU 10 -/* Increase rpl-border-router IP-buffer when using 128 */ +/* Increase rpl-border-router IP-buffer when using 128. */ #ifndef REST_MAX_CHUNK_SIZE #define REST_MAX_CHUNK_SIZE 64 #endif -/* Decrease to 2 if no space left for stack when using 128-byte chunks */ +/* Multiplies with chunk size, be aware of memory constraints. */ #ifndef COAP_MAX_OPEN_TRANSACTIONS #define COAP_MAX_OPEN_TRANSACTIONS 4 #endif -/* Must be <= open transaction number */ +/* Must be <= open transaction number. */ #ifndef COAP_MAX_OBSERVERS #define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS #endif diff --git a/examples/er-rest-example/rest-server-example.c b/examples/er-rest-example/rest-server-example.c index 48bfffb26..fb9e24b8d 100644 --- a/examples/er-rest-example/rest-server-example.c +++ b/examples/er-rest-example/rest-server-example.c @@ -125,7 +125,7 @@ helloworld_handler(void* request, void* response, uint8_t *buffer, uint16_t pref } /* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ -RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); +RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); void mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -282,7 +282,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre * These chunk-wise resources must set the offset value to its new position or -1 of the end is reached. * (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.) */ -RESOURCE(chunks, METHOD_GET, "chunks", "title=\"Blockwise demo\";rt=\"Data\""); +RESOURCE(chunks, METHOD_GET, "debug/chunks", "title=\"Blockwise demo\";rt=\"Data\""); #define CHUNKS_TOTAL 2050 @@ -335,7 +335,7 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre * It takes an additional period parameter, which defines the interval to call [name]_periodic_handler(). * A default post_handler takes care of subscriptions by managing a list of subscribers to notify. */ -PERIODIC_RESOURCE(polling, METHOD_GET, "poll", "title=\"Periodic demo\";rt=\"Observable\"", 5*CLOCK_SECOND); +PERIODIC_RESOURCE(polling, METHOD_GET, "debug/poll", "title=\"Periodic demo\";rt=\"Observable\"", 5*CLOCK_SECOND); void polling_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -372,7 +372,7 @@ polling_periodic_handler(resource_t *r) * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. */ -EVENT_RESOURCE(event, METHOD_GET, "event", "title=\"Event demo\";rt=\"Observable\""); +EVENT_RESOURCE(event, METHOD_GET, "sensors/button", "title=\"Event demo\";rt=\"Observable\""); void event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -405,7 +405,7 @@ event_event_handler(resource_t *r) #if defined (PLATFORM_HAS_LEDS) /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ -RESOURCE(led, METHOD_POST | METHOD_PUT , "leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); +RESOURCE(led, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); void led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -452,7 +452,7 @@ led_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_s } /* A simple actuator example. Toggles the red led */ -RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "toggle", "title=\"Red LED\";rt=\"Control\""); +RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); void toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -462,7 +462,7 @@ toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre #if defined (PLATFORM_HAS_LIGHT) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(light, METHOD_GET, "light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\""); +RESOURCE(light, METHOD_GET, "sensors/light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\""); void light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { @@ -503,7 +503,7 @@ light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred #if defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ -RESOURCE(battery, METHOD_GET, "battery", "title=\"Battery status\";rt=\"Battery\""); +RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"Battery\""); void battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { diff --git a/examples/ipv6/rpl-udp/udp-client.c b/examples/ipv6/rpl-udp/udp-client.c index 037408858..67e4de7e8 100644 --- a/examples/ipv6/rpl-udp/udp-client.c +++ b/examples/ipv6/rpl-udp/udp-client.c @@ -161,6 +161,10 @@ PROCESS_THREAD(udp_client_process, ev, data) /* new connection with remote host */ client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL); + if(client_conn == NULL) { + PRINTF("No UDP connection available, exiting the process!\n"); + PROCESS_EXIT(); + } udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT)); PRINTF("Created a connection with the server "); diff --git a/examples/ipv6/rpl-udp/udp-server.c b/examples/ipv6/rpl-udp/udp-server.c index e178b7e5d..0e6c88b3b 100644 --- a/examples/ipv6/rpl-udp/udp-server.c +++ b/examples/ipv6/rpl-udp/udp-server.c @@ -151,6 +151,10 @@ PROCESS_THREAD(udp_server_process, ev, data) NETSTACK_MAC.off(1); server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL); + if(server_conn == NULL) { + PRINTF("No UDP connection available, exiting the process!\n"); + PROCESS_EXIT(); + } udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT)); PRINTF("Created a server connection with remote address "); diff --git a/platform/cc2420dbk/Makefile b/platform/cc2420dbk/Makefile deleted file mode 100644 index 5713fd9f3..000000000 --- a/platform/cc2420dbk/Makefile +++ /dev/null @@ -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 diff --git a/platform/cc2420dbk/contiki-conf.h b/platform/cc2420dbk/contiki-conf.h deleted file mode 100644 index a4b24df1d..000000000 --- a/platform/cc2420dbk/contiki-conf.h +++ /dev/null @@ -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 - -#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 */ diff --git a/platform/cc2420dbk/dev/cb_uart01.c b/platform/cc2420dbk/dev/cb_uart01.c deleted file mode 100644 index 9f7f9b1b5..000000000 --- a/platform/cc2420dbk/dev/cb_uart01.c +++ /dev/null @@ -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 - -#include - -#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); -} diff --git a/platform/cc2420dbk/dev/qleds.c b/platform/cc2420dbk/dev/qleds.c deleted file mode 100644 index 54d29e8ae..000000000 --- a/platform/cc2420dbk/dev/qleds.c +++ /dev/null @@ -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 - -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 -} diff --git a/platform/cc2420dbk/dev/rom.c b/platform/cc2420dbk/dev/rom.c deleted file mode 100644 index 93136e182..000000000 --- a/platform/cc2420dbk/dev/rom.c +++ /dev/null @@ -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 - -#include -#include - -#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; -} diff --git a/platform/cc2420dbk/dev/xmem.c b/platform/cc2420dbk/dev/xmem.c deleted file mode 100644 index 37a8af220..000000000 --- a/platform/cc2420dbk/dev/xmem.c +++ /dev/null @@ -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 - -#include - -#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; -} diff --git a/platform/cc2420dbk/gateway.c b/platform/cc2420dbk/gateway.c deleted file mode 100644 index 7eb2ffab8..000000000 --- a/platform/cc2420dbk/gateway.c +++ /dev/null @@ -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 - -#include - -#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; -} diff --git a/platform/ethernut1/Makefile.ethernut1 b/platform/ethernut1/Makefile.ethernut1 deleted file mode 100644 index 726a9ee1f..000000000 --- a/platform/ethernut1/Makefile.ethernut1 +++ /dev/null @@ -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:$< diff --git a/platform/ethernut1/contiki-conf.h b/platform/ethernut1/contiki-conf.h deleted file mode 100644 index 2e569cf22..000000000 --- a/platform/ethernut1/contiki-conf.h +++ /dev/null @@ -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
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__ */ diff --git a/platform/ethernut1/ethernut-main.c b/platform/ethernut1/ethernut-main.c deleted file mode 100644 index 1ad9a4ffb..000000000 --- a/platform/ethernut1/ethernut-main.c +++ /dev/null @@ -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 -#include -#include - -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; -} diff --git a/platform/ethernut2/Makefile.ethernut2 b/platform/ethernut2/Makefile.ethernut2 deleted file mode 100644 index 6774a8ae2..000000000 --- a/platform/ethernut2/Makefile.ethernut2 +++ /dev/null @@ -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 diff --git a/platform/ethernut2/contiki-conf.h b/platform/ethernut2/contiki-conf.h deleted file mode 100644 index 132144712..000000000 --- a/platform/ethernut2/contiki-conf.h +++ /dev/null @@ -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
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__ */ diff --git a/platform/ethernut2/ethernut-main.c b/platform/ethernut2/ethernut-main.c deleted file mode 100644 index d124c4496..000000000 --- a/platform/ethernut2/ethernut-main.c +++ /dev/null @@ -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 -/*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; -} diff --git a/platform/netsim/Makefile.netsim b/platform/netsim/Makefile.netsim deleted file mode 100644 index d7c0625dd..000000000 --- a/platform/netsim/Makefile.netsim +++ /dev/null @@ -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 diff --git a/platform/netsim/contiki-conf.h b/platform/netsim/contiki-conf.h deleted file mode 100644 index ca712293b..000000000 --- a/platform/netsim/contiki-conf.h +++ /dev/null @@ -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 - -/** - * 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__ */ diff --git a/platform/netsim/contiki-main.c b/platform/netsim/contiki-main.c deleted file mode 100644 index 6600a8570..000000000 --- a/platform/netsim/contiki-main.c +++ /dev/null @@ -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 - * - * $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 -#ifndef HAVE_SNPRINTF -int snprintf(char *str, size_t size, const char *format, ...); -#endif /* HAVE_SNPRINTF */ - -#include -#include -#include - -#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; diff --git a/platform/netsim/contiki-main.h b/platform/netsim/contiki-main.h deleted file mode 100644 index 98257b3b8..000000000 --- a/platform/netsim/contiki-main.h +++ /dev/null @@ -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 - * - * $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__ */ diff --git a/platform/netsim/dev/beep.c b/platform/netsim/dev/beep.c deleted file mode 100644 index 6c589d973..000000000 --- a/platform/netsim/dev/beep.c +++ /dev/null @@ -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 - * - * $Id: beep.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ - */ -#include -#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) -{ - -} diff --git a/platform/netsim/dev/beep.h b/platform/netsim/dev/beep.h deleted file mode 100644 index 2a1519428..000000000 --- a/platform/netsim/dev/beep.h +++ /dev/null @@ -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 - * - */ - -#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__ */ diff --git a/platform/netsim/dev/button-sensor.c b/platform/netsim/dev/button-sensor.c deleted file mode 100644 index 82dba1de9..000000000 --- a/platform/netsim/dev/button-sensor.c +++ /dev/null @@ -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); diff --git a/platform/netsim/dev/button-sensor.h b/platform/netsim/dev/button-sensor.h deleted file mode 100644 index 2a3f28459..000000000 --- a/platform/netsim/dev/button-sensor.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/dev/dummy-sensors.c b/platform/netsim/dev/dummy-sensors.c deleted file mode 100644 index 1ba259330..000000000 --- a/platform/netsim/dev/dummy-sensors.c +++ /dev/null @@ -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); diff --git a/platform/netsim/dev/eeprom.c b/platform/netsim/dev/eeprom.c deleted file mode 100644 index 18c60edc8..000000000 --- a/platform/netsim/dev/eeprom.c +++ /dev/null @@ -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 - * - * $Id: eeprom.c,v 1.2 2007/11/17 18:09:18 adamdunkels Exp $ - */ -#include "dev/eeprom.h" -#include "node.h" -#include - -#include -#include -#include -#include - -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); -} diff --git a/platform/netsim/dev/esb-sensors.c b/platform/netsim/dev/esb-sensors.c deleted file mode 100644 index 037aa0d9e..000000000 --- a/platform/netsim/dev/esb-sensors.c +++ /dev/null @@ -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 - */ - -#include "esb-sensors.h" -#include -/*---------------------------------------------------------------------------*/ -void -esb_sensors_on(void) -{ - printf("esb_sensors_on()\n"); -} -/*---------------------------------------------------------------------------*/ -void -esb_sensors_off(void) -{ - printf("esb_sensors_off()\n"); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/esb-sensors.h b/platform/netsim/dev/esb-sensors.h deleted file mode 100644 index 4a1d50242..000000000 --- a/platform/netsim/dev/esb-sensors.h +++ /dev/null @@ -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 - */ - -#ifndef __ESB_SENSORS_H__ -#define __ESB_SENSORS_H__ - -void esb_sensors_on(void); -void esb_sensors_off(void); - -#endif /* __ESB_SENSORS_H__ */ diff --git a/platform/netsim/dev/flash.c b/platform/netsim/dev/flash.c deleted file mode 100644 index bd56a9b68..000000000 --- a/platform/netsim/dev/flash.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * \file - * Functions for reading and writing flash ROM. - * \author Adam Dunkels - */ - -/* 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 - * - */ - - -/*---------------------------------------------------------------------------*/ -void -flash_setup(void) -{ -} -/*---------------------------------------------------------------------------*/ -void -flash_done(void) -{ -} -/*---------------------------------------------------------------------------*/ -void -flash_clear(unsigned short *ptr) -{ -} -/*---------------------------------------------------------------------------*/ -void -flash_write(unsigned short *ptr, unsigned short word) -{ -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/flash.h b/platform/netsim/dev/flash.h deleted file mode 100644 index b2b5d2720..000000000 --- a/platform/netsim/dev/flash.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * \file - * Functions for reading and writing MSP430 flash ROM. - * \author Adam Dunkels - */ - -/* 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 - * - */ - -#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__ */ diff --git a/platform/netsim/dev/irq.c b/platform/netsim/dev/irq.c deleted file mode 100644 index 160e0c1b7..000000000 --- a/platform/netsim/dev/irq.c +++ /dev/null @@ -1,5 +0,0 @@ -void -irq_init(void) -{ -} - diff --git a/platform/netsim/dev/leds-arch.c b/platform/netsim/dev/leds-arch.c deleted file mode 100644 index 67a82808a..000000000 --- a/platform/netsim/dev/leds-arch.c +++ /dev/null @@ -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); - } -} diff --git a/platform/netsim/dev/lpm.h b/platform/netsim/dev/lpm.h deleted file mode 100644 index 892655306..000000000 --- a/platform/netsim/dev/lpm.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/dev/pir-sensor.c b/platform/netsim/dev/pir-sensor.c deleted file mode 100644 index f13b7cc41..000000000 --- a/platform/netsim/dev/pir-sensor.c +++ /dev/null @@ -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); diff --git a/platform/netsim/dev/pir-sensor.h b/platform/netsim/dev/pir-sensor.h deleted file mode 100644 index bb60a442c..000000000 --- a/platform/netsim/dev/pir-sensor.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/dev/radio-sensor.c b/platform/netsim/dev/radio-sensor.c deleted file mode 100644 index a77f966a9..000000000 --- a/platform/netsim/dev/radio-sensor.c +++ /dev/null @@ -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); diff --git a/platform/netsim/dev/radio-sensor.h b/platform/netsim/dev/radio-sensor.h deleted file mode 100644 index 35d97d33d..000000000 --- a/platform/netsim/dev/radio-sensor.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/dev/radio.c b/platform/netsim/dev/radio.c deleted file mode 100644 index 38f242815..000000000 --- a/platform/netsim/dev/radio.c +++ /dev/null @@ -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 - */ - -#include "radio.h" -/*---------------------------------------------------------------------------*/ -void -radio_on(void) -{ -} -/*---------------------------------------------------------------------------*/ -void -radio_off(void) -{ -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/rs232.c b/platform/netsim/dev/rs232.c deleted file mode 100644 index 24aa79d8d..000000000 --- a/platform/netsim/dev/rs232.c +++ /dev/null @@ -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 - */ - -#include "rs232.h" -#include -/*---------------------------------------------------------------------------*/ -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); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/rs232.h b/platform/netsim/dev/rs232.h deleted file mode 100644 index 02f5e1a20..000000000 --- a/platform/netsim/dev/rs232.h +++ /dev/null @@ -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 - */ - -#ifndef __RS232_H__ -#define __RS232_H__ - -void rs232_set_input(int (* f)(unsigned char)); - -#endif /* __RS232_H__ */ diff --git a/platform/netsim/dev/temperature-sensor.h b/platform/netsim/dev/temperature-sensor.h deleted file mode 100644 index 8718790b3..000000000 --- a/platform/netsim/dev/temperature-sensor.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/dev/tr1001-drv.c b/platform/netsim/dev/tr1001-drv.c deleted file mode 100644 index 3e08ac1e8..000000000 --- a/platform/netsim/dev/tr1001-drv.c +++ /dev/null @@ -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 -#include - -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; -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/tr1001-drv.h b/platform/netsim/dev/tr1001-drv.h deleted file mode 100644 index e7319d97a..000000000 --- a/platform/netsim/dev/tr1001-drv.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/dev/tr1001.c b/platform/netsim/dev/tr1001.c deleted file mode 100644 index 97b4c173c..000000000 --- a/platform/netsim/dev/tr1001.c +++ /dev/null @@ -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 - */ - -#include -#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; -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/vib-sensor.c b/platform/netsim/dev/vib-sensor.c deleted file mode 100644 index a70d9cb31..000000000 --- a/platform/netsim/dev/vib-sensor.c +++ /dev/null @@ -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); diff --git a/platform/netsim/dev/vib-sensor.h b/platform/netsim/dev/vib-sensor.h deleted file mode 100644 index 8272ad19c..000000000 --- a/platform/netsim/dev/vib-sensor.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/display.c b/platform/netsim/display.c deleted file mode 100644 index b8d9a7dcc..000000000 --- a/platform/netsim/display.c +++ /dev/null @@ -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 - * - */ - -#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 - -#include -#include -#include -#include - -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); -} -/*-----------------------------------------------------------------------------------*/ diff --git a/platform/netsim/display.h b/platform/netsim/display.h deleted file mode 100644 index 5eb8f797f..000000000 --- a/platform/netsim/display.h +++ /dev/null @@ -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 - * - */ -#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__ */ diff --git a/platform/netsim/ether.c b/platform/netsim/ether.c deleted file mode 100644 index f332a00ee..000000000 --- a/platform/netsim/ether.c +++ /dev/null @@ -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 - * - * $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 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#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 - -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)); -} -/*-----------------------------------------------------------------------------------*/ diff --git a/platform/netsim/ether.h b/platform/netsim/ether.h deleted file mode 100644 index 23db87504..000000000 --- a/platform/netsim/ether.h +++ /dev/null @@ -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 - * - * $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__ */ diff --git a/platform/netsim/init.c b/platform/netsim/init.c deleted file mode 100644 index a1039e547..000000000 --- a/platform/netsim/init.c +++ /dev/null @@ -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);*/ -} diff --git a/platform/netsim/init.h b/platform/netsim/init.h deleted file mode 100644 index abf66d9e8..000000000 --- a/platform/netsim/init.h +++ /dev/null @@ -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__ */ diff --git a/platform/netsim/main.c b/platform/netsim/main.c deleted file mode 100644 index 7766550b5..000000000 --- a/platform/netsim/main.c +++ /dev/null @@ -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 - * - * $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 - * - * 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 -#include -#include -#include -#include -#include -#include - -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 " - "\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 - -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) -{ - -}*/ diff --git a/platform/netsim/net/ethernode-rime.c b/platform/netsim/net/ethernode-rime.c deleted file mode 100644 index d6088aaa3..000000000 --- a/platform/netsim/net/ethernode-rime.c +++ /dev/null @@ -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 - * - * $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 -#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); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/net/ethernode-uip.c b/platform/netsim/net/ethernode-uip.c deleted file mode 100644 index 3f55b233f..000000000 --- a/platform/netsim/net/ethernode-uip.c +++ /dev/null @@ -1,99 +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 - * - * $Id: ethernode-uip.c,v 1.6 2008/01/04 21:59:13 oliverschmidt Exp $ - */ - -#include "contiki.h" - -#include "ethernode.h" - -#include "net/uip-fw.h" -#include "net/hc.h" -#ifdef __CYGWIN__ -#include "net/wpcap.h" -#else /* __CYGWIN__ */ -#include "net/tapdev.h" -#endif /* __CYGWIN__ */ - -#include "node-id.h" - -PROCESS(ethernode_uip_process, "Ethernode driver"); - -enum { NULLEVENT }; -/*---------------------------------------------------------------------------*/ -u8_t -ethernode_uip_send(void) -{ - /* printf("%d: ethernode_uip_send\n", node_id);*/ - uip_len = hc_compress(&uip_buf[UIP_LLH_LEN], uip_len); - - return ethernode_send(); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(ethernode_uip_process, ev, data) -{ - PROCESS_BEGIN(); - - while(1) { - process_poll(ðernode_uip_process); - PROCESS_WAIT_EVENT(); - - /* Poll Ethernet device to see if there is a frame avaliable. */ - uip_len = ethernode_read(uip_buf, UIP_BUFSIZE); - - if(uip_len > 0) { - /* printf("%d: new packet len %d\n", node_id, uip_len);*/ - - /* if((random_rand() % drop) <= drop / 2) { - printf("Bropp\n"); - } else*/ { - - uip_len = hc_inflate(&uip_buf[UIP_LLH_LEN], uip_len); - -#ifdef __CYGWIN__ - wpcap_send(); -#else /* __CYGWIN__ */ - tapdev_send(); -#endif /* __CYGWIN__ */ - /* if(uip_fw_forward() == UIP_FW_LOCAL)*/ { - /* A frame was avaliable (and is now read into the uip_buf), so - we process it. */ - tcpip_input(); - } - } - } - } - PROCESS_END(); - -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/net/ethernode-uip.h b/platform/netsim/net/ethernode-uip.h deleted file mode 100644 index 1663f0f46..000000000 --- a/platform/netsim/net/ethernode-uip.h +++ /dev/null @@ -1,43 +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 - * - * $Id: ethernode-uip.h,v 1.2 2007/03/22 18:59:34 adamdunkels Exp $ - */ -#ifndef __ETHERNODE_UIP_H__ -#define __ETHERNODE_UIP_H__ - -#include "contiki.h" - -PROCESS_NAME(ethernode_uip_process); - -u8_t ethernode_uip_send(void); - -#endif /* __ETHERNODE_UIP_H__ */ diff --git a/platform/netsim/net/ethernode.c b/platform/netsim/net/ethernode.c deleted file mode 100644 index 8bb64d2f9..000000000 --- a/platform/netsim/net/ethernode.c +++ /dev/null @@ -1,323 +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 - * - * $Id: ethernode.c,v 1.18 2010/06/14 19:19:17 adamdunkels Exp $ - */ -/** - * \file - * uIP virtual network interface using UDP tunnels. - * \author Adam Dunkels - * - */ - -#include "net/ethernode.h" -#include "net/uip_arch.h" -#include "net/uip-fw.h" -#include "ether.h" - -#include "dev/radio.h" -#include "net/netstack.h" -#include "net/packetbuf.h" - -#include "node.h" - -#include "lib/random.h" - -#include -#include -#include - -#include "net/ethernode.h" - -#define BUF ((uip_tcpip_hdr *)&uip_buf[HDR_LEN]) - -#define PRINTF(...) -/*#define PRINTF(x) printf x; fflush(NULL)*/ - -struct { - u8_t id; - int timer; - u8_t seqno; -} state; - -#define TYPE_DATA 1 -#define TYPE_ACK 2 - -struct hdr { - u8_t type; - u8_t src; - u8_t dest; - u8_t seqno; -}; - -static int radio_is_on = 1; - -/*---------------------------------------------------------------------------*/ -static int -ethernode_on(void) -{ - radio_is_on = 1; - ether_set_radio_status(radio_is_on); - - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -ethernode_safe_off(void) -{ - radio_is_on = 0; - ether_set_radio_status(radio_is_on); - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -channel_clear(void) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -receiving(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -pending(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ - - -#define HDR_LEN UIP_LLH_LEN - -#define ID_BROADCAST 0x80 - -PROCESS(ethernode_process, "Ethernode"); -/*-------------------------------------------------------------------------------*/ -static u8_t -do_send(u8_t type, u8_t dest, struct hdr *hdr, int len) -{ - - hdr->type = type; - hdr->src = state.id; - - hdr->dest = dest; - - hdr->seqno = state.seqno; - - ++state.seqno; - - PRINTF("ether_send len %d\n", len); - return ether_send((char *)hdr, len); - -} -/*-------------------------------------------------------------------------------*/ -/** - * Initialize the virtual UDP tunnel network interface. - * - * \param sid The ID number of this node. - * - */ -/*-------------------------------------------------------------------------------*/ -void -ethernode_init(int port) -{ - ether_client_init(port); - - do { - state.id = random_rand() & 0x7f; - } while(state.id == ID_BROADCAST); - - state.seqno = 0; -} -/*-------------------------------------------------------------------------------*/ -/** - * Poll the network device to see if a packet has arrived. - * - * \return The length of the incoming packet, or zero if no packet was - * found. - */ -/*-------------------------------------------------------------------------------*/ -int -ethernode_poll(void) -{ - return ether_client_poll(); -} -/*-------------------------------------------------------------------------------*/ -int -ethernode_read(void *buf, unsigned short bufsize) -{ - int len; - u8_t tmpbuf[2048]; - struct hdr *hdr = (struct hdr *)tmpbuf; - - len = ether_client_read(tmpbuf, sizeof(tmpbuf)); - if(len == 0) { - return 0; - } - - if(radio_is_on == 0) { - /* Drop the incoming packet if the simulated radio is switched off. */ - return 0; - } - /* printf("ethernode_poll: received data packet with len %d type %d\n", len, hdr->type);*/ - - switch(hdr->type) { - case TYPE_DATA: - if(hdr->dest == state.id || - hdr->dest == ID_BROADCAST) { - memcpy(buf, tmpbuf + HDR_LEN, bufsize); - return len - HDR_LEN; - } - break; - case TYPE_ACK: - printf("<%d>: Received ack packet from %d\n", state.id, hdr->src); - break; - default: - printf("<%d>: Received unknown packet type %d from %d\n", state.id, hdr->type, hdr->src); - break; - } - - return 0; - -} -/*-------------------------------------------------------------------------------*/ -/** - * Send a packet from the uip_buf buffer over the UDP tunnel. - * - * - * \retval UIP_FW_TOOLARGE A transmission of packet that was too large was attempted. - * - * \retval UIP_FW_DROPPED The packet is known to be dropped. - * - * \retval UIP_FW_OK The packet was transmitted. - */ -/*-------------------------------------------------------------------------------*/ -u8_t -ethernode_send(void) -{ - int len; - static char tmpbuf[2048]; - struct hdr *hdr = (struct hdr *)tmpbuf; - u8_t dest; - struct timeval tv; - - if(uip_len > sizeof(tmpbuf)) { - PRINTF(("Ethernode_send: too large uip_len %d\n", uip_len)); - return UIP_FW_TOOLARGE; - } - - memcpy(&tmpbuf[HDR_LEN], &uip_buf[HDR_LEN], uip_len); - len = uip_len + HDR_LEN; - - dest = ID_BROADCAST; - tv.tv_sec = 0; - tv.tv_usec = (random_rand() % 1000); - select(0, NULL, NULL, NULL, &tv); - - do_send(TYPE_DATA, dest, hdr, len); - - return UIP_FW_OK; -} -/*-------------------------------------------------------------------------------*/ -static char tmpbuf[2048]; -static struct hdr *hdr = (struct hdr *)tmpbuf; -static u8_t dest; - -static int -prepare(const void *buf, unsigned short len) -{ - memcpy(&tmpbuf[HDR_LEN], buf, len); - len = len + HDR_LEN; - - dest = ID_BROADCAST; - return len; -} -/*-------------------------------------------------------------------------------*/ -static int -transmit(unsigned short len) -{ - do_send(TYPE_DATA, dest, hdr, len + HDR_LEN); - return RADIO_TX_OK; -} -/*-------------------------------------------------------------------------------*/ -static int -send(const void *payload, unsigned short payload_len) -{ - prepare(payload, payload_len); - return transmit(payload_len); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(ethernode_process, ev, data) -{ - int len; - PROCESS_BEGIN(); - - while(1) { - process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); - PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); - - len = ethernode_poll(); - if(len > 0) { - - packetbuf_clear(); - len = ethernode_read(packetbuf_dataptr(), PACKETBUF_SIZE); - if(len > 0) { - packetbuf_set_datalen(len); - NETSTACK_RDC.input(); - } - - /* if(receiver_callback) { - receiver_callback(ðernode_driver); - }*/ - } - } - PROCESS_END(); -} -/*-------------------------------------------------------------------------------*/ -const struct radio_driver ethernode_driver = - { - (int (*)(void))ethernode_init, - prepare, - transmit, - send, - ethernode_read, - channel_clear, - receiving, - pending, - ethernode_on, - ethernode_safe_off, - }; - - diff --git a/platform/netsim/net/ethernode.h b/platform/netsim/net/ethernode.h deleted file mode 100644 index 174863098..000000000 --- a/platform/netsim/net/ethernode.h +++ /dev/null @@ -1,51 +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 - * - * $Id: ethernode.h,v 1.4 2007/11/17 18:09:19 adamdunkels Exp $ - */ -#ifndef __ETHERNODE_H__ -#define __ETHERNODE_H__ - -#include "contiki.h" - -#include "dev/radio.h" - -void ethernode_init(int port); -int ethernode_read(void *buf, unsigned short bufsize); -u8_t ethernode_send(void); -int ethernode_send_buf(const void *buf, unsigned short len); -void ethernode_periodic(void); -void ethernode_set_receiver(void (* recv)(const struct radio_driver *)); - -extern const struct radio_driver ethernode_driver; - -#endif /* __ETHERNODE_H__ */ diff --git a/platform/netsim/netsim-init.c b/platform/netsim/netsim-init.c deleted file mode 100644 index 083b7415a..000000000 --- a/platform/netsim/netsim-init.c +++ /dev/null @@ -1,52 +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: netsim-init.c,v 1.2 2007/03/22 18:59:34 adamdunkels Exp $ - */ -#include "init.h" -#include "random.h" - -void -netsim_init(void) -{ - int x, y; - - ether_set_strength(41); - - main_add_base(1, 1); - - for(x = 1; x < 201; x += 40) { - for(y = 1; y < 201; y += 40) { - if(!(x == 1 && y == 1)) { - main_add_node(x, y); - } - } - } -} diff --git a/platform/netsim/node-id.h b/platform/netsim/node-id.h deleted file mode 100644 index bd0bdb2df..000000000 --- a/platform/netsim/node-id.h +++ /dev/null @@ -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. - * - * Author: Adam Dunkels - * - * $Id: node-id.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ - */ - -#ifndef __NODE_ID_H__ -#define __NODE_ID_H__ - -#include "node.h" - -#define node_id (node.id) - -#endif /* __NODE_ID_H__ */ diff --git a/platform/netsim/node.c b/platform/netsim/node.c deleted file mode 100644 index b84303d96..000000000 --- a/platform/netsim/node.c +++ /dev/null @@ -1,152 +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 - * - * $Id: node.c,v 1.10 2008/01/04 23:23:29 oliverschmidt Exp $ - */ -#include "node.h" -#include "contiki.h" -#include "net/uip.h" -#include "net/rime.h" -#include -#include -#include - -extern in_addr_t gwaddr; - -static clock_time_t drift, timer; - -struct node node; - -static int fd; - -static void init_node_log(void); - -/*------------------------------------------------------------------------------*/ -void -node_init(int id, int posx, int posy, int b) -{ - uip_ipaddr_t addr; - - node.id = id; - node.x = posx; - node.y = posy; - /* node.type = NODE_TYPE_NORMAL;*/ - - if(b) { -#ifdef __CYGWIN__ - addr = *(uip_ipaddr_t *)&gwaddr; -#else /* __CYGWIN__ */ - uip_ipaddr(&addr, 192,168,1,2); -#endif /* __CYGWIN__ */ - } else { - uip_ipaddr(&addr, 172,16,posx,posy); - } - uip_sethostaddr(&addr); - - { - rimeaddr_t nodeaddr; - - nodeaddr.u8[0] = posx; - nodeaddr.u8[1] = posy; - rimeaddr_set_node_addr(&nodeaddr); - } - - drift = rand() % 95726272; - - init_node_log(); -} -/*------------------------------------------------------------------------------*/ -#include - -clock_time_t -node_time(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - - return tv.tv_sec * 1000 + tv.tv_usec / 1000/* + drift*/; -} -/*------------------------------------------------------------------------------*/ -unsigned long -node_seconds(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - - return tv.tv_sec; -} -/*------------------------------------------------------------------------------*/ -void -node_set_time(clock_time_t time) -{ - timer = time; -} -/*------------------------------------------------------------------------------*/ -int -node_x(void) -{ - return node.x; -} -/*------------------------------------------------------------------------------*/ -int -node_y(void) -{ - return node.y; -} -/*------------------------------------------------------------------------------*/ -#include -#include -#include -#include - -static void -init_node_log(void) -{ - fd = open("log", O_CREAT | O_WRONLY | O_APPEND, 0666); -} - -void -node_log(const char *fmt, ...) -{ - va_list ap; - char buf[4096]; - int len; - - len = sprintf(buf, "Node %d (%d, %d): ", node.id, node.x, node.y); - va_start(ap, fmt); - vsprintf(&buf[len], fmt, ap); - write(fd, buf, strlen(buf)); - va_end(ap); -} -/*------------------------------------------------------------------------------*/ diff --git a/platform/netsim/node.h b/platform/netsim/node.h deleted file mode 100644 index 4f72437e1..000000000 --- a/platform/netsim/node.h +++ /dev/null @@ -1,58 +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 - * - * $Id: node.h,v 1.3 2006/10/23 09:01:06 adamdunkels Exp $ - */ -#ifndef __NODE_H__ -#define __NODE_H__ - -#include "sys/clock.h" - -struct node { - int x, y; - int id; -}; - -extern struct node node; - -void node_init(int id, int x, int y, int b); -void node_set_time(clock_time_t time); -clock_time_t node_time(void); -unsigned long node_seconds(void); - -int node_x(void); -int node_y(void); - -void node_log(const char *fmt, ...); - - -#endif /* __NODE_H__ */ diff --git a/platform/netsim/nodes.c b/platform/netsim/nodes.c deleted file mode 100644 index 385fa6827..000000000 --- a/platform/netsim/nodes.c +++ /dev/null @@ -1,167 +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 - * - * $Id: nodes.c,v 1.8 2008/05/14 19:22:58 adamdunkels Exp $ - */ -#include -#include -#include -#include - -#include "nodes.h" - - -static int numnodes; - -static struct nodes_node nodes[2000]; - -int nodes_base_node_port = 0; -/*---------------------------------------------------------------------------*/ -void -nodes_init(void) -{ - numnodes = 0; -} -/*---------------------------------------------------------------------------*/ -void -nodes_add(int pid, int x, int y, int port, int id) -{ - nodes[numnodes].pid = pid; - nodes[numnodes].x = x; - nodes[numnodes].y = y; - nodes[numnodes].port = port; - nodes[numnodes].leds = 0; - nodes[numnodes].done = 0; - nodes[numnodes].id = id; - ++numnodes; -} -/*---------------------------------------------------------------------------*/ -void -nodes_kill(void) -{ - int i; - for(i = 0; i < numnodes; ++i) { - kill(nodes[i].pid, SIGTERM); - } -} -/*---------------------------------------------------------------------------*/ -int -nodes_num(void) -{ - return numnodes; -} -/*---------------------------------------------------------------------------*/ -struct nodes_node * -nodes_node(int num) -{ - if(num > numnodes) { - fprintf(stderr, "nodes_node: request for %d > %d\n", num, numnodes); - abort(); - } - return &nodes[num]; -} -/*---------------------------------------------------------------------------*/ -static struct nodes_node * -find_node(int x, int y) -{ - int i; - - for(i = numnodes; i >= 0; --i) { - if(nodes[i].x == x && nodes[i].y == y) { - return &nodes[i]; - } - } - return &nodes[0]; -} -/*---------------------------------------------------------------------------*/ -void -nodes_set_leds(int x, int y, int leds) -{ - find_node(x, y)->leds = leds; -} -/*---------------------------------------------------------------------------*/ -void -nodes_set_text(int x, int y, char *text) -{ - strncpy(find_node(x, y)->text, text, NODES_TEXTLEN); -} -/*---------------------------------------------------------------------------*/ -void -nodes_set_radio_status(int x, int y, int radio_status) -{ - find_node(x, y)->radio_status = radio_status; -} -/*---------------------------------------------------------------------------*/ -void -nodes_set_line(int x, int y, int linex, int liney) -{ - struct nodes_node *n; - - n = find_node(x, y); - n->linex = linex; - n->liney = liney; -} -/*---------------------------------------------------------------------------*/ -struct nodes_node * -nodes_find_pid(pid_t pid) -{ - int i; - printf("Nofodes %d\n", numnodes); - for(i = 0; i < numnodes; ++i) { - printf("%d == %d\n", pid, nodes[i].pid); fflush(NULL); - if(nodes[i].pid == pid) { - return &nodes[i]; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -nodes_done(int id) -{ - int i; - int num_done = 0; - - for(i = numnodes; i >= 0; --i) { - if(nodes[i].id == id) { - nodes[i].done = 1; - } - if(nodes[i].done != 0) { - num_done++; - } - } - - if(num_done == numnodes) { - exit(0); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/nodes.h b/platform/netsim/nodes.h deleted file mode 100644 index 240a0a932..000000000 --- a/platform/netsim/nodes.h +++ /dev/null @@ -1,72 +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 - * - * $Id: nodes.h,v 1.6 2008/05/14 19:22:58 adamdunkels Exp $ - */ -#ifndef __NODES_H__ -#define __NODES_H__ - -#include - -#define NODES_TEXTLEN 10 - -void nodes_init(void); -void nodes_add(int pid, int x, int y, int port, int id); -void nodes_kill(void); -void nodes_set_leds(int x, int y, int leds); -void nodes_set_text(int x, int y, char *text); -void nodes_set_line(int x, int y, int linex, int liney); -void nodes_set_radio_status(int x, int y, int radio_status); - -void nodes_done(int id); - -int nodes_num(void); -struct nodes_node *nodes_node(int num); -struct nodes_node *nodes_find_pid(pid_t pid); - -struct nodes_node { - int pid; - int id; - int x, y; - int port; - int leds; - int done; - int linex, liney; - int radio_status; - char text[NODES_TEXTLEN]; -}; - -#define NODES_PORTBASE 5000 - -extern int nodes_base_node_port; - -#endif /* __NODES_H__ */ diff --git a/platform/netsim/random.c b/platform/netsim/random.c deleted file mode 100644 index 76a2dce25..000000000 --- a/platform/netsim/random.c +++ /dev/null @@ -1,60 +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 - * - * $Id: random.c,v 1.2 2007/11/17 18:09:18 adamdunkels Exp $ - */ -/*----------------------------------------------------------------------------*/ -/* - * \file - * Stubs for pseudo-random generator. - * \author Adam Dunkels - * - * - */ -/*----------------------------------------------------------------------------*/ -#include -#include -#include - -/*----------------------------------------------------------------------------*/ -void -random_init(void) -{ - srand(getpid()); -} -/*----------------------------------------------------------------------------*/ -unsigned short -random_rand(void) -{ - return (rand() >> 4) & 0xffff; -} -/*----------------------------------------------------------------------------*/ diff --git a/platform/netsim/random.h b/platform/netsim/random.h deleted file mode 100644 index c4bb9bf9f..000000000 --- a/platform/netsim/random.h +++ /dev/null @@ -1,53 +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 - * - * $Id: random.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ - */ -#ifndef __RANDOM_H__ -#define __RANDOM_H__ - -/* - * Initialize the pseudo-random generator. - * - */ -void random_init(void); - -/* - * Calculate a pseudo random number between 0 and 65535. - * - * \return A pseudo-random number between 0 and 65535. - */ -unsigned short random_rand(void); - - - -#endif /* __RANDOM_H__ */ diff --git a/platform/netsim/sensor.c b/platform/netsim/sensor.c deleted file mode 100644 index 1318ad092..000000000 --- a/platform/netsim/sensor.c +++ /dev/null @@ -1,82 +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 - * - * $Id: sensor.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ - */ -#include "sensor.h" -#include "dev/pir-sensor.h" -#include "dev/button-sensor.h" -#include "dev/vib-sensor.h" - -static int strength = 20; - -static int pir, button, vib; - -/*---------------------------------------------------------------------------*/ -void -sensor_init(void) -{ - -} -/*---------------------------------------------------------------------------*/ -int -sensor_strength(void) -{ - return strength; -} -/*---------------------------------------------------------------------------*/ -void -sensor_set_strength(int s) -{ - strength = s; -} -/*---------------------------------------------------------------------------*/ -void -sensor_input(struct sensor_data *d, int strength) -{ - pir += d->pir; - if(d->pir) { - pir_sensor_changed(strength); - } - if(d->button) { - button_press(); - } - button += d->button; - /* if(button) { - printf("Button %d %d\n", button, d->button); - }*/ - if(d->vib) { - vib_sensor_changed(); - } - vib += d->vib; -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/sensor.h b/platform/netsim/sensor.h deleted file mode 100644 index f506fb868..000000000 --- a/platform/netsim/sensor.h +++ /dev/null @@ -1,55 +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 - * - * $Id: sensor.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ - */ -#ifndef __SENSOR_H__ -#define __SENSOR_H__ - -#include - -struct sensor_data { - int pir; - int button; - int vib; -}; - -void sensor_input(struct sensor_data *d, int strength); -void sensor_init(void); -int sensor_poll(void); - -int sensor_strength(void); -void sensor_set_strength(int s); - -#define sensor_data_init(s) memset(s, 0, sizeof(struct sensor_data)) - -#endif /* __SENSOR_H__ */ diff --git a/platform/netsim/symbols.c b/platform/netsim/symbols.c deleted file mode 100644 index c4a2baf0d..000000000 --- a/platform/netsim/symbols.c +++ /dev/null @@ -1,35 +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: symbols.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ - */ -#include "loader/symbols.h" -const struct symbols symbols[] = { -{(void *)0, 0} }; diff --git a/platform/sky/platform-conf.h b/platform/sky/platform-conf.h index ee08f4b23..7c3eec2e0 100644 --- a/platform/sky/platform-conf.h +++ b/platform/sky/platform-conf.h @@ -47,8 +47,11 @@ /* Platform TMOTE_SKY */ #define TMOTE_SKY 1 -#define PLATFORM_HAS_LEDS 1 -#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_LIGHT 1 +#define PLATFORM_HAS_BATTERY 1 +#define PLATFORM_HAS_SHT11 1 #ifdef __IAR_SYSTEMS_ICC__ #define __MSP430F1611__ 1 diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java index cc23b1843..4ad0ca2e1 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java @@ -25,8 +25,6 @@ * 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: MspCodeWatcher.java,v 1.24 2010/08/26 14:10:43 nifi Exp $ */ package se.sics.cooja.mspmote.plugins; @@ -68,24 +66,25 @@ import org.jdom.Element; import se.sics.cooja.ClassDescription; import se.sics.cooja.GUI; +import se.sics.cooja.GUI.RunnableInEDT; import se.sics.cooja.Mote; import se.sics.cooja.MotePlugin; import se.sics.cooja.PluginType; import se.sics.cooja.Simulation; import se.sics.cooja.VisPlugin; -import se.sics.cooja.GUI.RunnableInEDT; import se.sics.cooja.mspmote.MspMote; import se.sics.cooja.mspmote.MspMoteType; import se.sics.cooja.util.StringUtils; import se.sics.mspsim.core.EmulationException; import se.sics.mspsim.core.MSP430; import se.sics.mspsim.ui.DebugUI; -import se.sics.mspsim.util.ELFDebug; import se.sics.mspsim.util.DebugInfo; +import se.sics.mspsim.util.ELFDebug; @ClassDescription("Msp Code Watcher") @PluginType(PluginType.MOTE_PLUGIN) public class MspCodeWatcher extends VisPlugin implements MotePlugin { + private static final long serialVersionUID = -8463196456352243367L; private static Logger logger = Logger.getLogger(MspCodeWatcher.class); private Simulation simulation; private Observer simObserver; @@ -131,6 +130,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } }); fileComboBox.setRenderer(new BasicComboBoxRenderer() { + private static final long serialVersionUID = -2135703608960229528L; public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (isSelected) { @@ -165,13 +165,9 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { browseBox.add(mapButton); browseBox.add(Box.createHorizontalStrut(10)); - mapAction.putValue(Action.NAME, "Map"); - - /* Execution control panel (south) */ JPanel controlPanel = new JPanel(); JButton button = new JButton(stepAction); - stepAction.putValue(Action.NAME, "Step instruction"); controlPanel.add(button); @@ -272,7 +268,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { currentFileAction.setEnabled(true); currentFileAction.putValue(Action.NAME, currentCodeFile.getName() + ":" + currentLineNumber); currentFileAction.putValue(Action.SHORT_DESCRIPTION, currentCodeFile.getAbsolutePath() + ":" + currentLineNumber); - fileComboBox.setSelectedIndex(0); + fileComboBox.setSelectedItem(currentCodeFile.getName()); displaySourceFile(currentCodeFile, currentLineNumber); } @@ -294,24 +290,23 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { return; } - String path = - new File(debugInfo.getPath(), debugInfo.getFile()).getPath().replace('\\', '/'); + String path = new File(debugInfo.getPath(), debugInfo.getFile()).getPath(); if (path == null) { return; } + path = path.replace('\\', '/'); /* Debug info to source file map */ if (debugInfoMap != null && debugInfoMap.length == 2) { if (path.startsWith(debugInfoMap[0])) { - path = path.replace(debugInfoMap[0], debugInfoMap[1]); + path = debugInfoMap[1] + path.substring(debugInfoMap[0].length()); } } /* Nasty Cygwin-Windows fix */ - if (path.contains("/cygdrive/")) { - int index = path.indexOf("/cygdrive/"); - char driveCharacter = path.charAt(index+10); - path = path.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/"); + if (path.length() > 10 && path.startsWith("/cygdrive/")) { + char driveCharacter = path.charAt(10); + path = driveCharacter + ":/" + path.substring(11); } currentCodeFile = new File(path).getCanonicalFile(); @@ -327,16 +322,16 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { final String[] debugFiles; try { ELFDebug debug = ((MspMoteType)mspMote.getType()).getELF().getDebug(); - if (debug == null) { + debugFiles = debug != null ? debug.getSourceFiles() : null; + if (debugFiles == null) { logger.fatal("Error: No debug information is available"); return; } - debugFiles = debug.getSourceFiles(); } catch (IOException e1) { logger.fatal("Error: " + e1.getMessage(), e1); return; } - debugInfoMap = new RunnableInEDT() { + String[] map = new RunnableInEDT() { public String[] work() { /* Select which source file to use */ int counter = 0, n; @@ -345,12 +340,12 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { n = JOptionPane.showOptionDialog(GUI.getTopParentContainer(), "Choose which source file to manually locate.\n\n" + "Some source files may not exist, as debug info is also inherited from the toolchain.\n" + - "\"Next\" selects the next source file in the debug info.\n\n" + - (counter+1) + "/" + debugFiles.length + ": " + debugFiles[counter], + "\"Next File\" proceeds to the next source file in the debug info.\n\n" + + debugFiles[counter] + " (" + (counter+1) + '/' + debugFiles.length + ')', "Select source file to locate", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, - new String[] { "Next", "Locate", "Cancel"}, "Next"); - if (n == JOptionPane.CANCEL_OPTION) { + new String[] { "Next File", "Locate File", "Cancel"}, "Next File"); + if (n == JOptionPane.CANCEL_OPTION || n == JOptionPane.CLOSED_OPTION) { return null; } if (n == JOptionPane.NO_OPTION) { @@ -369,6 +364,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { return "Source file " + filename; } }); + fc.setCurrentDirectory(new File(GUI.getExternalToolsSetting("PATH_CONTIKI", "."))); int returnVal = fc.showOpenDialog(GUI.getTopParentContainer()); if (returnVal == JFileChooser.APPROVE_OPTION) { correspondingFile = fc.getSelectedFile(); @@ -442,18 +438,22 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } } }.invokeAndWait(); - updateFileComboBox(); + + if (map != null) { + debugInfoMap = map; + updateFileComboBox(); + } } private static File[] getSourceFiles(MspMote mote, String[] map) { final String[] sourceFiles; try { ELFDebug debug = ((MspMoteType)mote.getType()).getELF().getDebug(); - if (debug == null) { + sourceFiles = debug != null ? debug.getSourceFiles() : null; + if (sourceFiles == null) { logger.fatal("Error: No debug information is available"); return new File[0]; } - sourceFiles = debug.getSourceFiles(); } catch (IOException e1) { logger.fatal("Error: " + e1.getMessage(), e1); return null; @@ -474,15 +474,14 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { sourceFile = sourceFile.replace('\\', '/'); if (map != null && map.length == 2) { if (sourceFile.startsWith(map[0])) { - sourceFile = sourceFile.replace(map[0], map[1]); + sourceFile = map[1] + sourceFile.substring(map[0].length()); } } /* Nasty Cygwin-Windows fix */ - if (sourceFile.contains("/cygdrive/")) { - int index = sourceFile.indexOf("/cygdrive/"); - char driveCharacter = sourceFile.charAt(index+10); - sourceFile = sourceFile.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/"); + if (sourceFile.length() > 10 && sourceFile.contains("/cygdrive/")) { + char driveCharacter = sourceFile.charAt(10); + sourceFile = driveCharacter + ":/" + sourceFile.substring(11); } File file = new File(sourceFile); @@ -569,9 +568,6 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } catch (MalformedURLException e) { logger.warn("Failure to read source code: " + e); return null; - } catch (IOException e) { - logger.warn("Failure to read source code: " + e); - return null; } } @@ -606,6 +602,8 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } private AbstractAction currentFileAction = new AbstractAction() { + private static final long serialVersionUID = -3218306989816724883L; + public void actionPerformed(ActionEvent e) { if (currentCodeFile == null) { return; @@ -614,13 +612,17 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin { } }; - private AbstractAction mapAction = new AbstractAction() { + private AbstractAction mapAction = new AbstractAction("Map") { + private static final long serialVersionUID = -3929432830596292495L; + public void actionPerformed(ActionEvent e) { tryMapDebugInfo(); } }; - private AbstractAction stepAction = new AbstractAction() { + private AbstractAction stepAction = new AbstractAction("Step instruction") { + private static final long serialVersionUID = 3520750710757816575L; + public void actionPerformed(ActionEvent e) { try { mspMote.getCPU().stepInstructions(1);