diff --git a/drivers/cc110x/cc1100.c b/drivers/cc110x/cc1100.c index 50a5574fd8c1b553552155b5f90b7c2b1ca2e9e8..c0a40251fb21d9724a1b00001c0c961ab245c008 100644 --- a/drivers/cc110x/cc1100.c +++ b/drivers/cc110x/cc1100.c @@ -1,28 +1,13 @@ -/****************************************************************************** -Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved. - -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of RIOT. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -RIOT is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de -*******************************************************************************/ +/** + * TI Chipcon CC110x radio driver + * + * Copyright (C) 2009-2013 Freie Universität Berlin + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + */ /** * @ingroup dev_cc110x diff --git a/sys/lib/hash_string.c b/sys/lib/hash_string.c old mode 100755 new mode 100644 index a7611bcf6d9ec2c93e3b9b6099af6509d0b7b68d..9374a5cdf91b3663c69c3f4b33a9446ad635f8c0 --- a/sys/lib/hash_string.c +++ b/sys/lib/hash_string.c @@ -6,12 +6,14 @@ unsigned long hash_string(unsigned char *str) unsigned long hash = 5381; int c; - while ((c = *str++)) - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + while((c = *str++)) { + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } return hash; } -int cmp_string(char* a, char* b) { - return (strcmp(a,b) == 0); +int cmp_string(char *a, char *b) +{ + return (strcmp(a, b) == 0); } diff --git a/sys/lib/hash_string.h b/sys/lib/hash_string.h old mode 100755 new mode 100644 index a51c6abcc97dc0768bf71519ed0d265160c8d18f..e927cf15dd4d96ab5a136a89966b9dd5a55199c8 --- a/sys/lib/hash_string.h +++ b/sys/lib/hash_string.h @@ -1,7 +1,7 @@ #ifndef __HASH_STRING_H -#define __HASH_STRING_H +#define __HASH_STRING_H unsigned long hash_string(unsigned char *str); -int cmp_string(char* a, char* b); +int cmp_string(char *a, char *b); #endif /* __HASH_STRING_H */ diff --git a/sys/lib/hashtable.c b/sys/lib/hashtable.c old mode 100755 new mode 100644 index 80cbba934345b795d7450be229e61d2c9c3ab19a..305fc68551b5f8b8f42713a5a8b9c62c060bc8a3 --- a/sys/lib/hashtable.c +++ b/sys/lib/hashtable.c @@ -14,35 +14,52 @@ Credit for primes table: Aaron Krowne http://planetmath.org/encyclopedia/GoodHashTablePrimes.html */ static const uint32_t primes[] = { -53, 97, 193, 389, -769, 1543, 3079, 6151, -12289, 24593, 49157, 98317, -196613, 393241, 786433, 1572869, -3145739, 6291469, 12582917, 25165843, -50331653, 100663319, 201326611, 402653189, -805306457, 1610612741 + 53, 97, 193, 389, + 769, 1543, 3079, 6151, + 12289, 24593, 49157, 98317, + 196613, 393241, 786433, 1572869, + 3145739, 6291469, 12582917, 25165843, + 50331653, 100663319, 201326611, 402653189, + 805306457, 1610612741 }; -const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]); +const unsigned int prime_table_length = sizeof(primes) / sizeof(primes[0]); const float max_load_factor = 0.65; /*****************************************************************************/ struct hashtable * create_hashtable(uint32_t minsize, - unsigned int (*hashf) (void*), - int (*eqf) (void*,void*)) + unsigned int (*hashf)(void *), + int (*eqf)(void *, void *)) { struct hashtable *h; unsigned int pindex, size = primes[0]; + /* Check requested hashtable isn't too large */ - if (minsize > (1u << 30)) return NULL; + if(minsize > (1u << 30)) { + return NULL; + } + /* Enforce size as prime */ - for (pindex=0; pindex < prime_table_length; pindex++) { - if (primes[pindex] > minsize) { size = primes[pindex]; break; } + for(pindex = 0; pindex < prime_table_length; pindex++) { + if(primes[pindex] > minsize) { + size = primes[pindex]; + break; + } } + h = (struct hashtable *)malloc(sizeof(struct hashtable)); - if (NULL == h) return NULL; /*oom*/ - h->table = (struct entry **)malloc(sizeof(struct entry*) * size); - if (NULL == h->table) { free(h); return NULL; } /*oom*/ + + if(NULL == h) { + return NULL; /*oom*/ + } + + h->table = (struct entry **)malloc(sizeof(struct entry *) * size); + + if(NULL == h->table) { + free(h); /*oom*/ + return NULL; + } + memset(h->table, 0, size * sizeof(struct entry *)); h->tablelength = size; h->primeindex = pindex; @@ -61,9 +78,9 @@ hash(struct hashtable *h, void *k) * - logic taken from java 1.4 hashtable source */ unsigned int i = h->hashfn(k); i += ~(i << 9); - i ^= ((i >> 14) | (i << 18)); /* >>> */ - i += (i << 4); - i ^= ((i >> 10) | (i << 22)); /* >>> */ + i ^= ((i >> 14) | (i << 18)); /* >>> */ + i += (i << 4); + i ^= ((i >> 10) | (i << 22)); /* >>> */ return i; } @@ -76,44 +93,54 @@ hashtable_expand(struct hashtable *h) struct entry *e; struct entry **pE; unsigned int newsize, i, index; + /* Check we're not hitting max capacity */ - if (h->primeindex == (prime_table_length - 1)) return 0; + if(h->primeindex == (prime_table_length - 1)) { + return 0; + } + newsize = primes[++(h->primeindex)]; - newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize); - if (NULL != newtable) - { + newtable = (struct entry **)malloc(sizeof(struct entry *) * newsize); + + if(NULL != newtable) { memset(newtable, 0, newsize * sizeof(struct entry *)); + /* This algorithm is not 'stable'. ie. it reverses the list * when it transfers entries between the tables */ - for (i = 0; i < h->tablelength; i++) { - while (NULL != (e = h->table[i])) { + for(i = 0; i < h->tablelength; i++) { + while(NULL != (e = h->table[i])) { h->table[i] = e->next; - index = indexFor(newsize,e->h); + index = indexFor(newsize, e->h); e->next = newtable[index]; newtable[index] = e; } } + free(h->table); h->table = newtable; } /* Plan B: realloc instead */ - else - { + else { newtable = (struct entry **) realloc(h->table, newsize * sizeof(struct entry *)); - if (NULL == newtable) { (h->primeindex)--; return 0; } + + if(NULL == newtable) { + (h->primeindex)--; + return 0; + } + h->table = newtable; memset(newtable[h->tablelength], 0, newsize - h->tablelength); - for (i = 0; i < h->tablelength; i++) { - for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { - index = indexFor(newsize,e->h); - if (index == i) - { + + for(i = 0; i < h->tablelength; i++) { + for(pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { + index = indexFor(newsize, e->h); + + if(index == i) { pE = &(e->next); } - else - { + else { *pE = e->next; e->next = newtable[index]; newtable[index] = e; @@ -121,6 +148,7 @@ hashtable_expand(struct hashtable *h) } } } + h->tablelength = newsize; h->loadlimit = (unsigned int) ceil(newsize * max_load_factor); return -1; @@ -140,18 +168,24 @@ hashtable_insert(struct hashtable *h, void *k, void *v) /* This method allows duplicate keys - but they shouldn't be used */ unsigned int index; struct entry *e; - if (++(h->entrycount) > h->loadlimit) - { + + if(++(h->entrycount) > h->loadlimit) { /* Ignore the return value. If expand fails, we should * still try cramming just this value into the existing table * -- we may not have memory for a larger table, but one more * element may be ok. Next time we insert, we'll try expanding again.*/ hashtable_expand(h); } + e = (struct entry *)malloc(sizeof(struct entry)); - if (NULL == e) { --(h->entrycount); return 0; } /*oom*/ - e->h = hash(h,k); - index = indexFor(h->tablelength,e->h); + + if(NULL == e) { + --(h->entrycount); /*oom*/ + return 0; + } + + e->h = hash(h, k); + index = indexFor(h->tablelength, e->h); e->k = k; e->v = v; e->next = h->table[index]; @@ -165,15 +199,19 @@ hashtable_search(struct hashtable *h, void *k) { struct entry *e; unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); + hashvalue = hash(h, k); + index = indexFor(h->tablelength, hashvalue); e = h->table[index]; - while (NULL != e) - { + + while(NULL != e) { /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; + if((hashvalue == e->h) && (h->eqfn(k, e->k))) { + return e->v; + } + e = e->next; } + return NULL; } @@ -189,15 +227,14 @@ hashtable_remove(struct hashtable *h, void *k) void *v; unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hash(h,k)); + hashvalue = hash(h, k); + index = indexFor(h->tablelength, hash(h, k)); pE = &(h->table[index]); e = *pE; - while (NULL != e) - { + + while(NULL != e) { /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { + if((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; h->entrycount--; v = e->v; @@ -205,9 +242,11 @@ hashtable_remove(struct hashtable *h, void *k) free(e); return v; } + pE = &(e->next); e = e->next; } + return NULL; } @@ -219,24 +258,33 @@ hashtable_destroy(struct hashtable *h, int free_values) unsigned int i; struct entry *e, *f; struct entry **table = h->table; - if (free_values) - { - for (i = 0; i < h->tablelength; i++) - { + + if(free_values) { + for(i = 0; i < h->tablelength; i++) { e = table[i]; - while (NULL != e) - { f = e; e = e->next; freekey(f->k); free(f->v); free(f); } + + while(NULL != e) { + f = e; + e = e->next; + freekey(f->k); + free(f->v); + free(f); + } } } - else - { - for (i = 0; i < h->tablelength; i++) - { + else { + for(i = 0; i < h->tablelength; i++) { e = table[i]; - while (NULL != e) - { f = e; e = e->next; freekey(f->k); free(f); } + + while(NULL != e) { + f = e; + e = e->next; + freekey(f->k); + free(f); + } } } + free(h->table); free(h); } @@ -244,23 +292,23 @@ hashtable_destroy(struct hashtable *h, int free_values) /* * Copyright (c) 2002, Christopher Clark * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * - * + * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/sys/lib/hashtable.h b/sys/lib/hashtable.h old mode 100755 new mode 100644 index e53aea267b82913e845b3f3eaf868a7923210322..99eb88efc9391a12ba45f5b61929c64d9792f765 --- a/sys/lib/hashtable.h +++ b/sys/lib/hashtable.h @@ -19,7 +19,7 @@ struct hashtable; * v = (struct some_value *) malloc(sizeof(struct some_value)); * * (initialise k and v to suitable values) - * + * * if (! hashtable_insert(h,k,v) ) * { exit(-1); } * @@ -33,7 +33,7 @@ struct hashtable; /* Macros may be used to define type-safe(r) hashtable access functions, with * methods specialized to take known key and value types as parameters. - * + * * Example: * * Insert this at the start of your file: @@ -63,7 +63,7 @@ struct hashtable; /***************************************************************************** * create_hashtable - + * @name create_hashtable * @param minsize minimum initial size of hashtable * @param hashfunction function for hashing keys @@ -73,12 +73,12 @@ struct hashtable; struct hashtable * create_hashtable(uint32_t minsize, - unsigned int (*hashfunction) (void*), - int (*key_eq_fn) (void*,void*)); + unsigned int (*hashfunction)(void *), + int (*key_eq_fn)(void *, void *)); /***************************************************************************** * hashtable_insert - + * @name hashtable_insert * @param h the hashtable to insert into * @param k the key - hashtable claims ownership and will free on removal @@ -95,7 +95,7 @@ create_hashtable(uint32_t minsize, * If in doubt, remove before insert. */ -int +int hashtable_insert(struct hashtable *h, void *k, void *v); #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \ @@ -106,7 +106,7 @@ int fnname (struct hashtable *h, keytype *k, valuetype *v) \ /***************************************************************************** * hashtable_search - + * @name hashtable_search * @param h the hashtable to search * @param k the key to search for - does not claim ownership @@ -124,7 +124,7 @@ valuetype * fnname (struct hashtable *h, keytype *k) \ /***************************************************************************** * hashtable_remove - + * @name hashtable_remove * @param h the hashtable to remove the item from * @param k the key to search for - does not claim ownership @@ -143,7 +143,7 @@ valuetype * fnname (struct hashtable *h, keytype *k) \ /***************************************************************************** * hashtable_count - + * @name hashtable_count * @param h the hashtable * @return the number of items stored in the hashtable @@ -154,7 +154,7 @@ hashtable_count(struct hashtable *h); /***************************************************************************** * hashtable_destroy - + * @name hashtable_destroy * @param h the hashtable * @param free_values whether to call 'free' on the remaining values @@ -168,23 +168,23 @@ hashtable_destroy(struct hashtable *h, int free_values); /* * Copyright (c) 2002, Christopher Clark * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * - * + * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/sys/lib/hashtable_private.h b/sys/lib/hashtable_private.h old mode 100755 new mode 100644 index 3e95f600577540095d20b2551d1198556cf36361..58bbef81f4d5873bfcad51deb9fe9ab1b3cb60e1 --- a/sys/lib/hashtable_private.h +++ b/sys/lib/hashtable_private.h @@ -6,8 +6,7 @@ #include "hashtable.h" /*****************************************************************************/ -struct entry -{ +struct entry { void *k, *v; unsigned int h; struct entry *next; @@ -19,8 +18,8 @@ struct hashtable { unsigned int entrycount; unsigned int loadlimit; unsigned int primeindex; - unsigned int (*hashfn) (void *k); - int (*eqfn) (void *k1, void *k2); + unsigned int (*hashfn)(void *k); + int (*eqfn)(void *k1, void *k2); }; /*****************************************************************************/ @@ -30,7 +29,8 @@ hash(struct hashtable *h, void *k); /*****************************************************************************/ /* indexFor */ static inline unsigned int -indexFor(unsigned int tablelength, unsigned int hashvalue) { +indexFor(unsigned int tablelength, unsigned int hashvalue) +{ return (hashvalue % tablelength); }; @@ -54,23 +54,23 @@ indexFor(unsigned int tablelength, unsigned int hashvalue) /* * Copyright (c) 2002, Christopher Clark * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * - * + * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/sys/lib/ringbuffer.c b/sys/lib/ringbuffer.c old mode 100755 new mode 100644 index a64fa836a525d98dcf1797097ac9e6b9a16e1a4e..d0039495c2c9d29fc1186915568085905c022745 --- a/sys/lib/ringbuffer.c +++ b/sys/lib/ringbuffer.c @@ -1,3 +1,20 @@ +/** + * Ringbuffer implementation + * + * Copyright (C) 2013 Freie Universität Berlin + * Copyright (C) 2013 INRIA + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sys_lib + * @{ + * @file ringbuffer.c + * @author Kaspar Schleiser <kaspar.schleiser@fu-berlin.de> + * @} + */ + #include <stdio.h> #include <stdint.h> #include <string.h> @@ -13,7 +30,8 @@ //#define DEBUG(...) printf (__VA_ARGS__) #define DEBUG(...) -void ringbuffer_init(ringbuffer_t *rb, char* buffer, unsigned int bufsize) { +void ringbuffer_init(ringbuffer_t *rb, char *buffer, unsigned int bufsize) +{ rb->buf = buffer; rb->start = 0; rb->end = 0; @@ -21,37 +39,53 @@ void ringbuffer_init(ringbuffer_t *rb, char* buffer, unsigned int bufsize) { rb->avail = 0; } -void rb_add_elements(ringbuffer_t* rb, char *buf, int n) { - for (int i = 0; i < n; i++) { +void rb_add_elements(ringbuffer_t *rb, char *buf, int n) +{ + for(int i = 0; i < n; i++) { rb_add_element(rb, buf[i]); } } -void rb_add_element(ringbuffer_t* rb, char c) { - if (rb->avail == rb->size) rb_get_element(rb); +void rb_add_element(ringbuffer_t *rb, char c) +{ + if(rb->avail == rb->size) { + rb_get_element(rb); + } rb->buf[rb->end++] = c; - if (rb->end >= rb->size) rb->end = 0; + + if(rb->end >= rb->size) { + rb->end = 0; + } rb->avail++; } -int rb_get_element(ringbuffer_t *rb) { - if (rb->avail == 0) return -1; - +int rb_get_element(ringbuffer_t *rb) +{ + if(rb->avail == 0) { + return -1; + } + rb->avail--; int c = (char)rb->buf[rb->start++]; - if (rb->start >= rb->size) rb->start = 0; + + if(rb->start >= rb->size) { + rb->start = 0; + } return c; } -int rb_get_elements(ringbuffer_t *rb, char* buf, int n) { +int rb_get_elements(ringbuffer_t *rb, char *buf, int n) +{ int count = 0; - while (rb->avail && (count < n)) { + + while(rb->avail && (count < n)) { buf[count++] = rb_get_element(rb); } + return count; } @@ -71,7 +105,7 @@ int main(int argc, char *argv[] ){ rb_add_element(&r, 8); rb_add_element(&r, 9); rb_add_element(&r, 10); - + int c; while ( r.avail ) { c = rb_get_element(&r); @@ -103,7 +137,7 @@ int main(int argc, char *argv[] ){ rb_add_element(&r, 8); rb_add_element(&r, 9); rb_add_element(&r, 10); - + while ( r.avail ) { c = rb_get_element(&r); if (c == -1) break; diff --git a/sys/lib/ringbuffer.h b/sys/lib/ringbuffer.h old mode 100755 new mode 100644 index 3e646ae7951e63aa64965a0fb6bd3fa59193f002..0528b31bcedfedb52050f447d77aec7c076e1ca4 --- a/sys/lib/ringbuffer.h +++ b/sys/lib/ringbuffer.h @@ -1,5 +1,22 @@ +/** + * Ringbuffer header + * + * Copyright (C) 2013 Freie Universität Berlin + * Copyright (C) 2013 INRIA + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup sys_lib + * @{ + * @file ringbuffer.h + * @author Kaspar Schleiser <kaspar.schleiser@fu-berlin.de> + * @} + */ + #ifndef __RINGBUFFER_H -#define __RINGBUFFER_H +#define __RINGBUFFER_H typedef struct ringbuffer { char *buf; @@ -9,7 +26,7 @@ typedef struct ringbuffer { unsigned int avail; } ringbuffer_t; -void ringbuffer_init(ringbuffer_t *rb, char* buffer, unsigned int bufsize); +void ringbuffer_init(ringbuffer_t *rb, char *buffer, unsigned int bufsize); void rb_add_element(ringbuffer_t *rb, char c); void rb_add_elements(ringbuffer_t *rb, char *buf, int n); int rb_get_element(ringbuffer_t *rb); diff --git a/sys/logd/logd.c b/sys/logd/logd.c index 2552e7a78d1cff82ab3cb3c4c099fb7f229abc73..f7b707f6829a8ba7bd1c870b8f62feb60ed97b24 100644 --- a/sys/logd/logd.c +++ b/sys/logd/logd.c @@ -1,31 +1,15 @@ -/****************************************************************************** -Copyright 2009-2010, Freie Universitaet Berlin (FUB). All rights reserved. - -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of RIOT. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -RIOT is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de -*******************************************************************************/ +/** + * Logging daemon + * + * Copyright (C) 2009-2013 Freie Universitaet Berlin + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ /** - * @file + * @file logd.c * @brief Simple logging demon implementation * * @author Freie Universität Berlin, Computer Systems & Telematics @@ -39,26 +23,25 @@ and the mailinglist (subscription via web site) #include <stdlib.h> #include <fcntl.h> #include <string.h> -// core +/* core */ #include "msg.h" #include "flags.h" #include "mutex.h" #include "thread.h" #include "kernel.h" -// system +/* system */ #include "logd.h" #include "list.h" -typedef struct log_queue_t -{ - list_node_t listnode; - char* str; - int str_len; +typedef struct { + list_node_t listnode; + char *str; + int str_len; } log_queue_t; static volatile int log_pid = -1; static int logd_stack_size = LOGD_STACK_SIZE_NORMAL; -static FILE* fh = NULL; +static FILE *fh = NULL; static int log_count = 0; static mutex_t log_mutex; static list_t log_msg_queue; @@ -69,125 +52,156 @@ static volatile bool echo_on = false; static void close_file_handle(void) { - if (fh != NULL) { - fclose(fh); - fh = NULL; - } + if(fh != NULL) { + fclose(fh); + fh = NULL; + } } -static void write_to_file(char* str, int str_len) +static void write_to_file(char *str, int str_len) { - if (fh != NULL && str_len > 0) { - if (fwrite(str, sizeof(char), str_len, fh) != str_len) { - if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { - printf("LOGD [WARN]: file write failed, closing file\n"); - } - close_file_handle(); - return; - } - if (fflush(fh) == EOF) { - if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { - printf("LOGD [WARN]: file write failed, closing file\n"); - } - close_file_handle(); - return; - } - } else { - fh = fopen("/LOGD.LOG", "w"); - if (!fh) { - if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { - printf("LOGD [WARN]: file reopen failed, damn!\n"); - } - } else { - write_to_file(str, str_len); - } - } + if(fh != NULL && str_len > 0) { + if(fwrite(str, sizeof(char), str_len, fh) != str_len) { + if(echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { + printf("LOGD [WARN]: file write failed, closing file\n"); + } + + close_file_handle(); + return; + } + + if(fflush(fh) == EOF) { + if(echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { + printf("LOGD [WARN]: file write failed, closing file\n"); + } + + close_file_handle(); + return; + } + } + else { + fh = fopen("/LOGD.LOG", "w"); + + if(!fh) { + if(echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { + printf("LOGD [WARN]: file reopen failed, damn!\n"); + } + } + else { + write_to_file(str, str_len); + } + } } static void logd_process(void) { - msg m; - log_queue_t* node; - do - { - if (!exit_flag) msg_receive(&m); - mutex_lock(&log_mutex); - while ((node = (log_queue_t*) list_remove_head(&log_msg_queue)) != NULL) { - write_to_file(node->str, node->str_len); - if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { - printf("%s", node->str); - } - log_count++; - free(node->str); - free(node); - } - mutex_unlock(&log_mutex, 0); - } while (m.type != MSG_EXIT && !exit_flag); - /* Logging thread is terminating, close log file */ - close_file_handle(); + msg m; + log_queue_t *node; + + do { + if(!exit_flag) { + msg_receive(&m); + } + + mutex_lock(&log_mutex); + + while((node = (log_queue_t *) list_remove_head(&log_msg_queue)) != NULL) { + write_to_file(node->str, node->str_len); + + if(echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) { + printf("%s", node->str); + } + + log_count++; + free(node->str); + free(node); + } + + mutex_unlock(&log_mutex, 0); + } + while(m.type != MSG_EXIT && !exit_flag); + + /* Logging thread is terminating, close log file */ + close_file_handle(); } /*---------------------------------------------------------------------------*/ -static void logd_init0(void) { - fh = fopen("/LOGD.LOG", "w"); - if (!fh) return; - log_pid = thread_create(logd_stack_size, PRIORITY_LOGD, CREATE_STACKTEST, logd_process, "logd"); +static void logd_init0(void) +{ + fh = fopen("/LOGD.LOG", "w"); + + if(!fh) { + return; + } + + log_pid = thread_create(logd_stack_size, PRIORITY_LOGD, CREATE_STACKTEST, logd_process, "logd"); } void logd_init(int stack_size) { - logd_stack_size = stack_size; - mutex_init(&log_mutex); - list_init(&log_msg_queue); - logd_init0(); + logd_stack_size = stack_size; + mutex_init(&log_mutex); + list_init(&log_msg_queue); + logd_init0(); } void logd_set_console_enabled(bool enabled) { - echo_on = enabled; + echo_on = enabled; } -bool logd_log(char* str, int str_len) +bool logd_log(char *str, int str_len) { - msg m; - // Test if logd process was created - if (log_pid == -1) { - // no logd created, because fopen() on log file failed. So try again - logd_init0(); - if (log_pid == -1) { - // Still errors opening log file, exit now - return false; - } - } - log_queue_t* lq = malloc(sizeof(*lq)); - if (lq == NULL) return false; - lq->str = malloc(sizeof(char) * str_len + 1); // 1 byte for string termination char - if (lq->str == NULL) { - free(lq); - return false; - } - strncpy(lq->str, str, str_len); - lq->str_len = str_len; - lq->str[str_len] = '\0'; // add string termination char at end of buffer - mutex_lock(&log_mutex); - list_append(&log_msg_queue, (list_node_t*) lq); - mutex_unlock(&log_mutex, 0); - m.type = MSG_POLL; - m.content.ptr = NULL; - msg_send(&m, log_pid, false); - return true; + msg m; + + /* Test if logd process was created */ + if(log_pid == -1) { + /* no logd created, because fopen() on log file failed. So try again */ + logd_init0(); + + if(log_pid == -1) { + /* Still errors opening log file, exit now */ + return false; + } + } + + log_queue_t *lq = malloc(sizeof(*lq)); + + if(lq == NULL) { + return false; + } + + lq->str = malloc(sizeof(char) * str_len + 1); /* 1 byte for string termination char */ + + if(lq->str == NULL) { + free(lq); + return false; + } + + strncpy(lq->str, str, str_len); + lq->str_len = str_len; + lq->str[str_len] = '\0'; /* add string termination char at end of buffer */ + mutex_lock(&log_mutex); + list_append(&log_msg_queue, (list_node_t *) lq); + mutex_unlock(&log_mutex, 0); + m.type = MSG_POLL; + m.content.ptr = NULL; + msg_send(&m, log_pid, false); + return true; } void logd_exit(void) { - msg m; - // Test if logd process was created - if (log_pid == -1) { - return; - } - exit_flag = true; - m.type = MSG_EXIT; - m.content.ptr = NULL; - msg_send(&m, log_pid, false); + msg m; + + /* Test if logd process was created */ + if(log_pid == -1) { + return; + } + + exit_flag = true; + m.type = MSG_EXIT; + m.content.ptr = NULL; + msg_send(&m, log_pid, false); } diff --git a/sys/net/destiny/destiny.c b/sys/net/destiny/destiny.c index 84862d56449890359276345cbbb729834edd86b9..c2f069272bf83da12e8b0847d254283fd0ffdcb3 100644 --- a/sys/net/destiny/destiny.c +++ b/sys/net/destiny/destiny.c @@ -1,8 +1,18 @@ -/* - * destiny.c +/** + * Destiny transpor layer implementation * - * Created on: 03.09.2011 - * Author: Oliver + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file destiny.c + * @brief transpor layer functions + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ #include <thread.h> @@ -17,28 +27,34 @@ #include "destiny.h" void init_transport_layer(void) - { - printf("Initializing transport layer packages. Size of socket_type: %u\n", sizeof(socket_internal_t)); - // SOCKETS - memset(sockets, 0, MAX_SOCKETS*sizeof(socket_internal_t)); +{ + printf("Initializing transport layer packages. Size of socket_type: %u\n", + sizeof(socket_internal_t)); + /* SOCKETS */ + memset(sockets, 0, MAX_SOCKETS * sizeof(socket_internal_t)); - // UDP - int udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, udp_packet_handler, "udp_packet_handler"); - set_udp_packet_handler_pid(udp_thread_pid); + /* UDP */ + int udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE, + PRIORITY_MAIN, CREATE_STACKTEST, + udp_packet_handler,"udp_packet_handler"); + set_udp_packet_handler_pid(udp_thread_pid); - // TCP - timex_t now; - vtimer_now(&now); - srand(now.microseconds); + /* TCP */ + timex_t now; + vtimer_now(&now); + srand(now.microseconds); #ifdef TCP_HC - printf("TCP_HC enabled!\n"); - global_context_counter = rand(); + printf("TCP_HC enabled!\n"); + global_context_counter = rand(); #endif - global_sequence_counter = rand(); + global_sequence_counter = rand(); - int tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE, PRIORITY_MAIN, CREATE_STACKTEST, tcp_packet_handler, "tcp_packet_handler"); - set_tcp_packet_handler_pid(tcp_thread_pid); + int tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE, + PRIORITY_MAIN, CREATE_STACKTEST, + tcp_packet_handler, "tcp_packet_handler"); + set_tcp_packet_handler_pid(tcp_thread_pid); - thread_create(tcp_timer_stack, TCP_TIMER_STACKSIZE, PRIORITY_MAIN+1, CREATE_STACKTEST, tcp_general_timer, "tcp_general_timer"); + thread_create(tcp_timer_stack, TCP_TIMER_STACKSIZE, PRIORITY_MAIN + 1, + CREATE_STACKTEST, tcp_general_timer, "tcp_general_timer"); - } +} diff --git a/sys/net/destiny/socket.c b/sys/net/destiny/socket.c index 3feeb40665adfddb7ceb1d339f91d5c167b45bd0..5f8af82ff826caf6225371c4afe75a7b936f1c38 100644 --- a/sys/net/destiny/socket.c +++ b/sys/net/destiny/socket.c @@ -1,9 +1,20 @@ -/* - * socket.c +/** + * Destiny socket API * - * Created on: 16.09.2011 - * Author: Oliver + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file socket.c + * @brief functions for BSD socket API + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ + #include <thread.h> #include <stdio.h> #include <string.h> @@ -23,1228 +34,1305 @@ socket_internal_t sockets[MAX_SOCKETS]; void printf_tcp_context(tcp_hc_context_t *current_tcp_context) - { - printf("Context: %u\n", current_tcp_context->context_id); - printf("Rcv Seq: %" PRIu32 " Rcv Ack: %" PRIu32 ", Rcv Wnd: %u\n", current_tcp_context->seq_rcv, current_tcp_context->ack_rcv, current_tcp_context->wnd_rcv); - printf("Snd Seq: %" PRIu32 " Snd Ack: %" PRIu32 ", Snd Wnd: %u\n", current_tcp_context->seq_snd, current_tcp_context->ack_snd, current_tcp_context->wnd_snd); - } - -void print_tcp_flags (tcp_hdr_t *tcp_header) - { - printf("FLAGS: "); - switch(tcp_header->reserved_flags) - { - case TCP_ACK: - { - printf("ACK "); - break; - } - case TCP_RST: - { - printf("RST "); - break; - } - case TCP_SYN: - { - printf("SYN "); - break; - } - case TCP_FIN: - { - printf("FIN "); - break; - } - case TCP_URG_PSH: - { - printf("URG PSH "); - break; - } - case TCP_SYN_ACK: - { - printf("SYN ACK "); - break; - } - case TCP_FIN_ACK: - { - printf("FIN ACK "); - break; - } - } - printf("\n"); - } +{ + printf("Context: %u\n", current_tcp_context->context_id); + printf("Rcv Seq: %" PRIu32 " Rcv Ack: %" PRIu32 ", Rcv Wnd: %u\n", current_tcp_context->seq_rcv, current_tcp_context->ack_rcv, current_tcp_context->wnd_rcv); + printf("Snd Seq: %" PRIu32 " Snd Ack: %" PRIu32 ", Snd Wnd: %u\n", current_tcp_context->seq_snd, current_tcp_context->ack_snd, current_tcp_context->wnd_snd); +} + +void print_tcp_flags(tcp_hdr_t *tcp_header) +{ + printf("FLAGS: "); + + switch(tcp_header->reserved_flags) { + case TCP_ACK: { + printf("ACK "); + break; + } + + case TCP_RST: { + printf("RST "); + break; + } + + case TCP_SYN: { + printf("SYN "); + break; + } + + case TCP_FIN: { + printf("FIN "); + break; + } + + case TCP_URG_PSH: { + printf("URG PSH "); + break; + } + + case TCP_SYN_ACK: { + printf("SYN ACK "); + break; + } + + case TCP_FIN_ACK: { + printf("FIN ACK "); + break; + } + } + + printf("\n"); +} void print_tcp_cb(tcp_cb_t *cb) - { - timex_t now; - vtimer_now(&now); - printf("Send_ISS: %" PRIu32 "\nSend_UNA: %" PRIu32 "\nSend_NXT: %" PRIu32 "\nSend_WND: %u\n", cb->send_iss, cb->send_una, cb->send_nxt, cb->send_wnd); - printf("Rcv_IRS: %" PRIu32 "\nRcv_NXT: %" PRIu32 "\nRcv_WND: %u\n", cb->rcv_irs, cb->rcv_nxt, cb->rcv_wnd); - printf("Time difference: %" PRIu32 ", No_of_retries: %u, State: %u\n\n", timex_sub(now, cb->last_packet_time).microseconds, cb->no_of_retries, cb->state); - } - -void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_t *tcp_socket) - { - printf("--- %s TCP packet: ---\n", (in_or_out == INC_PACKET ? "Incoming" : "Outgoing")); - printf("IPv6 Source:"); - ipv6_print_addr(&ipv6_header->srcaddr); - printf("IPv6 Dest:"); - ipv6_print_addr(&ipv6_header->destaddr); - printf("TCP Length: %x\n", ipv6_header->length-TCP_HDR_LEN); - printf("Source Port: %x, Dest. Port: %x\n", NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); - printf("Source Port: %u, Dest. Port: %u\n", NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); - printf("ACK: %" PRIu32 ", SEQ: %" PRIu32 ", Window: %x\n", tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window); - printf("ACK: %" PRIu32 ", SEQ: %" PRIu32 ", Window: %u\n", tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window); - print_tcp_flags(tcp_header); - print_tcp_cb(&tcp_socket->tcp_control); +{ + timex_t now; + vtimer_now(&now); + printf("Send_ISS: %" PRIu32 "\nSend_UNA: %" PRIu32 "\nSend_NXT: %" PRIu32 "\nSend_WND: %u\n", + cb->send_iss, cb->send_una, cb->send_nxt, cb->send_wnd); + printf("Rcv_IRS: %" PRIu32 "\nRcv_NXT: %" PRIu32 "\nRcv_WND: %u\n", + cb->rcv_irs, cb->rcv_nxt, cb->rcv_wnd); + printf("Time difference: %" PRIu32 ", No_of_retries: %u, State: %u\n\n", + timex_sub(now, cb->last_packet_time).microseconds, cb->no_of_retries, cb->state); +} + +void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header, socket_t *tcp_socket) +{ + printf("--- %s TCP packet: ---\n", + (in_or_out == INC_PACKET ? "Incoming" : "Outgoing")); + printf("IPv6 Source:"); + ipv6_print_addr(&ipv6_header->srcaddr); + printf("IPv6 Dest:"); + ipv6_print_addr(&ipv6_header->destaddr); + printf("TCP Length: %x\n", ipv6_header->length - TCP_HDR_LEN); + printf("Source Port: %x, Dest. Port: %x\n", + NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); + printf("Source Port: %u, Dest. Port: %u\n", + NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); + printf("ACK: %" PRIu32 ", SEQ: %" PRIu32 ", Window: %x\n", + tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window); + printf("ACK: %" PRIu32 ", SEQ: %" PRIu32 ", Window: %u\n", + tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window); + print_tcp_flags(tcp_header); + print_tcp_cb(&tcp_socket->tcp_control); #ifdef TCP_HC - printf_tcp_context(&tcp_socket->tcp_control.tcp_context); + printf_tcp_context(&tcp_socket->tcp_control.tcp_context); #endif - } +} void print_socket(socket_t *current_socket) - { - printf("Domain: %i, Type: %i, Protocol: %i \n", - current_socket->domain, - current_socket->type, - current_socket->protocol); - ipv6_print_addr(¤t_socket->local_address.sin6_addr); - ipv6_print_addr(¤t_socket->foreign_address.sin6_addr); - printf("Local Port: %u, Foreign Port: %u\n", NTOHS(current_socket->local_address.sin6_port), - NTOHS(current_socket->foreign_address.sin6_port)); - } +{ + printf("Domain: %i, Type: %i, Protocol: %i \n", + current_socket->domain, + current_socket->type, + current_socket->protocol); + ipv6_print_addr(¤t_socket->local_address.sin6_addr); + ipv6_print_addr(¤t_socket->foreign_address.sin6_addr); + printf("Local Port: %u, Foreign Port: %u\n", + NTOHS(current_socket->local_address.sin6_port), + NTOHS(current_socket->foreign_address.sin6_port)); +} void print_internal_socket(socket_internal_t *current_socket_internal) - { - socket_t *current_socket = ¤t_socket_internal->socket_values; - printf("\n--------------------------\n"); - printf("ID: %i, RECV PID: %i SEND PID: %i\n", current_socket_internal->socket_id, current_socket_internal->recv_pid, current_socket_internal->send_pid); - print_socket(current_socket); - printf("\n--------------------------\n"); - } +{ + socket_t *current_socket = ¤t_socket_internal->socket_values; + printf("\n--------------------------\n"); + printf("ID: %i, RECV PID: %i SEND PID: %i\n", + current_socket_internal->socket_id, current_socket_internal->recv_pid, + current_socket_internal->send_pid); + print_socket(current_socket); + printf("\n--------------------------\n"); +} socket_internal_t *getSocket(uint8_t s) - { - if (exists_socket(s)) - { - return &(sockets[s-1]); - } - else - { - return NULL; - } - } +{ + if(exists_socket(s)) { + return &(sockets[s - 1]); + } + else { + return NULL; + } +} void print_sockets(void) - { - int i; - printf("\n--- Socket list: ---\n"); - for (i = 1; i < MAX_SOCKETS+1; i++) - { - if(getSocket(i) != NULL) - { - print_internal_socket(getSocket(i)); - } - } - } +{ + int i; + printf("\n--- Socket list: ---\n"); + + for(i = 1; i < MAX_SOCKETS + 1; i++) { + if(getSocket(i) != NULL) { + print_internal_socket(getSocket(i)); + } + } +} bool exists_socket(uint8_t socket) - { - if (sockets[socket-1].socket_id == 0) - { - return false; - } - else - { - return true; - } - } +{ + if(sockets[socket - 1].socket_id == 0) { + return false; + } + else { + return true; + } +} void close_socket(socket_internal_t *current_socket) - { - memset(current_socket, 0, sizeof(socket_internal_t)); - } +{ + memset(current_socket, 0, sizeof(socket_internal_t)); +} bool isUDPSocket(uint8_t s) - { - if ( (exists_socket(s)) && - (getSocket(s)->socket_values.domain == PF_INET6) && - (getSocket(s)->socket_values.type == SOCK_DGRAM) && - ((getSocket(s)->socket_values.protocol == IPPROTO_UDP) || - (getSocket(s)->socket_values.protocol == 0))) - return true; - else - return false; - } +{ + if((exists_socket(s)) && + (getSocket(s)->socket_values.domain == PF_INET6) && + (getSocket(s)->socket_values.type == SOCK_DGRAM) && + ((getSocket(s)->socket_values.protocol == IPPROTO_UDP) || + (getSocket(s)->socket_values.protocol == 0))) { + return true; + } + else { + return false; + } +} bool isTCPSocket(uint8_t s) - { - if ( (exists_socket(s)) && - (getSocket(s)->socket_values.domain == PF_INET6) && - (getSocket(s)->socket_values.type == SOCK_STREAM) && - ((getSocket(s)->socket_values.protocol == IPPROTO_TCP) || - (getSocket(s)->socket_values.protocol == 0))) - return true; - else - return false; - } +{ + if((exists_socket(s)) && + (getSocket(s)->socket_values.domain == PF_INET6) && + (getSocket(s)->socket_values.type == SOCK_STREAM) && + ((getSocket(s)->socket_values.protocol == IPPROTO_TCP) || + (getSocket(s)->socket_values.protocol == 0))) { + return true; + } + else { + return false; + } +} int bind_udp_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid) - { - int i; - if (!exists_socket(s)) - { - return -1; - } - for (i = 1; i < MAX_SOCKETS+1; i++) - { - if (isUDPSocket(i) && (getSocket(i)->socket_values.local_address.sin6_port == name->sin6_port)) - { - return -1; - } - } - memcpy(&getSocket(s)->socket_values.local_address, name, namelen); - getSocket(s)->recv_pid = pid; - return 1; - } +{ + int i; + + if(!exists_socket(s)) { + return -1; + } + + for(i = 1; i < MAX_SOCKETS + 1; i++) { + if(isUDPSocket(i) && + (getSocket(i)->socket_values.local_address.sin6_port == name->sin6_port)) { + return -1; + } + } + + memcpy(&getSocket(s)->socket_values.local_address, name, namelen); + getSocket(s)->recv_pid = pid; + return 1; +} int bind_tcp_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid) - { - int i; - if (!exists_socket(s)) - { - return -1; - } - for (i = 1; i < MAX_SOCKETS+1; i++) - { - if (isTCPSocket(i) && (getSocket(i)->socket_values.local_address.sin6_port == name->sin6_port)) - { - return -1; - } - } - memcpy(&getSocket(s)->socket_values.local_address, name, namelen); - getSocket(s)->recv_pid = pid; - getSocket(s)->socket_values.tcp_control.rto = TCP_INITIAL_ACK_TIMEOUT; - return 1; - } +{ + int i; + + if(!exists_socket(s)) { + return -1; + } + + for(i = 1; i < MAX_SOCKETS + 1; i++) { + if(isTCPSocket(i) && + (getSocket(i)->socket_values.local_address.sin6_port == name->sin6_port)) { + return -1; + } + } + + memcpy(&getSocket(s)->socket_values.local_address, name, namelen); + getSocket(s)->recv_pid = pid; + getSocket(s)->socket_values.tcp_control.rto = TCP_INITIAL_ACK_TIMEOUT; + return 1; +} int socket(int domain, int type, int protocol) - { - int i = 1; - while (getSocket(i) != NULL) - { - i++; - } - if (i > MAX_SOCKETS+1) - { - return -1; - } - else - { - socket_t *current_socket = &sockets[i-1].socket_values; - sockets[i-1].socket_id = i; - current_socket->domain = domain; - current_socket->type = type; - current_socket->protocol = protocol; - current_socket->tcp_control.state = CLOSED; - return sockets[i-1].socket_id; - } - } +{ + int i = 1; + + while(getSocket(i) != NULL) { + i++; + } + + if(i > MAX_SOCKETS + 1) { + return -1; + } + else { + socket_t *current_socket = &sockets[i - 1].socket_values; + sockets[i - 1].socket_id = i; + current_socket->domain = domain; + current_socket->type = type; + current_socket->protocol = protocol; + current_socket->tcp_control.state = CLOSED; + return sockets[i - 1].socket_id; + } +} socket_internal_t *get_udp_socket(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header) - { - uint8_t i = 1; - while (i < MAX_SOCKETS+1) - { - if ( isUDPSocket(i) && - (getSocket(i)->socket_values.local_address.sin6_port == udp_header->dst_port)) - { - return getSocket(i); - } - i++; - } - return NULL; - } - -bool is_four_touple (socket_internal_t *current_socket, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header) - { - return ((ipv6_get_addr_match(¤t_socket->socket_values.local_address.sin6_addr, &ipv6_header->destaddr) == 128) && - (current_socket->socket_values.local_address.sin6_port == tcp_header->dst_port) && - (ipv6_get_addr_match(¤t_socket->socket_values.foreign_address.sin6_addr, &ipv6_header->srcaddr) == 128) && - (current_socket->socket_values.foreign_address.sin6_port == tcp_header->src_port)); - } +{ + uint8_t i = 1; + + while(i < MAX_SOCKETS + 1) { + if(isUDPSocket(i) && + (getSocket(i)->socket_values.local_address.sin6_port == + udp_header->dst_port)) { + return getSocket(i); + } + + i++; + } + + return NULL; +} + +bool is_four_touple(socket_internal_t *current_socket, ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header) +{ + return ((ipv6_get_addr_match(¤t_socket->socket_values.local_address.sin6_addr + &ipv6_header->destaddr) == 128) && + (current_socket->socket_values.local_address.sin6_port == tcp_header->dst_port) && + (ipv6_get_addr_match(¤t_socket->socket_values.foreign_address.sin6_addr, + &ipv6_header->srcaddr) == 128) && + (current_socket->socket_values.foreign_address.sin6_port == tcp_header->src_port)); +} socket_internal_t *get_tcp_socket(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header) - { - uint8_t i = 1; - socket_internal_t *current_socket = NULL; - socket_internal_t *listening_socket = NULL; - uint8_t compare[16]; - memset(compare, 0, 16); - - while (i < MAX_SOCKETS+1) - { - current_socket = getSocket(i); - // Check for matching 4 touple, ESTABLISHED connection - if( isTCPSocket(i) && is_four_touple(current_socket, ipv6_header, tcp_header)) - { - return current_socket; - } - // Sockets in LISTEN and SYN_RCVD state should only be tested on local TCP values - else if ( isTCPSocket(i) && - ((current_socket->socket_values.tcp_control.state == LISTEN) || (current_socket->socket_values.tcp_control.state == SYN_RCVD)) && - (current_socket->socket_values.local_address.sin6_addr.uint8[15] == ipv6_header->destaddr.uint8[15]) && - (current_socket->socket_values.local_address.sin6_port == tcp_header->dst_port) && - (current_socket->socket_values.foreign_address.sin6_addr.uint8[15] == 0x00) && - (current_socket->socket_values.foreign_address.sin6_port == 0)) - { - listening_socket = current_socket; - } - i++; - } - // Return either NULL if nothing was matched or the listening 2 touple socket - return listening_socket; - } +{ + uint8_t i = 1; + socket_internal_t *current_socket = NULL; + socket_internal_t *listening_socket = NULL; + uint8_t compare[16]; + memset(compare, 0, 16); + + while(i < MAX_SOCKETS + 1) { + current_socket = getSocket(i); + + /* Check for matching 4 touple, ESTABLISHED connection */ + if(isTCPSocket(i) && is_four_touple(current_socket, ipv6_header, + tcp_header)) { + return current_socket; + } + /* Sockets in LISTEN and SYN_RCVD state should only be tested on local TCP values */ + else if(isTCPSocket(i) && + ((current_socket->socket_values.tcp_control.state == LISTEN) || + (current_socket->socket_values.tcp_control.state == SYN_RCVD)) && + (current_socket->socket_values.local_address.sin6_addr.uint8[15] == + ipv6_header->destaddr.uint8[15]) && + (current_socket->socket_values.local_address.sin6_port == + tcp_header->dst_port) && + (current_socket->socket_values.foreign_address.sin6_addr.uint8[15] == + 0x00) && + (current_socket->socket_values.foreign_address.sin6_port == 0)) { + listening_socket = current_socket; + } + + i++; + } + + /* Return either NULL if nothing was matched or the listening 2 touple socket */ + return listening_socket; +} uint16_t get_free_source_port(uint8_t protocol) - { - int i; - uint16_t biggest_port = EPHEMERAL_PORTS-1; - // Remember biggest ephemeral port number used so far and add 1 - for (i = 0; i < MAX_SOCKETS; i++) - { - if ((sockets[i].socket_values.protocol == protocol) && (sockets[i].socket_values.local_address.sin6_port > biggest_port)) - { - biggest_port = sockets[i].socket_values.local_address.sin6_port; - } - } - return biggest_port + 1; - } - -void set_socket_address(sockaddr6_t *sockaddr, uint8_t sin6_family, uint16_t sin6_port, uint32_t sin6_flowinfo, ipv6_addr_t *sin6_addr) - { - sockaddr->sin6_family = sin6_family; - sockaddr->sin6_port = sin6_port; - sockaddr->sin6_flowinfo = sin6_flowinfo; - memcpy(&sockaddr->sin6_addr, sin6_addr, 16); - } - -void set_tcp_packet(tcp_hdr_t *tcp_hdr, uint16_t src_port, uint16_t dst_port, uint32_t seq_nr, uint32_t ack_nr, - uint8_t dataOffset_reserved, uint8_t reserved_flags, uint16_t window, uint16_t checksum, uint16_t urg_pointer) - { - tcp_hdr->ack_nr = ack_nr; - tcp_hdr->checksum = checksum; - tcp_hdr->dataOffset_reserved = dataOffset_reserved; - tcp_hdr->dst_port = dst_port; - tcp_hdr->reserved_flags = reserved_flags; - tcp_hdr->seq_nr = seq_nr; - tcp_hdr->src_port = src_port; - tcp_hdr->urg_pointer = urg_pointer; - tcp_hdr->window = window; - } - -// Check for consistent ACK and SEQ number +{ + int i; + uint16_t biggest_port = EPHEMERAL_PORTS - 1; + + /* Remember biggest ephemeral port number used so far and add 1 */ + for(i = 0; i < MAX_SOCKETS; i++) { + if((sockets[i].socket_values.protocol == protocol) && + (sockets[i].socket_values.local_address.sin6_port > biggest_port)) { + biggest_port = sockets[i].socket_values.local_address.sin6_port; + } + } + + return biggest_port + 1; +} + +void set_socket_address(sockaddr6_t *sockaddr, uint8_t sin6_family, + uint16_t sin6_port, uint32_t sin6_flowinfo, ipv6_addr_t *sin6_addr) +{ + sockaddr->sin6_family = sin6_family; + sockaddr->sin6_port = sin6_port; + sockaddr->sin6_flowinfo = sin6_flowinfo; + memcpy(&sockaddr->sin6_addr, sin6_addr, 16); +} + +void set_tcp_packet(tcp_hdr_t *tcp_hdr, uint16_t src_port, uint16_t dst_port, + uint32_t seq_nr, uint32_t ack_nr, uint8_t dataOffset_reserved, + uint8_t reserved_flags, uint16_t window, uint16_t checksum, + uint16_t urg_pointer) +{ + tcp_hdr->ack_nr = ack_nr; + tcp_hdr->checksum = checksum; + tcp_hdr->dataOffset_reserved = dataOffset_reserved; + tcp_hdr->dst_port = dst_port; + tcp_hdr->reserved_flags = reserved_flags; + tcp_hdr->seq_nr = seq_nr; + tcp_hdr->src_port = src_port; + tcp_hdr->urg_pointer = urg_pointer; + tcp_hdr->window = window; +} + +/* Check for consistent ACK and SEQ number */ int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header) - { - if (IS_TCP_ACK(tcp_header->reserved_flags)) - { - if(tcp_header->ack_nr > (current_tcp_socket->tcp_control.send_nxt)) - { - // ACK of not yet sent byte, discard - return ACK_NO_TOO_BIG; - } - else if (tcp_header->ack_nr <= (current_tcp_socket->tcp_control.send_una)) - { - // ACK of previous segments, maybe dropped? - return ACK_NO_TOO_SMALL; - } - } - else if ((current_tcp_socket->tcp_control.rcv_nxt > 0) && (tcp_header->seq_nr < current_tcp_socket->tcp_control.rcv_nxt)) - { - // segment repetition, maybe ACK got lost? - return SEQ_NO_TOO_SMALL; - } - return PACKET_OK; - } +{ + if(IS_TCP_ACK(tcp_header->reserved_flags)) { + if(tcp_header->ack_nr > (current_tcp_socket->tcp_control.send_nxt)) { + /* ACK of not yet sent byte, discard */ + return ACK_NO_TOO_BIG; + } + else if(tcp_header->ack_nr <= (current_tcp_socket->tcp_control.send_una)) { + /* ACK of previous segments, maybe dropped? */ + return ACK_NO_TOO_SMALL; + } + } + else if((current_tcp_socket->tcp_control.rcv_nxt > 0) && (tcp_header->seq_nr < current_tcp_socket->tcp_control.rcv_nxt)) { + /* segment repetition, maybe ACK got lost? */ + return SEQ_NO_TOO_SMALL; + } + + return PACKET_OK; +} void switch_tcp_packet_byte_order(tcp_hdr_t *current_tcp_packet) - { - if (current_tcp_packet->dataOffset_reserved*4 > TCP_HDR_LEN) - { - if (*(((uint8_t*)current_tcp_packet)+TCP_HDR_LEN) == TCP_MSS_OPTION) - { - uint8_t *packet_pointer = (uint8_t *)current_tcp_packet; - packet_pointer += (TCP_HDR_LEN+2); - uint8_t mss1 = *packet_pointer; - uint8_t mss2 = *(packet_pointer+1); - *packet_pointer = mss2; - *(packet_pointer+1) = mss1; - } - if (*(((uint8_t*)current_tcp_packet)+TCP_HDR_LEN) == TCP_TS_OPTION) - { - // TODO: Timestamp option not implemented - } - } - - current_tcp_packet->seq_nr = HTONL(current_tcp_packet->seq_nr); - current_tcp_packet->ack_nr = HTONL(current_tcp_packet->ack_nr); - current_tcp_packet->window = HTONS(current_tcp_packet->window); - current_tcp_packet->urg_pointer = HTONS(current_tcp_packet->urg_pointer); - } - -int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, ipv6_hdr_t *temp_ipv6_header, uint8_t flags, uint8_t payload_length) - { - socket_t *current_tcp_socket = ¤t_socket->socket_values; - uint8_t header_length = TCP_HDR_LEN/4; - if (IS_TCP_SYN(flags) || IS_TCP_SYN_ACK(flags)) - { - tcp_mss_option_t current_mss_option; - header_length += sizeof(tcp_mss_option_t)/4; - - current_mss_option.kind = TCP_MSS_OPTION; - current_mss_option.len = sizeof(tcp_mss_option_t); - current_mss_option.mss = STATIC_MSS; - memcpy(((uint8_t*)current_tcp_packet)+TCP_HDR_LEN, ¤t_mss_option, sizeof(tcp_mss_option_t)); - } - - set_tcp_packet(current_tcp_packet, current_tcp_socket->local_address.sin6_port, current_tcp_socket->foreign_address.sin6_port, - (flags == TCP_ACK ? current_tcp_socket->tcp_control.send_una-1 : current_tcp_socket->tcp_control.send_una), - current_tcp_socket->tcp_control.rcv_nxt, header_length, flags, current_tcp_socket->tcp_control.rcv_wnd, 0, 0); - - // Fill IPv6 Header - memcpy(&(temp_ipv6_header->destaddr), ¤t_tcp_socket->foreign_address.sin6_addr, 16); - memcpy(&(temp_ipv6_header->srcaddr), ¤t_tcp_socket->local_address.sin6_addr, 16); - temp_ipv6_header->length = header_length*4 + payload_length; - - current_tcp_packet->checksum = ~tcp_csum(temp_ipv6_header, current_tcp_packet); +{ + if(current_tcp_packet->dataOffset_reserved * 4 > TCP_HDR_LEN) { + if(*(((uint8_t *)current_tcp_packet) + TCP_HDR_LEN) == TCP_MSS_OPTION) { + uint8_t *packet_pointer = (uint8_t *)current_tcp_packet; + packet_pointer += (TCP_HDR_LEN + 2); + uint8_t mss1 = *packet_pointer; + uint8_t mss2 = *(packet_pointer + 1); + *packet_pointer = mss2; + *(packet_pointer + 1) = mss1; + } + + if(*(((uint8_t *)current_tcp_packet) + TCP_HDR_LEN) == TCP_TS_OPTION) { + /* TODO: Timestamp option not implemented */ + } + } + + current_tcp_packet->seq_nr = HTONL(current_tcp_packet->seq_nr); + current_tcp_packet->ack_nr = HTONL(current_tcp_packet->ack_nr); + current_tcp_packet->window = HTONS(current_tcp_packet->window); + current_tcp_packet->urg_pointer = HTONS(current_tcp_packet->urg_pointer); +} + +int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, + ipv6_hdr_t *temp_ipv6_header, uint8_t flags, uint8_t payload_length) +{ + socket_t *current_tcp_socket = ¤t_socket->socket_values; + uint8_t header_length = TCP_HDR_LEN / 4; + + if(IS_TCP_SYN(flags) || IS_TCP_SYN_ACK(flags)) { + tcp_mss_option_t current_mss_option; + header_length += sizeof(tcp_mss_option_t) / 4; + + current_mss_option.kind = TCP_MSS_OPTION; + current_mss_option.len = sizeof(tcp_mss_option_t); + current_mss_option.mss = STATIC_MSS; + memcpy(((uint8_t *)current_tcp_packet) + TCP_HDR_LEN, + ¤t_mss_option, sizeof(tcp_mss_option_t)); + } + + set_tcp_packet(current_tcp_packet, current_tcp_socket->local_address.sin6_port, + current_tcp_socket->foreign_address.sin6_port, + (flags == TCP_ACK ? current_tcp_socket->tcp_control.send_una - 1 : + current_tcp_socket->tcp_control.send_una), + current_tcp_socket->tcp_control.rcv_nxt, header_length, flags, + current_tcp_socket->tcp_control.rcv_wnd, 0, 0); + + /* Fill IPv6 Header */ + memcpy(&(temp_ipv6_header->destaddr), + ¤t_tcp_socket->foreign_address.sin6_addr, 16); + memcpy(&(temp_ipv6_header->srcaddr), + ¤t_tcp_socket->local_address.sin6_addr, 16); + temp_ipv6_header->length = header_length * 4 + payload_length; + + current_tcp_packet->checksum = ~tcp_csum(temp_ipv6_header, current_tcp_packet); #ifdef TCP_HC - uint16_t compressed_size; - - compressed_size = compress_tcp_packet(current_socket, (uint8_t *) current_tcp_packet, temp_ipv6_header, flags, payload_length); - - if (compressed_size == 0) - { - // Error in compressing tcp packet header - return -1; - } - sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), compressed_size, IPPROTO_TCP); - return 1; + uint16_t compressed_size; + + compressed_size = compress_tcp_packet(current_socket, + (uint8_t *)current_tcp_packet, + temp_ipv6_header, flags, + payload_length); + + if(compressed_size == 0) { + /* Error in compressing tcp packet header */ + return -1; + } + + sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, + (uint8_t *)(current_tcp_packet), compressed_size, + IPPROTO_TCP); + return 1; #else -// print_tcp_status(OUT_PACKET, temp_ipv6_header, current_tcp_packet, current_tcp_socket); - switch_tcp_packet_byte_order(current_tcp_packet); - sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, (uint8_t*)(current_tcp_packet), header_length*4+payload_length, IPPROTO_TCP); - return 1; + switch_tcp_packet_byte_order(current_tcp_packet); + sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr, + (uint8_t *)(current_tcp_packet), + header_length * 4 + payload_length, IPPROTO_TCP); + return 1; #endif - } - -void set_tcp_cb(tcp_cb_t *tcp_control, uint32_t rcv_nxt, uint16_t rcv_wnd, uint32_t send_nxt, uint32_t send_una, uint16_t send_wnd) - { - tcp_control->rcv_nxt = rcv_nxt; - tcp_control->rcv_wnd = rcv_wnd; - tcp_control->send_nxt = send_nxt; - tcp_control->send_una = send_una; - tcp_control->send_wnd = send_wnd; - } +} + +void set_tcp_cb(tcp_cb_t *tcp_control, uint32_t rcv_nxt, uint16_t rcv_wnd, + uint32_t send_nxt, uint32_t send_una, uint16_t send_wnd) +{ + tcp_control->rcv_nxt = rcv_nxt; + tcp_control->rcv_wnd = rcv_wnd; + tcp_control->send_nxt = send_nxt; + tcp_control->send_una = send_una; + tcp_control->send_wnd = send_wnd; +} int connect(int socket, sockaddr6_t *addr, uint32_t addrlen) - { - // Variables - ipv6_addr_t src_addr; - socket_internal_t *current_int_tcp_socket; - socket_t *current_tcp_socket; - msg_t msg_from_server; - uint8_t send_buffer[BUFFER_SIZE]; - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); - - // Check if socket exists - current_int_tcp_socket = getSocket(socket); - if (current_int_tcp_socket == NULL) - { - return -1; - } - - current_tcp_socket = ¤t_int_tcp_socket->socket_values; - - current_int_tcp_socket->recv_pid = thread_getpid(); - - // Local address information - ipv6_get_saddr(&src_addr, &addr->sin6_addr); - set_socket_address(¤t_tcp_socket->local_address, PF_INET6, HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr); - - // Foreign address information - set_socket_address(¤t_tcp_socket->foreign_address, addr->sin6_family, addr->sin6_port, addr->sin6_flowinfo, &addr->sin6_addr); - - // Fill lcoal TCP socket information - srand(addr->sin6_port); - - current_tcp_socket->tcp_control.rcv_irs = 0; - mutex_lock(&global_sequence_clunter_mutex); - current_tcp_socket->tcp_control.send_iss = global_sequence_counter; - mutex_unlock(&global_sequence_clunter_mutex, 0); - current_tcp_socket->tcp_control.state = SYN_SENT; +{ + /* Variables */ + ipv6_addr_t src_addr; + socket_internal_t *current_int_tcp_socket; + socket_t *current_tcp_socket; + msg_t msg_from_server; + uint8_t send_buffer[BUFFER_SIZE]; + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); + + /* Check if socket exists */ + current_int_tcp_socket = getSocket(socket); + + if(current_int_tcp_socket == NULL) { + return -1; + } + + current_tcp_socket = ¤t_int_tcp_socket->socket_values; + + current_int_tcp_socket->recv_pid = thread_getpid(); + + /* Local address information */ + ipv6_get_saddr(&src_addr, &addr->sin6_addr); + set_socket_address(¤t_tcp_socket->local_address, PF_INET6, + HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr); + + /* Foreign address information */ + set_socket_address(¤t_tcp_socket->foreign_address, addr->sin6_family, + addr->sin6_port, addr->sin6_flowinfo, &addr->sin6_addr); + + /* Fill lcoal TCP socket information */ + srand(addr->sin6_port); + + current_tcp_socket->tcp_control.rcv_irs = 0; + mutex_lock(&global_sequence_clunter_mutex); + current_tcp_socket->tcp_control.send_is = global_sequence_counter; + mutex_unlock(&global_sequence_clunter_mutex, 0); + current_tcp_socket->tcp_control.state = SYN_SENT; #ifdef TCP_HC - // Choosing random number Context ID - mutex_lock(&global_context_counter_mutex); - current_tcp_socket->tcp_control.tcp_context.context_id = global_context_counter; - mutex_unlock(&global_context_counter_mutex, 0); + /* Choosing random number Context ID */ + mutex_lock(&global_context_counter_mutex); + current_tcp_socket->tcp_control.tcp_context.context_id = global_context_counter; + mutex_unlock(&global_context_counter_mutex, 0); - current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; - // Remember TCP Context for possible TCP_RETRY - tcp_hc_context_t saved_tcp_context; - memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)); + /* Remember TCP Context for possible TCP_RETRY */ + tcp_hc_context_t saved_tcp_context; + memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, + sizeof(tcp_hc_context_t)); #endif - set_tcp_cb(¤t_tcp_socket->tcp_control, 0, STATIC_WINDOW, current_tcp_socket->tcp_control.send_iss, current_tcp_socket->tcp_control.send_iss, 0); + set_tcp_cb(¤t_tcp_socket->tcp_control, 0, STATIC_WINDOW, + current_tcp_socket->tcp_control.send_iss, + current_tcp_socket->tcp_control.send_iss, 0); + + /* Remember current time */ + timex_t now; + vtimer_now(&now); + current_tcp_socket->tcp_control.last_packet_time = now; + current_tcp_socket->tcp_control.no_of_retries = 0; - // Remember current time - timex_t now; - vtimer_now(&now); - current_tcp_socket->tcp_control.last_packet_time = now; - current_tcp_socket->tcp_control.no_of_retries = 0; + msg_from_server.type = TCP_RETRY; - msg_from_server.type = TCP_RETRY; + while(msg_from_server.type == TCP_RETRY) { + /* Send packet */ + send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, + TCP_SYN, 0); - while (msg_from_server.type == TCP_RETRY) - { - // Send packet - send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_SYN, 0); + /* wait for SYN ACK or RETRY */ + msg_receive(&msg_from_server); - // wait for SYN ACK or RETRY - msg_receive(&msg_from_server); - if (msg_from_server.type == TCP_TIMEOUT) - { + if(msg_from_server.type == TCP_TIMEOUT) { #ifdef TCP_HC - // We did not send anything successful so restore last context - memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); + /* We did not send anything successful so restore last context */ + memcpy(¤t_tcp_socket->tcp_control.tcp_context, + &saved_tcp_context, sizeof(tcp_hc_context_t)); #endif - return -1; - } + return -1; + } + #ifdef TCP_HC - else if (msg_from_server.type == TCP_RETRY) - { - // We retry sending a packet so set everything to last values again - memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); - } + else if(msg_from_server.type == TCP_RETRY) { + /* We retry sending a packet so set everything to last values again */ + memcpy(¤t_tcp_socket->tcp_control.tcp_context, + &saved_tcp_context, sizeof(tcp_hc_context_t)); + } + #endif - } - - // Read packet content - tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(msg_from_server.content.ptr)); - - // Check for consistency - if (tcp_header->ack_nr != current_tcp_socket->tcp_control.send_nxt+1) - { - printf("TCP packets not consistent!\n"); - } - - // Got SYN ACK from Server - // Refresh foreign TCP socket information - if ((tcp_header->dataOffset_reserved*4 > TCP_HDR_LEN) && (*(((uint8_t*)tcp_header)+TCP_HDR_LEN) == TCP_MSS_OPTION)) - { - current_tcp_socket->tcp_control.mss = *((uint16_t*)(((uint8_t*)tcp_header)+TCP_HDR_LEN+2)); - } - else - { - current_tcp_socket->tcp_control.mss = STATIC_MSS; - } - current_tcp_socket->tcp_control.rcv_irs = tcp_header->seq_nr; - set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr+1, current_tcp_socket->tcp_control.rcv_wnd, - current_tcp_socket->tcp_control.send_una, current_tcp_socket->tcp_control.send_una, tcp_header->window); - current_tcp_socket->tcp_control.send_una++; - current_tcp_socket->tcp_control.send_nxt++; - - msg_from_server.type = UNDEFINED; - - // Remember current time - vtimer_now(&now); - current_tcp_socket->tcp_control.last_packet_time = now; - current_tcp_socket->tcp_control.no_of_retries = 0; + } + + /* Read packet content */ + tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(msg_from_server.content.ptr)); + + /* Check for consistency */ + if(tcp_header->ack_nr != current_tcp_socket->tcp_control.send_nxt + 1) { + printf("TCP packets not consistent!\n"); + } + + /* Got SYN ACK from Server */ + /* Refresh foreign TCP socket information */ + if((tcp_header->dataOffset_reserved * 4 > TCP_HDR_LEN) && + (*(((uint8_t *)tcp_header) + TCP_HDR_LEN) == TCP_MSS_OPTION)) { + current_tcp_socket->tcp_control.mss = + *((uint16_t *)(((uint8_t *)tcp_header) + TCP_HDR_LEN + 2)); + } + else { + current_tcp_socket->tcp_control.mss = STATIC_MSS; + } + + current_tcp_socket->tcp_control.rcv_irs = tcp_header->seq_nr; + set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr + 1, + current_tcp_socket->tcp_control.rcv_wnd, + current_tcp_socket->tcp_control.send_una, + current_tcp_socket->tcp_control.send_una, + tcp_header->window); + current_tcp_socket->tcp_control.send_una++; + current_tcp_socket->tcp_control.send_nxt++; + + msg_from_server.type = UNDEFINED; + + /* Remember current time */ + vtimer_now(&now); + current_tcp_socket->tcp_control.last_packet_time = now; + current_tcp_socket->tcp_control.no_of_retries = 0; #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; - // Remember TCP Context for possible TCP_RETRY - memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)); + current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; + /* Remember TCP Context for possible TCP_RETRY */ + memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, + sizeof(tcp_hc_context_t)); #endif - while (msg_from_server.type != TCP_RETRY) - { - // Send packet - send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); + while(msg_from_server.type != TCP_RETRY) { + /* Send packet */ + send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, + TCP_ACK, 0); - msg_receive(&msg_from_server); + msg_receive(&msg_from_server); #ifdef TCP_HC - if (msg_from_server.type == TCP_SYN_ACK) - { - // TCP_SYN_ACK from server arrived again, copy old context and send TCP_ACK again - memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); - } - else if (msg_from_server.type == TCP_RETRY) - { - // We waited for RTT, no TCP_SYN_ACK received, so we assume the TCP_ACK packet arrived safely - } + + if(msg_from_server.type == TCP_SYN_ACK) { + /* TCP_SYN_ACK from server arrived again, copy old context and + * send TCP_ACK again */ + memcpy(¤t_tcp_socket->tcp_control.tcp_context, + &saved_tcp_context, sizeof(tcp_hc_context_t)); + } + else if(msg_from_server.type == TCP_RETRY) { + /* We waited for RTT, no TCP_SYN_ACK received, so we assume the + * TCP_ACK packet arrived safely */ + } + #endif - } + } - current_tcp_socket->tcp_control.state = ESTABLISHED; + current_tcp_socket->tcp_control.state = ESTABLISHED; - current_int_tcp_socket->recv_pid = 255; + current_int_tcp_socket->recv_pid = 255; - print_sockets(); - return 0; - } + print_sockets(); + return 0; +} void calculate_rto(tcp_cb_t *tcp_control, long current_time) - { - double rtt = current_time - tcp_control->last_packet_time.microseconds; - double srtt = tcp_control->srtt; - double rttvar = tcp_control->rttvar; - double rto = tcp_control->rto; - - if ((srtt == 0) && (rttvar == 0) && (rto == TCP_INITIAL_ACK_TIMEOUT)) - { - // First calculation - srtt = rtt; - rttvar = 0.5*rtt; - rto = rtt + (((4*rttvar) < TCP_TIMER_RESOLUTION) ? (TCP_TIMER_RESOLUTION) : (4*rttvar)); - } - else - { - // every other calculation - srtt = (1-TCP_ALPHA)*srtt+TCP_ALPHA*rtt; - rttvar = (1-TCP_BETA)*rttvar+TCP_BETA*abs(srtt-rtt); - rto = srtt + (((4*rttvar) < TCP_TIMER_RESOLUTION) ? (TCP_TIMER_RESOLUTION) : (4*rttvar)); - } - if (rto < SECOND) - { - rto = SECOND; - } - tcp_control->srtt = srtt; - tcp_control->rttvar = rttvar; - tcp_control->rto = rto; - } +{ + double rtt = current_time - tcp_control->last_packet_time.microseconds; + double srtt = tcp_control->srtt; + double rttvar = tcp_control->rttvar; + double rto = tcp_control->rto; + + if((srtt == 0) && (rttvar == 0) && (rto == TCP_INITIAL_ACK_TIMEOUT)) { + /* First calculation */ + srtt = rtt; + rttvar = 0.5 * rtt; + rto = rtt + (((4 * rttvar) < TCP_TIMER_RESOLUTION) ? + (TCP_TIMER_RESOLUTION) : (4 * rttvar)); + } + else { + /* every other calculation */ + srtt = (1 - TCP_ALPHA) * srtt + TCP_ALPHA * rtt; + rttvar = (1 - TCP_BETA) * rttvar + TCP_BETA * abs(srtt - rtt); + rto = srtt + (((4 * rttvar) < TCP_TIMER_RESOLUTION) ? + (TCP_TIMER_RESOLUTION) : (4 * rttvar)); + } + + if(rto < SECOND) { + rto = SECOND; + } + + tcp_control->srtt = srtt; + tcp_control->rttvar = rttvar; + tcp_control->rto = rto; +} int32_t send(int s, void *msg, uint32_t len, int flags) - { - // Variables - msg_t recv_msg; - int32_t sent_bytes = 0, total_sent_bytes = 0; - socket_internal_t *current_int_tcp_socket; - socket_t *current_tcp_socket; - uint8_t send_buffer[BUFFER_SIZE]; - memset(send_buffer, 0, BUFFER_SIZE); - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); - - - // Check if socket exists and is TCP socket - if (!isTCPSocket(s)) - { - return -1; - } - - current_int_tcp_socket = getSocket(s); - current_tcp_socket = ¤t_int_tcp_socket->socket_values; - - // Check for ESTABLISHED STATE - if (current_tcp_socket->tcp_control.state != ESTABLISHED) - { - return -1; - } - - // Add thread PID - current_int_tcp_socket->send_pid = thread_getpid(); - - recv_msg.type = UNDEFINED; - - while (1) - { - current_tcp_socket->tcp_control.no_of_retries = 0; +{ + /* Variables */ + msg_t recv_msg; + int32_t sent_bytes = 0, total_sent_bytes = 0; + socket_internal_t *current_int_tcp_socket; + socket_t *current_tcp_socket; + uint8_t send_buffer[BUFFER_SIZE]; + memset(send_buffer, 0, BUFFER_SIZE); + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); + + /* Check if socket exists and is TCP socket */ + if(!isTCPSocket(s)) { + return -1; + } + + current_int_tcp_socket = getSocket(s); + current_tcp_socket = ¤t_int_tcp_socket->socket_values; + + /* Check for ESTABLISHED STATE */ + if(current_tcp_socket->tcp_control.state != ESTABLISHED) { + return -1; + } + + /* Add thread PID */ + current_int_tcp_socket->send_pid = thread_getpid(); + + recv_msg.type = UNDEFINED; + + while(1) { + current_tcp_socket->tcp_control.no_of_retries = 0; #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; - // Remember TCP Context for possible TCP_RETRY - tcp_hc_context_t saved_tcp_context; - memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, sizeof(tcp_hc_context_t)-1); + current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + /* Remember TCP Context for possible TCP_RETRY */ + tcp_hc_context_t saved_tcp_context; + memcpy(&saved_tcp_context, ¤t_tcp_socket->tcp_control.tcp_context, + sizeof(tcp_hc_context_t) - 1); #endif - while (recv_msg.type != TCP_ACK) - { - // Add packet data - if (current_tcp_socket->tcp_control.send_wnd > current_tcp_socket->tcp_control.mss) - { - // Window size > Maximum Segment Size - if ((len-total_sent_bytes) > current_tcp_socket->tcp_control.mss) - { - memcpy(&send_buffer[IPV6_HDR_LEN+TCP_HDR_LEN], msg, current_tcp_socket->tcp_control.mss); - sent_bytes = current_tcp_socket->tcp_control.mss; - total_sent_bytes += sent_bytes; - } - else - { - memcpy(&send_buffer[IPV6_HDR_LEN+TCP_HDR_LEN], msg+total_sent_bytes, len-total_sent_bytes); - sent_bytes = len-total_sent_bytes; - total_sent_bytes = len; - } - } - else - { - // Window size <= Maximum Segment Size - if ((len-total_sent_bytes) > current_tcp_socket->tcp_control.send_wnd) - { - memcpy(&send_buffer[IPV6_HDR_LEN+TCP_HDR_LEN], msg, current_tcp_socket->tcp_control.send_wnd); - sent_bytes = current_tcp_socket->tcp_control.send_wnd; - total_sent_bytes += sent_bytes; - } - else - { - memcpy(&send_buffer[IPV6_HDR_LEN+TCP_HDR_LEN], msg+total_sent_bytes, len-total_sent_bytes); - sent_bytes = len-total_sent_bytes; - total_sent_bytes = len; - } - } - - current_tcp_socket->tcp_control.send_nxt += sent_bytes; - current_tcp_socket->tcp_control.send_wnd -= sent_bytes; - - if (send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header, 0, sent_bytes) != 1) - { - // Error while sending tcp data - current_tcp_socket->tcp_control.send_nxt -= sent_bytes; - current_tcp_socket->tcp_control.send_wnd += sent_bytes; + while(recv_msg.type != TCP_ACK) { + /* Add packet data */ + if(current_tcp_socket->tcp_control.send_wnd > + current_tcp_socket->tcp_control.mss) { + /* Window size > Maximum Segment Size */ + if((len - total_sent_bytes) > current_tcp_socket->tcp_control.mss) { + memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], msg, + current_tcp_socket->tcp_control.mss); + sent_bytes = current_tcp_socket->tcp_control.mss; + total_sent_bytes += sent_bytes; + } + else { + memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], + msg + total_sent_bytes, len - total_sent_bytes); + sent_bytes = len - total_sent_bytes; + total_sent_bytes = len; + } + } + else { + /* Window size <= Maximum Segment Size */ + if((len - total_sent_bytes) > current_tcp_socket->tcp_control.send_wnd) { + memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], msg, + current_tcp_socket->tcp_control.send_wnd); + sent_bytes = current_tcp_socket->tcp_control.send_wnd; + total_sent_bytes += sent_bytes; + } + else { + memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], + msg + total_sent_bytes, len - total_sent_bytes); + sent_bytes = len - total_sent_bytes; + total_sent_bytes = len; + } + } + + current_tcp_socket->tcp_control.send_nxt += sent_bytes; + current_tcp_socket->tcp_control.send_wnd -= sent_bytes; + + if(send_tcp(current_int_tcp_socket, current_tcp_packet, + temp_ipv6_header, 0, sent_bytes) != 1) { + /* Error while sending tcp data */ + current_tcp_socket->tcp_control.send_nxt -= sent_bytes; + current_tcp_socket->tcp_control.send_wnd += sent_bytes; #ifdef TCP_HC - memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + memcpy(¤t_tcp_socket->tcp_control.tcp_context, + &saved_tcp_context, sizeof(tcp_hc_context_t)); + current_tcp_socket->tcp_control.tcp_context.hc_type = + COMPRESSED_HEADER; #endif - printf("Error while sending, returning to application thread!\n"); - return -1; - } - - // Remember current time - current_tcp_socket->tcp_control.last_packet_time.microseconds = hwtimer_now(); - net_msg_receive(&recv_msg); - switch (recv_msg.type) - { - case TCP_ACK: - { - if (current_tcp_socket->tcp_control.no_of_retries == 0) - { - calculate_rto(¤t_tcp_socket->tcp_control, hwtimer_now()); - } - tcp_hdr_t *tcp_header = ((tcp_hdr_t*)(recv_msg.content.ptr)); - if ((current_tcp_socket->tcp_control.send_nxt == tcp_header->ack_nr) && (total_sent_bytes == len)) - { - current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr; - current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr; - current_tcp_socket->tcp_control.send_wnd = tcp_header->window; - // Got ACK for every sent byte + printf("Error while sending, returning to application thread!\n"); + return -1; + } + + /* Remember current time */ + current_tcp_socket->tcp_control.last_packet_time.microseconds = + hwtimer_now(); + net_msg_receive(&recv_msg); + + switch(recv_msg.type) { + case TCP_ACK: { + if(current_tcp_socket->tcp_control.no_of_retries == 0) { + calculate_rto(¤t_tcp_socket->tcp_control, + hwtimer_now()); + } + + tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(recv_msg.content.ptr)); + + if((current_tcp_socket->tcp_control.send_nxt == + tcp_header->ack_nr) && (total_sent_bytes == len)) { + current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr; + current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr; + current_tcp_socket->tcp_control.send_wnd = tcp_header->window; + /* Got ACK for every sent byte */ #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = + COMPRESSED_HEADER; #endif - return sent_bytes; - } - else if ((current_tcp_socket->tcp_control.send_nxt == tcp_header->ack_nr) && (total_sent_bytes != len)) - { - current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr; - current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr; - current_tcp_socket->tcp_control.send_wnd = tcp_header->window; - // Got ACK for every sent byte + return sent_bytes; + } + else if((current_tcp_socket->tcp_control.send_nxt == + tcp_header->ack_nr) && (total_sent_bytes != len)) { + current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr; + current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr; + current_tcp_socket->tcp_control.send_wnd = tcp_header->window; + /* Got ACK for every sent byte */ #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = + COMPRESSED_HEADER; #endif - break; - } -// else -// { -// // TODO: If window size > MSS, ACK was valid only for a few segments, handle retransmit of missing segments -// break; -// } - break; - } - case TCP_RETRY: - { - current_tcp_socket->tcp_control.send_nxt -= sent_bytes; - current_tcp_socket->tcp_control.send_wnd += sent_bytes; - total_sent_bytes -= sent_bytes; + break; + } + + /* else { + * TODO: If window size > MSS, ACK was valid only for + * a few segments, handle retransmit of missing + * segments + * break; + * } */ + break; + } + + case TCP_RETRY: { + current_tcp_socket->tcp_control.send_nxt -= sent_bytes; + current_tcp_socket->tcp_control.send_wnd += sent_bytes; + total_sent_bytes -= sent_bytes; #ifdef TCP_HC - memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); - current_tcp_socket->tcp_control.tcp_context.hc_type = MOSTLY_COMPRESSED_HEADER; + memcpy(¤t_tcp_socket->tcp_control.tcp_context, + $&saved_tcp_context, sizeof(tcp_hc_context_t)); + current_tcp_socket->tcp_control.tcp_context.hc_type = + MOSTLY_COMPRESSED_HEADER; #endif - break; - } - case TCP_TIMEOUT: - { - current_tcp_socket->tcp_control.send_nxt -= sent_bytes; - current_tcp_socket->tcp_control.send_wnd += sent_bytes; + break; + } + + case TCP_TIMEOUT: { + current_tcp_socket->tcp_control.send_nxt -= sent_bytes; + current_tcp_socket->tcp_control.send_wnd += sent_bytes; #ifdef TCP_HC - memcpy(¤t_tcp_socket->tcp_control.tcp_context, &saved_tcp_context, sizeof(tcp_hc_context_t)); - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + memcpy(¤t_tcp_socket->tcp_control.tcp_context, + &saved_tcp_context, sizeof(tcp_hc_context_t)); + current_tcp_socket->tcp_control.tcp_context.hc_type = + COMPRESSED_HEADER; #endif - return -1; - break; - } - } - } - } - return sent_bytes; - } - -uint8_t read_from_socket(socket_internal_t *current_int_tcp_socket, void *buf, int len) - { - if (len >= current_int_tcp_socket->tcp_input_buffer_end) - { - mutex_lock(¤t_int_tcp_socket->tcp_buffer_mutex); - uint8_t read_bytes = current_int_tcp_socket->tcp_input_buffer_end; - memcpy(buf, current_int_tcp_socket->tcp_input_buffer, current_int_tcp_socket->tcp_input_buffer_end); - current_int_tcp_socket->tcp_input_buffer_end = 0; - current_int_tcp_socket->socket_values.tcp_control.rcv_wnd += read_bytes; - mutex_unlock(¤t_int_tcp_socket->tcp_buffer_mutex, 0); - return read_bytes; - } - else - { - mutex_lock(¤t_int_tcp_socket->tcp_buffer_mutex); - memcpy(buf, current_int_tcp_socket->tcp_input_buffer, len); - memmove(current_int_tcp_socket->tcp_input_buffer, (current_int_tcp_socket->tcp_input_buffer+len), current_int_tcp_socket->tcp_input_buffer_end-len); - current_int_tcp_socket->tcp_input_buffer_end = current_int_tcp_socket->tcp_input_buffer_end-len; - current_int_tcp_socket->socket_values.tcp_control.rcv_wnd += len; - mutex_unlock(¤t_int_tcp_socket->tcp_buffer_mutex, 0); - return len; - } - } + return -1; + break; + } + } + } + } + + return sent_bytes; +} + +uint8_t read_from_socket(socket_internal_t *current_int_tcp_socket, + void *buf, int len) +{ + if(len >= current_int_tcp_socket->tcp_input_buffer_end) { + mutex_lock(¤t_int_tcp_socket->tcp_buffer_mutex); + uint8_t read_bytes = current_int_tcp_socket->tcp_input_buffer_end; + memcpy(buf, current_int_tcp_socket->tcp_input_buffer, + current_int_tcp_socket->tcp_input_buffer_end); + current_int_tcp_socket->tcp_input_buffer_end = 0; + current_int_tcp_socket->socket_values.tcp_control.rcv_wnd += read_bytes; + mutex_unlock(¤t_int_tcp_socket->tcp_buffer_mutex, 0); + return read_bytes; + } + else { + mutex_lock(¤t_int_tcp_socket->tcp_buffer_mutex); + memcpy(buf, current_int_tcp_socket->tcp_input_buffer, len); + memmove(current_int_tcp_socket->tcp_input_buffer, + (current_int_tcp_socket->tcp_input_buffer + len), + current_int_tcp_socket->tcp_input_buffer_end - len); + current_int_tcp_socket->tcp_input_buffer_end = + current_int_tcp_socket->tcp_input_buffer_end - len; + current_int_tcp_socket->socket_values.tcp_control.rcv_wnd += len; + mutex_unlock(¤t_int_tcp_socket->tcp_buffer_mutex, 0); + return len; + } +} int recv(int s, void *buf, uint32_t len, int flags) - { - // Variables - uint8_t read_bytes; - msg_t m_recv, m_send; - socket_internal_t *current_int_tcp_socket; - // Check if socket exists - if (!isTCPSocket(s)) - { - printf("INFO: NO TCP SOCKET!\n"); - return -1; - } - - current_int_tcp_socket = getSocket(s); - - // Setting Thread PID - current_int_tcp_socket->recv_pid = thread_getpid(); - if (current_int_tcp_socket->tcp_input_buffer_end > 0) - { - return read_from_socket(current_int_tcp_socket, buf, len); - } - msg_receive(&m_recv); - if ((exists_socket(s)) && (current_int_tcp_socket->tcp_input_buffer_end > 0)) - { - read_bytes = read_from_socket(current_int_tcp_socket, buf, len); - net_msg_reply(&m_recv, &m_send, UNDEFINED); - return read_bytes; - } - - // Received FIN - if (m_recv.type == CLOSE_CONN) - { - // Sent FIN_ACK, wait for ACK - msg_receive(&m_recv); - // Received ACK, return with closed socket! - return -1; - } - // Received Last ACK (connection closed) or no data to read yet - return -1; - } - -int32_t recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen) - { - if (isUDPSocket(s)) - { - msg_t m_recv, m_send; - ipv6_hdr_t *ipv6_header; - udp_hdr_t *udp_header; - uint8_t *payload; - getSocket(s)->recv_pid = thread_getpid(); - - msg_receive(&m_recv); - - ipv6_header = ((ipv6_hdr_t*)m_recv.content.ptr); - udp_header = ((udp_hdr_t*)(m_recv.content.ptr + IPV6_HDR_LEN)); - payload = (uint8_t*)(m_recv.content.ptr + IPV6_HDR_LEN+UDP_HDR_LEN); - - memset(buf, 0, len); - memcpy(buf, payload, udp_header->length-UDP_HDR_LEN); - memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16); - from->sin6_family = AF_INET6; - from->sin6_flowinfo = 0; - from->sin6_port = udp_header->src_port; - *fromlen = sizeof(sockaddr6_t); - - msg_reply(&m_recv, &m_send); - return udp_header->length-UDP_HDR_LEN; - } - else if (isTCPSocket(s)) - { - return recv(s, buf, len, flags); - } - else - { - printf("Socket Type not supported!\n"); - return -1; - } - } - -int32_t sendto(int s, const void *msg, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen) - { - if (isUDPSocket(s) && (getSocket(s)->socket_values.foreign_address.sin6_port == 0)) - { - uint8_t send_buffer[BUFFER_SIZE]; - - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - udp_hdr_t *current_udp_packet = ((udp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); - uint8_t *payload = &send_buffer[IPV6_HDR_LEN+UDP_HDR_LEN]; - - memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); - ipv6_get_saddr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); - - current_udp_packet->src_port = get_free_source_port(IPPROTO_UDP); - current_udp_packet->dst_port = to->sin6_port; - current_udp_packet->checksum = 0; - - memcpy(payload, msg, len); - current_udp_packet->length = UDP_HDR_LEN + len; - temp_ipv6_header->length = UDP_HDR_LEN + len; - - current_udp_packet->checksum = ~udp_csum(temp_ipv6_header, current_udp_packet); - - sixlowpan_send(&to->sin6_addr, (uint8_t*)(current_udp_packet), current_udp_packet->length, IPPROTO_UDP); - return current_udp_packet->length; - } - else - { - return -1; - } - } +{ + /* Variables */ + uint8_t read_bytes; + msg_t m_recv, m_send; + socket_internal_t *current_int_tcp_socket; + + /* Check if socket exists */ + if(!isTCPSocket(s)) { + printf("INFO: NO TCP SOCKET!\n"); + return -1; + } + + current_int_tcp_socket = getSocket(s); + + /* Setting Thread PID */ + current_int_tcp_socket->recv_pid = thread_getpid(); + + if(current_int_tcp_socket->tcp_input_buffer_end > 0) { + return read_from_socket(current_int_tcp_socket, buf, len); + } + + msg_receive(&m_recv); + + if((exists_socket(s)) && (current_int_tcp_socket->tcp_input_buffer_end > 0)) { + read_bytes = read_from_socket(current_int_tcp_socket, buf, len); + net_msg_reply(&m_recv, &m_send, UNDEFINED); + return read_bytes; + } + + /* Received FIN */ + if(m_recv.type == CLOSE_CONN) { + /* Sent FIN_ACK, wait for ACK */ + msg_receive(&m_recv); + /* Received ACK, return with closed socket! */ + return -1; + } + + /* Received Last ACK (connection closed) or no data to read yet */ + return -1; +} + +int32_t recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, + uint32_t *fromlen) +{ + if(isUDPSocket(s)) { + msg_t m_recv, m_send; + ipv6_hdr_t *ipv6_header; + udp_hdr_t *udp_header; + uint8_t *payload; + getSocket(s)->recv_pid = thread_getpid(); + + msg_receive(&m_recv); + + ipv6_header = ((ipv6_hdr_t *)m_recv.content.ptr); + udp_header = ((udp_hdr_t *)(m_recv.content.ptr + IPV6_HDR_LEN)); + payload = (uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN); + + memset(buf, 0, len); + memcpy(buf, payload, udp_header->length - UDP_HDR_LEN); + memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16); + from->sin6_family = AF_INET6; + from->sin6_flowinfo = 0; + from->sin6_port = udp_header->src_port; + *fromlen = sizeof(sockaddr6_t); + + msg_reply(&m_recv, &m_send); + return udp_header->length - UDP_HDR_LEN; + } + else if(isTCPSocket(s)) { + return recv(s, buf, len, flags); + } + else { + printf("Socket Type not supported!\n"); + return -1; + } +} + +int32_t sendto(int s, const void *msg, uint32_t len, int flags, + sockaddr6_t *to, uint32_t tolen) +{ + if(isUDPSocket(s) && + (getSocket(s)->socket_values.foreign_address.sin6_port == 0)) { + uint8_t send_buffer[BUFFER_SIZE]; + + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + udp_hdr_t *current_udp_packet = ((udp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); + uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN]; + + memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); + ipv6_get_saddr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); + + current_udp_packet->src_port = get_free_source_port(IPPROTO_UDP); + current_udp_packet->dst_port = to->sin6_port; + current_udp_packet->checksum = 0; + + memcpy(payload, msg, len); + current_udp_packet->length = UDP_HDR_LEN + len; + temp_ipv6_header->length = UDP_HDR_LEN + len; + + current_udp_packet->checksum = ~udp_csum(temp_ipv6_header, + current_udp_packet); + + sixlowpan_send(&to->sin6_addr, (uint8_t *)(current_udp_packet), + current_udp_packet->length, IPPROTO_UDP); + return current_udp_packet->length; + } + else { + return -1; + } +} int close(int s) - { - socket_internal_t *current_socket = getSocket(s); - if (current_socket != NULL) - { - if (isTCPSocket(s)) - { - // Variables - msg_t m_recv; - uint8_t send_buffer[BUFFER_SIZE]; - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); - - // Check if socket exists and is TCP socket - if (!isTCPSocket(s)) - { - return -1; - } - - // Check for ESTABLISHED STATE - if (current_socket->socket_values.tcp_control.state != ESTABLISHED) - { - close_socket(current_socket); - return 1; - } - - current_socket->send_pid = thread_getpid(); - - // Refresh local TCP socket information - current_socket->socket_values.tcp_control.send_una++; - current_socket->socket_values.tcp_control.state = FIN_WAIT_1; +{ + socket_internal_t *current_socket = getSocket(s); + + if(current_socket != NULL) { + if(isTCPSocket(s)) { + /* Variables */ + msg_t m_recv; + uint8_t send_buffer[BUFFER_SIZE]; + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); + + /* Check if socket exists and is TCP socket */ + if(!isTCPSocket(s)) { + return -1; + } + + /* Check for ESTABLISHED STATE */ + if(current_socket->socket_values.tcp_control.state != ESTABLISHED) { + close_socket(current_socket); + return 1; + } + + current_socket->send_pid = thread_getpid(); + + /* Refresh local TCP socket information */ + current_socket->socket_values.tcp_control.send_una++; + current_socket->socket_values.tcp_control.state = FIN_WAIT_1; #ifdef TCP_HC - current_socket->socket_values.tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + current_socket->socket_values.tcp_control.tcp_context.hc_type = + COMPRESSED_HEADER; #endif - send_tcp(current_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN, 0); - msg_receive(&m_recv); - close_socket(current_socket); - return 1; - } - else if(isUDPSocket(s)) - { - close_socket(current_socket); - return 1; - } - return -1; - } - else - { - return -1; - } - } + send_tcp(current_socket, current_tcp_packet, temp_ipv6_header, + TCP_FIN, 0); + msg_receive(&m_recv); + close_socket(current_socket); + return 1; + } + else if(isUDPSocket(s)) { + close_socket(current_socket); + return 1; + } + + return -1; + } + else { + return -1; + } +} int bind(int s, sockaddr6_t *name, int namelen) - { - if (exists_socket(s)) - { - socket_t *current_socket = &getSocket(s)->socket_values; - switch (current_socket->domain) - { - case (PF_INET): - { - // Not provided - return -1; - break; - } - case (PF_INET6): - { - switch (current_socket->type) - { - // TCP - case (SOCK_STREAM): - { - if ((current_socket->protocol == 0) || (current_socket->protocol == IPPROTO_TCP)) - { - return bind_tcp_socket(s, name, namelen, thread_getpid()); - break; - } - else - { - return -1; - break; - } - break; - } - // UDP - case (SOCK_DGRAM): - { - if ((current_socket->protocol == 0) || (current_socket->protocol == IPPROTO_UDP)) - { - return bind_udp_socket(s, name, namelen, thread_getpid()); - break; - } - else - { - return -1; - break; - } - break; - } - case (SOCK_SEQPACKET): - { - // not provided - return -1; - break; - } - case (SOCK_RAW): - { - // not provided - return -1; - break; - } - default: - { - return -1; - break; - } - } - break; - } - case (PF_UNIX): - { - // Not provided - return -1; - break; - } - } - } - else - { - printf("SOCKET DOES NOT EXIST!\n"); - return -1; - } - return -1; - } +{ + if(exists_socket(s)) { + socket_t *current_socket = &getSocket(s)->socket_values; + + switch(current_socket->domain) { + case(PF_INET): { + /* Not provided */ + return -1; + break; + } + + case(PF_INET6): { + switch(current_socket->type) { + /* TCP */ + case(SOCK_STREAM): { + if((current_socket->protocol == 0) || + (current_socket->protocol == IPPROTO_TCP)) { + return bind_tcp_socket(s, name, namelen, + thread_getpid()); + break; + } + else { + return -1; + break; + } + + break; + } + + /* UDP */ + case(SOCK_DGRAM): { + if((current_socket->protocol == 0) || + (current_socket->protocol == IPPROTO_UDP)) { + return bind_udp_socket(s, name, namelen, + thread_getpid()); + break; + } + else { + return -1; + break; + } + + break; + } + + case(SOCK_SEQPACKET): { + /* not provided */ + return -1; + break; + } + + case(SOCK_RAW): { + /* not provided */ + return -1; + break; + } + + default: { + return -1; + break; + } + } + + break; + } + + case(PF_UNIX): { + /* Not provided */ + return -1; + break; + } + } + } + else { + printf("SOCKET DOES NOT EXIST!\n"); + return -1; + } + + return -1; +} int listen(int s, int backlog) - { - if (isTCPSocket(s) && getSocket(s)->socket_values.tcp_control.state == CLOSED) - { - socket_internal_t *current_socket = getSocket(s); - current_socket->socket_values.tcp_control.state = LISTEN; - return 0; - } - else - { - return -1; - } - } - -socket_internal_t *getWaitingConnectionSocket(int socket, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header) - { - int i; - socket_internal_t *current_socket, *listening_socket = getSocket(socket); - for (i = 1; i < MAX_SOCKETS+1; i++) - { - current_socket = getSocket(i); - // Connection establishment ACK, Check for 4 touple and state - if ((ipv6_header != NULL) && (tcp_header != NULL)) - { - if (is_four_touple(current_socket, ipv6_header, tcp_header) && (current_socket->socket_values.tcp_control.state == SYN_RCVD)) - { - return current_socket; - } - } - // Connection establishment SYN ACK, check only for port and state - else - { - if ((current_socket->socket_values.tcp_control.state == SYN_RCVD) && - (current_socket->socket_values.local_address.sin6_port == listening_socket->socket_values.local_address.sin6_port)) - { - return current_socket; - } - } - } - return NULL; - } - -int handle_new_tcp_connection(socket_internal_t *current_queued_int_socket, socket_internal_t *server_socket, uint8_t pid) - { - msg_t msg_recv_client_ack, msg_send_client_ack; - socket_t *current_queued_socket = ¤t_queued_int_socket->socket_values; - uint8_t send_buffer[BUFFER_SIZE]; - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *syn_ack_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); - - current_queued_int_socket->recv_pid = thread_getpid(); +{ + if(isTCPSocket(s) && getSocket(s)->socket_values.tcp_control.state == CLOSED) { + socket_internal_t *current_socket = getSocket(s); + current_socket->socket_values.tcp_control.state = LISTEN; + return 0; + } + else { + return -1; + } +} + +socket_internal_t *getWaitingConnectionSocket(int socket, + ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header) +{ + int i; + socket_internal_t *current_socket, *listening_socket = getSocket(socket); + + for(i = 1; i < MAX_SOCKETS + 1; i++) { + current_socket = getSocket(i); + + /* Connection establishment ACK, Check for 4 touple and state */ + if((ipv6_header != NULL) && (tcp_header != NULL)) { + if(is_four_touple(current_socket, ipv6_header, tcp_header) && + (current_socket->socket_values.tcp_control.state == SYN_RCVD)) { + return current_socket; + } + } + /* Connection establishment SYN ACK, check only for port and state */ + else { + if((current_socket->socket_values.tcp_control.state == SYN_RCVD) && + (current_socket->socket_values.local_address.sin6_port == + listening_socket->socket_values.local_address.sin6_port)) { + return current_socket; + } + } + } + + return NULL; +} + +int handle_new_tcp_connection(socket_internal_t *current_queued_int_socket, + socket_internal_t *server_socket, uint8_t pid) +{ + msg_t msg_recv_client_ack, msg_send_client_ack; + socket_t *current_queued_socket = ¤t_queued_int_socket->socket_values; + uint8_t send_buffer[BUFFER_SIZE]; + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *syn_ack_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); + + current_queued_int_socket->recv_pid = thread_getpid(); #ifdef TCP_HC - current_queued_int_socket->socket_values.tcp_control.tcp_context.hc_type = FULL_HEADER; - memcpy(¤t_queued_int_socket->socket_values.tcp_control.tcp_context.context_id, - &server_socket->socket_values.tcp_control.tcp_context.context_id, sizeof(server_socket->socket_values.tcp_control.tcp_context.context_id)); + current_queued_int_socket->socket_values.tcp_control.tcp_context.hc_type = + FULL_HEADER; + memcpy(¤t_queued_int_socket->socket_values.tcp_control.tcp_context.context_id, + &server_socket->socket_values.tcp_control.tcp_context.context_id, + sizeof(server_socket->socket_values.tcp_control.tcp_context.context_id)); #endif - // Remember current time - timex_t now; - vtimer_now(&now); - current_queued_int_socket->socket_values.tcp_control.last_packet_time = now; + /* Remember current time */ + timex_t now; + vtimer_now(&now); + current_queued_int_socket->socket_values.tcp_control.last_packet_time = now; + + current_queued_int_socket->socket_values.tcp_control.no_of_retries = 0; - current_queued_int_socket->socket_values.tcp_control.no_of_retries = 0; + /* Set message type to Retry for while loop */ + msg_recv_client_ack.type = TCP_RETRY; - // Set message type to Retry for while loop - msg_recv_client_ack.type = TCP_RETRY; + while(msg_recv_client_ack.type == TCP_RETRY) { + /* Send packet */ + send_tcp(current_queued_int_socket, syn_ack_packet, temp_ipv6_header, + TCP_SYN_ACK, 0); - while (msg_recv_client_ack.type == TCP_RETRY) - { - // Send packet - send_tcp(current_queued_int_socket, syn_ack_packet, temp_ipv6_header, TCP_SYN_ACK, 0); + /* wait for ACK from Client */ + msg_receive(&msg_recv_client_ack); - // wait for ACK from Client - msg_receive(&msg_recv_client_ack); - if (msg_recv_client_ack.type == TCP_TIMEOUT) - { - // Set status of internal socket back to LISTEN - server_socket->socket_values.tcp_control.state = LISTEN; + if(msg_recv_client_ack.type == TCP_TIMEOUT) { + /* Set status of internal socket back to LISTEN */ + server_socket->socket_values.tcp_control.state = LISTEN; - close_socket(current_queued_int_socket); - return -1; - } - } + close_socket(current_queued_int_socket); + return -1; + } + } - tcp_hdr_t *tcp_header; + tcp_hdr_t *tcp_header; - tcp_header = ((tcp_hdr_t*)(msg_recv_client_ack.content.ptr)); + tcp_header = ((tcp_hdr_t *)(msg_recv_client_ack.content.ptr)); - // Check for consistency - if (tcp_header->ack_nr != current_queued_socket->tcp_control.send_nxt+1) - { - printf("TCP packets not consistent!\n"); - } + /* Check for consistency */ + if(tcp_header->ack_nr != current_queued_socket->tcp_control.send_nxt + 1) { + printf("TCP packets not consistent!\n"); + } - // Got ack, connection established, refresh local and foreign tcp socket status - set_tcp_cb(¤t_queued_socket->tcp_control, tcp_header->seq_nr+1, current_queued_socket->tcp_control.rcv_wnd, tcp_header->ack_nr, - tcp_header->ack_nr, tcp_header->window); + /* Got ack, connection established, refresh local and foreign tcp socket + * status */ + set_tcp_cb(¤t_queued_socket->tcp_control, tcp_header->seq_nr + 1, + current_queued_socket->tcp_control.rcv_wnd, tcp_header->ack_nr, + tcp_header->ack_nr, tcp_header->window); #ifdef TCP_HC - // Copy TCP context information into new socket - memset(&server_socket->socket_values.tcp_control.tcp_context, 0, sizeof(tcp_hc_context_t)); + /* Copy TCP context information into new socket */ + memset(&server_socket->socket_values.tcp_control.tcp_context, 0, + sizeof(tcp_hc_context_t)); #endif - // Update connection status information - current_queued_socket->tcp_control.state = ESTABLISHED; + /* Update connection status information */ + current_queued_socket->tcp_control.state = ESTABLISHED; - // Set status of internal socket back to LISTEN - server_socket->socket_values.tcp_control.state = LISTEN; + /* Set status of internal socket back to LISTEN */ + server_socket->socket_values.tcp_control.state = LISTEN; - // send a reply to the TCP handler after processing every information from the TCP ACK packet - msg_reply(&msg_recv_client_ack, &msg_send_client_ack); + /* send a reply to the TCP handler after processing every information from + * the TCP ACK packet */ + msg_reply(&msg_recv_client_ack, &msg_send_client_ack); - // Reset PID to an unlikely value - current_queued_int_socket->recv_pid = 255; + /* Reset PID to an unlikely value */ + current_queued_int_socket->recv_pid = 255; - // Waiting for Clients ACK waiting period to time out - vtimer_usleep(TCP_SYN_INITIAL_TIMEOUT/2); + /* Waiting for Clients ACK waiting period to time out */ + vtimer_usleep(TCP_SYN_INITIAL_TIMEOUT / 2); - print_sockets(); + print_sockets(); - return current_queued_int_socket->socket_id; - } + return current_queued_int_socket->socket_id; +} int accept(int s, sockaddr6_t *addr, uint32_t *addrlen) - { - socket_internal_t *server_socket = getSocket(s); - if (isTCPSocket(s) && (server_socket->socket_values.tcp_control.state == LISTEN)) - { - socket_internal_t *current_queued_socket = getWaitingConnectionSocket(s, NULL, NULL); - if (current_queued_socket != NULL) - { - return handle_new_tcp_connection(current_queued_socket, server_socket, thread_getpid()); - } - else - { - // No waiting connections, waiting for message from TCP Layer - msg_t msg_recv_client_syn; - msg_recv_client_syn.type = UNDEFINED; - while (msg_recv_client_syn.type != TCP_SYN) - { - msg_receive(&msg_recv_client_syn); - } - - current_queued_socket = getWaitingConnectionSocket(s, NULL, NULL); - - return handle_new_tcp_connection(current_queued_socket, server_socket, thread_getpid()); - } - } - else - { - return -1; - } - } - -socket_internal_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header) - { - int queued_socket_id; - - queued_socket_id = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); - socket_internal_t *current_queued_socket = getSocket(queued_socket_id); - - // Foreign address - set_socket_address(¤t_queued_socket->socket_values.foreign_address, AF_INET6, tcp_header->src_port, ipv6_header->flowlabel, &ipv6_header->srcaddr); - - // Local address - set_socket_address(¤t_queued_socket->socket_values.local_address, AF_INET6, tcp_header->dst_port, 0, &ipv6_header->destaddr); - - // Foreign TCP information - if ((tcp_header->dataOffset_reserved*4 > TCP_HDR_LEN) && (*(((uint8_t*)tcp_header)+TCP_HDR_LEN) == TCP_MSS_OPTION)) - { - current_queued_socket->socket_values.tcp_control.mss = *((uint16_t*)(((uint8_t*)tcp_header)+TCP_HDR_LEN+2)); - } - else - { - current_queued_socket->socket_values.tcp_control.mss = STATIC_MSS; - } - current_queued_socket->socket_values.tcp_control.rcv_irs = tcp_header->seq_nr; - mutex_lock(&global_sequence_clunter_mutex); - current_queued_socket->socket_values.tcp_control.send_iss = global_sequence_counter; - mutex_unlock(&global_sequence_clunter_mutex, 0); - current_queued_socket->socket_values.tcp_control.state = SYN_RCVD; - set_tcp_cb(¤t_queued_socket->socket_values.tcp_control, tcp_header->seq_nr+1, STATIC_WINDOW, - current_queued_socket->socket_values.tcp_control.send_iss, - current_queued_socket->socket_values.tcp_control.send_iss, tcp_header->window); - - return current_queued_socket; - } +{ + socket_internal_t *server_socket = getSocket(s); + + if(isTCPSocket(s) && (server_socket->socket_values.tcp_control.state == LISTEN)) { + socket_internal_t *current_queued_socket = + getWaitingConnectionSocket(s, NULL, NULL); + + if(current_queued_socket != NULL) { + return handle_new_tcp_connection(current_queued_socket, + server_socket, thread_getpid()); + } + else { + /* No waiting connections, waiting for message from TCP Layer */ + msg_t msg_recv_client_syn; + msg_recv_client_syn.type = UNDEFINED; + + while(msg_recv_client_syn.type != TCP_SYN) { + msg_receive(&msg_recv_client_syn); + } + + current_queued_socket = getWaitingConnectionSocket(s, NULL, NULL); + + return handle_new_tcp_connection(current_queued_socket, + server_socket, thread_getpid()); + } + } + else { + return -1; + } +} + +socket_internal_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header) +{ + int queued_socket_id; + + queued_socket_id = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); + socket_internal_t *current_queued_socket = getSocket(queued_socket_id); + + /* Foreign address */ + set_socket_address(¤t_queued_socket->socket_values.foreign_address, + AF_INET6, tcp_header->src_port, ipv6_header->flowlabel, + &ipv6_header->srcaddr); + + /* Local address */ + set_socket_address(¤t_queued_socket->socket_values.local_address, + AF_INET6, tcp_header->dst_port, 0, + &ipv6_header->destaddr); + + /* Foreign TCP information */ + if((tcp_header->dataOffset_reserved * 4 > TCP_HDR_LEN) && + (*(((uint8_t *)tcp_header) + TCP_HDR_LEN) == TCP_MSS_OPTION)) { + current_queued_socket->socket_values.tcp_control.mss = + *((uint16_t *)(((uint8_t *)tcp_header) + TCP_HDR_LEN + 2)); + } + else { + current_queued_socket->socket_values.tcp_control.mss = STATIC_MSS; + } + + current_queued_socket->socket_values.tcp_control.rcv_irs = + tcp_header->seq_nr; + mutex_lock(&global_sequence_clunter_mutex); + current_queued_socket->socket_values.tcp_control.send_iss = + global_sequence_counter; + mutex_unlock(&global_sequence_clunter_mutex, 0); + current_queued_socket->socket_values.tcp_control.state = SYN_RCVD; + set_tcp_cb(¤t_queued_socket->socket_values.tcp_control, + tcp_header->seq_nr + 1, STATIC_WINDOW, + current_queued_socket->socket_values.tcp_control.send_iss, + current_queued_socket->socket_values.tcp_control.send_iss, + tcp_header->window); + + return current_queued_socket; +} diff --git a/sys/net/destiny/socket.h b/sys/net/destiny/socket.h index bcda90733293cb65fdda87dfebbc2c0745f2bc97..c043700f1c3eb47b3077c54c03d17d5c9dcb6231 100644 --- a/sys/net/destiny/socket.h +++ b/sys/net/destiny/socket.h @@ -1,10 +1,21 @@ -/* - * socket.h +/** + * Destiny socket API + * + * Copyright (C) 2013 INRIA. * - * Created on: 16.09.2011 - * Author: Oliver + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file socket.h + * @brief header for BSD socket API + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ + #ifndef SOCKET_H_ #define SOCKET_H_ @@ -119,82 +130,81 @@ #define SEND_MSG_BUF_SIZE 64 -typedef struct socka6 - { +typedef struct socka6 { uint8_t sin6_family; /* AF_INET6 */ uint16_t sin6_port; /* transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 flow information */ ipv6_addr_t sin6_addr; /* IPv6 address */ - } sockaddr6_t; - -typedef struct tcp_hc_con - { - uint16_t context_id; - uint32_t seq_rcv; // Last received packet values - uint32_t ack_rcv; - uint16_t wnd_rcv; - uint32_t seq_snd; // Last sent packet values - uint32_t ack_snd; - uint16_t wnd_snd; - uint8_t hc_type; - } tcp_hc_context_t; - -typedef struct tcp_control_block - { - uint32_t send_una; - uint32_t send_nxt; - uint16_t send_wnd; - uint32_t send_iss; - - uint32_t rcv_nxt; - uint16_t rcv_wnd; - uint32_t rcv_irs; - - timex_t last_packet_time; - uint8_t no_of_retries; - uint16_t mss; - - uint8_t state; - - double srtt; - double rttvar; - double rto; +} sockaddr6_t; + +typedef struct tcp_hc_con { + uint16_t context_id; + uint32_t seq_rcv; // Last received packet values + uint32_t ack_rcv; + uint16_t wnd_rcv; + uint32_t seq_snd; // Last sent packet values + uint32_t ack_snd; + uint16_t wnd_snd; + uint8_t hc_type; +} tcp_hc_context_t; + +typedef struct tcp_control_block { + uint32_t send_una; + uint32_t send_nxt; + uint16_t send_wnd; + uint32_t send_iss; + + uint32_t rcv_nxt; + uint16_t rcv_wnd; + uint32_t rcv_irs; + + timex_t last_packet_time; + uint8_t no_of_retries; + uint16_t mss; + + uint8_t state; + + double srtt; + double rttvar; + double rto; #ifdef TCP_HC - tcp_hc_context_t tcp_context; + tcp_hc_context_t tcp_context; #endif - } tcp_cb_t; - -typedef struct sock_t - { - uint8_t domain; - uint8_t type; - uint8_t protocol; - tcp_cb_t tcp_control; - sockaddr6_t local_address; - sockaddr6_t foreign_address; - } socket_t; - -typedef struct socket_in_t - { - uint8_t socket_id; - uint8_t recv_pid; - uint8_t send_pid; - uint8_t tcp_input_buffer_end; - mutex_t tcp_buffer_mutex; - socket_t socket_values; - uint8_t tcp_input_buffer[MAX_TCP_BUFFER]; - } socket_internal_t; +} tcp_cb_t; + +typedef struct sock_t { + uint8_t domain; + uint8_t type; + uint8_t protocol; + tcp_cb_t tcp_control; + sockaddr6_t local_address; + sockaddr6_t foreign_address; +} socket_t; + +typedef struct socket_in_t { + uint8_t socket_id; + uint8_t recv_pid; + uint8_t send_pid; + uint8_t tcp_input_buffer_end; + mutex_t tcp_buffer_mutex; + socket_t socket_values; + uint8_t tcp_input_buffer[MAX_TCP_BUFFER]; +} socket_internal_t; extern socket_internal_t sockets[MAX_SOCKETS]; int socket(int domain, int type, int protocol); int connect(int socket, sockaddr6_t *addr, uint32_t addrlen); -socket_internal_t *getWaitingConnectionSocket(int socket, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header); +socket_internal_t *getWaitingConnectionSocket(int socket, + ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header); void close_socket(socket_internal_t *current_socket); -int32_t recvfrom( int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen ); -int32_t sendto( int s, const void *msg, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen); +int32_t recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, + uint32_t *fromlen); +int32_t sendto(int s, const void *msg, uint32_t len, int flags, + sockaddr6_t *to, uint32_t tolen); int32_t send(int s, void *msg, uint32_t len, int flags); int recv(int s, void *buf, uint32_t len, int flags); int close(int s); @@ -210,14 +220,23 @@ void print_internal_socket(socket_internal_t *current_socket_internal); void print_socket(socket_t *current_socket); void printf_tcp_context(tcp_hc_context_t *current_tcp_context); bool exists_socket(uint8_t socket); -socket_internal_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header); -void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_t *tcp_socket); -void set_socket_address(sockaddr6_t *sockaddr, uint8_t sin6_family, uint16_t sin6_port, uint32_t sin6_flowinfo, ipv6_addr_t *sin6_addr); -void set_tcp_cb(tcp_cb_t *tcp_control, uint32_t rcv_nxt, uint16_t rcv_wnd, uint32_t send_nxt, uint32_t send_una, uint16_t send_wnd); -void set_tcp_packet(tcp_hdr_t *tcp_hdr, uint16_t src_port, uint16_t dst_port, uint32_t seq_nr, uint32_t ack_nr, - uint8_t dataOffset_reserved, uint8_t reserved_flags, uint16_t window, uint16_t checksum, uint16_t urg_pointer); +socket_internal_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header); +void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, + tcp_hdr_t *tcp_header, socket_t *tcp_socket); +void set_socket_address(sockaddr6_t *sockaddr, uint8_t sin6_family, + uint16_t sin6_port, uint32_t sin6_flowinfo, + ipv6_addr_t *sin6_addr); +void set_tcp_cb(tcp_cb_t *tcp_control, uint32_t rcv_nxt, uint16_t rcv_wnd, + uint32_t send_nxt, uint32_t send_una, uint16_t send_wnd); +void set_tcp_packet(tcp_hdr_t *tcp_hdr, uint16_t src_port, uint16_t dst_port, + uint32_t seq_nr, uint32_t ack_nr, + uint8_t dataOffset_reserved, uint8_t reserved_flags, + uint16_t window, uint16_t checksum, uint16_t urg_pointer); int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header); void switch_tcp_packet_byte_order(tcp_hdr_t *current_tcp_packet); -int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, ipv6_hdr_t *temp_ipv6_header, uint8_t flags, uint8_t payload_length); +int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet, + ipv6_hdr_t *temp_ipv6_header, uint8_t flags, + uint8_t payload_length); bool isTCPSocket(uint8_t s); #endif /* SOCKET_H_ */ diff --git a/sys/net/destiny/tcp.c b/sys/net/destiny/tcp.c index 8e2b8a48a4f403a53df566d5877280cecf9f27f8..8f82f641e24cd1dfc3de6b040d49d1b69123e93c 100644 --- a/sys/net/destiny/tcp.c +++ b/sys/net/destiny/tcp.c @@ -1,10 +1,21 @@ -/* - * tcp.c +/** + * Destiny TCP implementation * - * Created on: 29.09.2011 - * Author: Oliver + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file tcp.c + * @brief TCP implementation + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ + #include <stdio.h> #include <thread.h> #include <string.h> @@ -22,342 +33,349 @@ #include "../sixlowpan/sixlowpan.h" void printTCPHeader(tcp_hdr_t *tcp_header) - { - printf("\nBEGIN: TCP HEADER\n"); - printf("ack_nr: %" PRIu32 "\n", tcp_header->ack_nr); - printf("checksum: %i\n", tcp_header->checksum); - printf("dataOffset_reserved: %i\n", tcp_header->dataOffset_reserved); - printf("dst_port: %i\n", tcp_header->dst_port); - printf("reserved_flags: %i\n", tcp_header->reserved_flags); - printf("seq_nr: %" PRIu32 "\n", tcp_header->seq_nr); - printf("src_port: %i\n", tcp_header->src_port); - printf("urg_pointer: %i\n", tcp_header->urg_pointer); - printf("window: %i\n", tcp_header->window); - printf("END: TCP HEADER\n"); - } +{ + printf("\nBEGIN: TCP HEADER\n"); + printf("ack_nr: %" PRIu32 "\n", tcp_header->ack_nr); + printf("checksum: %i\n", tcp_header->checksum); + printf("dataOffset_reserved: %i\n", tcp_header->dataOffset_reserved); + printf("dst_port: %i\n", tcp_header->dst_port); + printf("reserved_flags: %i\n", tcp_header->reserved_flags); + printf("seq_nr: %" PRIu32 "\n", tcp_header->seq_nr); + printf("src_port: %i\n", tcp_header->src_port); + printf("urg_pointer: %i\n", tcp_header->urg_pointer); + printf("window: %i\n", tcp_header->window); + printf("END: TCP HEADER\n"); +} void printArrayRange_tcp(uint8_t *udp_header, uint16_t len) - { - int i = 0; - printf("-------------MEMORY-------------\n"); - for (i = 0; i < len; i++) - { - printf("%#x ", *(udp_header+i)); - } - printf("-------------MEMORY-------------\n"); - } +{ + int i = 0; + printf("-------------MEMORY-------------\n"); + + for(i = 0; i < len; i++) { + printf("%#x ", *(udp_header + i)); + } + + printf("-------------MEMORY-------------\n"); +} uint16_t tcp_csum(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header) - { +{ uint16_t sum; uint16_t len = ipv6_header->length; sum = len + IPPROTO_TCP; - sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t)); - sum = csum(sum, (uint8_t *)tcp_header, len); + sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t)); + sum = csum(sum, (uint8_t *)tcp_header, len); return (sum == 0) ? 0xffff : HTONS(sum); - } - -uint8_t handle_payload(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket, uint8_t *payload) - { - msg_t m_send_tcp, m_recv_tcp; - uint8_t tcp_payload_len = ipv6_header->length-TCP_HDR_LEN; - uint8_t acknowledged_bytes = 0; - if (tcp_payload_len > tcp_socket->socket_values.tcp_control.rcv_wnd) - { - mutex_lock(&tcp_socket->tcp_buffer_mutex); - memcpy(tcp_socket->tcp_input_buffer, payload, tcp_socket->socket_values.tcp_control.rcv_wnd); - acknowledged_bytes = tcp_socket->socket_values.tcp_control.rcv_wnd; - tcp_socket->socket_values.tcp_control.rcv_wnd = 0; - tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end + tcp_socket->socket_values.tcp_control.rcv_wnd; - mutex_unlock(&tcp_socket->tcp_buffer_mutex, 0); - } - else - { - mutex_lock(&tcp_socket->tcp_buffer_mutex); - memcpy(tcp_socket->tcp_input_buffer, payload, tcp_payload_len); - tcp_socket->socket_values.tcp_control.rcv_wnd = tcp_socket->socket_values.tcp_control.rcv_wnd - tcp_payload_len; - acknowledged_bytes = tcp_payload_len; - tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end + tcp_payload_len; - mutex_unlock(&tcp_socket->tcp_buffer_mutex, 0); - } - if (thread_getstatus(tcp_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) - { - net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, UNDEFINED); - } - - return acknowledged_bytes; - } - -void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket) - { - msg_t m_recv_tcp, m_send_tcp; - uint8_t target_pid; - - if (tcp_socket->socket_values.tcp_control.state == LAST_ACK) - { - target_pid = tcp_socket->recv_pid; - close_socket(tcp_socket); - msg_send(&m_send_tcp, target_pid, 0); - return; - } - else if (tcp_socket->socket_values.tcp_control.state == CLOSING) - { - msg_send(&m_send_tcp, tcp_socket->recv_pid, 0); - msg_send(&m_send_tcp, tcp_socket->send_pid, 0); - return; - } - else if (getWaitingConnectionSocket(tcp_socket->socket_id, ipv6_header, tcp_header) != NULL) - { -// printf("sending ACK to queued socket!\n"); - m_send_tcp.content.ptr = (char*)tcp_header; - net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, TCP_ACK); - return; - } - else if (tcp_socket->socket_values.tcp_control.state == ESTABLISHED) - { - if (check_tcp_consistency(&tcp_socket->socket_values, tcp_header) == PACKET_OK) - { - m_send_tcp.content.ptr = (char*)tcp_header; - net_msg_send(&m_send_tcp, tcp_socket->send_pid, 0, TCP_ACK); - return; - } - } - printf("NO WAY OF HANDLING THIS ACK!\n"); - } - -void handle_tcp_rst_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket) - { - // TODO: Reset connection - } - -void handle_tcp_syn_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket) - { - msg_t m_send_tcp; - if (tcp_socket->socket_values.tcp_control.state == LISTEN) - { - socket_internal_t *new_socket = new_tcp_queued_socket(ipv6_header, tcp_header); - if (new_socket != NULL) - { +} + +uint8_t handle_payload(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket, uint8_t *payload) +{ + msg_t m_send_tcp, m_recv_tcp; + uint8_t tcp_payload_len = ipv6_header->length - TCP_HDR_LEN; + uint8_t acknowledged_bytes = 0; + + if(tcp_payload_len > tcp_socket->socket_values.tcp_control.rcv_wnd) { + mutex_lock(&tcp_socket->tcp_buffer_mutex); + memcpy(tcp_socket->tcp_input_buffer, payload, + tcp_socket->socket_values.tcp_control.rcv_wnd); + acknowledged_bytes = tcp_socket->socket_values.tcp_control.rcv_wnd; + tcp_socket->socket_values.tcp_control.rcv_wnd = 0; + tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end + + tcp_socket->socket_values.tcp_control.rcv_wnd; + mutex_unlock(&tcp_socket->tcp_buffer_mutex, 0); + } + else { + mutex_lock(&tcp_socket->tcp_buffer_mutex); + memcpy(tcp_socket->tcp_input_buffer, payload, tcp_payload_len); + tcp_socket->socket_values.tcp_control.rcv_wnd = + tcp_socket->socket_values.tcp_control.rcv_wnd - tcp_payload_len; + acknowledged_bytes = tcp_payload_len; + tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end + + tcp_payload_len; + mutex_unlock(&tcp_socket->tcp_buffer_mutex, 0); + } + + if(thread_getstatus(tcp_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) { + net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, UNDEFINED); + } + + return acknowledged_bytes; +} + +void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket) +{ + msg_t m_recv_tcp, m_send_tcp; + uint8_t target_pid; + + if(tcp_socket->socket_values.tcp_control.state == LAST_ACK) { + target_pid = tcp_socket->recv_pid; + close_socket(tcp_socket); + msg_send(&m_send_tcp, target_pid, 0); + return; + } + else if(tcp_socket->socket_values.tcp_control.state == CLOSING) { + msg_send(&m_send_tcp, tcp_socket->recv_pid, 0); + msg_send(&m_send_tcp, tcp_socket->send_pid, 0); + return; + } + else if(getWaitingConnectionSocket(tcp_socket->socket_id, ipv6_header, + tcp_header) != NULL) { + m_send_tcp.content.ptr = (char *)tcp_header; + net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, TCP_ACK); + return; + } + else if(tcp_socket->socket_values.tcp_control.state == ESTABLISHED) { + if(check_tcp_consistency(&tcp_socket->socket_values, tcp_header) == PACKET_OK) { + m_send_tcp.content.ptr = (char *)tcp_header; + net_msg_send(&m_send_tcp, tcp_socket->send_pid, 0, TCP_ACK); + return; + } + } + + printf("NO WAY OF HANDLING THIS ACK!\n"); +} + +void handle_tcp_rst_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket) +{ + /* TODO: Reset connection */ +} + +void handle_tcp_syn_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket) +{ + msg_t m_send_tcp; + + if(tcp_socket->socket_values.tcp_control.state == LISTEN) { + socket_internal_t *new_socket = new_tcp_queued_socket(ipv6_header, + tcp_header); + + if(new_socket != NULL) { #ifdef TCP_HC - update_tcp_hc_context(true, new_socket, tcp_header); + update_tcp_hc_context(true, new_socket, tcp_header); #endif - // notify socket function accept(..) that a new connection request has arrived - // No need to wait for an answer because the server accept() function isnt reading from anything other than the queued sockets - net_msg_send(&m_send_tcp, tcp_socket->recv_pid, 0, TCP_SYN); - } - else - { - printf("Dropped TCP SYN Message because an error occured while requesting a new queued socket!\n"); - } - } - else - { - printf("Dropped TCP SYN Message because socket was not in state LISTEN!"); - } - } - -void handle_tcp_syn_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket) - { - msg_t m_send_tcp; - if (tcp_socket->socket_values.tcp_control.state == SYN_SENT) - { - m_send_tcp.content.ptr = (char*) tcp_header; - net_msg_send(&m_send_tcp, tcp_socket->recv_pid, 0, TCP_SYN_ACK); - } - else - { - printf("Socket not in state SYN_SENT, dropping SYN-ACK-packet!"); - } - } - -void handle_tcp_fin_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket) - { - msg_t m_send; - socket_t *current_tcp_socket = &tcp_socket->socket_values; - uint8_t send_buffer[BUFFER_SIZE]; - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); - - set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr+1, current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr, - tcp_header->ack_nr, tcp_header->window); + /* notify socket function accept(..) that a new connection request + * has arrived. No need to wait for an answer because the server + * accept() function isnt reading from anything other than the + * queued sockets */ + net_msg_send(&m_send_tcp, tcp_socket->recv_pid, 0, TCP_SYN); + } + else { + printf("Dropped TCP SYN Message because an error occured while + requesting a new queued socket!\n"); + } + } + else { + printf("Dropped TCP SYN Message because socket was not in state LISTEN!"); + } +} + +void handle_tcp_syn_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket) +{ + msg_t m_send_tcp; + + if(tcp_socket->socket_values.tcp_control.state == SYN_SENT) { + m_send_tcp.content.ptr = (char *) tcp_header; + net_msg_send(&m_send_tcp, tcp_socket->recv_pid, 0, TCP_SYN_ACK); + } + else { + printf("Socket not in state SYN_SENT, dropping SYN-ACK-packet!"); + } +} + +void handle_tcp_fin_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket) +{ + msg_t m_send; + socket_t *current_tcp_socket = &tcp_socket->socket_values; + uint8_t send_buffer[BUFFER_SIZE]; + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); + + set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr + 1, + current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr, + tcp_header->ack_nr, tcp_header->window); #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; #endif - if (current_tcp_socket->tcp_control.state == FIN_WAIT_1) - { - current_tcp_socket->tcp_control.state = CLOSING; + if(current_tcp_socket->tcp_control.state == FIN_WAIT_1) { + current_tcp_socket->tcp_control.state = CLOSING; + + send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN_ACK, 0); + } + else { + current_tcp_socket->tcp_control.state = LAST_ACK; - send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN_ACK, 0); - } - else - { - current_tcp_socket->tcp_control.state = LAST_ACK; + send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN_ACK, 0); + } - send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN_ACK, 0); - } - net_msg_send(&m_send, tcp_socket->recv_pid, 0, CLOSE_CONN); - } + net_msg_send(&m_send, tcp_socket->recv_pid, 0, CLOSE_CONN); +} -void handle_tcp_fin_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket) - { - msg_t m_send; - socket_t *current_tcp_socket = &tcp_socket->socket_values; - uint8_t send_buffer[BUFFER_SIZE]; - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); +void handle_tcp_fin_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket) +{ + msg_t m_send; + socket_t *current_tcp_socket = &tcp_socket->socket_values; + uint8_t send_buffer[BUFFER_SIZE]; + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); - current_tcp_socket->tcp_control.state = CLOSED; + current_tcp_socket->tcp_control.state = CLOSED; - set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr+1, current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr, - tcp_header->ack_nr, tcp_header->window); + set_tcp_cb(¤t_tcp_socket->tcp_control, tcp_header->seq_nr + 1, + current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr, + tcp_header->ack_nr, tcp_header->window); #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; #endif - send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); + send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); - msg_send(&m_send, tcp_socket->send_pid, 0); - msg_send(&m_send, tcp_socket->recv_pid, 0); - } + msg_send(&m_send, tcp_socket->send_pid, 0); + msg_send(&m_send, tcp_socket->recv_pid, 0); +} -void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_internal_t *tcp_socket, uint8_t *payload) - { - uint8_t tcp_payload_len = ipv6_header->length-TCP_HDR_LEN, read_bytes = 0; - socket_t *current_tcp_socket = &tcp_socket->socket_values; - uint8_t send_buffer[BUFFER_SIZE]; - ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t*)(&send_buffer)); - tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t*)(&send_buffer[IPV6_HDR_LEN])); +void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, + socket_internal_t *tcp_socket, uint8_t *payload) +{ + uint8_t tcp_payload_len = ipv6_header->length - TCP_HDR_LEN, read_bytes = 0; + socket_t *current_tcp_socket = &tcp_socket->socket_values; + uint8_t send_buffer[BUFFER_SIZE]; + ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); + tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); - if (tcp_payload_len > 0) - { + if(tcp_payload_len > 0) { - if (check_tcp_consistency(current_tcp_socket, tcp_header) == PACKET_OK) - { - read_bytes = handle_payload(ipv6_header, tcp_header, tcp_socket, payload); + if(check_tcp_consistency(current_tcp_socket, tcp_header) == PACKET_OK) { + read_bytes = handle_payload(ipv6_header, tcp_header, tcp_socket, payload); - // Refresh TCP status values - current_tcp_socket->tcp_control.state = ESTABLISHED; + /* Refresh TCP status values */ + current_tcp_socket->tcp_control.state = ESTABLISHED; - set_tcp_cb(¤t_tcp_socket->tcp_control, - tcp_header->seq_nr + read_bytes, - current_tcp_socket->tcp_control.rcv_wnd, - current_tcp_socket->tcp_control.send_nxt, - current_tcp_socket->tcp_control.send_una, - current_tcp_socket->tcp_control.send_wnd); + set_tcp_cb(¤t_tcp_socket->tcp_control, + tcp_header->seq_nr + read_bytes, + current_tcp_socket->tcp_control.rcv_wnd, + current_tcp_socket->tcp_control.send_nxt, + current_tcp_socket->tcp_control.send_una, + current_tcp_socket->tcp_control.send_wnd); - // Send packet -// block_continue_thread(); + /* Send packet */ + // block_continue_thread(); #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER; #endif - send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); - } - // ACK packet probably got lost - else - { -// block_continue_thread(); + send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); + } + /* ACK packet probably got lost */ + else { + // block_continue_thread(); #ifdef TCP_HC - current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; + current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER; #endif - send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); - } - } - } - -void tcp_packet_handler (void) - { - msg_t m_recv_ip, m_send_ip; - ipv6_hdr_t *ipv6_header; - tcp_hdr_t *tcp_header; - uint8_t *payload; - socket_internal_t *tcp_socket = NULL; - uint16_t chksum; - - while (1) - { - msg_receive(&m_recv_ip); - - ipv6_header = ((ipv6_hdr_t*)m_recv_ip.content.ptr); - tcp_header = ((tcp_hdr_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); + send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0); + } + } +} + +void tcp_packet_handler(void) +{ + msg_t m_recv_ip, m_send_ip; + ipv6_hdr_t *ipv6_header; + tcp_hdr_t *tcp_header; + uint8_t *payload; + socket_internal_t *tcp_socket = NULL; + uint16_t chksum; + + while(1) { + msg_receive(&m_recv_ip); + + ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr); + tcp_header = ((tcp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); #ifdef TCP_HC - tcp_socket = decompress_tcp_packet(ipv6_header); + tcp_socket = decompress_tcp_packet(ipv6_header); #else - switch_tcp_packet_byte_order(tcp_header); - tcp_socket = get_tcp_socket(ipv6_header, tcp_header); + switch_tcp_packet_byte_order(tcp_header); + tcp_socket = get_tcp_socket(ipv6_header, tcp_header); #endif - chksum = tcp_csum(ipv6_header, tcp_header); + chksum = tcp_csum(ipv6_header, tcp_header); - payload = (uint8_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN + tcp_header->dataOffset_reserved*4); + payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + + tcp_header->dataOffset_reserved * 4); - if ((chksum == 0xffff) && (tcp_socket != NULL)) - { + if((chksum == 0xffff) && (tcp_socket != NULL)) { #ifdef TCP_HC - update_tcp_hc_context(true, tcp_socket, tcp_header); + update_tcp_hc_context(true, tcp_socket, tcp_header); #endif - // Remove reserved bits from tcp flags field - uint8_t tcp_flags = tcp_header->reserved_flags & REMOVE_RESERVED; - - switch (tcp_flags) - { - case TCP_ACK: - { - // only ACK Bit set - handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket); - break; - } - case TCP_RST: - { - printf("RST Bit set!\n"); - // only RST Bit set - handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket); - break; - } - case TCP_SYN: - { - // only SYN Bit set, look for matching, listening socket and request new queued socket - printf("SYN Bit set!\n"); - handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket); - break; - } - case TCP_SYN_ACK: - { - // only SYN and ACK Bit set, complete three way handshake when socket in state SYN_SENT - handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket); - break; - } - case TCP_FIN: - { - printf("FIN Bit set!\n"); - // only FIN Bit set - handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket); - break; - } - case TCP_FIN_ACK: - { - printf("FIN ACK Bit set!\n"); - // only FIN and ACK Bit set - handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket); - break; - } - default: - { -// printf("DEFAULT!\n"); - handle_tcp_no_flags_packet(ipv6_header, tcp_header, tcp_socket, payload); - } - } - } - else - { - printf("Wrong checksum (%x) or no corresponding socket found!\n", chksum); - printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN+ipv6_header->length, "Incoming"); - print_tcp_status(INC_PACKET, ipv6_header, tcp_header, &tcp_socket->socket_values); - } - - msg_reply(&m_recv_ip, &m_send_ip); - } - } - + /* Remove reserved bits from tcp flags field */ + uint8_t tcp_flags = tcp_header->reserved_flags & REMOVE_RESERVED; + + switch(tcp_flags) { + case TCP_ACK: { + /* only ACK Bit set */ + handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket); + break; + } + + case TCP_RST: { + printf("RST Bit set!\n"); + /* only RST Bit set */ + handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket); + break; + } + + case TCP_SYN: { + /* only SYN Bit set, look for matching, listening socket + * and request new queued socket */ + printf("SYN Bit set!\n"); + handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket); + break; + } + + case TCP_SYN_ACK: { + /* only SYN and ACK Bit set, complete three way handshake + * when socket in state SYN_SENT */ + handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket); + break; + } + + case TCP_FIN: { + printf("FIN Bit set!\n"); + /* only FIN Bit set */ + handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket); + break; + } + + case TCP_FIN_ACK: { + printf("FIN ACK Bit set!\n"); + /* only FIN and ACK Bit set */ + handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket); + break; + } + + default: { + handle_tcp_no_flags_packet(ipv6_header, tcp_header, + tcp_socket, payload); + } + } + } + else { + printf("Wrong checksum (%x) or no corresponding socket found!\n", + chksum); + printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN + + ipv6_header->length, "Incoming"); + print_tcp_status(INC_PACKET, ipv6_header, tcp_header, + &tcp_socket->socket_values); + } + + msg_reply(&m_recv_ip, &m_send_ip); + } +} diff --git a/sys/net/destiny/tcp.h b/sys/net/destiny/tcp.h index f2c37dbb669ffc54f000f903e2b19650f52b1f7a..7c33c56f85f426521374799364d68f3b93250d90 100644 --- a/sys/net/destiny/tcp.h +++ b/sys/net/destiny/tcp.h @@ -1,8 +1,18 @@ -/* - * tcp.h +/** + * Destiny TCP header * - * Created on: 29.09.2011 - * Author: Oliver + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file tcp.c + * @brief TCP data structs and prototypes + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ #ifndef TCP_H_ @@ -16,42 +26,39 @@ #define TCP_WSF_OPTION 0x03 // Window scale factor #define TCP_TS_OPTION 0x08 // Timestamp -enum tcp_flags - { - TCP_ACK = 0x08, - TCP_URG_PSH = 0x14, - TCP_RST = 0x20, - TCP_SYN = 0x40, - TCP_SYN_ACK = 0x48, - TCP_FIN = 0x80, - TCP_FIN_ACK = 0x88 - }; - -enum tcp_states - { - CLOSED = 0, - LISTEN = 1, - SYN_SENT = 2, - SYN_RCVD = 3, - ESTABLISHED = 4, - FIN_WAIT_1 = 5, - FIN_WAIT_2 = 6, - CLOSE_WAIT = 7, - CLOSING = 8, - LAST_ACK = 9, - TIME_WAIT = 10, - UNKNOWN = 11 - }; - -enum tcp_codes - { - UNDEFINED = 0, - PACKET_OK = 1, - CLOSE_CONN = 2, - SEQ_NO_TOO_SMALL = 3, - ACK_NO_TOO_SMALL = 4, - ACK_NO_TOO_BIG = 5 - }; +enum tcp_flags { + TCP_ACK = 0x08, + TCP_URG_PSH = 0x14, + TCP_RST = 0x20, + TCP_SYN = 0x40, + TCP_SYN_ACK = 0x48, + TCP_FIN = 0x80, + TCP_FIN_ACK = 0x88 +}; + +enum tcp_states { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10, + UNKNOWN = 11 +}; + +enum tcp_codes { + UNDEFINED = 0, + PACKET_OK = 1, + CLOSE_CONN = 2, + SEQ_NO_TOO_SMALL = 3, + ACK_NO_TOO_SMALL = 4, + ACK_NO_TOO_BIG = 5 +}; #define REMOVE_RESERVED 0xFC @@ -73,15 +80,13 @@ enum tcp_codes #include "../sixlowpan/sixlowip.h" -typedef struct __attribute__ ((packed)) tcp_mms_o_t - { +typedef struct __attribute__((packed)) tcp_mms_o_t { uint8_t kind; uint8_t len; uint16_t mss; - } tcp_mss_option_t; +} tcp_mss_option_t; -typedef struct __attribute__ ((packed)) tcp_h_t - { +typedef struct __attribute__((packed)) tcp_h_t { uint16_t src_port; uint16_t dst_port; uint32_t seq_nr; @@ -91,7 +96,7 @@ typedef struct __attribute__ ((packed)) tcp_h_t uint16_t window; uint16_t checksum; uint16_t urg_pointer; - } tcp_hdr_t; +} tcp_hdr_t; // uint8_t buffer_tcp[BUFFER_SIZE]; @@ -105,7 +110,7 @@ uint8_t global_context_counter; mutex_t global_sequence_clunter_mutex; uint32_t global_sequence_counter; -void tcp_packet_handler (void); +void tcp_packet_handler(void); uint16_t tcp_csum(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header); void printTCPHeader(tcp_hdr_t *tcp_header); void printArrayRange_tcp(uint8_t *udp_header, uint16_t len); diff --git a/sys/net/destiny/tcp_hc.c b/sys/net/destiny/tcp_hc.c index 97f3827eaeee7c39c0a368e451ab4acb258e3991..00ba506578f47a1569d31a38c948b68201336354 100644 --- a/sys/net/destiny/tcp_hc.c +++ b/sys/net/destiny/tcp_hc.c @@ -1,10 +1,21 @@ -/* - * tcp_hc.c +/** + * Destiny TCP header compression * - * Created on: 01.02.2012 - * Author: Oliver + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file tcp_hc.c + * @brief TCP HC + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ + #include <stdio.h> #include <string.h> #include <stdint.h> @@ -17,582 +28,606 @@ #ifdef TCP_HC -socket_internal_t *get_tcp_socket_by_context(ipv6_hdr_t *current_ipv6_header, uint16_t current_context) - { - socket_internal_t *temp_socket; - for (int i = 1; i < MAX_SOCKETS+1; i++) - { - temp_socket = getSocket(i); - if ((temp_socket != NULL) && - (ipv6_get_addr_match(&temp_socket->socket_values.foreign_address.sin6_addr, ¤t_ipv6_header->srcaddr) == 128) && - (ipv6_get_addr_match(&temp_socket->socket_values.local_address.sin6_addr, ¤t_ipv6_header->destaddr) == 128) && - (temp_socket->socket_values.tcp_control.tcp_context.context_id == current_context)) - { - return temp_socket; - } - } - return NULL; - } - -void update_tcp_hc_context(bool incoming, socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet) - { - tcp_hc_context_t *current_context = ¤t_socket->socket_values.tcp_control.tcp_context; - if (incoming) - { - current_context->ack_rcv = current_tcp_packet->ack_nr; - current_context->seq_rcv = current_tcp_packet->seq_nr; - current_context->wnd_rcv = current_tcp_packet->window; - } - else - { - current_context->ack_snd = current_tcp_packet->ack_nr; - current_context->seq_snd = current_tcp_packet->seq_nr; - current_context->wnd_snd = current_tcp_packet->window; - } - } - -uint16_t compress_tcp_packet(socket_internal_t *current_socket, uint8_t *current_tcp_packet, ipv6_hdr_t *temp_ipv6_header, uint8_t flags, uint8_t payload_length) - { - socket_t *current_tcp_socket = ¤t_socket->socket_values; - tcp_hc_context_t *tcp_context = ¤t_tcp_socket->tcp_control.tcp_context; - tcp_cb_t *tcp_cb = ¤t_tcp_socket->tcp_control; - tcp_hdr_t full_tcp_header; - uint16_t packet_size = 0; - // Connection establisment phase, use FULL_HEADER TCP - if (tcp_context->hc_type == FULL_HEADER) - { - // draft-aayadi-6lowpan-tcphc-01: 5.1 Full header TCP segment. Establishing Connection - - // Move tcp packet 3 bytes to add padding and Context ID - memmove(current_tcp_packet+3, current_tcp_packet, ((((tcp_hdr_t *)current_tcp_packet)->dataOffset_reserved)*4)+payload_length); - - // 1 padding byte with value 0x01 to introduce full header TCP_HC segment - memset(current_tcp_packet, 0x01, 1); - - // Adding Context ID - uint16_t current_context = HTONS(tcp_context->context_id); - memcpy(current_tcp_packet + 1, ¤t_context, 2); - - // Return correct header length (+3) - packet_size = ((((tcp_hdr_t *)(current_tcp_packet+3))->dataOffset_reserved)*4) + 3 + payload_length; - - // Update the tcp context fields - update_tcp_hc_context(false, current_socket, (tcp_hdr_t *)(current_tcp_packet+3)); - - // Convert TCP packet to network byte order - switch_tcp_packet_byte_order((tcp_hdr_t *)(current_tcp_packet+3)); - - return packet_size; - } - // Check for header compression type: COMPRESSED_HEADER - else if (tcp_context->hc_type == COMPRESSED_HEADER) - { - // draft-aayadi-6lowpan-tcphc-01: 5.1 Compressed header TCP segment. - - // Temporary variable for TCP_HC_Header Bytes - uint16_t tcp_hc_header = 0x0000; - - // Save TCP_Header to refresh TCP Context values after compressing the packet - memcpy(&full_tcp_header, current_tcp_packet, TCP_HDR_LEN); - - // Temporary variable for storing TCP header beginning - uint8_t *tcp_packet_begin = current_tcp_packet; - - // Position for first TCP header value, TCP_HC_Header and Context ID - current_tcp_packet += 4; - - // Packet size value - packet_size += 4; - - // 5.2. LOWPAN_TCPHC Format - - // First 3 bits of TCP_HC_Header are not exactly specified. In this implementation they are (1|1|0) - // for compressed headers and the CID is always 16 bits (1) - // (1|1|0|1) = D - tcp_hc_header |= 0xD000; - - /*----------------------------------*/ - /*| Sequence number handling |*/ - /*----------------------------------*/ - if (full_tcp_header.seq_nr == tcp_context->seq_snd) - { - // Nothing to do, Seq = (0|0) - } - // If the 24 most significant bits haven't changed from previous packet, don't transmit them - else if ((full_tcp_header.seq_nr&0xFFFFFF00) == (tcp_context->seq_snd&0xFFFFFF00)) - { - // Seq = (0|1) - tcp_hc_header |= 0x0400; - - // Copy first 8 less significant bits of sequence number into buffer - *current_tcp_packet = (uint8_t)(full_tcp_header.seq_nr & 0x000000FF); - current_tcp_packet += 1; - packet_size += 1; - } - // If the 16 most significant bits haven't changed from previous packet, don't transmit them - else if ((full_tcp_header.seq_nr&0xFFFF0000) == (tcp_context->seq_snd&0xFFFF0000)) - { - // Seq = (1|0) - tcp_hc_header |= 0x0800; - - // Copy first 16 less significant bits of sequence number into buffer - *((uint16_t *)current_tcp_packet) = HTONS((uint16_t)(full_tcp_header.seq_nr & 0x0000FFFF)); - current_tcp_packet += 2; - packet_size += 2; - } - // Sending uncompressed sequence number - else - { - // Seq = (1|1) - tcp_hc_header |= 0x0C00; - - // Copy all bits of sequence number into buffer - uint32_t cur_seq_no = HTONL(full_tcp_header.seq_nr); - memcpy(current_tcp_packet, &cur_seq_no, 4); - current_tcp_packet += 4; - packet_size += 4; - } - - /*----------------------------------*/ - /*| Acknowledgment number handling |*/ - /*----------------------------------*/ - if ((IS_TCP_ACK(full_tcp_header.reserved_flags) && - (tcp_cb->tcp_context.ack_snd == full_tcp_header.ack_nr))) - { - tcp_context->ack_snd = tcp_context->seq_rcv; - } - if (full_tcp_header.ack_nr == tcp_context->ack_snd) - { - // Nothing to do, Ack = (0|0) - } - // If the 24 most significant bits haven't changed from previous packet, don't transmit them - else if ((full_tcp_header.ack_nr&0xFFFFFF00) == (tcp_context->ack_snd&0xFFFFFF00)) - { - // Ack = (0|1) - tcp_hc_header |= 0x0100; - - // Copy first 8 less significant bits of acknowledgment number into buffer - *current_tcp_packet = (uint8_t)(full_tcp_header.ack_nr & 0x000000FF); - current_tcp_packet += 1; - packet_size += 1; - } - // If the 16 most significant bits haven't changed from previous packet, don't transmit them - else if ((full_tcp_header.ack_nr&0xFFFF0000) == (tcp_context->ack_snd&0xFFFF0000)) - { - // Ack = (1|0) - tcp_hc_header |= 0x0200; - - // Copy first 16 less significant bits of acknowledgment number into buffer - *((uint16_t *)current_tcp_packet) = HTONS((uint16_t)(full_tcp_header.ack_nr & 0x0000FFFF)); - current_tcp_packet += 2; - packet_size += 2; - } - // Sending uncompressed acknowledgment number - else - { - // Ack = (1|1) - tcp_hc_header |= 0x0300; - - // Copy all bits of acknowledgment number into buffer - uint32_t cur_ack_nr = HTONL(full_tcp_header.ack_nr); - memcpy(current_tcp_packet, &cur_ack_nr, 4); - current_tcp_packet += 4; - packet_size += 4; - } - - /*----------------------------------*/ - /*| Window handling |*/ - /*----------------------------------*/ - if (full_tcp_header.window == tcp_context->wnd_snd) - { - // Nothing to do, Wnd = (0|0) - } - // If the 8 most significant bits haven't changed from previous packet, don't transmit them - else if ((full_tcp_header.window&0xFF00) == (tcp_context->wnd_snd&0xFF00)) - { - // Wnd = (0|1) - tcp_hc_header |= 0x0040; - - // Copy first 8 less significant bits of window size into buffer - *current_tcp_packet = (uint8_t)(full_tcp_header.window & 0x00FF); - current_tcp_packet += 1; - packet_size += 1; - } - // If the 8 less significant bits haven't changed from previous packet, don't transmit them - else if ((full_tcp_header.window&0x00FF) == (tcp_context->wnd_snd&0x00FF)) - { - // Wnd = (1|0) - tcp_hc_header |= 0x0080; - - // Copy first 8 most significant bits of window size into buffer - *current_tcp_packet = (uint8_t)(full_tcp_header.window & 0xFF00); - current_tcp_packet += 1; - packet_size += 1; - } - // Sending uncompressed window - else - { - // Wnd = (1|1) - tcp_hc_header |= 0x00C0; - - // Copy all bits of window size into buffer - uint16_t cur_window = HTONS(full_tcp_header.window); - memcpy(current_tcp_packet, &cur_window, 2); - current_tcp_packet += 2; - packet_size += 2; - } - - // FIN flag - if (IS_TCP_FIN(full_tcp_header.reserved_flags)) - { - // F = (1) - tcp_hc_header |= 0x0008; - } - - // Copy checksum into buffer - uint16_t cur_chk_sum = HTONS(full_tcp_header.checksum); - memcpy(current_tcp_packet, &cur_chk_sum, 2); - current_tcp_packet += 2; - packet_size += 2; - - // Copy TCP_HC Bytes into buffer - uint16_t cur_tcp_hc_header = HTONS(tcp_hc_header); - memcpy(tcp_packet_begin, &cur_tcp_hc_header, 2); - - // Copy TCP_HC Context ID into buffer - uint16_t cur_context_id = HTONS(tcp_context->context_id); - memcpy(tcp_packet_begin+2, &cur_context_id, 2); - - // Move payload to end of tcp header - memmove(current_tcp_packet, tcp_packet_begin+TCP_HDR_LEN, payload_length); - - // Adding TCP payload length to TCP_HC header length - packet_size += payload_length; - - update_tcp_hc_context(false, current_socket, &full_tcp_header); - - return packet_size; - } - // Check for header compression type: MOSTLY_COMPRESSED_HEADER - else if (tcp_context->hc_type == MOSTLY_COMPRESSED_HEADER) - { - // draft-aayadi-6lowpan-tcphc-01: 5.1 Compressed header TCP segment. - - // Temporary variable for TCP_HC_Header Bytes - uint16_t tcp_hc_header = 0x0000; - - // Save TCP_Header to refresh TCP Context values after compressing the packet - memcpy(&full_tcp_header, current_tcp_packet, TCP_HDR_LEN); - - // Temporary variable for storing TCP header beginning - uint8_t *tcp_packet_begin = current_tcp_packet; - - // Position for first TCP header value, TCP_HC_Header and Context ID - current_tcp_packet += 4; - - // Packet size value - packet_size += 4; - - // 5.2. LOWPAN_TCPHC Format - - // First 3 bits of TCP_HC_Header are not exactly specified. In this implementation they are (1|0|0) - // for mostly compressed headers and the CID is always 16 bits (1) - // (1|0|0|1) = 9 - tcp_hc_header |= 0x9000; - - /*----------------------------------*/ - /*| Sequence number handling |*/ - /*----------------------------------*/ - // Sending uncompressed sequence number - // Seq = (1|1) - tcp_hc_header |= 0x0C00; - - // Copy all bits of sequence number into buffer - uint32_t cur_seq_no = HTONL(full_tcp_header.seq_nr); - memcpy(current_tcp_packet, &cur_seq_no, 4); - current_tcp_packet += 4; - packet_size += 4; - - /*----------------------------------*/ - /*| Acknowledgment number handling |*/ - /*----------------------------------*/ - // Ack = (1|1) - tcp_hc_header |= 0x0300; - - // Copy all bits of acknowledgment number into buffer - uint32_t cur_ack_nr = HTONL(full_tcp_header.ack_nr); - memcpy(current_tcp_packet, &cur_ack_nr, 4); - current_tcp_packet += 4; - packet_size += 4; - - /*----------------------------------*/ - /*| Window handling |*/ - /*----------------------------------*/ - // Wnd = (1|1) - tcp_hc_header |= 0x00C0; - - // Copy all bits of window size into buffer - uint16_t cur_window = HTONS(full_tcp_header.window); - memcpy(current_tcp_packet, &cur_window, 2); - current_tcp_packet += 2; - packet_size += 2; - - // FIN flag - if (IS_TCP_FIN(full_tcp_header.reserved_flags)) - { - // F = (1) - tcp_hc_header |= 0x0008; - } - - // Copy checksum into buffer - uint16_t cur_chk_sum = HTONS(full_tcp_header.checksum); - memcpy(current_tcp_packet, &cur_chk_sum, 2); - current_tcp_packet += 2; - packet_size += 2; - - // Copy TCP_HC Bytes into buffer - uint16_t cur_tcp_hc_header = HTONS(tcp_hc_header); - memcpy(tcp_packet_begin, &cur_tcp_hc_header, 2); - - // Copy TCP_HC Context ID into buffer - uint16_t cur_context_id = HTONS(tcp_context->context_id); - memcpy(tcp_packet_begin+2, &cur_context_id, 2); - - // Move payload to end of tcp header - memmove(current_tcp_packet, tcp_packet_begin+TCP_HDR_LEN, payload_length); - - // Adding TCP payload length to TCP_HC header length - packet_size += payload_length; - - update_tcp_hc_context(false, current_socket, &full_tcp_header); - return packet_size; - } - return 0; - } +socket_internal_t *get_tcp_socket_by_context(ipv6_hdr_t *current_ipv6_header, + uint16_t current_context) +{ + socket_internal_t *temp_socket; + + for(int i = 1; i < MAX_SOCKETS + 1; i++) { + temp_socket = getSocket(i); + + if((temp_socket != NULL) && + (ipv6_get_addr_match(&temp_socket->socket_values.foreign_address.sin6_addr, + ¤t_ipv6_header->srcaddr) == 128) && + (ipv6_get_addr_match(&temp_socket->socket_values.local_address.sin6_addr, + ¤t_ipv6_header->destaddr) == 128) && + (temp_socket->socket_values.tcp_control.tcp_context.context_id == + current_context)) { + return temp_socket; + } + } + + return NULL; +} + +void update_tcp_hc_context(bool incoming, socket_internal_t *current_socket, + tcp_hdr_t *current_tcp_packet) +{ + tcp_hc_context_t *current_context = + ¤t_socket->socket_values.tcp_control.tcp_context; + + if(incoming) { + current_context->ack_rcv = current_tcp_packet->ack_nr; + current_context->seq_rcv = current_tcp_packet->seq_nr; + current_context->wnd_rcv = current_tcp_packet->window; + } + else { + current_context->ack_snd = current_tcp_packet->ack_nr; + current_context->seq_snd = current_tcp_packet->seq_nr; + current_context->wnd_snd = current_tcp_packet->window; + } +} + +uint16_t compress_tcp_packet(socket_internal_t *current_socket, + uint8_t *current_tcp_packet, + ipv6_hdr_t *temp_ipv6_header, + uint8_t flags, + uint8_t payload_length) +{ + socket_t *current_tcp_socket = ¤t_socket->socket_values; + tcp_hc_context_t *tcp_context = ¤t_tcp_socket->tcp_control.tcp_context; + tcp_cb_t *tcp_cb = ¤t_tcp_socket->tcp_control; + tcp_hdr_t full_tcp_header; + uint16_t packet_size = 0; + + /* Connection establisment phase, use FULL_HEADER TCP */ + if(tcp_context->hc_type == FULL_HEADER) { + /* draft-aayadi-6lowpan-tcphc-01: 5.1 Full header TCP segment. + * Establishing Connection */ + + /* Move tcp packet 3 bytes to add padding and Context ID */ + memmove(current_tcp_packet + 3, current_tcp_packet, + ((((tcp_hdr_t *)current_tcp_packet)->dataOffset_reserved) * 4) + + payload_length); + + /* 1 padding byte with value 0x01 to introduce full header TCP_HC + * segment */ + memset(current_tcp_packet, 0x01, 1); + + /* Adding Context ID */ + uint16_t current_context = HTONS(tcp_context->context_id); + memcpy(current_tcp_packet + 1, ¤t_context, 2); + + /* Return correct header length (+3) */ + packet_size = ((((tcp_hdr_t *)(current_tcp_packet + 3))->dataOffset_reserved) * 4) + 3 + + payload_length; + + /* Update the tcp context fields */ + update_tcp_hc_context(false, current_socket, (tcp_hdr_t *)(current_tcp_packet + 3)); + + /* Convert TCP packet to network byte order */ + switch_tcp_packet_byte_order((tcp_hdr_t *)(current_tcp_packet + 3)); + + return packet_size; + } + /* Check for header compression type: COMPRESSED_HEADER */ + else if(tcp_context->hc_type == COMPRESSED_HEADER) { + /* draft-aayadi-6lowpan-tcphc-01: 5.1 Compressed header TCP segment. */ + + /* Temporary variable for TCP_HC_Header Bytes */ + uint16_t tcp_hc_header = 0x0000; + + /* Save TCP_Header to refresh TCP Context values after compressing the + * packet */ + memcpy(&full_tcp_header, current_tcp_packet, TCP_HDR_LEN); + + /* Temporary variable for storing TCP header beginning */ + uint8_t *tcp_packet_begin = current_tcp_packet; + + /* Position for first TCP header value, TCP_HC_Header and Context ID */ + current_tcp_packet += 4; + + /* Packet size value */ + packet_size += 4; + + /* 5.2. LOWPAN_TCPHC Format */ + + /* First 3 bits of TCP_HC_Header are not exactly specified. In this + * implementation they are (1|1|0) * for compressed headers and the + * CID is always 16 bits (1) */ + /* (1|1|0|1) = D */ + tcp_hc_header |= 0xD000; + + /*----------------------------------*/ + /*| Sequence number handling |*/ + /*----------------------------------*/ + if(full_tcp_header.seq_nr == tcp_context->seq_snd) { + /* Nothing to do, Seq = (0|0) */ + } + /* If the 24 most significant bits haven't changed from previous + * packet, don't transmit them */ + else if((full_tcp_header.seq_nr & 0xFFFFFF00) == (tcp_context->seq_snd & + 0xFFFFFF00)) { + /* Seq = (0|1) */ + tcp_hc_header |= 0x0400; + + /* Copy first 8 less significant bits of sequence number into + * buffer */ + *current_tcp_packet = (uint8_t)(full_tcp_header.seq_nr & 0x000000FF); + current_tcp_packet += 1; + packet_size += 1; + } + /* If the 16 most significant bits haven't changed from previous packet, + * don't transmit them */ + else if((full_tcp_header.seq_nr & 0xFFFF0000) == (tcp_context->seq_snd & 0xFFFF0000)) { + /* Seq = (1|0) */ + tcp_hc_header |= 0x0800; + + /* Copy first 16 less significant bits of sequence number into buffer */ + *((uint16_t *)current_tcp_packet) = + HTONS((uint16_t)(full_tcp_header.seq_nr & 0x0000FFFF)); + current_tcp_packet += 2; + packet_size += 2; + } + /* Sending uncompressed sequence number */ + else { + /* Seq = (1|1) */ + tcp_hc_header |= 0x0C00; + + /* Copy all bits of sequence number into buffer */ + uint32_t cur_seq_no = HTONL(full_tcp_header.seq_nr); + memcpy(current_tcp_packet, &cur_seq_no, 4); + current_tcp_packet += 4; + packet_size += 4; + } + + /*----------------------------------*/ + /*| Acknowledgment number handling |*/ + /*----------------------------------*/ + if((IS_TCP_ACK(full_tcp_header.reserved_flags) && + (tcp_cb->tcp_context.ack_snd == full_tcp_header.ack_nr))) { + tcp_context->ack_snd = tcp_context->seq_rcv; + } + + if(full_tcp_header.ack_nr == tcp_context->ack_snd) { + /* Nothing to do, Ack = (0|0) */ + } + /* If the 24 most significant bits haven't changed from previous packet, + * don't transmit them */ + else if((full_tcp_header.ack_nr & 0xFFFFFF00) == (tcp_context->ack_snd & + 0xFFFFFF00)) { + /* Ack = (0|1) */ + tcp_hc_header |= 0x0100; + + /* Copy first 8 less significant bits of acknowledgment number into + * buffer */ + *current_tcp_packet = (uint8_t)(full_tcp_header.ack_nr & 0x000000FF); + current_tcp_packet += 1; + packet_size += 1; + } + /* If the 16 most significant bits haven't changed from previous packet, + * don't transmit them */ + else if((full_tcp_header.ack_nr & 0xFFFF0000) == (tcp_context->ack_snd & + 0xFFFF0000)) { + /* Ack = (1|0) */ + tcp_hc_header |= 0x0200; + + /* Copy first 16 less significant bits of acknowledgment number + * into buffer */ + *((uint16_t *)current_tcp_packet) = + HTONS((uint16_t)(full_tcp_header.ack_nr & 0x0000FFFF)); + current_tcp_packet += 2; + packet_size += 2; + } + /* Sending uncompressed acknowledgment number */ + else { + /* Ack = (1|1) */ + tcp_hc_header |= 0x0300; + + /* Copy all bits of acknowledgment number into buffer */ + uint32_t cur_ack_nr = HTONL(full_tcp_header.ack_nr); + memcpy(current_tcp_packet, &cur_ack_nr, 4); + current_tcp_packet += 4; + packet_size += 4; + } + + /*----------------------------------*/ + /*| Window handling |*/ + /*----------------------------------*/ + if(full_tcp_header.window == tcp_context->wnd_snd) { + /* Nothing to do, Wnd = (0|0) */ + } + /* If the 8 most significant bits haven't changed from previous packet, + * don't transmit them */ + else if((full_tcp_header.window & 0xFF00) == (tcp_context->wnd_snd & 0xFF00)) { + /* Wnd = (0|1) */ + tcp_hc_header |= 0x0040; + + /* Copy first 8 less significant bits of window size into buffer */ + *current_tcp_packet = (uint8_t)(full_tcp_header.window & 0x00FF); + current_tcp_packet += 1; + packet_size += 1; + } + /* If the 8 less significant bits haven't changed from previous packet, + * don't transmit them */ + else if((full_tcp_header.window & 0x00FF) == (tcp_context->wnd_snd & + 0x00FF)) { + /* Wnd = (1|0) */ + tcp_hc_header |= 0x0080; + + /* Copy first 8 most significant bits of window size into buffer */ + *current_tcp_packet = (uint8_t)(full_tcp_header.window & 0xFF00); + current_tcp_packet += 1; + packet_size += 1; + } + /* Sending uncompressed window */ + else { + /* Wnd = (1|1) */ + tcp_hc_header |= 0x00C0; + + /* Copy all bits of window size into buffer */ + uint16_t cur_window = HTONS(full_tcp_header.window); + memcpy(current_tcp_packet, &cur_window, 2); + current_tcp_packet += 2; + packet_size += 2; + } + + /* FIN flag */ + if(IS_TCP_FIN(full_tcp_header.reserved_flags)) { + /* F = (1) */ + tcp_hc_header |= 0x0008; + } + + /* Copy checksum into buffer */ + uint16_t cur_chk_sum = HTONS(full_tcp_header.checksum); + memcpy(current_tcp_packet, &cur_chk_sum, 2); + current_tcp_packet += 2; + packet_size += 2; + + /* Copy TCP_HC Bytes into buffer */ + uint16_t cur_tcp_hc_header = HTONS(tcp_hc_header); + memcpy(tcp_packet_begin, &cur_tcp_hc_header, 2); + + /* Copy TCP_HC Context ID into buffer */ + uint16_t cur_context_id = HTONS(tcp_context->context_id); + memcpy(tcp_packet_begin + 2, &cur_context_id, 2); + + /* Move payload to end of tcp header */ + memmove(current_tcp_packet, tcp_packet_begin + TCP_HDR_LEN, + payload_length); + + /* Adding TCP payload length to TCP_HC header length */ + packet_size += payload_length; + + update_tcp_hc_context(false, current_socket, &full_tcp_header); + + return packet_size; + } + /* Check for header compression type: MOSTLY_COMPRESSED_HEADER */ + else if(tcp_context->hc_type == MOSTLY_COMPRESSED_HEADER) { + /* draft-aayadi-6lowpan-tcphc-01: 5.1 Compressed header TCP segment. */ + + /* Temporary variable for TCP_HC_Header Bytes */ + uint16_t tcp_hc_header = 0x0000; + + /* Save TCP_Header to refresh TCP Context values after compressing the + * packet */ + memcpy(&full_tcp_header, current_tcp_packet, TCP_HDR_LEN); + + /* Temporary variable for storing TCP header beginning */ + uint8_t *tcp_packet_begin = current_tcp_packet; + + /* Position for first TCP header value, TCP_HC_Header and Context ID */ + current_tcp_packet += 4; + + /* Packet size value */ + packet_size += 4; + + /* 5.2. LOWPAN_TCPHC Format */ + + /* First 3 bits of TCP_HC_Header are not exactly specified. In this + * implementation they are (1|0|0) for mostly compressed headers and + * the CID is always 16 bits (1) */ + /* (1|0|0|1) = 9 */ + tcp_hc_header |= 0x9000; + + /*----------------------------------*/ + /*| Sequence number handling |*/ + /*----------------------------------*/ + /* Sending uncompressed sequence number */ + /* Seq = (1|1) */ + tcp_hc_header |= 0x0C00; + + /* Copy all bits of sequence number into buffer */ + uint32_t cur_seq_no = HTONL(full_tcp_header.seq_nr); + memcpy(current_tcp_packet, &cur_seq_no, 4); + current_tcp_packet += 4; + packet_size += 4; + + /*----------------------------------*/ + /*| Acknowledgment number handling |*/ + /*----------------------------------*/ + /* Ack = (1|1) */ + tcp_hc_header |= 0x0300; + + /* Copy all bits of acknowledgment number into buffer */ + uint32_t cur_ack_nr = HTONL(full_tcp_header.ack_nr); + memcpy(current_tcp_packet, &cur_ack_nr, 4); + current_tcp_packet += 4; + packet_size += 4; + + /*----------------------------------*/ + /*| Window handling |*/ + /*----------------------------------*/ + /* Wnd = (1|1) */ + tcp_hc_header |= 0x00C0; + + /* Copy all bits of window size into buffer */ + uint16_t cur_window = HTONS(full_tcp_header.window); + memcpy(current_tcp_packet, &cur_window, 2); + current_tcp_packet += 2; + packet_size += 2; + + /* FIN flag */ + if(IS_TCP_FIN(full_tcp_header.reserved_flags)) { + /* F = (1) */ + tcp_hc_header |= 0x0008; + } + + /* Copy checksum into buffer */ + uint16_t cur_chk_sum = HTONS(full_tcp_header.checksum); + memcpy(current_tcp_packet, &cur_chk_sum, 2); + current_tcp_packet += 2; + packet_size += 2; + + /* Copy TCP_HC Bytes into buffer */ + uint16_t cur_tcp_hc_header = HTONS(tcp_hc_header); + memcpy(tcp_packet_begin, &cur_tcp_hc_header, 2); + + /* Copy TCP_HC Context ID into buffer */ + uint16_t cur_context_id = HTONS(tcp_context->context_id); + memcpy(tcp_packet_begin + 2, &cur_context_id, 2); + + /* Move payload to end of tcp header */ + memmove(current_tcp_packet, tcp_packet_begin + TCP_HDR_LEN, + payload_length); + + /* Adding TCP payload length to TCP_HC header length */ + packet_size += payload_length; + + update_tcp_hc_context(false, current_socket, &full_tcp_header); + return packet_size; + } + + return 0; +} socket_internal_t *decompress_tcp_packet(ipv6_hdr_t *temp_ipv6_header) - { - uint8_t *packet_buffer = ((uint8_t*)temp_ipv6_header)+IPV6_HDR_LEN; - uint16_t tcp_hc_header; - socket_internal_t *current_socket = NULL; - uint16_t packet_size = 0; - - // Full header TCP segment - if (*(((uint8_t *)temp_ipv6_header)+IPV6_HDR_LEN) == 0x01) - { - switch_tcp_packet_byte_order(((tcp_hdr_t *)(((uint8_t*)temp_ipv6_header)+IPV6_HDR_LEN+3))); - current_socket = get_tcp_socket(temp_ipv6_header, ((tcp_hdr_t *)(((uint8_t*)temp_ipv6_header)+IPV6_HDR_LEN+3))); - if (current_socket != NULL) - { - if (current_socket->socket_values.tcp_control.state == LISTEN) - { - memcpy(¤t_socket->socket_values.tcp_control.tcp_context.context_id, ((uint8_t *)temp_ipv6_header)+IPV6_HDR_LEN+1, 2); - current_socket->socket_values.tcp_control.tcp_context.context_id = NTOHS(current_socket->socket_values.tcp_control.tcp_context.context_id); - } - memmove(((uint8_t *)temp_ipv6_header)+IPV6_HDR_LEN, (((uint8_t*)temp_ipv6_header)+IPV6_HDR_LEN+3), temp_ipv6_header->length-3); - temp_ipv6_header->length -= 3; - return current_socket; - } - else - { - printf("Socket Null!\n"); - // Found no matching socket for this packet -> Drop it - return NULL; - } - } - // Compressed header TCP segment - else - { - // Temporary TCP Header - tcp_hdr_t full_tcp_header; - memset(&full_tcp_header, 0, sizeof(tcp_hdr_t)); - - // Current context ID - uint16_t current_context; - memcpy(¤t_context, (packet_buffer+2), 2); - current_context = NTOHS(current_context); - - // Copy TCP_HC header into local variable (1,0,0,1|SEQ,SEQ,0)(1,0,0,1|0,0,0,0) - memcpy(&tcp_hc_header, packet_buffer, 2); - tcp_hc_header = NTOHS(tcp_hc_header); - - uint8_t header_type = UNDEFINED; - if (BITSET(tcp_hc_header, 15) && !BITSET(tcp_hc_header, 14) && !BITSET(tcp_hc_header, 13)) - { - header_type = MOSTLY_COMPRESSED_HEADER; - } - else if (BITSET(tcp_hc_header, 15) && BITSET(tcp_hc_header, 14) && !BITSET(tcp_hc_header, 13)) - { - header_type = COMPRESSED_HEADER; - } - - // Setting pointer to first tcp_hc field - packet_buffer += 4; - packet_size += 4; - - // Current socket - socket_internal_t *current_socket = get_tcp_socket_by_context(temp_ipv6_header, current_context); - - if (current_socket == NULL) - { - printf("Current Socket == NULL!\n"); - return NULL; - } - - // Current TCP Context values - tcp_hc_context_t *current_tcp_context = ¤t_socket->socket_values.tcp_control.tcp_context; - - /*----------------------------------*/ - /*| Sequence number handling |*/ - /*----------------------------------*/ - if (!BITSET(tcp_hc_header, 11) && !BITSET(tcp_hc_header, 10)) - { - // Seq = (0|0), sequence number didn't change, copy old value - memcpy(&full_tcp_header.seq_nr, ¤t_tcp_context->seq_rcv, 4); - } - // The 24 most significant bits haven't changed from previous packet - else if (!BITSET(tcp_hc_header, 11) && BITSET(tcp_hc_header, 10)) - { - // Seq = (0|1), copy 1 byte of tcp_hc packet and 3 bytes from previous packet - full_tcp_header.seq_nr |= *packet_buffer; - full_tcp_header.seq_nr |= ((current_tcp_context->seq_rcv)&0xFFFFFF00); - packet_buffer += 1; - packet_size += 1; - } - // If the 16 most significant bits haven't changed from previous packet - else if (BITSET(tcp_hc_header, 11) && !BITSET(tcp_hc_header, 10)) - { - // Seq = (1|0), copy 2 bytes of tcp_hc packet and 2 bytes from previous packet - full_tcp_header.seq_nr |= NTOHS(*((uint16_t *)packet_buffer)); - full_tcp_header.seq_nr |= ((current_tcp_context->seq_rcv)&0xFFFF0000); - packet_buffer += 2; - packet_size += 2; - } - // Sending uncompressed sequence number - else - { - // Seq = (1|1), copy 4 bytes of tcp_hc packet - memcpy(&full_tcp_header.seq_nr, packet_buffer, 4); - full_tcp_header.seq_nr = NTOHL(full_tcp_header.seq_nr); - packet_buffer += 4; - packet_size += 4; - } - - /*----------------------------------*/ - /*| Acknowledgment number handling |*/ - /*----------------------------------*/ - if (!BITSET(tcp_hc_header, 9) && !BITSET(tcp_hc_header, 8)) - { - // Ack = (0|0), acknowledgment number didn't change, copy old value - memcpy(&full_tcp_header.ack_nr, ¤t_tcp_context->ack_rcv, 4); - } - // The 24 most significant bits haven't changed from previous packet - else if (!BITSET(tcp_hc_header, 9) && BITSET(tcp_hc_header, 8)) - { - // Ack = (0|1), copy 1 byte of tcp_hc packet and 3 bytes from previous packet - full_tcp_header.ack_nr |= *packet_buffer; - full_tcp_header.ack_nr |= ((current_tcp_context->ack_rcv)&0xFFFFFF00); - packet_buffer += 1; - packet_size += 1; - SET_TCP_ACK(full_tcp_header.reserved_flags); - } - // If the 16 most significant bits haven't changed from previous packet - else if (BITSET(tcp_hc_header, 9) && !BITSET(tcp_hc_header, 8)) - { - // Ack = (1|0), copy 2 bytes of tcp_hc packet and 2 bytes from previous packet - full_tcp_header.ack_nr |= NTOHS(*((uint16_t *)packet_buffer)); - full_tcp_header.ack_nr |= ((current_tcp_context->ack_rcv)&0xFFFF0000); - packet_buffer += 2; - packet_size += 2; - SET_TCP_ACK(full_tcp_header.reserved_flags); - } - // Sending uncompressed acknowledgment number - else - { - // Ack = (1|1), copy 4 bytes of tcp_hc packet - memcpy(&full_tcp_header.ack_nr, packet_buffer, 4); - full_tcp_header.ack_nr = NTOHL(full_tcp_header.ack_nr); - packet_buffer += 4; - packet_size += 4; - if (header_type == COMPRESSED_HEADER) - { - SET_TCP_ACK(full_tcp_header.reserved_flags); - } - } - - /*----------------------------------*/ - /*| Window handling |*/ - /*----------------------------------*/ - if (!BITSET(tcp_hc_header, 7) && !BITSET(tcp_hc_header, 6)) - { - // Wnd = (0|0), copy old value - memcpy(&full_tcp_header.window, ¤t_tcp_context->wnd_rcv, 2); - } - // The 8 most significant bits haven't changed from previous packet - else if (!BITSET(tcp_hc_header, 7) && BITSET(tcp_hc_header, 6)) - { - // Wnd = (0|1), copy 1 byte of tcp_hc packet and 1 byte from previous packet - full_tcp_header.window |= *packet_buffer; - full_tcp_header.window |= ((current_tcp_context->wnd_rcv)&0xFF00); - packet_buffer += 1; - packet_size += 1; - } - // If the 8 less significant bits haven't changed from previous packet - else if (BITSET(tcp_hc_header, 7) && !BITSET(tcp_hc_header, 6)) - { - // Wnd = (1|0), copy 1 byte of tcp_hc packet and 1 byte from previous packet - full_tcp_header.window |= ((*((uint16_t *)packet_buffer))&0xFF00); - full_tcp_header.window |= ((current_tcp_context->wnd_rcv)&0x00FF); - packet_buffer += 1; - packet_size += 1; - } - // Sending uncompressed window size - else - { - // Wnd = (1|1), copy 2 bytes of tcp_hc packet - memcpy(&full_tcp_header.window, packet_buffer, 2); - full_tcp_header.window = NTOHS(full_tcp_header.window); - packet_buffer += 2; - packet_size += 2; - } - - // FIN flag - if (BITSET(tcp_hc_header, 3)) - { - // F = (1) - if (IS_TCP_ACK(full_tcp_header.reserved_flags)) - { - SET_TCP_FIN_ACK(full_tcp_header.reserved_flags); - } - else - { - SET_TCP_FIN(full_tcp_header.reserved_flags); - } - } - - // Copy checksum into into tcp header - memcpy(&full_tcp_header.checksum, packet_buffer, 2); - full_tcp_header.checksum = NTOHS(full_tcp_header.checksum); - packet_buffer += 2; - packet_size += 2; - - // Copy dest. and src. port into tcp header - memcpy(&full_tcp_header.dst_port, ¤t_socket->socket_values.local_address.sin6_port, 2); - memcpy(&full_tcp_header.src_port, ¤t_socket->socket_values.foreign_address.sin6_port, 2); - - // Ordinary TCP header length - full_tcp_header.dataOffset_reserved = TCP_HDR_LEN/4; - - // Move payload to end of tcp header - memmove(((uint8_t*)temp_ipv6_header)+IPV6_HDR_LEN+TCP_HDR_LEN, packet_buffer, temp_ipv6_header->length-packet_size); - - // Copy TCP uncompressed header in front of payload - memcpy(((uint8_t*)temp_ipv6_header)+IPV6_HDR_LEN, &full_tcp_header, TCP_HDR_LEN); - - // Set IPV6 header length - temp_ipv6_header->length = temp_ipv6_header->length - packet_size + TCP_HDR_LEN; - return current_socket; - } - } +{ + uint8_t *packet_buffer = ((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN; + uint16_t tcp_hc_header; + socket_internal_t *current_socket = NULL; + uint16_t packet_size = 0; + + /* Full header TCP segment */ + if(*(((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN) == 0x01) { + switch_tcp_packet_byte_order(((tcp_hdr_t *)(((uint8_t *)temp_ipv6_header) + + IPV6_HDR_LEN + 3))); + current_socket = get_tcp_socket(temp_ipv6_header, + ((tcp_hdr_t *)(((uint8_t *)temp_ipv6_header) + + IPV6_HDR_LEN + 3))); + + if(current_socket != NULL) { + if(current_socket->socket_values.tcp_control.state == LISTEN) { + memcpy(¤t_socket->socket_values.tcp_control.tcp_context.context_id, + ((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN + 1, 2); + current_socket->socket_values.tcp_control.tcp_context.context_id = + NTOHS(current_socket->socket_values.tcp_control.tcp_context.context_id); + } + + memmove(((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN, + (((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN + 3), + temp_ipv6_header->length - 3); + temp_ipv6_header->length -= 3; + return current_socket; + } + else { + printf("Socket Null!\n"); + /* Found no matching socket for this packet -> Drop it */ + return NULL; + } + } + /* Compressed header TCP segment */ + else { + /* Temporary TCP Header */ + tcp_hdr_t full_tcp_header; + memset(&full_tcp_header, 0, sizeof(tcp_hdr_t)); + + /* Current context ID */ + uint16_t current_context; + memcpy(¤t_context, (packet_buffer + 2), 2); + current_context = NTOHS(current_context); + + /* Copy TCP_HC header into local variable + * (1,0,0,1|SEQ,SEQ,0)(1,0,0,1|0,0,0,0) */ + memcpy(&tcp_hc_header, packet_buffer, 2); + tcp_hc_header = NTOHS(tcp_hc_header); + + uint8_t header_type = UNDEFINED; + + if(BITSET(tcp_hc_header, 15) && !BITSET(tcp_hc_header, 14) && + !BITSET(tcp_hc_header, 13)) { + header_type = MOSTLY_COMPRESSED_HEADER; + } + else if(BITSET(tcp_hc_header, 15) && BITSET(tcp_hc_header, 14) && + !BITSET(tcp_hc_header, 13)) { + header_type = COMPRESSED_HEADER; + } + + /* Setting pointer to first tcp_hc field */ + packet_buffer += 4; + packet_size += 4; + + /* Current socket */ + socket_internal_t *current_socket = + get_tcp_socket_by_context(temp_ipv6_header, current_context); + + if(current_socket == NULL) { + printf("Current Socket == NULL!\n"); + return NULL; + } + + /* Current TCP Context values */ + tcp_hc_context_t *current_tcp_context = + ¤t_socket->socket_values.tcp_control.tcp_context; + + /*----------------------------------*/ + /*| Sequence number handling |*/ + /*----------------------------------*/ + if(!BITSET(tcp_hc_header, 11) && !BITSET(tcp_hc_header, 10)) { + /* Seq = (0|0), sequence number didn't change, copy old value */ + memcpy(&full_tcp_header.seq_nr, ¤t_tcp_context->seq_rcv, 4); + } + /* The 24 most significant bits haven't changed from previous packet */ + else if(!BITSET(tcp_hc_header, 11) && BITSET(tcp_hc_header, 10)) { + /* Seq = (0|1), copy 1 byte of tcp_hc packet and 3 bytes from + * previous packet */ + full_tcp_header.seq_nr |= *packet_buffer; + full_tcp_header.seq_nr |= ((current_tcp_context->seq_rcv) & + 0xFFFFFF00); + packet_buffer += 1; + packet_size += 1; + } + /* If the 16 most significant bits haven't changed from previous packet */ + else if(BITSET(tcp_hc_header, 11) && !BITSET(tcp_hc_header, 10)) { + /* Seq = (1|0), copy 2 bytes of tcp_hc packet and 2 bytes from + * previous packet */ + full_tcp_header.seq_nr |= NTOHS(*((uint16_t *)packet_buffer)); + full_tcp_header.seq_nr |= ((current_tcp_context->seq_rcv) & 0xFFFF0000); + packet_buffer += 2; + packet_size += 2; + } + /* Sending uncompressed sequence number */ + else { + /* Seq = (1|1), copy 4 bytes of tcp_hc packet */ + memcpy(&full_tcp_header.seq_nr, packet_buffer, 4); + full_tcp_header.seq_nr = NTOHL(full_tcp_header.seq_nr); + packet_buffer += 4; + packet_size += 4; + } + + /*----------------------------------*/ + /*| Acknowledgment number handling |*/ + /*----------------------------------*/ + if(!BITSET(tcp_hc_header, 9) && !BITSET(tcp_hc_header, 8)) { + /* Ack = (0|0), acknowledgment number didn't change, copy old value */ + memcpy(&full_tcp_header.ack_nr, ¤t_tcp_context->ack_rcv, 4); + } + /* The 24 most significant bits haven't changed from previous packet */ + else if(!BITSET(tcp_hc_header, 9) && BITSET(tcp_hc_header, 8)) { + /* Ack = (0|1), copy 1 byte of tcp_hc packet and 3 bytes from + * previous packet */ + full_tcp_header.ack_nr |= *packet_buffer; + full_tcp_header.ack_nr |= ((current_tcp_context->ack_rcv) & 0xFFFFFF00); + packet_buffer += 1; + packet_size += 1; + SET_TCP_ACK(full_tcp_header.reserved_flags); + } + /* If the 16 most significant bits haven't changed from previous packet */ + else if(BITSET(tcp_hc_header, 9) && !BITSET(tcp_hc_header, 8)) { + /* Ack = (1|0), copy 2 bytes of tcp_hc packet and 2 bytes from + * previous packet */ + full_tcp_header.ack_nr |= NTOHS(*((uint16_t *)packet_buffer)); + full_tcp_header.ack_nr |= ((current_tcp_context->ack_rcv) & 0xFFFF0000); + packet_buffer += 2; + packet_size += 2; + SET_TCP_ACK(full_tcp_header.reserved_flags); + } + /* Sending uncompressed acknowledgment number */ + else { + /* Ack = (1|1), copy 4 bytes of tcp_hc packet */ + memcpy(&full_tcp_header.ack_nr, packet_buffer, 4); + full_tcp_header.ack_nr = NTOHL(full_tcp_header.ack_nr); + packet_buffer += 4; + packet_size += 4; + + if(header_type == COMPRESSED_HEADER) { + SET_TCP_ACK(full_tcp_header.reserved_flags); + } + } + + /*----------------------------------*/ + /*| Window handling |*/ + /*----------------------------------*/ + if(!BITSET(tcp_hc_header, 7) && !BITSET(tcp_hc_header, 6)) { + /* Wnd = (0|0), copy old value */ + memcpy(&full_tcp_header.window, ¤t_tcp_context->wnd_rcv, 2); + } + /* The 8 most significant bits haven't changed from previous packet */ + else if(!BITSET(tcp_hc_header, 7) && BITSET(tcp_hc_header, 6)) { + /* Wnd = (0|1), copy 1 byte of tcp_hc packet and 1 byte from + * previous packet */ + full_tcp_header.window |= *packet_buffer; + full_tcp_header.window |= ((current_tcp_context->wnd_rcv) & 0xFF00); + packet_buffer += 1; + packet_size += 1; + } + /* If the 8 less significant bits haven't changed from previous packet */ + else if(BITSET(tcp_hc_header, 7) && !BITSET(tcp_hc_header, 6)) { + /* Wnd = (1|0), copy 1 byte of tcp_hc packet and 1 byte from previous packet */ + full_tcp_header.window |= ((*((uint16_t *)packet_buffer)) & 0xFF00); + full_tcp_header.window |= ((current_tcp_context->wnd_rcv) & 0x00FF); + packet_buffer += 1; + packet_size += 1; + } + /* Sending uncompressed window size */ + else { + /* Wnd = (1|1), copy 2 bytes of tcp_hc packet */ + memcpy(&full_tcp_header.window, packet_buffer, 2); + full_tcp_header.window = NTOHS(full_tcp_header.window); + packet_buffer += 2; + packet_size += 2; + } + + /* FIN flag */ + if(BITSET(tcp_hc_header, 3)) { + /* F = (1) */ + if(IS_TCP_ACK(full_tcp_header.reserved_flags)) { + SET_TCP_FIN_ACK(full_tcp_header.reserved_flags); + } + else { + SET_TCP_FIN(full_tcp_header.reserved_flags); + } + } + + /* Copy checksum into into tcp header */ + memcpy(&full_tcp_header.checksum, packet_buffer, 2); + full_tcp_header.checksum = NTOHS(full_tcp_header.checksum); + packet_buffer += 2; + packet_size += 2; + + /* Copy dest. and src. port into tcp header */ + memcpy(&full_tcp_header.dst_port, + ¤t_socket->socket_values.local_address.sin6_port, 2); + memcpy(&full_tcp_header.src_port, + ¤t_socket->socket_values.foreign_address.sin6_port, 2); + + /* Ordinary TCP header length */ + full_tcp_header.dataOffset_reserved = TCP_HDR_LEN / 4; + + /* Move payload to end of tcp header */ + memmove(((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN + TCP_HDR_LEN, + packet_buffer, temp_ipv6_header->length - packet_size); + + /* Copy TCP uncompressed header in front of payload */ + memcpy(((uint8_t *)temp_ipv6_header) + IPV6_HDR_LEN, &full_tcp_header, + TCP_HDR_LEN); + + /* Set IPV6 header length */ + temp_ipv6_header->length = temp_ipv6_header->length - packet_size + + TCP_HDR_LEN; + return current_socket; + } +} #endif diff --git a/sys/net/destiny/tcp_timer.c b/sys/net/destiny/tcp_timer.c index 986017764b882aef8af3d09a26aff02e3d51a101..0ff442aa347afb3a3f87c13ddacb5a8590f6b1f3 100644 --- a/sys/net/destiny/tcp_timer.c +++ b/sys/net/destiny/tcp_timer.c @@ -1,10 +1,21 @@ -/* - * tcp_timer.c +/** + * Destiny TCP timer implementation * - * Created on: 21.01.2012 - * Author: Oliver + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file tcp_timer.c + * @brief TCP timer + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} */ + #include <thread.h> #include <stdio.h> #include <string.h> @@ -19,135 +30,127 @@ #include "../sixlowpan/sixlowpan.h" void handle_synchro_timeout(socket_internal_t *current_socket) - { - msg_t send; - if (thread_getstatus(current_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) - { - timex_t now; - vtimer_now(&now); - if ((current_socket->socket_values.tcp_control.no_of_retries == 0) && - (timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds > - TCP_SYN_INITIAL_TIMEOUT)) - { - current_socket->socket_values.tcp_control.no_of_retries++; - net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY); -// printf("FIRST RETRY!\n"); - } - else if ((current_socket->socket_values.tcp_control.no_of_retries > 0) && - (timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds > - (current_socket->socket_values.tcp_control.no_of_retries * TCP_SYN_TIMEOUT + TCP_SYN_INITIAL_TIMEOUT))) - { - current_socket->socket_values.tcp_control.no_of_retries++; - if (current_socket->socket_values.tcp_control.no_of_retries > TCP_MAX_SYN_RETRIES) - { - net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT); -// printf("TCP SYN TIMEOUT!!\n"); - } - else - { - net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY); -// printf("NEXT RETRY!\n"); - } - } - } - } +{ + msg_t send; + + if(thread_getstatus(current_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) { + timex_t now; + vtimer_now(&now); + + if((current_socket->socket_values.tcp_control.no_of_retries == 0) && + (timex_sub(now, + current_socket->socket_values.tcp_control.last_packet_time).microseconds > + TCP_SYN_INITIAL_TIMEOUT)) { + current_socket->socket_values.tcp_control.no_of_retries++; + net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY); + } + else if((current_socket->socket_values.tcp_control.no_of_retries > 0) && + (timex_sub(now, + current_socket->socket_values.tcp_control.last_packet_time).microseconds > + (current_socket->socket_values.tcp_control.no_of_retries * + TCP_SYN_TIMEOUT + TCP_SYN_INITIAL_TIMEOUT))) { + current_socket->socket_values.tcp_control.no_of_retries++; + + if(current_socket->socket_values.tcp_control.no_of_retries > + TCP_MAX_SYN_RETRIES) { + net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT); + } + else { + net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY); + } + } + } +} void handle_established(socket_internal_t *current_socket) - { - msg_t send; - double current_timeout = current_socket->socket_values.tcp_control.rto; - if (current_timeout < SECOND) - { - current_timeout = SECOND; - } - uint8_t i; - if ((current_socket->socket_values.tcp_control.send_nxt > current_socket->socket_values.tcp_control.send_una) && - (thread_getstatus(current_socket->send_pid) == STATUS_RECEIVE_BLOCKED)) - { - for(i = 0; i < current_socket->socket_values.tcp_control.no_of_retries; i++) - { - current_timeout *= 2; - } - timex_t now; - vtimer_now(&now); - if (current_timeout > TCP_ACK_MAX_TIMEOUT) - { - net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT); -// printf("GOT NO ACK: TIMEOUT!\n"); - } - else if (timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds > - current_timeout) - { -// printReasBuffers(); - current_socket->socket_values.tcp_control.no_of_retries++; - net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY); -// printf("GOT NO ACK YET, %i. RETRY! Now: %lu Before: %lu, Diff: %lu, Cur Timeout: %f\n", current_socket->socket_values.tcp_control.no_of_retries, -// now.microseconds, current_socket->socket_values.tcp_control.last_packet_time.microseconds, -// now.microseconds - current_socket->socket_values.tcp_control.last_packet_time.microseconds, -// current_timeout); - } - } - } +{ + msg_t send; + double current_timeout = current_socket->socket_values.tcp_control.rto; + + if(current_timeout < SECOND) { + current_timeout = SECOND; + } + + uint8_t i; + + if((current_socket->socket_values.tcp_control.send_nxt > + current_socket->socket_values.tcp_control.send_una) && + (thread_getstatus(current_socket->send_pid) == STATUS_RECEIVE_BLOCKED)) { + for(i = 0; i < current_socket->socket_values.tcp_control.no_of_retries; + i++) { + current_timeout *= 2; + } + + timex_t now; + vtimer_now(&now); + + if(current_timeout > TCP_ACK_MAX_TIMEOUT) { + net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT); + } + else if(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds > + current_timeout) { + current_socket->socket_values.tcp_control.no_of_retries++; + net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY); + } + } +} void check_sockets(void) - { - socket_internal_t *current_socket; - uint8_t i = 1; - while (i < MAX_SOCKETS+1) - { - current_socket = getSocket(i); - - if(isTCPSocket(i)) - { - switch (current_socket->socket_values.tcp_control.state) - { - case ESTABLISHED: - { - handle_established(current_socket); - break; - } - case SYN_SENT: - { - handle_synchro_timeout(current_socket); - break; - } - case SYN_RCVD: - { - handle_synchro_timeout(current_socket); - break; - } - default: - { - break; - } - } - } - i++; - } - } +{ + socket_internal_t *current_socket; + uint8_t i = 1; + + while(i < MAX_SOCKETS + 1) { + current_socket = getSocket(i); + + if(isTCPSocket(i)) { + switch(current_socket->socket_values.tcp_control.state) { + case ESTABLISHED: { + handle_established(current_socket); + break; + } + + case SYN_SENT: { + handle_synchro_timeout(current_socket); + break; + } + + case SYN_RCVD: { + handle_synchro_timeout(current_socket); + break; + } + + default: { + break; + } + } + } + + i++; + } +} void inc_global_variables(void) - { - mutex_lock(&global_sequence_clunter_mutex); - global_sequence_counter += rand(); - mutex_unlock(&global_sequence_clunter_mutex, 0); +{ + mutex_lock(&global_sequence_clunter_mutex); + global_sequence_counter += rand(); + mutex_unlock(&global_sequence_clunter_mutex, 0); #ifdef TCP_HC - mutex_lock(&global_context_counter_mutex); - global_context_counter += rand(); - mutex_unlock(&global_context_counter_mutex, 0); + mutex_lock(&global_context_counter_mutex); + global_context_counter += rand(); + mutex_unlock(&global_context_counter_mutex, 0); #endif - } +} void tcp_general_timer(void) - { - vtimer_t tcp_vtimer; - timex_t interval = timex_set(0, TCP_TIMER_RESOLUTION); - - while (1) - { - inc_global_variables(); - check_sockets(); - vtimer_set_wakeup(&tcp_vtimer, interval, thread_getpid()); - thread_sleep(); - } - } +{ + vtimer_t tcp_vtimer; + timex_t interval = timex_set(0, TCP_TIMER_RESOLUTION); + + while(1) { + inc_global_variables(); + check_sockets(); + vtimer_set_wakeup(&tcp_vtimer, interval, thread_getpid()); + thread_sleep(); + } +} diff --git a/sys/net/destiny/udp.c b/sys/net/destiny/udp.c index b96738e2c814bebcc0c1fc565f06a5a84ebeb5e5..18fac61b3068f8c3031fb5e40e2627f896475eb2 100644 --- a/sys/net/destiny/udp.c +++ b/sys/net/destiny/udp.c @@ -1,3 +1,20 @@ +/** + * Destiny UDP implementation + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file udp.c + * @brief UDP implementation + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} + */ + #include <stdio.h> #include <thread.h> @@ -13,53 +30,48 @@ #include "../net_help/msg_help.h" uint16_t udp_csum(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header) - { +{ uint16_t sum; uint16_t len = udp_header->length; - sum = len + IPPROTO_UDP; - sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t)); - sum = csum(sum, (uint8_t*)udp_header, len); + sum = len + IPPROTO_UDP; + sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t)); + sum = csum(sum, (uint8_t *)udp_header, len); return (sum == 0) ? 0xffff : HTONS(sum); - } +} void udp_packet_handler(void) - { - msg_t m_recv_ip, m_send_ip, m_recv_udp, m_send_udp; - ipv6_hdr_t *ipv6_header; - udp_hdr_t *udp_header; - uint8_t *payload; - socket_internal_t *udp_socket = NULL; - uint16_t chksum; +{ + msg_t m_recv_ip, m_send_ip, m_recv_udp, m_send_udp; + ipv6_hdr_t *ipv6_header; + udp_hdr_t *udp_header; + uint8_t *payload; + socket_internal_t *udp_socket = NULL; + uint16_t chksum; - while (1) - { - msg_receive(&m_recv_ip); - ipv6_header = ((ipv6_hdr_t*)m_recv_ip.content.ptr); - udp_header = ((udp_hdr_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); - payload = (uint8_t*)(m_recv_ip.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN); + while(1) { + msg_receive(&m_recv_ip); + ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr); + udp_header = ((udp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); + payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN); - chksum = udp_csum(ipv6_header, udp_header); + chksum = udp_csum(ipv6_header, udp_header); - if (chksum == 0xffff) - { - udp_socket = get_udp_socket(ipv6_header, udp_header); - if (udp_socket != NULL) - { - m_send_udp.content.ptr = (char*)ipv6_header; - msg_send_receive(&m_send_udp, &m_recv_udp, udp_socket->recv_pid); - } - else - { - printf("Dropped UDP Message because no thread ID was found for delivery!\n"); - } - } - else - { - printf("Wrong checksum (%x)!\n", chksum); - } - msg_reply(&m_recv_ip, &m_send_ip); - } - } + if(chksum == 0xffff) { + udp_socket = get_udp_socket(ipv6_header, udp_header); + if(udp_socket != NULL) { + m_send_udp.content.ptr = (char *)ipv6_header; + msg_send_receive(&m_send_udp, &m_recv_udp, udp_socket->recv_pid); + } + else { + printf("Dropped UDP Message because no thread ID was found for delivery!\n"); + } + } + else { + printf("Wrong checksum (%x)!\n", chksum); + } + msg_reply(&m_recv_ip, &m_send_ip); + } +} diff --git a/sys/net/destiny/udp.h b/sys/net/destiny/udp.h index 5a232ab1fa76b520e218cbef7149fff967df4823..ba581ba28e2166279055ed497acf8eea6d36c346 100644 --- a/sys/net/destiny/udp.h +++ b/sys/net/destiny/udp.h @@ -1,3 +1,20 @@ +/** + * Destiny TCP header + * + * Copyright (C) 2013 INRIA. + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup destiny + * @{ + * @file udp.c + * @brief UDP data structs and prototypes + * @author Oliver Gesch <oliver.gesch@googlemail.com> + * @} + */ + /* * udp.h * @@ -14,7 +31,7 @@ #include "../sixlowpan/sixlowip.h" -typedef struct __attribute__ ((packed)) udp_h_t{ +typedef struct __attribute__((packed)) udp_h_t { uint16_t src_port; uint16_t dst_port; uint16_t length; diff --git a/sys/net/net_help/inet_ntop.c b/sys/net/net_help/inet_ntop.c index d72e8a0aaf88c9b4007ad345a96734016777a029..db05d87479ce111e2b7174c318625067e0557006 100644 --- a/sys/net/net_help/inet_ntop.c +++ b/sys/net/net_help/inet_ntop.c @@ -33,34 +33,38 @@ * author: * Paul Vixie, 1996. */ -static const char * -inet_ntop4(const unsigned char *src, char *dst, size_t size) +static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size) { - const size_t MIN_SIZE = 16; /* space for 255.255.255.255\0 */ - int n = 0; - char *next = dst; - - if (size < MIN_SIZE) { - return NULL; - } - do { - unsigned char u = *src++; - if (u > 99) { - *next++ = '0' + u/100; - u %= 100; - *next++ = '0' + u/10; - u %= 10; - } - else if (u > 9) { - *next++ = '0' + u/10; - u %= 10; - } - *next++ = '0' + u; - *next++ = '.'; - n++; - } while (n < 4); - *--next = 0; - return dst; + const size_t MIN_SIZE = 16; /* space for 255.255.255.255\0 */ + int n = 0; + char *next = dst; + + if(size < MIN_SIZE) { + return NULL; + } + + do { + unsigned char u = *src++; + + if(u > 99) { + *next++ = '0' + u / 100; + u %= 100; + *next++ = '0' + u / 10; + u %= 10; + } + else if(u > 9) { + *next++ = '0' + u / 10; + u %= 10; + } + + *next++ = '0' + u; + *next++ = '.'; + n++; + } + while(n < 4); + + *--next = 0; + return dst; } /* const char * @@ -69,8 +73,7 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size) * author: * Paul Vixie, 1996. */ -static const char * -inet_ntop6(const unsigned char *src, char *dst, size_t size) +static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough @@ -80,7 +83,9 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; - struct { int base, len; } best = {-1, 0}, cur = {-1, 0}; + struct { + int base, len; + } best = { -1, 0}, cur = { -1, 0}; unsigned int words[IN6ADDRSZ / INT16SZ]; int i; const unsigned char *next_src, *src_end; @@ -95,38 +100,43 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) src_end = src + IN6ADDRSZ; next_dest = words; i = 0; + do { - unsigned int next_word = (unsigned int)*next_src++; + unsigned int next_word = (unsigned int) *next_src++; next_word <<= 8; - next_word |= (unsigned int)*next_src++; + next_word |= (unsigned int) *next_src++; *next_dest++ = next_word; - if (next_word == 0) { - if (cur.base == -1) { + if(next_word == 0) { + if(cur.base == -1) { cur.base = i; cur.len = 1; } else { cur.len++; } - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) { + } + else { + if(cur.base != -1) { + if(best.base == -1 || cur.len > best.len) { best = cur; } + cur.base = -1; } } i++; - } while (next_src < src_end); + } + while(next_src < src_end); - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) { + if(cur.base != -1) { + if(best.base == -1 || cur.len > best.len) { best = cur; } } - if (best.base != -1 && best.len < 2) { + + if(best.base != -1 && best.len < 2) { best.base = -1; } @@ -134,41 +144,49 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) * Format the result. */ tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ);) { + + for(i = 0; i < (IN6ADDRSZ / INT16SZ);) { /* Are we inside the best run of 0x00's? */ - if (i == best.base) { + if(i == best.base) { *tp++ = ':'; i += best.len; continue; } + /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) { + if(i != 0) { *tp++ = ':'; } + /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) { + if(i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if(!inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp))) { return (NULL); } + tp += strlen(tp); break; } + tp += snprintf(tp, sizeof tmp - (tp - tmp), "%x", words[i]); i++; } + /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { + if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { *tp++ = ':'; } + *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ - if ((size_t)(tp - tmp) > size) { + if((size_t)(tp - tmp) > size) { return (NULL); } + strcpy(dst, tmp); return (dst); } @@ -181,16 +199,18 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) * author: * Paul Vixie, 1996. */ -const char * -inet_ntop(int af, const void *src, char *dst, size_t size) +const char *inet_ntop(int af, const void *src, char *dst, size_t size) { - switch (af) { - case AF_INET: - return (inet_ntop4(src, dst, size)); - case AF_INET6: - return (inet_ntop6(src, dst, size)); - default: - return (NULL); - } - /* NOTREACHED */ + switch(af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + + case AF_INET6: + return (inet_ntop6(src, dst, size)); + + default: + return (NULL); + } + + /* NOTREACHED */ } diff --git a/sys/net/net_help/inet_ntop.h b/sys/net/net_help/inet_ntop.h index 281f1ffa9bc73aed7f910f6615ab26e3a3823354..2e94fa4bf52ec5c53923893bdde52036e86755d9 100644 --- a/sys/net/net_help/inet_ntop.h +++ b/sys/net/net_help/inet_ntop.h @@ -18,6 +18,6 @@ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -const char *inet_ntop (int af, const void *src, char *dst, size_t size); +const char *inet_ntop(int af, const void *src, char *dst, size_t size); #endif /* INET_NTOP_H_ */ diff --git a/sys/net/net_help/inet_pton.c b/sys/net/net_help/inet_pton.c index cbf1193dd5aea7acc1ec43d78827106f59f6952b..59b6adf2570d1a561b76ceee9cbe8dd5c44acf77 100644 --- a/sys/net/net_help/inet_pton.c +++ b/sys/net/net_help/inet_pton.c @@ -17,9 +17,9 @@ #include <stdio.h> #include <string.h> #include <stdint.h> - + #include "sys/net/destiny/socket.h" - + #include "inet_pton.h" /* int @@ -32,8 +32,7 @@ * author: * Paul Vixie, 1996. */ -static int -inet_pton4(const char *src, unsigned char *dst) +static int inet_pton4(const char *src, unsigned char *dst) { static const char digits[] = "0123456789"; int saw_digit, octets, ch; @@ -42,30 +41,43 @@ inet_pton4(const char *src, unsigned char *dst) saw_digit = 0; octets = 0; *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - unsigned int new = *tp * 10 + (unsigned int)(pch - digits); - - if (new > 255) - return (0); - *tp = new; - if (! saw_digit) { - if (++octets > 4) - return (0); - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } else - return (0); + + while((ch = *src++) != '\0') { + const char *pch; + + if((pch = strchr(digits, ch)) != NULL) { + unsigned int new = *tp * 10 + (unsigned int)(pch - digits); + + if(new > 255) { + return (0); + } + + *tp = new; + + if(! saw_digit) { + if(++octets > 4) { + return (0); + } + + saw_digit = 1; + } + } + else if(ch == '.' && saw_digit) { + if(octets == 4) { + return (0); + } + + *++tp = 0; + saw_digit = 0; + } + else { + return (0); + } + } + + if(octets < 4) { + return (0); } - if (octets < 4) - return (0); memcpy(dst, tmp, INADDRSZ); return (1); @@ -84,87 +96,112 @@ inet_pton4(const char *src, unsigned char *dst) * author: * Paul Vixie, 1996. */ -static int -inet_pton6(const char *src, unsigned char *dst) +static int inet_pton6(const char *src, unsigned char *dst) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - unsigned int val; - - memset((tp = tmp), '\0', IN6ADDRSZ); - endp = tp + IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) - return (0); - saw_xdigit = 1; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) - return (0); - colonp = tp; - continue; - } - if (tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if (saw_xdigit) { - if (tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const ssize_t n = tp - colonp; - ssize_t i; - - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) - return (0); - memcpy(dst, tmp, IN6ADDRSZ); - return (1); + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + unsigned int val; + + memset((tp = tmp), '\0', IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + + /* Leading :: requires some special handling. */ + if(*src == ':') + if(*++src != ':') { + return (0); + } + + curtok = src; + saw_xdigit = 0; + val = 0; + + while((ch = *src++) != '\0') { + const char *pch; + + if((pch = strchr((xdigits = xdigits_l), ch)) == NULL) { + pch = strchr((xdigits = xdigits_u), ch); + } + + if(pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + + if(val > 0xffff) { + return (0); + } + + saw_xdigit = 1; + continue; + } + + if(ch == ':') { + curtok = src; + + if(!saw_xdigit) { + if(colonp) { + return (0); + } + + colonp = tp; + continue; + } + + if(tp + INT16SZ > endp) { + return (0); + } + + *tp++ = (unsigned char)(val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + + if(ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + + return (0); + } + + if(saw_xdigit) { + if(tp + INT16SZ > endp) { + return (0); + } + + *tp++ = (unsigned char)(val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + } + + if(colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const ssize_t n = tp - colonp; + ssize_t i; + + for(i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + + tp = endp; + } + + if(tp != endp) { + return (0); + } + + memcpy(dst, tmp, IN6ADDRSZ); + return (1); } /* int @@ -178,16 +215,18 @@ inet_pton6(const char *src, unsigned char *dst) * author: * Paul Vixie, 1996. */ -int -inet_pton(int af, const char *src, void *dst) +int inet_pton(int af, const char *src, void *dst) { - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); - case AF_INET6: - return (inet_pton6(src, dst)); - default: - return (-1); - } - /* NOTREACHED */ + switch(af) { + case AF_INET: + return (inet_pton4(src, dst)); + + case AF_INET6: + return (inet_pton6(src, dst)); + + default: + return (-1); + } + + /* NOTREACHED */ } diff --git a/sys/net/net_help/msg_help.c b/sys/net/net_help/msg_help.c index 89d6fd518ffdc0baabb7896551dd2e34012cc238..c490ec738bf16f36bacd493f83d386fb28e5cc7c 100644 --- a/sys/net/net_help/msg_help.c +++ b/sys/net/net_help/msg_help.c @@ -11,34 +11,34 @@ #include "sys/net/destiny/tcp_timer.h" void block_continue_thread(void) - { -// msg_t recv_m; -// recv_m.type = TCP_NOT_DEFINED; -// while (recv_m.type != TCP_CONTINUE) -// { -// net_msg_receive(&recv_m); -// } - } +{ + // msg_t recv_m; + // recv_m.type = TCP_NOT_DEFINED; + // while (recv_m.type != TCP_CONTINUE) + // { + // net_msg_receive(&recv_m); + // } +} int net_msg_receive(msg_t *m) - { - return msg_receive(m); - } +{ + return msg_receive(m); +} int net_msg_reply(msg_t *m, msg_t *reply, uint16_t message) - { - reply->type = message; - return msg_reply(m, reply); - } +{ + reply->type = message; + return msg_reply(m, reply); +} int net_msg_send(msg_t *m, unsigned int pid, bool block, uint16_t message) - { - m->type = message; - return msg_send(m, pid, block); - } +{ + m->type = message; + return msg_send(m, pid, block); +} int net_msg_send_recv(msg_t *m, msg_t *reply, unsigned int pid, uint16_t message) - { - m->type = message; - return msg_send_receive(m, reply, pid);; - } +{ + m->type = message; + return msg_send_receive(m, reply, pid);; +} diff --git a/sys/net/net_help/net_help.c b/sys/net/net_help/net_help.c index 5d008e0eb9c688557f7cec8cdb4db1c8b65638c5..2b249a33a4d4d3df9dfc50b14599603890c1dc79 100644 --- a/sys/net/net_help/net_help.c +++ b/sys/net/net_help/net_help.c @@ -12,48 +12,50 @@ #include "net_help.h" void printArrayRange(uint8_t *array, uint16_t len, char *str) - { - int i = 0; - printf("-------------%s-------------\n", str); - for (i = 0; i < len; i++) - { - printf("%#x ", *(array+i)); - } - printf("\n-----------%u-------------\n", len); - } +{ + int i = 0; + printf("-------------%s-------------\n", str); + + for(i = 0; i < len; i++) { + printf("%#x ", *(array + i)); + } + + printf("\n-----------%u-------------\n", len); +} uint16_t csum(uint16_t sum, uint8_t *buf, uint16_t len) - { +{ int count; uint16_t carry; count = len >> 1; - if(count) - { - if(count) - { + + if(count) { + if(count) { carry = 0; - do - { - uint16_t t = (*buf << 8) + *(buf+1); + + do { + uint16_t t = (*buf << 8) + *(buf + 1); count--; buf += 2; sum += carry; sum += t; carry = (t > sum); - } while(count); + } + while(count); + sum += carry; - } - } - if(len & 1) - { + } + } + + if(len & 1) { uint16_t u = (*buf << 8); sum += (*buf << 8); - if(sum < u) - { + + if(sum < u) { sum++; - } - } + } + } return sum; - } +} diff --git a/sys/net/protocol-multiplex/protocol-multiplex.c b/sys/net/protocol-multiplex/protocol-multiplex.c index d5ac1894fa61de4de98efc287a32e06b060842ea..72c1d6254bdc5a7975d2f1be25ad45e6d18bf4a8 100644 --- a/sys/net/protocol-multiplex/protocol-multiplex.c +++ b/sys/net/protocol-multiplex/protocol-multiplex.c @@ -49,97 +49,103 @@ and the mailinglist (subscription via web site) //#define DEBUG #ifdef DEBUG - #include <stdio.h> - #define PRINTF(fmt,args...) printf("pm: " fmt "\n", ##args) +#include <stdio.h> +#define PRINTF(fmt,args...) printf("pm: " fmt "\n", ##args) #else - #define PRINTF(...) +#define PRINTF(...) #endif /*---------------------------------------------------------------------------*/ -void -pm_init_table(pm_table_t* table, uint8_t size, handler_entry_t* handler) +void pm_init_table(pm_table_t *table, uint8_t size, handler_entry_t *handler) { - table->size = size; - table->handler = handler; - memset(handler, 0, sizeof(handler_entry_t) * size); + table->size = size; + table->handler = handler; + memset(handler, 0, sizeof(handler_entry_t) * size); } /*---------------------------------------------------------------------------*/ -int -pm_find_handler_index(const pm_table_t* table, protocol_t protocol, unsigned int start) +int pm_find_handler_index(const pm_table_t *table, protocol_t protocol, + unsigned int start) { - int i; - handler_entry_t* e = &table->handler[start]; - for(i = start; i < table->size; i++, e++) - { - if (e->protocol == protocol) - return i; - } - return -1; + int i; + handler_entry_t *e = &table->handler[start]; + + for(i = start; i < table->size; i++, e++) { + if(e->protocol == protocol) { + return i; + } + } + + return -1; } /*---------------------------------------------------------------------------*/ -int -pm_set_handler(const pm_table_t* table, protocol_t protocol, packet_handler_t handler) +int pm_set_handler(const pm_table_t *table, protocol_t protocol, + packet_handler_t handler) { - // Reject illegal values - if (protocol == 0 || handler == NULL) { - PRINTF("proto %u rejected", protocol); - return -1; - } - // Check if there is already a handler for given protocol - int index = pm_find_handler_index(table, protocol, 0); - if (index >= 0) - { - // Two handlers for same protocol not allowed because only - // one gets called. This hasn't to be the last one who - // registered! - PRINTF("proto %u handler found, reset", protocol); - table->handler[index].protocol = 0; - table->handler[index].handler = NULL; - - } - // Find free position for handler (protocol value is 0) - index = pm_find_handler_index(table, 0, 0); - // Store handler if free index found - if (index >= 0) - { - PRINTF("proto %u, set", protocol); - table->handler[index].protocol = protocol; - table->handler[index].handler = handler; - } - // Return result (-1 on error or no free index) - return index; + /* Reject illegal values */ + if(protocol == 0 || handler == NULL) { + PRINTF("proto %u rejected", protocol); + return -1; + } + + /* Check if there is already a handler for given protocol */ + int index = pm_find_handler_index(table, protocol, 0); + + if(index >= 0) { + /* Two handlers for same protocol not allowed because only + * one gets called. This hasn't to be the last one who + * registered! */ + PRINTF("proto %u handler found, reset", protocol); + table->handler[index].protocol = 0; + table->handler[index].handler = NULL; + } + + /* Find free position for handler (protocol value is 0) */ + index = pm_find_handler_index(table, 0, 0); + + /* Store handler if free index found */ + if(index >= 0) { + PRINTF("proto %u, set", protocol); + table->handler[index].protocol = protocol; + table->handler[index].handler = handler; + } + + /* Return result (-1 on error or no free index) */ + return index; } /*---------------------------------------------------------------------------*/ -void -pm_remove_handler(const pm_table_t* table, protocol_t protocol, packet_handler_t handler) +void pm_remove_handler(const pm_table_t *table, protocol_t protocol, + packet_handler_t handler) { - int i; - for (i = 0; i < table->size; i++) - { - if (table->handler[i].protocol == protocol && table->handler[i].handler == handler) - { - PRINTF("proto %u handler found, reset", protocol); - table->handler[i].protocol = 0; - table->handler[i].handler = NULL; - } - } + int i; + + for(i = 0; i < table->size; i++) { + if(table->handler[i].protocol == protocol && table->handler[i].handler == handler) { + PRINTF("proto %u handler found, reset", protocol); + table->handler[i].protocol = 0; + table->handler[i].handler = NULL; + } + } } /*---------------------------------------------------------------------------*/ -int -pm_invoke(const pm_table_t* table, protocol_t protocol, void* payload, int payload_size, packet_info_t* packet_info) +int pm_invoke(const pm_table_t *table, protocol_t protocol, void *payload, + int payload_size, packet_info_t *packet_info) { - int index = 0; - - // Reject illegal values - if (protocol == 0) return -1; - - if ( (index = pm_find_handler_index(table, protocol, index)) != -1 ) { - PRINTF("proto %u, invoke", protocol); - table->handler[index].handler(payload, payload_size, packet_info); - } else { - PRINTF("proto %u invoke failed (no handler)", protocol); - } - return index; + int index = 0; + + /* Reject illegal values */ + if(protocol == 0) { + return -1; + } + + if((index = pm_find_handler_index(table, protocol, index)) != -1) { + PRINTF("proto %u, invoke", protocol); + table->handler[index].handler(payload, payload_size, packet_info); + } + else { + PRINTF("proto %u invoke failed (no handler)", protocol); + } + + return index; } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/sys/net/protocol-multiplex/protocol-multiplex.h b/sys/net/protocol-multiplex/protocol-multiplex.h index b324aede5b2e4b18fcc039f6f849d7ab6ed316e6..f235138317db66d3c7354e7527562ba7bfdea7d3 100644 --- a/sys/net/protocol-multiplex/protocol-multiplex.h +++ b/sys/net/protocol-multiplex/protocol-multiplex.h @@ -49,20 +49,20 @@ and the mailinglist (subscription via web site) #include "radio/types.h" typedef struct { - packet_handler_t handler; - protocol_t protocol; + packet_handler_t handler; + protocol_t protocol; } handler_entry_t; typedef struct { - uint8_t size; - handler_entry_t* handler; + uint8_t size; + handler_entry_t *handler; } pm_table_t; -void pm_init_table(pm_table_t* table, uint8_t size, handler_entry_t* handler); -int pm_find_handler_index(const pm_table_t* table, protocol_t protocol, unsigned int start); -int pm_set_handler(const pm_table_t* table, protocol_t protocol, packet_handler_t handler); -void pm_remove_handler(const pm_table_t* table, protocol_t protocol, packet_handler_t handler); -int pm_invoke(const pm_table_t* table, protocol_t protocol, void* payload, int payload_size, packet_info_t* packet_info); +void pm_init_table(pm_table_t *table, uint8_t size, handler_entry_t *handler); +int pm_find_handler_index(const pm_table_t *table, protocol_t protocol, unsigned int start); +int pm_set_handler(const pm_table_t *table, protocol_t protocol, packet_handler_t handler); +void pm_remove_handler(const pm_table_t *table, protocol_t protocol, packet_handler_t handler); +int pm_invoke(const pm_table_t *table, protocol_t protocol, void *payload, int payload_size, packet_info_t *packet_info); /** @} */ diff --git a/sys/ping/ping.c b/sys/ping/ping.c index 62d23ac2b8d02b2be2f98ac322b72e75255505f7..bec8010970d2d5b35870bb8e329ca07807a11264 100644 --- a/sys/ping/ping.c +++ b/sys/ping/ping.c @@ -17,64 +17,79 @@ radio_address_t r_address = 0; timex_t start = 0; float rtt = 0; -void ping_handler(void *payload, int payload_size, - packet_info_t *packet_info){ - pong(packet_info->phy_src); +void ping_handler(void *payload, int payload_size, + packet_info_t *packet_info) +{ + pong(packet_info->phy_src); } void pong_handler(void *payload, int payload_size, - packet_info_t *packet_info){ - calc_rtt(); - print_success(); + packet_info_t *packet_info) +{ + calc_rtt(); + print_success(); } -void pong(uint16_t src){ - int trans_ok = cc1100_send_csmaca(src,protocol_id,2,pipa->payload, - sizeof(pipa->payload)); - if(trans_ok < 0) - print_failed(); +void pong(uint16_t src) +{ + int trans_ok = cc1100_send_csmaca(src, protocol_id, 2, pipa->payload, + sizeof(pipa->payload)); + + if(trans_ok < 0) { + print_failed(); + } } -void ping_init(protocol_t protocol, uint8_t channr, radio_address_t addr){ - protocol_id = protocol; - r_address = addr; - cc1100_set_packet_handler(protocol, ping_handler); - cc1100_set_channel(channr); - cc1100_set_address(r_address); - init_payload(); +void ping_init(protocol_t protocol, uint8_t channr, radio_address_t addr) +{ + protocol_id = protocol; + r_address = addr; + cc1100_set_packet_handler(protocol, ping_handler); + cc1100_set_channel(channr); + cc1100_set_address(r_address); + init_payload(); } -void ping(radio_address_t addr, uint8_t channr){ - cc1100_set_packet_handler(protocol_id, pong_handler); - cc1100_set_channel(channr); - cc1100_set_address(r_address); - while(1){ - vtimer_now(&start); - int trans_ok = cc1100_send_csmaca(addr, - protocol_id,2,pipa->payload,sizeof(pipa->payload)); - if(trans_ok < 0) - print_failed(); - hwtimer_wait(500000); - } +void ping(radio_address_t addr, uint8_t channr) +{ + cc1100_set_packet_handler(protocol_id, pong_handler); + cc1100_set_channel(channr); + cc1100_set_address(r_address); + + while(1) { + vtimer_now(&start); + int trans_ok = cc1100_send_csmaca(addr, + protocol_id, 2, pipa->payload, sizeof(pipa->payload)); + + if(trans_ok < 0) { + print_failed(); + } + + hwtimer_wait(500000); + } } -void calc_rtt(void){ - timex_t end; - vtimer_now(&end); - timex_t result = vtimer_sub(end, start); - - rtt = result.seconds+(float)result.microseconds/100000; +void calc_rtt(void) +{ + timex_t end; + vtimer_now(&end); + timex_t result = vtimer_sub(end, start); + + rtt = result.seconds + (float)result.microseconds / 100000; } -void print_success(void){ - printf("%s%f%s\n","time=",rtt,"ms"); +void print_success(void) +{ + printf("%s%f%s\n", "time=", rtt, "ms"); } -void print_failed(void){ - printf("%s\n","ping failed"); +void print_failed(void) +{ + printf("%s\n", "ping failed"); } -void init_payload(void){ - pipa = malloc(sizeof(pipa)); - pipa->payload = NULL; +void init_payload(void) +{ + pipa = malloc(sizeof(pipa)); + pipa->payload = NULL; } diff --git a/sys/syslog/syslog-api.c b/sys/syslog/syslog-api.c index 63528532e8b1c24054c0395e203e2b63ccfe42f8..0ff92971cde3b00b65fecee4f10cc1bed8525590 100644 --- a/sys/syslog/syslog-api.c +++ b/sys/syslog/syslog-api.c @@ -1,27 +1,19 @@ -/****************************************************************************** -Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. +/** + * Syslog daemon + * + * Copyright (C) 2009-2013 Freie Universitaet Berlin + * + * This file subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup syslog + * @{ + * @file syslog-api.c + * @author Freie Universitaet Berlin + * @} + */ -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of RIOT. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -RIOT is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de *******************************************************************************/ #include <stdarg.h>