1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

more coding convention fixes

This commit is contained in:
Oliver Hahm 2013-06-21 04:00:45 +02:00
parent 5d70656343
commit 201f593641
13 changed files with 809 additions and 613 deletions

View File

@ -8,24 +8,24 @@
void hard_reset_to_bootloader(void)
{
printf("Reset CPU (into bootloader)\r\n");
set_rts(1); // RTS (ttl level) connects to P0.14
set_dtr(1); // DTR (ttl level) connects to RST
send_break_signal(); // or break detect circuit to RST
usleep(75000);
set_dtr(0); // allow the CPU to run
set_baud(baud_rate);
set_rts(1); // set RTS again (as it has been reset by set_baudrate)
usleep(40000);
printf("Reset CPU (into bootloader)\r\n");
set_rts(1); /* RTS (ttl level) connects to P0.14 */
set_dtr(1); /* DTR (ttl level) connects to RST */
send_break_signal(); /* or break detect circuit to RST */
usleep(75000);
set_dtr(0); /* allow the CPU to run */
set_baud(baud_rate);
set_rts(1); /* set RTS again (as it has been reset by set_baudrate) */
usleep(40000);
}
void hard_reset_to_user_code(void)
{
printf("Reset CPU (into user code)\r\n");
set_rts(0); // RTS (ttl level) connects to P0.14
set_dtr(1); // DTR (ttl level) connects to RST
send_break_signal(); // or break detect circuit to RST
usleep(75000);
set_dtr(0); // allow the CPU to run
usleep(40000);
printf("Reset CPU (into user code)\r\n");
set_rts(0); /* RTS (ttl level) connects to P0.14 */
set_dtr(1); /* DTR (ttl level) connects to RST */
send_break_signal(); /* or break detect circuit to RST */
usleep(75000);
set_dtr(0); /* allow the CPU to run */
usleep(40000);
}

View File

@ -14,21 +14,25 @@
flowcontrol_stat_t slwin_stat;
uint8_t connection_established;
void* resend_thread_f (void *args) {
void *resend_thread_f(void *args)
{
uint8_t seq_num = *((uint8_t *)args);
struct send_slot *slot = &(slwin_stat.send_win[seq_num % BORDER_SWS]);
while(1) {
usleep(BORDER_SL_TIMEOUT);
if (seq_num == ((border_packet_t *)(slot->frame))->seq_num) {
writepacket(slot->frame,slot->frame_len);
} else {
if(seq_num == ((border_packet_t *)(slot->frame))->seq_num) {
writepacket(slot->frame, slot->frame_len);
}
else {
return NULL;
}
}
}
void init_threeway_handshake(const struct in6_addr *addr) {
void init_threeway_handshake(const struct in6_addr *addr)
{
border_syn_packet_t *syn = (border_syn_packet_t *)get_serial_out_buffer(0);
syn->empty = 0;
syn->type = BORDER_PACKET_CONF_TYPE;
@ -36,62 +40,72 @@ void init_threeway_handshake(const struct in6_addr *addr) {
syn->conftype = BORDER_CONF_SYN;
syn->next_exp = slwin_stat.next_exp;
memcpy(&(syn->addr), addr, 16);
do {
writepacket((uint8_t *)syn, sizeof (border_syn_packet_t));
writepacket((uint8_t *)syn, sizeof(border_syn_packet_t));
usleep(BORDER_SL_TIMEOUT);
} while (!connection_established);
}
while(!connection_established);
}
void signal_connection_established(void) {
void signal_connection_established(void)
{
connection_established = 1;
}
void flowcontrol_init(const struct in6_addr *addr) {
void flowcontrol_init(const struct in6_addr *addr)
{
int i;
slwin_stat.last_frame = 0xFF;
slwin_stat.last_ack = slwin_stat.last_frame;
connection_established = 0;
sem_init(&slwin_stat.send_win_not_full,0,BORDER_SWS);
for(i = 0; i < BORDER_SWS; i++) {
sem_init(&slwin_stat.send_win_not_full, 0, BORDER_SWS);
for(i = 0; i < BORDER_SWS; i++) {
slwin_stat.send_win[i].frame_len = 0;
}
memset(&slwin_stat.send_win,0, sizeof(struct send_slot) * BORDER_SWS);
memset(&slwin_stat.send_win, 0, sizeof(struct send_slot) * BORDER_SWS);
slwin_stat.next_exp = 0;
for(i = 0; i < BORDER_RWS; i++) {
slwin_stat.recv_win[i].received = 0;
slwin_stat.recv_win[i].frame_len = 0;
}
memset(&slwin_stat.recv_win,0, sizeof(struct recv_slot) * BORDER_RWS);
memset(&slwin_stat.recv_win, 0, sizeof(struct recv_slot) * BORDER_RWS);
init_threeway_handshake(addr);
}
void flowcontrol_destroy(void) {
void flowcontrol_destroy(void)
{
sem_destroy(&slwin_stat.send_win_not_full);
}
static int in_window(uint8_t seq_num, uint8_t min, uint8_t max) {
static int in_window(uint8_t seq_num, uint8_t min, uint8_t max)
{
uint8_t pos = seq_num - min;
uint8_t maxpos = max - min + 1;
return pos < maxpos;
}
void send_ack(uint8_t seq_num) {
void send_ack(uint8_t seq_num)
{
border_packet_t *packet = (border_packet_t *)get_serial_out_buffer(0);
packet->empty = 0;
packet->type = BORDER_PACKET_ACK_TYPE;
packet->seq_num = seq_num;
writepacket((uint8_t *)packet, sizeof (border_packet_t));
writepacket((uint8_t *)packet, sizeof(border_packet_t));
}
void flowcontrol_send_over_tty(border_packet_t *packet, int len) {
void flowcontrol_send_over_tty(border_packet_t *packet, int len)
{
struct send_slot *slot;
uint8_t args[] = {packet->seq_num};
sem_wait(&(slwin_stat.send_win_not_full));
packet->seq_num = ++slwin_stat.last_frame;
slot = &(slwin_stat.send_win[packet->seq_num % BORDER_SWS]);
@ -104,9 +118,10 @@ void flowcontrol_send_over_tty(border_packet_t *packet, int len) {
writepacket((uint8_t *)packet, len);
}
void flowcontrol_deliver_from_tty(const border_packet_t *packet, int len) {
if (packet->type == BORDER_PACKET_ACK_TYPE) {
if (in_window(packet->seq_num, slwin_stat.last_ack+1, slwin_stat.last_frame)) {
void flowcontrol_deliver_from_tty(const border_packet_t *packet, int len)
{
if(packet->type == BORDER_PACKET_ACK_TYPE) {
if(in_window(packet->seq_num, slwin_stat.last_ack + 1, slwin_stat.last_frame)) {
do {
struct send_slot *slot;
slot = &(slwin_stat.send_win[++slwin_stat.last_ack % BORDER_SWS]);
@ -114,32 +129,36 @@ void flowcontrol_deliver_from_tty(const border_packet_t *packet, int len) {
testing_stop(slwin_stat.last_ack);
#endif
pthread_cancel(slot->resend_thread);
memset(&slot->frame,0,BUFFER_SIZE);
memset(&slot->frame, 0, BUFFER_SIZE);
slot->frame_len = 0;
sem_post(&slwin_stat.send_win_not_full);
} while (slwin_stat.last_ack != packet->seq_num);
}
while(slwin_stat.last_ack != packet->seq_num);
}
} else {
}
else {
struct recv_slot *slot;
slot = &slwin_stat.recv_win[packet->seq_num % BORDER_RWS];
if ( !in_window(packet->seq_num,
slwin_stat.next_exp,
slwin_stat.next_exp + BORDER_RWS - 1)) {
if(!in_window(packet->seq_num,
slwin_stat.next_exp,
slwin_stat.next_exp + BORDER_RWS - 1)) {
return;
}
memcpy(slot->frame, (uint8_t *)packet, len);
slot->received = 1;
if (packet->seq_num == slwin_stat.next_exp) {
while (slot->received) {
if(packet->seq_num == slwin_stat.next_exp) {
while(slot->received) {
demultiplex((border_packet_t *)slot->frame, slot->frame_len);
memset(&slot->frame,0,BUFFER_SIZE);
memset(&slot->frame, 0, BUFFER_SIZE);
slot->received = 0;
slot = &slwin_stat.recv_win[++slwin_stat.next_exp % BORDER_RWS];
}
}
send_ack(slwin_stat.next_exp - 1);
}
}

View File

@ -2,7 +2,7 @@
* @file flowcontrol.h
* @author Freie Universität Berlin, Computer Systems & Telemetics
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @brief Public declarations for the flow control jobs via the
* @brief Public declarations for the flow control jobs via the
* serial interface for the 6LoWPAN Border Router driver.
*/
@ -30,7 +30,7 @@
/**
* @brief State of the sliding window algorithm, used for flow control
* @see "Computernetze -- Eine systemorientierte Einführung",
* @see "Computernetze -- Eine systemorientierte Einführung",
* L.L. Peterson, B.S. Davie, dpunkt-lehrbuch, 2008
*/
typedef struct flowcontrol_stat_t {
@ -49,7 +49,7 @@ typedef struct flowcontrol_stat_t {
uint8_t frame[BUFFER_SIZE]; ///< This slot's frame.
size_t frame_len; ///< The length of this slot's frame.
} send_win[BORDER_SWS]; ///< The sending window.
/* Receiver state */
uint8_t next_exp; ///< The next expected sequence number to be received.
/**
@ -67,15 +67,15 @@ typedef struct flowcontrol_stat_t {
* the serial line.
* @extends border_conf_header_t
*/
typedef struct __attribute__ ((packed)) border_syn_packet_t {
typedef struct __attribute__((packed)) border_syn_packet_t {
uint8_t empty;
uint8_t type;
/**
* @brief Next sequence number
*
* Communicates the next local sequence number to be send to the
*
* Communicates the next local sequence number to be send to the
* MSB-A2 (for flow control).
*
*
* This replaces @ref border_conf_header_t::seq_num of normal
* configuration packets.
*/
@ -83,8 +83,8 @@ typedef struct __attribute__ ((packed)) border_syn_packet_t {
uint8_t conftype;
/**
* @brief Next expected sequence number
*
* Communicates to the MSB-A2 which sequence number the driver
*
* Communicates to the MSB-A2 which sequence number the driver
* expects next.
*/
uint8_t next_exp;
@ -112,7 +112,7 @@ void signal_connection_established(void);
/**
* @brief Sends a packet via the serial interface.
* @param[in,out] packet The packet that is to be send via the
* serial interface. The function sets the
* serial interface. The function sets the
* sequence number of the packet for flow
* control.
* @param[in] len Length of the packet.

View File

@ -8,34 +8,40 @@
#include "testing.h"
#endif
int main(int argc, char **argv) {
if (argc < 4) {
int main(int argc, char **argv)
{
if(argc < 4) {
fprintf(stderr, "Usage: %s r_addr if_name tty_dev\n", argv[0]);
return -1;
}
char addr[IPV6_ADDR_LEN];
sprintf(addr, "abcd::1034:00FF:FE00:%s/64",argv[1]);
sprintf(addr, "abcd::1034:00FF:FE00:%s/64", argv[1]);
char if_name[IF_NAME_LEN];
strncpy(if_name, argv[2], IF_NAME_LEN);
char tty_dev[DEV_LEN];
strncpy(tty_dev, argv[3], DEV_LEN);
if (border_initialize(if_name, addr, tty_dev) == 0) {
if(border_initialize(if_name, addr, tty_dev) == 0) {
#ifdef BORDER_TESTING
char ping_addr[IPV6_ADDR_LEN];
float interval;
if (argc < 9) {
if(argc < 9) {
fprintf(stderr, "Usage: %s r_addr if_name tty_dev ping_id result_dir skeleton_file ping_count interval\n", argv[0]);
return -1;
}
sscanf(argv[8], "%f", &interval);
sprintf(ping_addr, "abcd::%s/64",argv[4]);
start_test(ping_addr,argv[5],argv[6],atoi(argv[7]),interval);
#else
sprintf(ping_addr, "abcd::%s/64", argv[4]);
start_test(ping_addr, argv[5], argv[6], atoi(argv[7]), interval);
#else
while(1);
#endif
}
return 0;
}

View File

@ -17,180 +17,203 @@
uint8_t serial_out_buf[BUFFER_SIZE];
uint8_t serial_in_buf[BUFFER_SIZE];
uint8_t *get_serial_out_buffer(int offset) {
if (offset > BUFFER_SIZE) {
uint8_t *get_serial_out_buffer(int offset)
{
if(offset > BUFFER_SIZE) {
return NULL;
}
return &(serial_out_buf[offset]);
}
uint8_t *get_serial_in_buffer(int offset) {
if (offset > BUFFER_SIZE) {
uint8_t *get_serial_in_buffer(int offset)
{
if(offset > BUFFER_SIZE) {
return NULL;
}
return &(serial_in_buf[offset]);
}
int init_multiplex(const char *tty_dev) {
int init_multiplex(const char *tty_dev)
{
return open_serial_port(tty_dev);
}
uint8_t serial_read_byte() {
uint8_t serial_read_byte()
{
unsigned char c;
read_serial_port(&c, 1);
return (uint8_t)c;
}
int readpacket(uint8_t *packet_buf, size_t size) {
int readpacket(uint8_t *packet_buf, size_t size)
{
uint8_t *line_buf_ptr = packet_buf;
uint8_t byte = END+1;
uint8_t byte = END + 1;
uint8_t esc = 0;
uint8_t translate = 1;
while ((line_buf_ptr - packet_buf) < size-1) {
while((line_buf_ptr - packet_buf) < size - 1) {
byte = serial_read_byte();
if (translate && byte == END) {
if(translate && byte == END) {
break;
}
if (line_buf_ptr == packet_buf && byte != 0) {
if(line_buf_ptr == packet_buf && byte != 0) {
translate = 0;
}
if (line_buf_ptr > packet_buf && !translate && byte == '\n') {
if(line_buf_ptr > packet_buf && !translate && byte == '\n') {
*line_buf_ptr++ = '\0';
return line_buf_ptr - packet_buf;
}
if (translate) {
if (esc) {
if(translate) {
if(esc) {
esc = 0;
switch (byte) {
case(END_ESC):{
switch(byte) {
case(END_ESC): {
*line_buf_ptr++ = END;
continue;
}
case(ESC_ESC):{
case(ESC_ESC): {
*line_buf_ptr++ = ESC;
continue;
}
default:
continue;
}
}
if (byte == ESC) {
if(byte == ESC) {
esc = 1;
continue;
}
}
*line_buf_ptr++ = byte;
}
return (line_buf_ptr - packet_buf);
}
int writepacket(uint8_t *packet_buf, size_t size) {
uint8_t packet_tmp[2*BUFFER_SIZE];
int writepacket(uint8_t *packet_buf, size_t size)
{
uint8_t packet_tmp[2 * BUFFER_SIZE];
uint8_t *byte_ptr = packet_buf;
uint8_t *tmp_ptr = packet_tmp;
if (2*size + 1 > BUFFER_SIZE) {
if(2 * size + 1 > BUFFER_SIZE) {
return -1;
}
while ((byte_ptr - packet_buf) < size) {
switch (*byte_ptr) {
case(END):{
while((byte_ptr - packet_buf) < size) {
switch(*byte_ptr) {
case(END): {
*byte_ptr = END_ESC;
*tmp_ptr = ESC;
tmp_ptr++;
break;
}
case(ESC):{
case(ESC): {
*byte_ptr = ESC_ESC;
*tmp_ptr = ESC;
tmp_ptr++;
break;
}
default:{
default: {
break;
}
}
*tmp_ptr = *byte_ptr;
byte_ptr++;
tmp_ptr++;
}
*tmp_ptr++ = END;
write_serial_port(packet_tmp, tmp_ptr - packet_tmp);
return 0;
}
void demultiplex(const border_packet_t *packet, int len) {
switch (packet->type) {
case (BORDER_PACKET_RAW_TYPE):{
void demultiplex(const border_packet_t *packet, int len)
{
switch(packet->type) {
case(BORDER_PACKET_RAW_TYPE): {
printf("\033[00;33m[via serial interface] %s\033[00m\n",
((unsigned char *)packet) + sizeof (border_packet_t)
);
((unsigned char *)packet) + sizeof(border_packet_t)
);
break;
}
case (BORDER_PACKET_L3_TYPE):{
case(BORDER_PACKET_L3_TYPE): {
border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet;
switch (l3_header_buf->ethertype) {
case (ETHERTYPE_IPV6):{
switch(l3_header_buf->ethertype) {
case(ETHERTYPE_IPV6): {
printf("INFO: IPv6-Packet %d received\n", l3_header_buf->seq_num);
struct ip6_hdr *ip6_buf = (struct ip6_hdr *)(((unsigned char *)packet) + sizeof (border_l3_header_t));
struct ip6_hdr *ip6_buf = (struct ip6_hdr *)(((unsigned char *)packet) + sizeof(border_l3_header_t));
border_send_ipv6_over_tun(get_tun_fd(), ip6_buf);
break;
}
default:
printf("INFO: Unknown ethertype %04x for packet %d\n", l3_header_buf->ethertype, l3_header_buf->seq_num);
break;
}
break;
}
case (BORDER_PACKET_CONF_TYPE):{
case(BORDER_PACKET_CONF_TYPE): {
border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet;
switch (conf_header_buf->conftype) {
case (BORDER_CONF_SYNACK):{
printf("INFO: SYNACK-Packet %d received\n",conf_header_buf->seq_num);
switch(conf_header_buf->conftype) {
case(BORDER_CONF_SYNACK): {
printf("INFO: SYNACK-Packet %d received\n", conf_header_buf->seq_num);
signal_connection_established();
break;
}
case (BORDER_CONF_CONTEXT):{
case(BORDER_CONF_CONTEXT): {
printf("INFO: Context packet (%d) received, "
"but nothing is implemented yet for this case.\n",
conf_header_buf->seq_num);
"but nothing is implemented yet for this case.\n",
conf_header_buf->seq_num);
break;
}
case (BORDER_CONF_IPADDR):{
case(BORDER_CONF_IPADDR): {
char str_addr[IPV6_ADDR_LEN];
border_addr_packet_t *addr_packet = (border_addr_packet_t *)packet;
printf("INFO: Address packet (%d) received.\n",
conf_header_buf->seq_num);
conf_header_buf->seq_num);
inet_ntop(AF_INET6, &addr_packet->addr, str_addr, IPV6_ADDR_LEN);
tun_add_addr(str_addr);
}
default:
printf("INFO: Unknown conftype %02x for packet %d\n",
conf_header_buf->conftype,
conf_header_buf->seq_num);
printf("INFO: Unknown conftype %02x for packet %d\n",
conf_header_buf->conftype,
conf_header_buf->seq_num);
break;
}
break;
}
default:
printf("INFO: Unknown border packet type %02x for packet %d\n", packet->type, packet->seq_num);
//print_packet_hex((unsigned char *)packet,len);
@ -198,57 +221,60 @@ void demultiplex(const border_packet_t *packet, int len) {
}
}
void multiplex_send_context_over_tty(const border_context_t *context) {
void multiplex_send_context_over_tty(const border_context_t *context)
{
border_context_packet_t *con_packet = (border_context_packet_t *)get_serial_out_buffer(0);
con_packet->empty = 0;
con_packet->type = BORDER_PACKET_CONF_TYPE;
con_packet->conftype = BORDER_CONF_CONTEXT;
memcpy(
&con_packet->context,
context,
sizeof (border_context_t)
);
&con_packet->context,
context,
sizeof(border_context_t)
);
flowcontrol_send_over_tty(
(border_packet_t *) con_packet,
sizeof (border_context_packet_t)
);
(border_packet_t *) con_packet,
sizeof(border_context_packet_t)
);
}
void multiplex_send_addr_over_tty(struct in6_addr *addr) {
void multiplex_send_addr_over_tty(struct in6_addr *addr)
{
border_addr_packet_t *packet = (border_addr_packet_t *)get_serial_out_buffer(0);
packet->empty = 0;
packet->type = BORDER_PACKET_CONF_TYPE;
packet->conftype = BORDER_CONF_IPADDR;
memcpy(
&packet->addr,
addr,
sizeof (struct in6_addr)
);
&packet->addr,
addr,
sizeof(struct in6_addr)
);
flowcontrol_send_over_tty(
(border_packet_t *) packet,
sizeof (border_addr_packet_t)
);
(border_packet_t *) packet,
sizeof(border_addr_packet_t)
);
}
void multiplex_send_ipv6_over_tty(const struct ip6_hdr *packet) {
void multiplex_send_ipv6_over_tty(const struct ip6_hdr *packet)
{
border_l3_header_t *l3_hdr = (border_l3_header_t *)get_serial_out_buffer(0);
size_t packet_size = sizeof (struct ip6_hdr) + packet->ip6_plen;
size_t packet_size = sizeof(struct ip6_hdr) + packet->ip6_plen;
l3_hdr->empty = 0;
l3_hdr->type = BORDER_PACKET_L3_TYPE;
l3_hdr->ethertype = ETHERTYPE_IPV6;
memcpy(
get_serial_out_buffer(0) + sizeof (border_l3_header_t),
packet,
packet_size
);
get_serial_out_buffer(0) + sizeof(border_l3_header_t),
packet,
packet_size
);
flowcontrol_send_over_tty(
(border_packet_t *) l3_hdr,
sizeof (border_l3_header_t) + packet_size
);
(border_packet_t *) l3_hdr,
sizeof(border_l3_header_t) + packet_size
);
}

View File

@ -2,7 +2,7 @@
* @file multiplex.h
* @author Freie Universität Berlin, Computer Systems & Telemetics
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @brief Public declarations for the multiplexing jobs via the
* @brief Public declarations for the multiplexing jobs via the
* serial interface for the 6LoWPAN Border Router driver.
*/
#ifndef MULTIPLEX_H
@ -30,11 +30,11 @@
/**
* @brief Describes packets for transmission via serial interface.
*/
typedef struct __attribute__ ((packed)) border_packet_t {
typedef struct __attribute__((packed)) border_packet_t {
/**
* @brief Reserved byte.
*
* Must be always 0 to distinguish packets from MSB-A2
*
* Must be always 0 to distinguish packets from MSB-A2
* stdout/stdin/stderr.
*/
uint8_t empty;
@ -47,7 +47,7 @@ typedef struct __attribute__ ((packed)) border_packet_t {
* serial interface.
* @extends border_packet_t
*/
typedef struct __attribute__ ((packed)) border_l3_header_t {
typedef struct __attribute__((packed)) border_l3_header_t {
uint8_t empty;
uint8_t type;
uint8_t seq_num;
@ -59,7 +59,7 @@ typedef struct __attribute__ ((packed)) border_l3_header_t {
* serial interface.
* @extends border_packet_t
*/
typedef struct __attribute__ ((packed)) border_conf_header_t {
typedef struct __attribute__((packed)) border_conf_header_t {
uint8_t empty;
uint8_t type;
uint8_t seq_num;
@ -69,11 +69,11 @@ typedef struct __attribute__ ((packed)) border_conf_header_t {
/**
* @brief Describes an address configuration packet.
* @extends border_conf_header_t
*
*
* This packet type enables the driver to add new IPv6 addresses to
* the border router.
*/
typedef struct __attribute__ ((packed)) border_addr_packet_t {
typedef struct __attribute__((packed)) border_addr_packet_t {
uint8_t empty;
uint8_t type;
uint8_t seq_num;
@ -82,18 +82,18 @@ typedef struct __attribute__ ((packed)) border_conf_header_t {
* @brief Version for this IP address (send with the ABRO for PIs,
* s. draft-ietf-6lowpan-nd-17).
*/
uint16_t version;
uint16_t version;
struct in6_addr addr; ///< New IPv6-Address to be added to this border router.
} border_addr_packet_t;
/**
* @brief Describes a context configuration packet.
* @extends border_conf_header_t
*
*
* This packet type enables the driver to manipulate Context Informations
* in the LoWPAN.
*/
typedef struct __attribute__ ((packed)) border_context_packet_t {
typedef struct __attribute__((packed)) border_context_packet_t {
uint8_t empty;
uint8_t type;
uint8_t seq_num;
@ -103,8 +103,8 @@ typedef struct __attribute__ ((packed)) border_context_packet_t {
/**
* @brief Size of all packet buffers in this driver.
*
* @ref border_l3_header_t was since packets of this type may be the
*
* @ref border_l3_header_t was since packets of this type may be the
* longest (with payload).
*/
#define BUFFER_SIZE sizeof (border_l3_header_t) + MTU
@ -122,7 +122,7 @@ int init_multiplex(const char *tty_dev);
* data, that shall be send via the serial interface.
* @param[in] offset The offset from the start of the buffer.
* @return Pointer to a cell in the buffer for the output
* data. The size of the buffer is then
* data. The size of the buffer is then
* \ref BUFFER_SIZE - <em>offset</em>.
*/
uint8_t *get_serial_out_buffer(int offset);
@ -132,7 +132,7 @@ uint8_t *get_serial_out_buffer(int offset);
* data, that was received via the serial interface.
* @param[in] offset The offset from the start of the buffer.
* @return Pointer to a cell in the buffer for the input
* data. The size of the buffer is then
* data. The size of the buffer is then
* \ref BUFFER_SIZE - <em>offset</em>.
*/
uint8_t *get_serial_in_buffer(int offset);
@ -141,7 +141,7 @@ uint8_t *get_serial_in_buffer(int offset);
* @brief Demultiplexes a packet, that was received via the serial
* interface.
* @param[in] packet Packet, that should be demultiplexed.
* @param[in] len Length of the packet, that should be
* @param[in] len Length of the packet, that should be
* demultiplexed.
*/
void demultiplex(const border_packet_t *packet, int len);
@ -150,29 +150,29 @@ void demultiplex(const border_packet_t *packet, int len);
* @brief Sends an IPv6 datagram via the serial interface.
* @param[in] packet The IPv6 datagram that is to be send via the
* serial interface and starts with an IPv6 header.
*
* The function uses the payload length field of the IPv6 Header to
* determine the length of the overall packet. The payload bytes
*
* The function uses the payload length field of the IPv6 Header to
* determine the length of the overall packet. The payload bytes
* <em>must</em> follow the header in memory.
*/
void multiplex_send_ipv6_over_tty(const struct ip6_hdr *packet);
/**
* @brief Sends context information via the serial interface.
* @param[in] context The context information that is to be send via
* @param[in] context The context information that is to be send via
* the serial interface.
*/
void multiplex_send_context_over_tty(const border_context_t *context);
/**
* @brief Sends new IPv6 address via the serial interface.
* @param[in] addr The new address that is to be send via
* @param[in] addr The new address that is to be send via
* the serial interface.
*/
void multiplex_send_addr_over_tty(struct in6_addr *addr);
/**
* @brief Reads a packet up to a length of <em>size</em> bytes from
* @brief Reads a packet up to a length of <em>size</em> bytes from
* the serial interface and saves it to <em>packet_buf</em>.
* @param[out] packet_buf The buffer the read packet should be written
* into.
@ -182,9 +182,9 @@ void multiplex_send_addr_over_tty(struct in6_addr *addr);
int readpacket(uint8_t *packet_buf, size_t size);
/**
* @brief Writes a packet up to a length of <em>size</em> bytes from
* @brief Writes a packet up to a length of <em>size</em> bytes from
* <em>packet_buf</em> to the serial interface.
* @param[in] packet_buf The buffer from which the packet should be
* @param[in] packet_buf The buffer from which the packet should be
* written.
* @param[in] size The maximum number of bytes to be written.
* @return The number of bytes written.

View File

@ -50,43 +50,53 @@
#include "serial.h"
int port_fd=-1;
int port_fd = -1;
static tcflag_t baud_name_to_flags(const char *baud_name);
static void report_open_error(const char *filename, int err);
char* baud_rate = "115200";
char *baud_rate = "115200";
int open_serial_port(const char *port_name)
{
int r;
int r;
if (port_fd >= 0) {
close(port_fd);
}
port_fd = open(port_name, O_RDWR);
if (port_fd < 0) {
report_open_error(port_name, errno);
return -1;
}
r = set_baud(baud_rate);
if (r == 0) {
printf("Port \"%s\" opened at %s baud\r\n",
port_name, baud_rate);
} else {
printf("Port \"%s\" opened, unable to set baud to %s\r\n",
port_name, baud_rate);
}
#ifdef LINUX
{
struct serial_struct kernel_serial_settings;
/* attempt to set low latency mode, but don't worry if we can't */
r = ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings);
if (r < 0) return 0;
kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
}
#endif
if(port_fd >= 0) {
close(port_fd);
}
port_fd = open(port_name, O_RDWR);
if(port_fd < 0) {
report_open_error(port_name, errno);
return -1;
}
r = set_baud(baud_rate);
if(r == 0) {
printf("Port \"%s\" opened at %s baud\r\n",
port_name, baud_rate);
}
else {
printf("Port \"%s\" opened, unable to set baud to %s\r\n",
port_name, baud_rate);
}
#ifdef LINUX
{
struct serial_struct kernel_serial_settings;
/* attempt to set low latency mode, but don't worry if we can't */
r = ioctl(port_fd, TIOCGSERIAL, &kernel_serial_settings);
if(r < 0) {
return 0;
}
kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
ioctl(port_fd, TIOCSSERIAL, &kernel_serial_settings);
}
#endif
return 0;
}
@ -96,190 +106,255 @@ int open_serial_port(const char *port_name)
*/
static void report_open_error(const char *filename, int err)
{
struct stat info;
uid_t my_uid;
gid_t my_gid;
char my_uname[64], my_gname[64], file_uname[64], file_gname[64];
struct passwd *p;
struct group *g;
mode_t perm;
int r, perm_ok=0;
struct stat info;
uid_t my_uid;
gid_t my_gid;
char my_uname[64], my_gname[64], file_uname[64], file_gname[64];
struct passwd *p;
struct group *g;
mode_t perm;
int r, perm_ok = 0;
printf("\r\n");
printf("Unable to open \"%s\"\r\n", filename);
if (err == EACCES) {
printf("You don't have permission to access %s\r\n", filename);
}
//printf("Attemping to find more information about %s....\r\n", filename);
r = stat(filename, &info);
if (r < 0) {
if (errno == ENOENT) {
printf("file %s does not exist\r\n", filename);
} else if (errno == ELOOP) {
printf("too many symbolic links\r\n");
} else if (errno == EACCES) {
printf("permission denied to get file status\r\n");
} else {
printf("Unable to get file status, err%d\r\n", errno);
}
return;
}
my_uid = getuid();
my_gid = getgid();
printf("\r\n");
printf("Unable to open \"%s\"\r\n", filename);
p = getpwuid(my_uid);
if (p) {
snprintf(my_uname, sizeof(my_uname),
"\"%s\" (gid=%d)", p->pw_name, (int)my_uid);
} else {
snprintf(my_uname, sizeof(my_uname),
"(gid=%d)", (int)my_uid);
}
if(err == EACCES) {
printf("You don't have permission to access %s\r\n", filename);
}
p = getpwuid(info.st_uid);
if (p) {
snprintf(file_uname, sizeof(file_uname),
"\"%s\" (uid=%d)", p->pw_name, (int)info.st_uid);
} else {
snprintf(file_uname, sizeof(file_uname),
"(uid=%d)", (int)info.st_uid);
}
r = stat(filename, &info);
g = getgrgid(my_gid);
if (g) {
snprintf(my_gname, sizeof(my_gname),
"\"%s\" (gid=%d)", g->gr_name, (int)my_gid);
} else {
snprintf(my_gname, sizeof(my_gname),
"(gid=%d)", (int)my_gid);
}
if(r < 0) {
if(errno == ENOENT) {
printf("file %s does not exist\r\n", filename);
}
else if(errno == ELOOP) {
printf("too many symbolic links\r\n");
}
else if(errno == EACCES) {
printf("permission denied to get file status\r\n");
}
else {
printf("Unable to get file status, err%d\r\n", errno);
}
g = getgrgid(info.st_gid);
if (g) {
snprintf(file_gname, sizeof(file_gname),
"\"%s\" (uid=%d)", g->gr_name, (int)info.st_gid);
} else {
snprintf(file_gname, sizeof(file_gname),
"(uid=%d)", (int)info.st_gid);
}
return;
}
/* printf("%s is owned by: user %s, group %s\r\n",
filename, file_uname, file_gname); */
my_uid = getuid();
my_gid = getgid();
perm = info.st_mode;
p = getpwuid(my_uid);
if ((perm & S_IROTH) && (perm & S_IWOTH)) {
printf("%s has read/write permission for everybody\r\n",
filename);
} else {
printf("%s is not read/write for everybody, so\r\n", filename);
printf(" you must match either user or group permission\r\n");
if ((perm & S_IRUSR) && (perm & S_IWUSR)) {
printf("%s has read/write permission for user %s\r\n",
filename, file_uname);
perm_ok = 1;
}
if ((perm & S_IRGRP) && (perm & S_IWGRP)) {
printf("%s has read/write permission for group %s\r\n",
filename, file_gname);
perm_ok = 1;
}
if (perm_ok == 0) {
printf("%s does not read/write permission for user or group!\r\n",
filename);
} else {
printf("Your access privs: user %s, group %s\r\n",
my_uname, my_gname);
}
}
printf("\r\n");
if(p) {
snprintf(my_uname, sizeof(my_uname),
"\"%s\" (gid=%d)", p->pw_name, (int)my_uid);
}
else {
snprintf(my_uname, sizeof(my_uname),
"(gid=%d)", (int)my_uid);
}
p = getpwuid(info.st_uid);
if(p) {
snprintf(file_uname, sizeof(file_uname),
"\"%s\" (uid=%d)", p->pw_name, (int)info.st_uid);
}
else {
snprintf(file_uname, sizeof(file_uname),
"(uid=%d)", (int)info.st_uid);
}
g = getgrgid(my_gid);
if(g) {
snprintf(my_gname, sizeof(my_gname),
"\"%s\" (gid=%d)", g->gr_name, (int)my_gid);
}
else {
snprintf(my_gname, sizeof(my_gname),
"(gid=%d)", (int)my_gid);
}
g = getgrgid(info.st_gid);
if(g) {
snprintf(file_gname, sizeof(file_gname),
"\"%s\" (uid=%d)", g->gr_name, (int)info.st_gid);
}
else {
snprintf(file_gname, sizeof(file_gname),
"(uid=%d)", (int)info.st_gid);
}
/* printf("%s is owned by: user %s, group %s\r\n",
filename, file_uname, file_gname); */
perm = info.st_mode;
if((perm & S_IROTH) && (perm & S_IWOTH)) {
printf("%s has read/write permission for everybody\r\n",
filename);
}
else {
printf("%s is not read/write for everybody, so\r\n", filename);
printf(" you must match either user or group permission\r\n");
if((perm & S_IRUSR) && (perm & S_IWUSR)) {
printf("%s has read/write permission for user %s\r\n",
filename, file_uname);
perm_ok = 1;
}
if((perm & S_IRGRP) && (perm & S_IWGRP)) {
printf("%s has read/write permission for group %s\r\n",
filename, file_gname);
perm_ok = 1;
}
if(perm_ok == 0) {
printf("%s does not read/write permission for user or group!\r\n",
filename);
}
else {
printf("Your access privs: user %s, group %s\r\n",
my_uname, my_gname);
}
}
printf("\r\n");
}
int write_serial_port(const void *buf, int num)
{
return(write(port_fd, buf, num));
return(write(port_fd, buf, num));
}
void input_flush_serial_port(void)
{
tcflush(port_fd, TCIFLUSH);
tcflush(port_fd, TCIFLUSH);
}
int read_serial_port_nb(unsigned char *buf, int bufsize)
{
int num, flags;
int num, flags;
flags = fcntl(port_fd, F_GETFL);
fcntl(port_fd, F_SETFL, flags | O_NONBLOCK);
num = read(port_fd, buf, bufsize);
fcntl(port_fd, F_SETFL, flags);
return num;
flags = fcntl(port_fd, F_GETFL);
fcntl(port_fd, F_SETFL, flags | O_NONBLOCK);
num = read(port_fd, buf, bufsize);
fcntl(port_fd, F_SETFL, flags);
return num;
}
int read_serial_port(unsigned char *buf, int bufsize)
{
int num;
int num;
num = read(port_fd, buf, bufsize);
num = read(port_fd, buf, bufsize);
return num;
return num;
}
void send_break_signal(void)
{
tcsendbreak(port_fd, 0);
tcsendbreak(port_fd, 0);
}
void close_serial_port(void)
{
if (port_fd >= 0) {
close(port_fd);
port_fd = -1;
}
if(port_fd >= 0) {
close(port_fd);
port_fd = -1;
}
}
tcflag_t baud_name_to_flags(const char *baud_name)
{
if (strcmp(baud_name, "230400") == 0) return B230400;
if (strcmp(baud_name, "115200") == 0) return B115200;
if (strcmp(baud_name, "57600") == 0) return B57600;
if (strcmp(baud_name, "38400") == 0) return B38400;
if (strcmp(baud_name, "19200") == 0) return B19200;
if (strcmp(baud_name, "9600") == 0) return B9600;
if (strcmp(baud_name, "4800") == 0) return B4800;
if (strcmp(baud_name, "2400") == 0) return B2400;
if (strcmp(baud_name, "1200") == 0) return B1200;
if (strcmp(baud_name, "300") == 0) return B300;
return B0;
if(strcmp(baud_name, "230400") == 0) {
return B230400;
}
if(strcmp(baud_name, "115200") == 0) {
return B115200;
}
if(strcmp(baud_name, "57600") == 0) {
return B57600;
}
if(strcmp(baud_name, "38400") == 0) {
return B38400;
}
if(strcmp(baud_name, "19200") == 0) {
return B19200;
}
if(strcmp(baud_name, "9600") == 0) {
return B9600;
}
if(strcmp(baud_name, "4800") == 0) {
return B4800;
}
if(strcmp(baud_name, "2400") == 0) {
return B2400;
}
if(strcmp(baud_name, "1200") == 0) {
return B1200;
}
if(strcmp(baud_name, "300") == 0) {
return B300;
}
return B0;
}
int set_baud(const char *baud_name)
{
struct termios port_setting;
tcflag_t baud;
int r;
struct termios port_setting;
tcflag_t baud;
int r;
if (port_fd < 0) return -1;
baud = baud_name_to_flags(baud_name);
if (baud == B0) return -2;
r = tcgetattr(port_fd, &port_setting);
if (r != 0) return -3;
//port_setting.c_iflag = IGNBRK | IGNPAR | IXANY | IXON;
port_setting.c_iflag = IGNBRK | IGNPAR;
port_setting.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
port_setting.c_oflag = 0;
port_setting.c_lflag = 0;
r = tcsetattr(port_fd, TCSAFLUSH, &port_setting);
if (r != 0) return -4;
return 0;
if(port_fd < 0) {
return -1;
}
baud = baud_name_to_flags(baud_name);
if(baud == B0) {
return -2;
}
r = tcgetattr(port_fd, &port_setting);
if(r != 0) {
return -3;
}
port_setting.c_iflag = IGNBRK | IGNPAR;
port_setting.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
port_setting.c_oflag = 0;
port_setting.c_lflag = 0;
r = tcsetattr(port_fd, TCSAFLUSH, &port_setting);
if(r != 0) {
return -4;
}
return 0;
}
@ -288,31 +363,35 @@ int set_baud(const char *baud_name)
// use of the serial port is supposed to happen in the file.
int serial_port_fd(void)
{
return port_fd;
return port_fd;
}
void set_rts(int val)
{
int flags;
int result;
int flags;
int result;
result = ioctl(port_fd, TIOCMGET, &flags);
if( result == -1 ) {
printf("Error %i while reading port io flags\n", errno);
return;
}
result = ioctl(port_fd, TIOCMGET, &flags);
if (val) {
flags |= TIOCM_RTS;
} else {
flags &= ~(TIOCM_RTS);
}
if(result == -1) {
printf("Error %i while reading port io flags\n", errno);
return;
}
result = ioctl(port_fd, TIOCMSET, &flags);
if( result == -1 )
printf("Error %i while setting port io flags\n", errno);
if(val) {
flags |= TIOCM_RTS;
}
else {
flags &= ~(TIOCM_RTS);
}
result = ioctl(port_fd, TIOCMSET, &flags);
if(result == -1) {
printf("Error %i while setting port io flags\n", errno);
}
}
@ -323,24 +402,28 @@ void set_rts(int val)
void set_dtr(int val)
{
int flags;
int result;
int flags;
int result;
result = ioctl(port_fd, TIOCMGET, &flags);
if( result == -1 ) {
printf("Error %i while reading port io flags\n", errno);
return;
}
result = ioctl(port_fd, TIOCMGET, &flags);
if (val) {
flags |= TIOCM_DTR;
} else {
flags &= ~(TIOCM_DTR);
}
if(result == -1) {
printf("Error %i while reading port io flags\n", errno);
return;
}
result = ioctl(port_fd, TIOCMSET, &flags);
if( result == -1 )
printf("Error %i while setting port io flags\n", errno);
if(val) {
flags |= TIOCM_DTR;
}
else {
flags &= ~(TIOCM_DTR);
}
result = ioctl(port_fd, TIOCMSET, &flags);
if(result == -1) {
printf("Error %i while setting port io flags\n", errno);
}
}

View File

@ -2,7 +2,7 @@
#ifndef SERIAL_H
#define SERIAL_H
extern char* baud_rate;
extern char *baud_rate;
int open_serial_port(const char *port_name);
int write_serial_port(const void *buf, int num);

View File

@ -1,58 +1,82 @@
#include "serialnumber.h"
int serial_add8(uint8_t s, uint8_t n) {
if (n > 127)
int serial_add8(uint8_t s, uint8_t n)
{
if(n > 127) {
return -1;
uint16_t sum = s+n;
return (uint8_t)(sum%256);
}
uint16_t sum = s + n;
return (uint8_t)(sum % 256);
}
int serial_add16(uint16_t s, uint16_t n) {
if (n > 32767)
int serial_add16(uint16_t s, uint16_t n)
{
if(n > 32767) {
return -1;
uint32_t sum = s+n;
return (uint16_t)(sum%65536);
}
uint32_t sum = s + n;
return (uint16_t)(sum % 65536);
}
int serial_add32(uint32_t s, uint32_t n) {
if (n > 2147483647)
int serial_add32(uint32_t s, uint32_t n)
{
if(n > 2147483647) {
return -1;
uint64_t sum = s+n;
return (uint32_t)(sum%4294967296);
}
uint64_t sum = s + n;
return (uint32_t)(sum % 4294967296);
}
serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2) {
if (s1 == s2)
serial_comp_res_t serial_comp8(uint8_t s1, uint8_t s2)
{
if(s1 == s2) {
return EQUAL;
if ((s1 < s2 && s1 - s2 < 128) || (s1 > s2 && s1 - s2 > 128)) {
}
if((s1 < s2 && s1 - s2 < 128) || (s1 > s2 && s1 - s2 > 128)) {
return LESS;
}
if ((s1 < s2 && s1 - s2 > 128) || (s1 > s2 && s1 - s2 < 128)) {
if((s1 < s2 && s1 - s2 > 128) || (s1 > s2 && s1 - s2 < 128)) {
return GREATER;
}
return UNDEF;
}
serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2) {
if (s1 == s2)
serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2)
{
if(s1 == s2) {
return EQUAL;
if ((s1 < s2 && s1 - s2 < 32768) || (s1 > s2 && s1 - s2 > 32768)) {
}
if((s1 < s2 && s1 - s2 < 32768) || (s1 > s2 && s1 - s2 > 32768)) {
return LESS;
}
if ((s1 < s2 && s1 - s2 > 32768) || (s1 > s2 && s1 - s2 < 32768)) {
if((s1 < s2 && s1 - s2 > 32768) || (s1 > s2 && s1 - s2 < 32768)) {
return GREATER;
}
return UNDEF;
}
serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2) {
if (s1 == s2)
serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2)
{
if(s1 == s2) {
return EQUAL;
if ((s1 < s2 && s1 - s2 < 2147483648) || (s1 > s2 && s1 - s2 > 2147483648)) {
}
if((s1 < s2 && s1 - s2 < 2147483648) || (s1 > s2 && s1 - s2 > 2147483648)) {
return LESS;
}
if ((s1 < s2 && s1 - s2 > 2147483648) || (s1 > s2 && s1 - s2 < 2147483648)) {
if((s1 < s2 && s1 - s2 > 2147483648) || (s1 > s2 && s1 - s2 < 2147483648)) {
return GREATER;
}
return UNDEF;
}

View File

@ -37,144 +37,156 @@ int tun_fd;
pthread_t serial_reader, tun_reader;
uint16_t abro_version = 0;
uint16_t get_abro_version() {
uint16_t get_abro_version()
{
return abro_version;
}
uint16_t get_next_abro_version() {
uint16_t get_next_abro_version()
{
abro_version = serial_add16(abro_version, 1);
return abro_version;
}
int get_tun_fd(void) {
int get_tun_fd(void)
{
return tun_fd;
}
void * serial_reader_f(void *arg) {
void *serial_reader_f(void *arg)
{
unsigned char buf[BUFFER_SIZE];
border_packet_t *packet_buf;
while(1) {
int n = readpacket(buf, BUFFER_SIZE);
if (n > 0) {
if (buf[0] == 0) {
if(n > 0) {
if(buf[0] == 0) {
packet_buf = (border_packet_t *)buf;
flowcontrol_deliver_from_tty(packet_buf, n);
continue;
}
printf("\033[00;33m[via serial interface] %s\033[00m\n",buf);
printf("\033[00;33m[via serial interface] %s\033[00m\n", buf);
}
}
}
int tun_to_serial_packet(uint8_t *serial_packet, uint8_t *tun_packet, size_t packet_size) {
int tun_to_serial_packet(uint8_t *serial_packet, uint8_t *tun_packet, size_t packet_size)
{
struct tun_pi *tun_hdr = (struct tun_pi *)tun_packet;
border_l3_header_t *l3_hdr = (border_l3_header_t *)serial_packet;
l3_hdr->empty = 0;
l3_hdr->type = BORDER_PACKET_L3_TYPE;
l3_hdr->ethertype = ntohs(tun_hdr->proto);
memcpy(
serial_packet + sizeof (border_l3_header_t),
tun_packet + sizeof (struct tun_pi),
packet_size - sizeof (struct tun_pi)
);
return (sizeof (border_l3_header_t) + (packet_size - sizeof (struct tun_pi)));
serial_packet + sizeof(border_l3_header_t),
tun_packet + sizeof(struct tun_pi),
packet_size - sizeof(struct tun_pi)
);
return (sizeof(border_l3_header_t) + (packet_size - sizeof(struct tun_pi)));
}
void * tun_reader_f(void *args) {
void *tun_reader_f(void *args)
{
unsigned char data[BUFFER_SIZE];
size_t bytes;
while (1) {
bytes = read(tun_fd,(void*)data, BUFFER_SIZE);
if (bytes > 0) {
while(1) {
bytes = read(tun_fd, (void *)data, BUFFER_SIZE);
if(bytes > 0) {
bytes = tun_to_serial_packet(tun_in_buf, (uint8_t *)data, bytes);
flowcontrol_send_over_tty((border_packet_t *)tun_in_buf, bytes);
}
}
}
void border_send_ipv6_over_tun(int fd, const struct ip6_hdr *packet) {
void border_send_ipv6_over_tun(int fd, const struct ip6_hdr *packet)
{
uint8_t tun_packet[BUFFER_SIZE];
int packet_size = packet->ip6_plen + sizeof (struct ip6_hdr);
int packet_size = packet->ip6_plen + sizeof(struct ip6_hdr);
struct tun_pi *tun_hdr = (struct tun_pi *)tun_packet;
tun_hdr->flags = 0;
tun_hdr->proto = htons(ETHERTYPE_IPV6);
memcpy(tun_packet+sizeof (struct tun_pi),(uint8_t *)packet, packet_size);
write(tun_fd,tun_packet,packet_size+sizeof (struct tun_pi));
memcpy(tun_packet + sizeof(struct tun_pi), (uint8_t *)packet, packet_size);
write(tun_fd, tun_packet, packet_size + sizeof(struct tun_pi));
}
int tun_set_owner(int fd, const uid_t *uid, const gid_t *gid) {
if (uid != NULL) {
if (*uid != -1 && ioctl(fd, TUNSETOWNER, *uid)) {
int tun_set_owner(int fd, const uid_t *uid, const gid_t *gid)
{
if(uid != NULL) {
if(*uid != -1 && ioctl(fd, TUNSETOWNER, *uid)) {
return -1;
}
}
if (gid != NULL) {
if (*gid != -1 && ioctl(fd, TUNSETGROUP, *gid)) {
if(gid != NULL) {
if(*gid != -1 && ioctl(fd, TUNSETGROUP, *gid)) {
return -1;
}
}
return 0;
}
int tun_add_addr(const char *ip_addr) {
int tun_add_addr(const char *ip_addr)
{
char command[21 + IPV6_ADDR_LEN + IF_NAME_LEN];
printf("INFO: ip addr add %s dev %s\n", ip_addr, tun_if_name);
sprintf(command, "ip addr add %s dev %s", ip_addr, tun_if_name);
if (system(command) != 0) {
if(system(command) != 0) {
return -1;
}
return 0;
}
/* Source: http://backreference.org/2010/03/26/tuntap-interface-tutorial/
*/
int open_tun(char *if_name, int flags) {
int open_tun(char *if_name, int flags)
{
struct ifreq ifr;
int fd, err;
/* Arguments taken by the function:
*
* char *if_name: the name of an interface (or '\0'). MUST have enough
* space to hold the interface name if '\0' is passed
* int flags: interface flags (eg, IFF_TUN etc.)
*/
/* open the clone device */
if ( (fd = open(TUNDEV, O_RDWR)) < 0 ) {
if((fd = open(TUNDEV, O_RDWR)) < 0) {
return fd;
}
/* preparation of the struct ifr, of type "struct ifreq" */
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */
if (*if_name) {
if(*if_name) {
/* if a device name was specified, put it in the structure; otherwise,
* the kernel will try to allocate the "next" device of the
* specified type */
strncpy(ifr.ifr_name, if_name, IFNAMSIZ);
}
/* try to create the device */
if ( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
close(fd);
return err;
}
/* if the operation was successful, write back the name of the
* interface to the variable "if_name", so the caller can know
* it. Note that the caller MUST reserve space in *if_name (see calling
@ -186,124 +198,131 @@ int open_tun(char *if_name, int flags) {
return fd;
}
int context_empty(uint8_t cid) {
int context_empty(uint8_t cid)
{
return context_cache[cid].cid != cid;
}
int border_update_context( uint8_t cid, const struct in6_addr *prefix,
uint8_t len, uint8_t comp,
uint16_t lifetime) {
if (cid >= MAXIMUM_CONTEXTS) {
int border_update_context(uint8_t cid, const struct in6_addr *prefix,
uint8_t len, uint8_t comp,
uint16_t lifetime)
{
if(cid >= MAXIMUM_CONTEXTS) {
return -1;
}
len = (len <= 128) ? len : 128;
if (context_empty(cid)) {
if(context_empty(cid)) {
context_cache[cid].version = get_abro_version();
} else {
}
else {
context_cache[cid].version = get_next_abro_version();
}
context_cache[cid].cid = cid;
memcpy(&(context_cache[cid].prefix),prefix,len);
memcpy(&(context_cache[cid].prefix), prefix, len);
context_cache[cid].len = len;
context_cache[cid].comp = comp;
context_cache[cid].lifetime = lifetime;
multiplex_send_context_over_tty(&context_cache[cid]);
return 0;
}
int border_renew_existing_context(uint8_t cid) {
if (cid >= MAXIMUM_CONTEXTS) {
int border_renew_existing_context(uint8_t cid)
{
if(cid >= MAXIMUM_CONTEXTS) {
return -1;
}
if (context_empty(cid)) {
if(context_empty(cid)) {
return -1;
}
multiplex_send_context_over_tty(&context_cache[cid]);
return 0;
}
void border_remove_context(uint8_t cid) {
if (cid >= MAXIMUM_CONTEXTS) {
void border_remove_context(uint8_t cid)
{
if(cid >= MAXIMUM_CONTEXTS) {
return;
}
if (context_empty(cid)) {
if(context_empty(cid)) {
return;
}
context_cache[cid].version = get_next_abro_version();
context_cache[cid].lifetime = 0;
multiplex_send_context_over_tty(&context_cache[cid]);
context_cache[cid].cid = 0xFF;
}
int border_add_addr(const char *ip_addr) {
int border_add_addr(const char *ip_addr)
{
struct in6_addr parsed_addr;
if (inet_pton(AF_INET6, ip_addr, &parsed_addr) != 1) {
if(inet_pton(AF_INET6, ip_addr, &parsed_addr) != 1) {
return -1;
}
tun_add_addr(ip_addr);
multiplex_send_addr_over_tty(&parsed_addr);
return 0;
}
int border_initialize(char *if_name, const char *ip_addr, const char *tty_dev) {
int border_initialize(char *if_name, const char *ip_addr, const char *tty_dev)
{
int res, i;
char command[21 + IPV6_ADDR_LEN + IF_NAME_LEN];
char ip_addr_cpy[IPV6_ADDR_LEN];
struct in6_addr parsed_addr;
strncpy(ip_addr_cpy,ip_addr,IPV6_ADDR_LEN);
strncpy(ip_addr_cpy, ip_addr, IPV6_ADDR_LEN);
strtok(ip_addr_cpy, "/");
if ((res = inet_pton(AF_INET6, ip_addr_cpy, &parsed_addr)) != 1) {
if((res = inet_pton(AF_INET6, ip_addr_cpy, &parsed_addr)) != 1) {
return res;
}
if ((res = init_multiplex(tty_dev)) != 0) {
if((res = init_multiplex(tty_dev)) != 0) {
return res;
}
tun_fd = open_tun(if_name, IFF_TUN);
printf("INFO: ip link set %s up\n", if_name);
sprintf(command, "ip link set %s up", if_name);
strncpy(tun_if_name, if_name, IF_NAME_LEN);
if ((res = system(command)) != 0) {
if((res = system(command)) != 0) {
return res;
}
if ((res = tun_add_addr(ip_addr)) != 0) {
if((res = tun_add_addr(ip_addr)) != 0) {
return res;
}
// initialize context cache as empty.
for (i = 0; i < MAXIMUM_CONTEXTS; i++) {
for(i = 0; i < MAXIMUM_CONTEXTS; i++) {
context_cache[i].cid = 0xFF;
}
pthread_create(&serial_reader, NULL, serial_reader_f, NULL);
hard_reset_to_user_code();
flowcontrol_init(&parsed_addr);
pthread_create(&tun_reader, NULL, tun_reader_f, NULL);
return 0;
}

View File

@ -24,7 +24,7 @@
/**
* @brief Defines the format of the context information.
*/
typedef struct __attribute__ ((packed)) border_context_t {
typedef struct __attribute__((packed)) border_context_t {
uint16_t version; ///< Version of this context, send via the ABRO (s. draft-ietf-6lowpan-nd-17).
uint8_t cid; ///< The CID of the Context (s. draft-ietf-6lowpan-nd-17).
struct in6_addr prefix; ///< The prefix this context defines.
@ -39,25 +39,25 @@ typedef struct __attribute__ ((packed)) border_context_t {
* is not given, it is chosen by the kernel
* and returned to the caller.
* @param[in] flags Flags that signify the interface type
* (<tt>IFF_TUN</tt> = TUN interface,
* (<tt>IFF_TUN</tt> = TUN interface,
* <tt>IFF_TAP</tt> = TAP interface,
* @return The file descriptor to the new interface.
* <tt>IFF_NO_PI</tt> = provide no packet information).
* @see http://backreference.org/2010/03/26/tuntap-interface-tutorial/
* @see http://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/Documentation/networking/tuntap.txt
*
* Initializes a TUN- or TAP-Interface by the name <em>dev</em>. Which kind
*
* Initializes a TUN- or TAP-Interface by the name <em>dev</em>. Which kind
* of interface is defined by <em>flags</em>. The function returns the file
* descriptor to the interface, which can be accessed via the
* descriptor to the interface, which can be accessed via the
* POSIX.1-2001 functions <tt>read()</tt> and <tt>write()</tt>
*/
int open_tun(char *dev, int flags);
/**
* @brief Returns the file descriptor to the TUN interface.
* @return The file descriptor to the TUN interface initialized by
* @return The file descriptor to the TUN interface initialized by
* open_tun()
*
*
* open_tun() needs to be called before. Otherwise the result of this
* function may not make sense.
*/
@ -81,14 +81,14 @@ int tun_add_addr(const char *ip_addr);
/**
* @brief Initializes the border router.
* @param[in,out] if_name The name of the new TUN interface. If the
* name is not given, it is chosen by the
* @param[in,out] if_name The name of the new TUN interface. If the
* name is not given, it is chosen by the
* kernel and returned to the caller.
* @param[in] ip_addr The IPv6 Address, that is initially attached
* to the LoWPAN Border Router.
* @param[in] tty_dev Device file of the serial interface the
* MSB-A2 is attached to.
* @return 0 if successfull,
* @return 0 if successfull,
* != 0 if an error occurs.
*/
int border_initialize(char *if_name, const char *ip_addr, const char *tty_dev);
@ -98,29 +98,29 @@ int border_initialize(char *if_name, const char *ip_addr, const char *tty_dev);
* @param[in] fd The file descriptor of the TUN interface
* @param[in] packet The IPv6 datagram that is to be send via the
* TUN interface and starts with an IPv6 header.
*
* The function uses the payload length field of the IPv6 Header to
* determine the length of the overall packet. The payload bytes
*
* The function uses the payload length field of the IPv6 Header to
* determine the length of the overall packet. The payload bytes
* <em>must</em> follow the header in memory.
*/
void border_send_ipv6_over_tun(int fd, const struct ip6_hdr *packet);
/**
* @brief Updates 6LoWPAN contex information.
* @param[in] cid The context identifier, only values < 16
* @param[in] cid The context identifier, only values < 16
* are allowed.
* @param[in] prefix The prefix that shall be associated with the
* <em>cid</em>.
* @param[in] len The length of the <em>prefix</em> in bits.
* @param[in] comp Flag to determine if Context is allowed for
* @param[in] comp Flag to determine if Context is allowed for
* compression (s. draft-ietf-6lowpan-nd-17).
* @param[in] lifetime Lifetime of this context
* @param[in] lifetime Lifetime of this context
* (s. draft-ietf-6lowpan-nd-17).
* @return If cid < 16 than it is 0, otherwise -1.
*/
int border_update_context( uint8_t cid, const struct in6_addr *prefix,
uint8_t len, uint8_t comp,
uint16_t lifetime);
int border_update_context(uint8_t cid, const struct in6_addr *prefix,
uint8_t len, uint8_t comp,
uint16_t lifetime);
/**
* @brief Updates 6LoWPAN contex information, as it is stored in the
@ -129,8 +129,8 @@ int border_update_context( uint8_t cid, const struct in6_addr *prefix,
* @param[in] cid The context identifier.
* @return 0, if the context identifiet by cid is stored in the border
* router, -1 if not.
*
* The information taken for this update ist the last, that was used
*
* The information taken for this update ist the last, that was used
* with \ref border_update_context().
*/
int border_renew_existing_context(uint8_t cid);
@ -138,8 +138,8 @@ int border_renew_existing_context(uint8_t cid);
/**
* @brief Removes 6LoWPAN context information.
* @param[in] cid The context identifier.
*
* The information taken for this update ist the last, that was used
*
* The information taken for this update ist the last, that was used
* with \ref border_update_context().
*/
void border_remove_context(uint8_t cid);

View File

@ -14,135 +14,154 @@ int run_counter;
FILE *stats_file = NULL;
void init_file(const char* skeleton_file_name,
int runs_per_test, float interval) {
void init_file(const char *skeleton_file_name,
int runs_per_test, float interval)
{
FILE *skeleton_file = NULL;
char line[1024];
skeleton_file = fopen(skeleton_file_name, "r");
while( fgets(line,1024,skeleton_file) != NULL) {
if (strncmp(line,"# sending window size=%d\n",1024) == 0) {
while(fgets(line, 1024, skeleton_file) != NULL) {
if(strncmp(line, "# sending window size=%d\n", 1024) == 0) {
fprintf(stats_file, line, BORDER_SWS);
} else if (strncmp(line,"# count=%ld (-c)\n",1024) == 0) {
}
else if(strncmp(line, "# count=%ld (-c)\n", 1024) == 0) {
fprintf(stats_file, line, runs_per_test);
} else if (strncmp(line,"# interval=%f (-i)\n",1024) == 0) {
}
else if(strncmp(line, "# interval=%f (-i)\n", 1024) == 0) {
fprintf(stats_file, line, interval);
} else {
fprintf(stats_file,"%s",line);
}
else {
fprintf(stats_file, "%s", line);
}
}
}
int testing_init(const char *stats_file_name,
const char* skeleton_file_name,
int runs_per_test, float interval) {
if (stats_file != NULL) {
int testing_init(const char *stats_file_name,
const char *skeleton_file_name,
int runs_per_test, float interval)
{
if(stats_file != NULL) {
return -1;
}
stats = (struct test_stats *)calloc(runs_per_test, sizeof (struct test_stats));
stats = (struct test_stats *)calloc(runs_per_test, sizeof(struct test_stats));
run_counter = 0;
stats_file = fopen(stats_file_name, "w");
if (stats_file == NULL) {
if(stats_file == NULL) {
return -1;
}
init_file(skeleton_file_name, runs_per_test, interval);
return 0;
}
int testing_destroy() {
int testing_destroy()
{
int res, i;
for (i = 0; i < run_counter; i++) {
fprintf(stats_file,"%7d\t%3d\t%7ld\n",
i,stats[i].seq_num,stats[i].time_diff
);
for(i = 0; i < run_counter; i++) {
fprintf(stats_file, "%7d\t%3d\t%7ld\n",
i, stats[i].seq_num, stats[i].time_diff
);
}
free(stats);
stats = NULL;
res = fclose(stats_file);
stats_file = NULL;
return res;
}
void testing_start(uint8_t seq_num) {
if (stats_file == NULL) {
void testing_start(uint8_t seq_num)
{
if(stats_file == NULL) {
return;
}
gettimeofday(&(timers[seq_num]),NULL);
gettimeofday(&(timers[seq_num]), NULL);
}
void testing_stop(uint8_t seq_num) {
if (stats_file == NULL) {
void testing_stop(uint8_t seq_num)
{
if(stats_file == NULL) {
return;
}
struct timeval start = timers[seq_num], end;
gettimeofday(&end,NULL);
gettimeofday(&end, NULL);
stats[run_counter].seq_num = seq_num;
stats[run_counter].time_diff = (end.tv_sec - start.tv_sec) * 1000;
stats[run_counter].time_diff += (end.tv_usec - start.tv_usec) / 1000;
run_counter++;
}
void generate_filename(
char *filename,
const char *results_dir_name,
int runs_per_test,
float interval) {
char *filename,
const char *results_dir_name,
int runs_per_test,
float interval)
{
time_t today;
struct tm *tmp = NULL;
char timestr[16];
FILE *test = NULL;
int count = 1;
today = time(NULL);
tmp = localtime(&today);
if (tmp == NULL) {
if(tmp == NULL) {
perror("localtime");
return;
}
strftime(timestr,16,"%Y.%m.%d",tmp);
strftime(timestr, 16, "%Y.%m.%d", tmp);
do {
sprintf(filename,
"%s/%s-Results-Ping6_%d_%d_%f-%d.txt",
results_dir_name,
timestr,
BORDER_SWS,
runs_per_test,
interval,
count++
);
} while ((test = fopen(filename, "r")) != NULL);
if (test != NULL) {
"%s/%s-Results-Ping6_%d_%d_%f-%d.txt",
results_dir_name,
timestr,
BORDER_SWS,
runs_per_test,
interval,
count++
);
}
while((test = fopen(filename, "r")) != NULL);
if(test != NULL) {
fclose(test);
}
}
void start_test(const char *ping_addr,
const char *results_dir_name, const char *skeleton_file,
int runs_per_test, float interval) {
printf("%d, %f\n",runs_per_test, interval);
const char *results_dir_name, const char *skeleton_file,
int runs_per_test, float interval)
{
printf("%d, %f\n", runs_per_test, interval);
char command[50];
char filename[50];
generate_filename(filename, results_dir_name, runs_per_test, interval);
sprintf(command, "ping6 -v -f -c %d -i %f -W 1 abcd::d",
runs_per_test,
interval
);
);
testing_init(filename, skeleton_file, runs_per_test, interval);
puts(command);
system(command);

View File

@ -1,13 +1,13 @@
/**
* @file testing.h
* @brief Test suite for the 6LoWPAN Border Router.
*
*
* The tests are managed in the following way:
* Packets (ICMPv6 Echo Request) are send onto the sensor node
* via the serial interface. The user can then decide what she
* wants to measure by calling testing_start() to start the
* Packets (ICMPv6 Echo Request) are send onto the sensor node
* via the serial interface. The user can then decide what she
* wants to measure by calling testing_start() to start the
* measuring and testing_stop() to end it.
*
*
* @author Freie Universität Berlin, Computer Systems & Telemetics
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
@ -52,9 +52,9 @@ void testing_stop(uint8_t seq_num);
* is. Lines of the formats
* <tt>"# count=%ld (-c)\n"</tt> and
* <tt>"# interval=%0.2f (-i)\n"</tt>
* will be replaced with <tt>\%ld</tt>
* set to <em>runs_per_test</em> and
* <tt>\%0.2f</tt> set to
* will be replaced with <tt>\%ld</tt>
* set to <em>runs_per_test</em> and
* <tt>\%0.2f</tt> set to
* <em>interval</em>.
* @param[in] runs_per_test How many packets shall be send in
* this test.
@ -62,7 +62,7 @@ void testing_stop(uint8_t seq_num);
* the sending of each packet.
*/
void start_test(const char *ping_addr,
const char* results_dir_name, const char *skeleton_file,
int runs_per_test, float interval);
const char *results_dir_name, const char *skeleton_file,
int runs_per_test, float interval);
#endif /* TESTING_H*/