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:
parent
66b668d6e1
commit
5e26d199cc
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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]));
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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,27 +70,29 @@ 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);
|
||||
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
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();
|
||||
hdrlen = read_802154_frame(p->data, &frame, p->length);
|
||||
printf("hdrlen: %hu\n", hdrlen);
|
||||
printf("payload: %02x\n", frame.payload[0]);
|
||||
|
||||
p->processing--;
|
||||
printf("\n");
|
||||
*/
|
||||
hdrlen = read_802154_frame(p->data, &frame, p->length);
|
||||
length = p->length - hdrlen;
|
||||
|
||||
/* deliver packet to network(6lowpan)-layer */
|
||||
input(frame.payload, length);
|
||||
|
||||
p->processing--;
|
||||
// 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 */
|
||||
@ -137,32 +145,36 @@ void send_ieee802154_frame(uint16_t addr, uint8_t *buf){
|
||||
frame.dest_addr[1] = 4;
|
||||
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;
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user