1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

C6O implemented

This commit is contained in:
mlenders 2011-06-18 23:33:47 +02:00
parent d23d1ff256
commit 31d0e35c0b
2 changed files with 103 additions and 4 deletions

View File

@ -45,6 +45,8 @@ static struct opt_buf_t *opt_buf;
static struct opt_stllao_t *opt_stllao_buf;
static struct opt_mtu_t *opt_mtu_buf;
static struct opt_abro_t *opt_abro_buf;
static struct opt_6co_hdr_t *opt_6co_hdr_buf;
static uint8_t *opt_6co_prefix_buf;
static struct opt_pi_t *opt_pi_buf;
static struct opt_aro_t *opt_aro_buf;
@ -89,6 +91,16 @@ static struct opt_abro_t* get_opt_abro_buf(uint8_t ext_len, uint8_t opt_len){
ext_len + opt_len]));
}
static struct opt_6co_hdr_t* get_opt_6co_hdr_buf(uint8_t ext_len, uint8_t opt_len){
return ((struct opt_6co_hdr_t*)&(buffer[LLHDR_ICMPV6HDR_LEN +
ext_len + opt_len]));
}
static uint8_t* get_opt_6co_prefix_buf(uint8_t ext_len, uint8_t opt_len){
return ((uint8_t*)&(buffer[LLHDR_ICMPV6HDR_LEN +
ext_len + opt_len]));
}
static struct opt_pi_t* get_opt_pi_buf(uint8_t ext_len, uint8_t opt_len){
return ((struct opt_pi_t*)&(buffer[LLHDR_ICMPV6HDR_LEN +
ext_len + opt_len]));
@ -187,6 +199,24 @@ void recv_rtr_sol(void){
}
uint8_t set_opt_6co_flags(uint8_t compression_flag, uint8_t cid) {
uint8_t flags;
if (compression_flag)
flags = OPT_6CO_FLAG_C;
else
flags = 0;
flags |= cid ^ OPT_6CO_FLAG_CID;
return flags;
}
void get_opt_6co_flags(uint8_t *compression_flag, uint8_t *cid, uint8_t flags) {
compression_flag[0] = flags ^ OPT_6CO_FLAG_CID;
compression_flag[0] = compression_flag[0] != 0;
cid[0] = flags ^ OPT_6CO_FLAG_CID;
}
void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
uint8_t sixco, uint8_t abro){
abr_cache_t *msg_abr = NULL;
@ -257,6 +287,57 @@ void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
}
}
if(sixco == OPT_6CO){
/* set 6lowpan context option */
lowpan_context_t *contexts = NULL;
int contexts_len = 0;
if (msg_abr == NULL) {
contexts = lowpan_context_get();
contexts_len = lowpan_context_len();
} else {
contexts_len = msg_abr->contexts_num;
contexts = (lowpan_context_t*)calloc(contexts_len, sizeof(lowpan_context_t));
for (int i = 0; i < contexts_len; i++) {
contexts[i] = *(msg_abr->contexts[i]);
}
}
for(int i = 0; i < contexts_len; i++){
opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len);
opt_6co_hdr_buf->type = OPT_6CO_TYPE;
if (contexts[i].length > 64) {
opt_6co_hdr_buf->length = OPT_6CO_MAX_LEN;
} else {
opt_6co_hdr_buf->length = OPT_6CO_MIN_LEN;
}
opt_6co_hdr_buf->c_length = HTONL(contexts[i].length);
opt_6co_hdr_buf->c_flags = HTONL(set_opt_6co_flags(contexts[i].comp,contexts[i].num));
opt_6co_hdr_buf->reserved = 0;
opt_6co_hdr_buf->val_ltime = HTONL((vtimer_remaining(&(contexts[i].lifetime)).nanoseconds / 1000000) / 60);
opt_hdr_len += OPT_6CO_HDR_LEN;
packet_length += OPT_6CO_HDR_LEN;
// attach prefixes
opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len);
uint8_t target_size;
if (opt_6co_hdr_buf->c_length > 64) {
target_size = 16;
} else {
target_size = 8;
}
memset((void*)opt_6co_prefix_buf,0,target_size);
memcpy((void*)opt_6co_prefix_buf, (void*)&(contexts[i].prefix.uint8[0]), opt_6co_hdr_buf->c_length / 8);
opt_hdr_len += target_size;
packet_length += target_size;
}
if (msg_abr != NULL && contexts != NULL) {
free(contexts);
}
}
if(pi == OPT_PI){
plist_t *prefixes = NULL;
int plist_len = 0;
@ -409,6 +490,25 @@ void recv_rtr_adv(void){
break;
}
case(OPT_6CO_TYPE):{
opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len);
uint8_t context_len = opt_6co_hdr_buf->c_length;
uint8_t comp;
uint8_t num;
get_opt_6co_flags(&comp,&num, opt_6co_hdr_buf->c_flags);
uint8_t lifetime = opt_6co_hdr_buf->val_ltime;
lowpan_context_t *context;
ipv6_addr_t prefix;
memset(&prefix, 0, 16);
opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len + OPT_6CO_HDR_LEN);
memcpy(&prefix, opt_6co_prefix_buf, context_len);
context = lowpan_context_update(num, &prefix, context_len, comp, lifetime);
found_contexts[found_con_len] = context;
found_con_len = (found_con_len + 1)%LOWPAN_CONTEXT_MAX; // better solution here, i.e. some kind of stack
break;
}
case(OPT_ABRO_TYPE):{

View File

@ -50,8 +50,7 @@
#define OPT_6CO_TYPE 32
#define OPT_6CO_MIN_LEN 2
#define OPT_6CO_MAX_LEN 3
#define OPT_6CO_MIN_HDR_LEN 16
#define OPT_6CO_MAX_HDR_LEN 24
#define OPT_6CO_HDR_LEN 8
#define OPT_6CO_LTIME 5 // geeigneten Wert finden
#define OPT_6CO_FLAG_C 0x10
#define OPT_6CO_FLAG_CID 0x0F
@ -128,14 +127,14 @@ typedef struct __attribute__ ((packed)) opt_aro_t {
ieee_802154_long_t eui64;
} opt_aro_t;
typedef struct __attribute__ ((packed)) opt_6co_buf_t {
typedef struct __attribute__ ((packed)) opt_6co_hdr_t {
uint8_t type;
uint8_t length;
uint8_t c_length;
uint8_t c_flags;
uint16_t reserved;
uint16_t val_ltime;
} opt_6co_buf_t;
} opt_6co_hdr_t;
typedef struct __attribute__ ((packed)) opt_abro_t {
uint8_t type;