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

fragmentation and reassambly works now and cleaned up tons of warnings

This commit is contained in:
Stephan Zeisberg 2011-01-07 13:02:27 +01:00
parent 66b668d6e1
commit 5e26d199cc
10 changed files with 248 additions and 95 deletions

View File

@ -1,6 +1,6 @@
#include "ieee802154_frame.h"
uint8_t mac_buf[IEEE_802154_HDR_LEN + IEEE_802154_PAYLOAD_LEN];
//uint8_t mac_buf[IEEE_802154_HDR_LEN + IEEE_802154_PAYLOAD_LEN];
uint8_t ieee802154_hdr_ptr;
uint8_t ieee802154_payload_ptr;
@ -84,7 +84,6 @@ uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf){
*/
uint8_t get_802154_hdr_len(ieee802154_frame_t *frame){
uint8_t len = 0;
uint8_t comp;
if(frame->fcf.dest_addr_m == 0x02){
len += 2;
@ -131,7 +130,7 @@ uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len){
frame->fcf.frame_ver = (buf[index] >> 2) & 0x03;
frame->fcf.src_addr_m = buf[index] & 0x03;
print_802154_fcf_frame(frame);
//print_802154_fcf_frame(frame);
index++;
@ -223,31 +222,3 @@ void print_802154_fcf_frame(ieee802154_frame_t *frame){
frame->fcf.frame_ver,
frame->fcf.src_addr_m);
}
uint8_t get_802154_pkt_len(void){
return ((IEEE_802154_HDR_LEN - ieee802154_hdr_ptr) +
ieee802154_payload_len);
}
uint8_t check_802154_hdr_len(uint8_t len){
if((ieee802154_hdr_ptr >= len) &&
((get_802154_pkt_len() + len) <= IEEE_802154_PAYLOAD_LEN)){
ieee802154_hdr_ptr -= len;
return 1;
}
return 0;
}
uint8_t * get_802154_hdr_ptr(void){
return &mac_buf[ieee802154_hdr_ptr];
}
uint8_t * get_802154_payload_ptr(void){
return &mac_buf[ieee802154_payload_ptr + IEEE_802154_HDR_LEN];
}
void clear_802154_pkt(void){
ieee802154_payload_ptr = 0;
ieee802154_payload_len = 0;
ieee802154_hdr_ptr = IEEE_802154_HDR_LEN;
}

View File

@ -5,7 +5,7 @@
#include <stdint.h>
/* maximum 802.15.4 header length */
#define IEEE_802154_HDR_LEN 37
#define IEEE_802154_MAX_HDR_LEN 23
/* mininmum */
#define IEEE_802154_PAYLOAD_LEN 21
@ -44,10 +44,7 @@ typedef struct __attribute__ ((packed)) {
uint8_t init_802154_frame(ieee802154_frame_t *frame, uint8_t *buf);
uint8_t get_802154_hdr_len(ieee802154_frame_t *frame);
uint8_t get_802154_pkt_len(void);
uint8_t check_802154_hdr_len(uint8_t len);
uint8_t * get_802154_hdr_ptr(void);
uint8_t * get_802154_payload_ptr(void);
void clear_802154_pkt(void);
uint8_t read_802154_frame(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len);
void print_802154_fcf_frame(ieee802154_frame_t *frame);
#endif /* IEEE802154_FRAME */

View File

@ -1,5 +1,8 @@
//#include "sixlowpan.h"
#include "sixlowip.h"
#include "sixlowmac.h"
#include "sixlownd.h"
#include "sixlowpan.h"
#include <stdio.h>
#include "drivers/cc110x/cc1100.h"
#include "radio/radio.h"
@ -16,20 +19,23 @@ struct icmpv6_hdr_t* get_icmpv6_buf(uint8_t ext_len){
}
void bootstrapping(void){
void bootstrapping(uint8_t *addr){
#ifdef SIXLOWPAN_NODE
/* create link-local address based on eui-64 */
ipv6_buf = get_ipv6_buf();
RADIO.set_address(5);
//RADIO.set_address(5);
create_link_local_prefix(&ipv6_buf->srcaddr);
set_eui64(&ipv6_buf->srcaddr);
print6addr(&ipv6_buf->srcaddr);
init_802154_long_addr((uint8_t*)&(ipv6_buf->srcaddr.uint8[8]));
//set_eui64(&ipv6_buf->srcaddr);
// print6addr(&ipv6_buf->srcaddr);
/* send router solicitation */
send_rtr_sol();
init_rtr_sol();
output(addr,(uint8_t*)ipv6_buf);
//send_rtr_adv(&ipv6_buf->destaddr);
#endif
}
/*
void set_eui64(ipv6_addr_t *ipaddr){
uint16_t radio_driver_addr = RADIO.get_address();
@ -42,7 +48,7 @@ void set_eui64(ipv6_addr_t *ipaddr){
ipaddr->uint8[14] = (uint8_t) (radio_driver_addr >> 8);
ipaddr->uint8[15] = (uint8_t) radio_driver_addr;
}
*/
ieee_802154_long_t* get_eui(ipv6_addr_t *ipaddr){
return ((ieee_802154_long_t *) &(ipaddr->uint8[8]));
}

View File

@ -6,7 +6,7 @@
#include <stdint.h>
/* set maximum transmission unit */
#define MTU 0x3A
#define MTU 1280
/* IPv6 field values */
#define IPV6_VER 0x60
#define ICMPV6_NXT_HDR 0x3A
@ -93,7 +93,7 @@ void create_all_routers_mcast_addr(ipv6_addr_t *ipaddr);
void create_all_nodes_mcast_addr(ipv6_addr_t *ipaddr);
void set_eui64(ipv6_addr_t *ipaddr);
ieee_802154_long_t* get_eui(ipv6_addr_t *ipaddr);
void bootstrapping(void);
void bootstrapping(uint8_t *addr);
void print6addr(ipv6_addr_t *ipaddr);
#endif /* SIXLOWIP_H*/

View File

@ -1,9 +1,11 @@
/* 6LoWPAN MAC - layer 2 implementations */
#include <stdlib.h>
#include <string.h>
#include "sixlowmac.h"
#include "sixlowip.h"
#include "sixlownd.h"
#include "sixlowpan.h"
#include "thread.h"
#include "msg.h"
#include "radio/radio.h"
@ -15,9 +17,9 @@ msg msg_q[RADIO_RCV_BUF_SIZE];
uint8_t snd_buffer[RADIO_SND_BUF_SIZE][PAYLOAD_SIZE];
uint8_t buf[PAYLOAD_SIZE];
uint16_t packet_length;
static uint8_t macdsn;
static uint8_t macbsn;
//static uint8_t macbsn;
static radio_packet_t p;
static msg mesg;
@ -49,7 +51,9 @@ void init_802154_short_addr(ieee_802154_short_t *saddr){
saddr->uint8[1] = get_radio_address();
}
void init_802154_long_addr(ieee_802154_long_t *laddr){
void init_802154_long_addr(uint8_t *addr){
ieee_802154_long_t *laddr = (ieee_802154_long_t*)addr;
// 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit
laddr->uint16[0] = IEEE_802154_PAN_ID;
@ -66,7 +70,7 @@ void init_802154_long_addr(ieee_802154_long_t *laddr){
void recv_ieee802154_frame(void){
msg m;
radio_packet_t *p;
uint8_t i, hdrlen;
uint8_t hdrlen, length;
ieee802154_frame_t frame;
msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE);
@ -76,17 +80,19 @@ void recv_ieee802154_frame(void){
if (m.type == PKT_PENDING) {
p = (radio_packet_t*) m.content.ptr;
for (i = 0; i < p->length; i++) {
/* for (int i = 0; i < p->length; i++) {
printf("%02X ", p->data[i]);
}
//clear_802154_pkt();
printf("\n");
*/
hdrlen = read_802154_frame(p->data, &frame, p->length);
printf("hdrlen: %hu\n", hdrlen);
printf("payload: %02x\n", frame.payload[0]);
length = p->length - hdrlen;
/* deliver packet to network(6lowpan)-layer */
input(frame.payload, length);
p->processing--;
printf("\n");
// printf("\n");
}
else if (m.type == ENOBUFFER) {
puts("Transceiver buffer full");
@ -97,15 +103,16 @@ void recv_ieee802154_frame(void){
}
}
void set_ieee802154_fcf_values(ieee802154_frame_t *frame){
void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode,
uint8_t src_mode){
frame->fcf.frame_type = IEEE_802154_DATA_FRAME;
frame->fcf.sec_enb = 0;
frame->fcf.frame_pend = 0;
frame->fcf.ack_req = 0;
frame->fcf.panid_comp = 0;
frame->fcf.frame_ver = 0;
frame->fcf.src_addr_m = IEEE_802154_SHORT_ADDR_M;
frame->fcf.dest_addr_m = IEEE_802154_SHORT_ADDR_M;
frame->fcf.src_addr_m = src_mode;
frame->fcf.dest_addr_m = dest_mode;
}
void set_ieee802154_frame_values(ieee802154_frame_t *frame){
@ -113,10 +120,10 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame){
frame->dest_pan_id = IEEE_802154_PAN_ID;
frame->src_pan_id = IEEE_802154_PAN_ID;
frame->seq_nr = macdsn;
macdsn++;
}
void send_ieee802154_frame(uint16_t addr, uint8_t *buf){
unsigned int c, i;
void send_ieee802154_frame(uint8_t *addr, uint8_t *payload, uint8_t length){
set_radio_channel(13);
@ -129,7 +136,8 @@ void send_ieee802154_frame(uint16_t addr, uint8_t *buf){
ieee802154_frame_t frame;
memset(&frame, 0, sizeof(frame));
set_ieee802154_fcf_values(&frame);
set_ieee802154_fcf_values(&frame, IEEE_802154_SHORT_ADDR_M,
IEEE_802154_SHORT_ADDR_M);
set_ieee802154_frame_values(&frame);
/* ONLY FOR TESTING */
@ -138,31 +146,35 @@ void send_ieee802154_frame(uint16_t addr, uint8_t *buf){
frame.src_addr[0] = 0;
frame.src_addr[1] = 5;
uint8_t test = 30;
frame.payload = &test;
frame.payload_len = 1;
uint8_t hdrlen = get_802154_hdr_len(&frame);
//uint8_t buf[hdrlen + frame.payload_len];
printf("hdrlen: %02x\n",hdrlen);
//if(check_802154_hdr_len(hdrlen)){
memset(&buf,0,PAYLOAD_SIZE);
uint8_t index = init_802154_frame(&frame,&buf);
memcpy(&buf[hdrlen],frame.payload,frame.payload_len);
//p.length = get_802154_pkt_len();
//p.data = get_802154_hdr_ptr();
//}
p.length = PAYLOAD_SIZE;
p.dst = addr;
/* check if destination address is NULL => broadcast */
if(addr[0] == 0 && addr[1] == 0){
frame.dest_addr[0] = 0xff;
frame.dest_addr[1] = 0xff;
}
//uint8_t test = 30;
frame.payload = payload;
frame.payload_len = length;
//printf("length: %x\n",frame.payload_len);
uint8_t hdrlen = get_802154_hdr_len(&frame);
//printf("hdrlen: %02x\n",hdrlen);
memset(&buf,0,PAYLOAD_SIZE);
init_802154_frame(&frame,(uint8_t*)&buf);
memcpy(&buf[hdrlen],frame.payload,frame.payload_len);
p.length = hdrlen + frame.payload_len;
p.dst = *addr;
// TODO: geeignete ring-bufferung nötig
p.data = buf;
//p.data = snd_buffer[i % RADIO_SND_BUF_SIZE];
msg_send(&mesg, transceiver_pid, 1);
//swtimer_usleep(RADIO_SENDING_DELAY);
}
uint8_t sixlowmac_init(transceiver_type_t type){
void sixlowmac_init(transceiver_type_t type){
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
PRIORITY_MAIN-1, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
transceiver_type = type;

View File

@ -7,6 +7,7 @@
#include <stdint.h>
#include "sixlowip.h"
#include "radio/radio.h"
#include <transceiver.h>
#define RADIO_STACK_SIZE 2048
#define RADIO_RCV_BUF_SIZE 64
@ -15,8 +16,9 @@
uint8_t get_radio_address(void);
void send_ieee802154_frame(uint16_t addr);
void send_ieee802154_frame(uint8_t *addr, uint8_t *payload, uint8_t length);
void init_802154_long_addr(uint8_t *addr);
void sixlowmac_init(transceiver_type_t type);
void send(void);
#endif /* SIXLOWMAC_H*/

View File

@ -4,7 +4,7 @@
#include <stdio.h>
#include <string.h>
uint8_t rtr_sol_count;
uint8_t rtr_sol_count = 0;
uint8_t opt_hdr_len = 0;
uint8_t ipv6_ext_hdr_len = 0;
uint16_t packet_length;
@ -56,7 +56,7 @@ static struct opt_aro_t *opt_aro_buf;
/* send router solicitation message - RFC4861 section 4.1 */
void send_rtr_sol(void){
void init_rtr_sol(void){
ipv6_buf = get_ipv6_buf();
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
if(rtr_sol_count < RTR_SOL_MAX){
@ -71,21 +71,24 @@ void send_rtr_sol(void){
create_all_routers_mcast_addr(&ipv6_buf->destaddr);
print6addr(&ipv6_buf->destaddr);
// print6addr(&ipv6_buf->destaddr);
opt_hdr_len = RTR_SOL_LEN;
ipv6_buf->length = ICMPV6_HDR_LEN + RTR_SOL_LEN + OPT_STLLAO_LEN;
opt_stllao_buf = get_opt_stllao_buf(ipv6_ext_hdr_len, opt_hdr_len);
set_llao((uint8_t*)opt_stllao_buf, OPT_SLLAO_TYPE);
packet_length = IPV6_HDR_LEN + ICMPV6_HDR_LEN + RTR_SOL_LEN + OPT_STLLAO_LEN;
icmp_buf->checksum = 0;
icmp_buf->checksum = ~icmpv6_csum(ICMPV6_NXT_HDR);
printf("%x\n",icmp_buf->checksum);
// printf("%x\n",icmp_buf->checksum);
rtr_sol_count++;
// sleep 4 sec
swtimer_usleep(RTR_SOL_INTERVAL * 1000000);
//swtimer_usleep(RTR_SOL_INTERVAL * 1000000);
}
}
@ -103,7 +106,7 @@ void recv_rtr_sol(void){
//send_rtr_adv();
}
void send_rtr_adv(ipv6_addr_t *addr){
void init_rtr_adv(ipv6_addr_t *addr){
ipv6_buf = get_ipv6_buf();
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
@ -173,7 +176,7 @@ void send_rtr_adv(ipv6_addr_t *addr){
//printf("%x\n",icmp_buf->checksum);
}
void send_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ){
void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ){
ipv6_ext_hdr_len = 0;
ipv6_buf = get_ipv6_buf();
ipv6_buf->version_trafficclass = IPV6_VER;

View File

@ -95,9 +95,9 @@ struct __attribute__ ((packed)) nbr_sol_t {
};
void send_rtr_sol(void);
void init_rtr_sol(void);
void recv_rtr_sol(void);
void send_rtr_adv(ipv6_addr_t *addr);
void init_rtr_adv(ipv6_addr_t *addr);
uint8_t pfx_chk_list(ipv6_addr_t *addr, uint8_t size);
uint8_t pfx_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2);
void pfx_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime,

View File

@ -1,7 +1,160 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sixlowmac.h"
#include "sixlowpan.h"
#include "transceiver.h"
#include "ieee802154_frame.h"
uint16_t packet_length;
uint16_t tag;
uint8_t packet_size = 0;
uint8_t header_size = 0;
uint8_t max_frame = 0;
uint8_t max_frag_initial = 0;
uint8_t position;
uint8_t max_frag;
uint8_t frag_size;
uint8_t *reas_buf;
uint8_t byte_offset;
uint8_t first_frag = 0;
/* deliver packet to mac*/
void output(uint8_t *addr, uint8_t *data){
packet_size = (uint8_t)packet_length;
/* check if packet needs to be fragmented */
if(packet_size + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN){
printf("INFO: packet is to large, fragmentation started. size:"
" %hu byte\n", packet_length);
uint8_t *ptr = data;
uint8_t fragbuf[packet_size + header_size];
uint8_t remaining;
uint8_t i = 2;
/* first fragment */
max_frame = PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN;
max_frag_initial = ((max_frame - 4 - header_size) / 8) * 8;
memcpy(fragbuf + 4, ptr, max_frag_initial);
fragbuf[0] = (((0xc0 << 8) | packet_length) >> 8) & 0xff;
fragbuf[1] = ((0xc0 << 8) | packet_length) & 0xff;
fragbuf[2] = (tag >> 8) & 0xff;
fragbuf[3] = tag & 0xff;
send_ieee802154_frame(addr,(uint8_t*)&fragbuf, max_frag_initial + header_size + 4);
printf(" frag 1 size: %d byte\n", max_frag_initial);
/* subsequent fragments */
position = max_frag_initial;
max_frag = ((max_frame - 5) / 8) * 8;
ptr += position;
while(packet_size - position > max_frame - 5){
memset(&fragbuf,0,packet_size + header_size);
memcpy(fragbuf + 5, ptr, max_frag);
fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
fragbuf[2] = (tag >> 8) & 0xff;
fragbuf[3] = tag & 0xff;
fragbuf[4] = position / 8;
send_ieee802154_frame(addr,(uint8_t*)&fragbuf, max_frag + 5);
printf(" frag %d size: %d byte\n",i , max_frag);
ptr += position;
position += max_frag;
i++;
}
remaining = packet_size - position;
memset(&fragbuf,0,packet_size + header_size);
memcpy(fragbuf + 5, ptr, remaining);
fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
fragbuf[2] = (tag >> 8) & 0xff;
fragbuf[3] = tag & 0xff;
fragbuf[4] = position / 8;
send_ieee802154_frame(addr, (uint8_t*)&fragbuf, remaining + 5);
printf(" frag %d size: %d byte\n",i , remaining);
} else {
send_ieee802154_frame(addr, data, packet_size);
}
tag++;
}
void input(uint8_t *data, uint8_t length){
/* check if packet is fragmented */
uint8_t hdr_length = 0;
uint8_t datagram_offset = 0;
uint16_t datagram_size = 0;
uint16_t datagram_tag = 0;
/* check first 5-bit*/
switch(data[0] & 0xf8) {
/* first fragment */
case(0xc0):{
first_frag = 1;
datagram_offset = 0;
/* get 11-bit from first 2 byte*/
datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff;
/* get 16-bit datagram tag */
datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]);
/* discard fragment header */
hdr_length += 4;
/* set global variable frag_size to size of decompr. packet*/
frag_size = datagram_size;
/* create reassembly buffer */
reas_buf = (uint8_t*)malloc(frag_size * sizeof(uint8_t));
/* check dispatch byte */
switch(data[hdr_length]) {
case(DISPATCH_IPV6):{
break;
}
default:
break;
}
memcpy(reas_buf, data + hdr_length, length - 4);
break;
}
/* subsequent fragment */
case(0xe0):{
if(first_frag == 0){
printf("ERROR: first fragment not received\n");
break;
}
/* get 11-bit from first 2 byte*/
datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff;
/* get 16-bit datagram tag */
datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]);
/* get 8-bit datagram offset */
datagram_offset = data[4];
/* discard framentation header */
hdr_length += 5;
frag_size = length - hdr_length;
byte_offset = datagram_offset * 8;
if((frag_size % 8) != 0){
printf("ERROR: received invalid fragment\n");
return;
}
memcpy(reas_buf + byte_offset, data + hdr_length, byte_offset);
if((byte_offset + frag_size) == datagram_size){
free(reas_buf);
printf("INFO: packet reassembled\n");
}
break;
}
default:
break;
}
}
void sixlowpan_init(transceiver_type_t trans){
sixlowmac_init(trans);

View File

@ -1,8 +1,17 @@
#ifndef SIXLOWMAC_H
#define SIXLOWMAC_H
#ifndef SIXLOWPAN_H
#define SIXLOWPAN_H
/* fragment size in bytes*/
#define FRAG_PART_ONE_HDR_LEN 4
#define FRAG_PART_N_HDR_LEN 5
#define DISPATCH_IPV6 0x41
#include "transceiver.h"
void sixlowpan_init(transceiver_type_t trans);
void output(uint8_t *addr, uint8_t *data);
void input(uint8_t *data, uint8_t length);
#endif