2013-06-22 05:11:53 +02:00
|
|
|
/**
|
|
|
|
* 6lowpan border router multiplexer
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 INRIA.
|
|
|
|
*
|
2013-11-22 20:47:05 +01:00
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
2013-06-22 05:11:53 +02:00
|
|
|
* Public License. See the file LICENSE in the top level directory for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* @ingroup sixlowpan
|
|
|
|
* @{
|
|
|
|
* @file bordermultiplex.c
|
|
|
|
* @brief multiplexiing border router information
|
|
|
|
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
|
|
|
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2013-08-08 13:39:00 +02:00
|
|
|
#include "board_uart0.h"
|
2013-08-08 13:22:24 +02:00
|
|
|
#include "sixlowpan/error.h"
|
2011-07-25 17:00:18 +02:00
|
|
|
|
|
|
|
#include "flowcontrol.h"
|
2013-08-05 16:10:54 +02:00
|
|
|
#include "lowpan.h"
|
|
|
|
#include "icmp.h"
|
|
|
|
#include "border.h"
|
2011-07-25 17:00:18 +02:00
|
|
|
|
2011-07-26 10:31:57 +02:00
|
|
|
#include "bordermultiplex.h"
|
|
|
|
|
2013-08-12 11:08:19 +02:00
|
|
|
#define END (0xC0)
|
|
|
|
#define ESC (0xDB)
|
|
|
|
#define END_ESC (0xDC)
|
|
|
|
#define ESC_ESC (0xDD)
|
2011-07-25 17:00:18 +02:00
|
|
|
|
2013-11-21 19:06:26 +01:00
|
|
|
void demultiplex(border_packet_t *packet)
|
2013-06-22 05:11:53 +02:00
|
|
|
{
|
2013-08-08 13:39:00 +02:00
|
|
|
switch (packet->type) {
|
2013-06-24 22:37:35 +02:00
|
|
|
case (BORDER_PACKET_RAW_TYPE): {
|
2013-06-22 05:11:53 +02:00
|
|
|
fputs(((char *)packet) + sizeof(border_packet_t), stdin);
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
case (BORDER_PACKET_L3_TYPE): {
|
2011-07-25 17:00:18 +02:00
|
|
|
border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-08-08 13:39:00 +02:00
|
|
|
switch (l3_header_buf->ethertype) {
|
2013-06-24 22:37:35 +02:00
|
|
|
case (BORDER_ETHERTYPE_IPV6): {
|
2013-06-24 14:11:30 +02:00
|
|
|
ipv6_hdr_t *ipv6_buf = (ipv6_hdr_t *)(((unsigned char *)packet) + sizeof(border_l3_header_t));
|
2013-08-13 06:41:05 +02:00
|
|
|
ipv6_send_bytes(ipv6_buf);
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
default:
|
2011-07-27 19:42:59 +02:00
|
|
|
printf("ERROR: Unknown ethertype 0x%04x\n", l3_header_buf->ethertype);
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
case (BORDER_PACKET_CONF_TYPE): {
|
2011-07-25 17:00:18 +02:00
|
|
|
border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-08-08 13:39:00 +02:00
|
|
|
switch (conf_header_buf->conftype) {
|
2013-06-24 22:37:35 +02:00
|
|
|
case (BORDER_CONF_CONTEXT): {
|
2011-07-25 17:00:18 +02:00
|
|
|
border_context_packet_t *context = (border_context_packet_t *)packet;
|
|
|
|
ipv6_addr_t target_addr;
|
2013-08-13 06:41:05 +02:00
|
|
|
ipv6_addr_set_all_nodes_addr(&target_addr);
|
2011-07-25 17:00:18 +02:00
|
|
|
mutex_lock(&lowpan_context_mutex);
|
|
|
|
lowpan_context_update(
|
2013-06-22 05:11:53 +02:00
|
|
|
context->context.cid,
|
|
|
|
&context->context.prefix,
|
|
|
|
context->context.length,
|
|
|
|
context->context.comp,
|
|
|
|
context->context.lifetime
|
|
|
|
);
|
2013-08-04 04:06:31 +02:00
|
|
|
mutex_unlock(&lowpan_context_mutex);
|
2011-07-27 02:12:30 +02:00
|
|
|
abr_add_context(context->context.version, &abr_addr, context->context.cid);
|
2013-06-22 05:11:53 +02:00
|
|
|
/* Send router advertisement */
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
case (BORDER_CONF_IPADDR): {
|
2011-07-25 17:00:18 +02:00
|
|
|
//border_addr_packet_t *addr_packet = (border_addr_packet_t *)packet;
|
2013-06-22 05:11:53 +02:00
|
|
|
/* add address */
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
default:
|
|
|
|
printf("ERROR: Unknown conftype %02x\n", conf_header_buf->conftype);
|
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
default:
|
|
|
|
printf("ERROR: Unknown border packet type %02x\n", packet->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-24 14:11:30 +02:00
|
|
|
void multiplex_send_ipv6_over_uart(ipv6_hdr_t *packet)
|
2013-06-22 05:11:53 +02:00
|
|
|
{
|
2011-07-25 17:00:18 +02:00
|
|
|
border_l3_header_t *serial_buf;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
serial_buf = (border_l3_header_t *)get_serial_out_buffer(0);
|
2011-08-05 15:45:38 +02:00
|
|
|
serial_buf->empty = 0;
|
2011-07-25 17:00:18 +02:00
|
|
|
serial_buf->type = BORDER_PACKET_L3_TYPE;
|
|
|
|
serial_buf->ethertype = BORDER_ETHERTYPE_IPV6;
|
2013-06-22 05:11:53 +02:00
|
|
|
memcpy(get_serial_in_buffer(0) + sizeof(border_l3_header_t), packet, IPV6_HDR_LEN + packet->length);
|
|
|
|
|
|
|
|
flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof(border_l3_header_t));
|
2011-07-25 17:00:18 +02:00
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
void multiplex_send_addr_over_uart(ipv6_addr_t *addr)
|
|
|
|
{
|
2011-07-25 17:00:18 +02:00
|
|
|
border_addr_packet_t *serial_buf;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
serial_buf = (border_addr_packet_t *)get_serial_in_buffer(0);
|
2011-08-05 15:45:38 +02:00
|
|
|
serial_buf->empty = 0;
|
2011-07-25 17:00:18 +02:00
|
|
|
serial_buf->type = BORDER_PACKET_CONF_TYPE;
|
|
|
|
serial_buf->conftype = BORDER_CONF_IPADDR;
|
2012-01-11 17:02:43 +01:00
|
|
|
memcpy(&serial_buf->addr, addr, sizeof(ipv6_addr_t));
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
flowcontrol_send_over_uart((border_packet_t *) serial_buf, sizeof(border_addr_packet_t));
|
2011-07-25 17:00:18 +02:00
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
int readpacket(uint8_t *packet_buf, size_t size)
|
|
|
|
{
|
2011-07-25 17:00:18 +02:00
|
|
|
uint8_t *line_buf_ptr = packet_buf;
|
2013-06-22 05:11:53 +02:00
|
|
|
uint8_t byte = END + 1;
|
2011-07-25 17:00:18 +02:00
|
|
|
uint8_t esc = 0;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
while (1) {
|
2011-07-25 17:00:18 +02:00
|
|
|
byte = uart0_readc();
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
if (byte == END) {
|
2011-07-27 19:43:51 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-12-13 19:17:30 +01:00
|
|
|
if ((size_t) (line_buf_ptr - packet_buf) >= size - 1) {
|
2011-07-25 17:00:18 +02:00
|
|
|
return -SIXLOWERROR_ARRAYFULL;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
if (esc) {
|
2011-07-27 19:43:51 +02:00
|
|
|
esc = 0;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-08-08 13:39:00 +02:00
|
|
|
switch (byte) {
|
2013-06-24 22:37:35 +02:00
|
|
|
case (END_ESC): {
|
2011-07-27 19:43:51 +02:00
|
|
|
*line_buf_ptr++ = END;
|
|
|
|
continue;
|
2011-07-25 17:00:18 +02:00
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
case (ESC_ESC): {
|
2011-07-27 19:43:51 +02:00
|
|
|
*line_buf_ptr++ = ESC;
|
|
|
|
continue;
|
2011-07-25 17:00:18 +02:00
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
default:
|
2011-07-27 19:43:51 +02:00
|
|
|
continue;
|
2011-07-25 17:00:18 +02:00
|
|
|
}
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
if (byte == ESC) {
|
2011-07-25 17:00:18 +02:00
|
|
|
esc = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
*line_buf_ptr++ = byte;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
return (line_buf_ptr - packet_buf - 1);
|
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
int writepacket(uint8_t *packet_buf, size_t size)
|
|
|
|
{
|
2011-07-25 17:00:18 +02:00
|
|
|
uint8_t *byte_ptr = packet_buf;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-12-13 19:17:30 +01:00
|
|
|
while ((size_t) (byte_ptr - packet_buf) < size) {
|
|
|
|
if ((size_t) (byte_ptr - packet_buf) > BORDER_BUFFER_SIZE) {
|
2011-07-25 17:00:18 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-08-08 13:39:00 +02:00
|
|
|
switch (*byte_ptr) {
|
2013-06-24 22:37:35 +02:00
|
|
|
case (END): {
|
2011-07-25 17:00:18 +02:00
|
|
|
*byte_ptr = END_ESC;
|
|
|
|
uart0_putc(ESC);
|
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2013-06-24 22:37:35 +02:00
|
|
|
case (ESC): {
|
2011-07-25 17:00:18 +02:00
|
|
|
*byte_ptr = ESC_ESC;
|
|
|
|
uart0_putc(ESC);
|
|
|
|
break;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
default: {
|
2011-07-25 17:00:18 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
uart0_putc(*byte_ptr);
|
|
|
|
byte_ptr++;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
uart0_putc(END);
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-07-25 17:00:18 +02:00
|
|
|
return (byte_ptr - packet_buf);
|
|
|
|
}
|