+++ /dev/null
-AUTOMAKE_OPTIONS = foreign
-
-TOS=$(shell ncc -print-tosdir)
-SERIAL_H = $(TOS)/lib/serial/Serial.h
-
-BUILT_SOURCES = serialpacket.h serialprotocol.h
-
-bin_PROGRAMS=sf
-noinst_PROGRAMS=prettylisten sflisten sfsend seriallisten serialsend
-noinst_LIBRARIES=libmote.a
-
-sf_SOURCES = sf.c
-sf_LDADD = libmote.a
-
-prettylisten_SOURCES = prettylisten.c
-prettylisten_LDADD = libmote.a
-
-sflisten_SOURCES = sflisten.c
-sflisten_LDADD = libmote.a
-
-sfsend_SOURCES = sfsend.c
-sfsend_LDADD = libmote.a
-
-seriallisten_SOURCES = seriallisten.c
-seriallisten_LDADD = libmote.a
-
-serialsend_SOURCES = serialsend.c
-serialsend_LDADD = libmote.a
-
-libmote_a_SOURCES = \
- message.c \
- serialpacket.c \
- serialsource.c \
- sfsource.c
-
-serialpacket.c serialpacket.h: $(SERIAL_H)
- mig -o serialpacket.h -c-prefix=spacket c $(SERIAL_H) serial_packet
-
-serialprotocol.h: $(SERIAL_H)
- ncg -o $@ -c-prefix=SERIAL c $(SERIAL_H) Serial.h
+++ /dev/null
-Mini C-SDK for TinyOS
-=====================
-
-This directory contains a mini-SDK for C, for communicating with motes
-running TinyOS 2.0. To build this SDK, run
- ./bootstrap
- ./configure --prefix=<somewhere>
- make
-in the current directory and, if you wish, "make install" to install the
-C-based serial forwarder in <somewhere>/bin.
-
-This directory contains one utility:
-- sf: a C-based serial forwarder:
- sf <port> <device> <baudrate>
- Starts a serial forwarder listening for TCP connections on port <port>, and
- sending and receiving packets on serial port <device> at the specified
- <baudrate>.
-
- This serial forwarder implements the standard TinyOS 2.0 serial forwarder
- protocol (see comments in support/sdk/java/net/tinyos/packet/SFProtocol.java
- for a brief overview).
-
-a library (libmote.a) supporting mote communication:
-- serialsource.h: send and receive packets over a serial port (supports
- non-blocking I/O)
-- sfsource.h: send and receive packets using the serial forwarder
- protocol
-- message.h: support functions for mig, to encode and decode bitfields of
- arbitrary size and endianness
-- serialpacket.h: mig-generated code to encode and decode the header of
- TinyOS serial active-message packets (the packets sent and received by the
- BaseStation application)
-- serialprotocol.h: ncg-generated code containing the constants describing
- TinyOS serial packets (from tos/lib/serial/Serial.h)
-
-and four example programs that use that library:
-- seriallisten: print packets received from a serial port
-- sflisten: print packets received from a serial forwarder
-- prettylisten: print packets received from a serial forwarder, using
- mig-generated code to decode the standard serial-active-message header
-- sfsend: send a packet (specified on the command line) to a serial forwarder
-
-Note that sflisten prints, and sfsend sends, raw packets. In particular,
-the first byte indicates the packet type (e.g., 00 for the AM-over-serial
-packets). For more information on serial communication to and from motes,
-see TEP113.
-
-For more information on using ncg and mig with C, see the nescc-mig and
-nescc-ncg man pages.
-
-
+++ /dev/null
-/* autoconf.h. Generated from autoconf.h.in by configure. */
-/* autoconf.h.in. Generated from configure.ac by autoheader. */
-
-/* Name of package */
-#define PACKAGE "cmotesdk"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "cmotesdk"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "cmotesdk 1.0"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "cmotesdk"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0"
-
-/* Version number of package */
-#define VERSION "1.0"
+++ /dev/null
-mkdir config-aux
-aclocal
-autoheader
-autoconf
-automake -a -c
+++ /dev/null
-<project name="tinyos-2.x support sdk c" default="all">
-
- <target name="all" >
- <echo message = "Building support sdk c" />
- <exec executable="./bootstrap" failonerror="true">
- </exec>
- <exec executable="./configure" failonerror="true">
- <arg line="--quiet" />
- </exec>
- <exec executable="make" failonerror="true">
- <arg line="all" />
- </exec>
- </target>
-
- <target name="install" >
- <echo message = "Installing tinyos-2.x support sdk c" />
- <exec executable="./bootstrap" failonerror="true">
- </exec>
- <exec executable="./configure" failonerror="true">
- <arg line="--prefix=$TOSTOOLS_PREFIX --quiet" />
- </exec>
- <exec executable="make" failonerror="true">
- <arg line="install" />
- </exec>
- </target>
-
-</project>
+++ /dev/null
-AC_INIT(cmotesdk, 1.0)
-AC_CONFIG_SRCDIR(sfsource.c)
-AM_CONFIG_HEADER(autoconf.h)
-AC_CONFIG_AUX_DIR(config-aux)
-AM_INIT_AUTOMAKE
-
-AC_PROG_CC
-AC_PROG_RANLIB
-
-AC_OUTPUT(Makefile)
+++ /dev/null
-/* Copyright (c) 2006 Intel Corporation
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached INTEL-LICENSE
- * file. If you do not find these files, copies can be found by writing to
- * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
- * 94704. Attention: Intel License Inquiry.
- */
-/* Authors: David Gay <dgay@intel-research.net>
- * Intel Research Berkeley Lab
- */
-
-#include <stdlib.h>
-#include "message.h"
-
-struct tmsg {
- uint8_t *data;
- size_t len;
-};
-
-tmsg_t *new_tmsg(void *packet, size_t len)
-{
- tmsg_t *x = malloc(sizeof(tmsg_t));
-
- if (x)
- {
- x->data = packet;
- x->len = len;
- }
- return x;
-}
-
-void free_tmsg(tmsg_t *msg)
-{
- if (msg)
- free(msg);
-}
-
-void *tmsg_data(tmsg_t *msg)
-{
- return msg->data;
-}
-
-size_t tmsg_length(tmsg_t *msg)
-{
- return msg->len;
-}
-
-static void (*failfn)(void);
-
-void tmsg_fail(void)
-{
- if (failfn)
- failfn();
-}
-
-void (*tmsg_set_fail(void (*fn)(void)))(void)
-{
- void (*oldfn)(void) = failfn;
-
- failfn = fn;
-
- return oldfn;
-}
-
-/* Check if a specified bit field is in range for a buffer, and invoke
- tmsg_fail if not. Return TRUE if in range, FALSE otherwise */
-static int boundsp(tmsg_t *msg, size_t offset, size_t length)
-{
- if (offset + length <= msg->len * 8)
- return 1;
-
- tmsg_fail();
- return 0;
-}
-
-/* Convert 2's complement 'length' bit integer 'x' from unsigned to signed
- */
-static int64_t u2s(uint64_t x, size_t length)
-{
- if (x & 1ULL << (length - 1))
- return (int64_t)x - (1LL << length);
- else
- return x;
-}
-
-uint64_t tmsg_read_ule(tmsg_t *msg, size_t offset, size_t length)
-{
- uint64_t x = 0;
-
- if (boundsp(msg, offset, length))
- {
- size_t byte_offset = offset >> 3;
- size_t bit_offset = offset & 7;
- size_t shift = 0;
-
- /* all in one byte case */
- if (length + bit_offset <= 8)
- return (msg->data[byte_offset] >> bit_offset) & ((1 << length) - 1);
-
- /* get some high order bits */
- if (offset > 0)
- {
- x = msg->data[byte_offset] >> bit_offset;
- byte_offset++;
- shift += 8 - bit_offset;
- length -= 8 - bit_offset;
- }
-
- while (length >= 8)
- {
- x |= (uint64_t)msg->data[byte_offset++] << shift;
- shift += 8;
- length -= 8;
- }
-
- /* data from last byte */
- if (length > 0)
- x |= (uint64_t)(msg->data[byte_offset] & ((1 << length) - 1)) << shift;
- }
-
- return x;
-}
-
-int64_t tmsg_read_le(tmsg_t *msg, size_t offset, size_t length)
-{
- return u2s(tmsg_read_ule(msg, offset, length), length);
-}
-
-void tmsg_write_ule(tmsg_t *msg, size_t offset, size_t length, uint64_t x)
-{
- if (boundsp(msg, offset, length))
- {
- size_t byte_offset = offset >> 3;
- size_t bit_offset = offset & 7;
- size_t shift = 0;
-
- /* all in one byte case */
- if (length + bit_offset <= 8)
- {
- msg->data[byte_offset] =
- ((msg->data[byte_offset] & ~(((1 << length) - 1) << bit_offset))
- | x << bit_offset);
- return;
- }
-
- /* set some high order bits */
- if (bit_offset > 0)
- {
- msg->data[byte_offset] =
- ((msg->data[byte_offset] & ((1 << bit_offset) - 1)) | x << bit_offset);
- byte_offset++;
- shift += 8 - bit_offset;
- length -= 8 - bit_offset;
- }
-
- while (length >= 8)
- {
- msg->data[byte_offset++] = x >> shift;
- shift += 8;
- length -= 8;
- }
-
- /* data for last byte */
- if (length > 0)
- msg->data[byte_offset] =
- (msg->data[byte_offset] & ~((1 << length) - 1)) | x >> shift;
- }
-}
-
-void tmsg_write_le(tmsg_t *msg, size_t offset, size_t length, int64_t value)
-{
- tmsg_write_ule(msg, offset, length, value);
-}
-
-uint64_t tmsg_read_ube(tmsg_t *msg, size_t offset, size_t length)
-{
- uint64_t x = 0;
-
- if (boundsp(msg, offset, length))
- {
- size_t byte_offset = offset >> 3;
- size_t bit_offset = offset & 7;
-
- /* All in one byte case */
- if (length + bit_offset <= 8)
- return (msg->data[byte_offset] >> (8 - bit_offset - length)) &
- ((1 << length) - 1);
-
- /* get some high order bits */
- if (bit_offset > 0)
- {
- length -= 8 - bit_offset;
- x = (uint64_t)(msg->data[byte_offset] & ((1 << (8 - bit_offset)) - 1)) << length;
- byte_offset++;
- }
-
- while (length >= 8)
- {
- length -= 8;
- x |= (uint64_t)msg->data[byte_offset++] << length;
- }
-
- /* data from last byte */
- if (length > 0)
- x |= msg->data[byte_offset] >> (8 - length);
-
- return x;
- }
-
- return x;
-}
-
-int64_t tmsg_read_be(tmsg_t *msg, size_t offset, size_t length)
-{
- return u2s(tmsg_read_ube(msg, offset, length), length);
-}
-
-void tmsg_write_ube(tmsg_t *msg, size_t offset, size_t length, uint64_t x)
-{
- if (boundsp(msg, offset, length))
- {
- size_t byte_offset = offset >> 3;
- size_t bit_offset = offset & 7;
-
- /* all in one byte case */
- if (length + bit_offset <= 8) {
- size_t mask = ((1 << length) - 1) << (8 - bit_offset - length);
-
- msg->data[byte_offset] =
- ((msg->data[byte_offset] & ~mask) | x << (8 - bit_offset - length));
- return;
- }
-
- /* set some high order bits */
- if (bit_offset > 0)
- {
- size_t mask = (1 << (8 - bit_offset)) - 1;
-
- length -= 8 - bit_offset;
- msg->data[byte_offset] =
- ((msg->data[byte_offset] & ~mask) | x >> length);
- byte_offset++;
- }
-
- while (length >= 8)
- {
- length -= 8;
- msg->data[byte_offset++] = x >> length;
- }
-
- /* data for last byte */
- if (length > 0)
- {
- size_t mask = (1 << (8 - length)) - 1;
-
- msg->data[byte_offset] =
- ((msg->data[byte_offset] & mask) | x << (8 - length));
- }
- }
-}
-
-void tmsg_write_be(tmsg_t *msg, size_t offset, size_t length, int64_t value)
-{
- tmsg_write_ube(msg, offset, length, value);
-}
-
-/* u2f and f2u convert raw 32-bit values to/from float. This code assumes
- that the floating point rep in the uint32_t values:
- bit 31: sign, bits 30-23: exponent, bits 22-0: mantissa
- matches that of a floating point value when such a value is stored in
- memory.
-*/
-
-/* Note that C99 wants us to use the union approach rather than the
- cast-a-pointer approach... */
-union f_and_u {
- uint32_t u;
- float f;
-};
-
-static float u2f(uint32_t x)
-{
- union f_and_u y = { .u = x};
- return y.f;
-}
-
-static uint32_t f2u(float x)
-{
- union f_and_u y = { .f = x};
- return y.u;
-}
-
-float tmsg_read_float_le(tmsg_t *msg, size_t offset)
-{
- return u2f(tmsg_read_ule(msg, offset, 32));
-}
-
-void tmsg_write_float_le(tmsg_t *msg, size_t offset, float x)
-{
- tmsg_write_ule(msg, offset, 32, f2u(x));
-}
-
-float tmsg_read_float_be(tmsg_t *msg, size_t offset)
-{
- return u2f(tmsg_read_ube(msg, offset, 32));
-}
-
-void tmsg_write_float_be(tmsg_t *msg, size_t offset, float x)
-{
- tmsg_write_ube(msg, offset, 32, f2u(x));
-}
+++ /dev/null
-/* Copyright (c) 2006 Intel Corporation
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached INTEL-LICENSE
- * file. If you do not find these files, copies can be found by writing to
- * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
- * 94704. Attention: Intel License Inquiry.
- */
-/* Authors: David Gay <dgay@intel-research.net>
- * Intel Research Berkeley Lab
- */
-#ifndef MESSAGE_H
-#define MESSAGE_H
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** The type of message buffers */
-typedef struct tmsg tmsg_t;
-
-/** Invoke the function set by tmsg_set_fail.
- * tmsg_fail is called by the tmsg_read and tmsg_write functions when an
- * out-of-buffer access is attempted.
-*/
-void tmsg_fail(void);
-
-/** Set the function that tmsg_fail should call, and return the previous
- * function. If the function is NULL, tmsg_fail does nothing.
-*/
-void (*tmsg_set_fail(void (*fn)(void)))(void);
-
-/**
- * Create a message buffer from array 'packet' of 'len' bytes
- */
-tmsg_t *new_tmsg(void *packet, size_t len);
-
-/**
- * Free a message buffer. This does NOT free the underlying array.
- */
-void free_tmsg(tmsg_t *msg);
-
-/**
- * Return underlying array of a message buffer
- */
-void *tmsg_data(tmsg_t *msg);
-
-/**
- * Return length of a message buffer
- */
-size_t tmsg_length(tmsg_t *msg);
-
-/**
- * Read an unsigned little-endian integer of 'bit_length' bits from bit offset
- * 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and 0 is returned.
- */
-uint64_t tmsg_read_ule(tmsg_t *msg, size_t bit_offset, size_t bit_length);
-
-/**
- * Read a signed little-endian integer of 'bit_length' bits from bit offset
- * 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and 0 is returned.
- */
-int64_t tmsg_read_le(tmsg_t *msg, size_t bit_offset, size_t bit_length);
-
-/**
- * Write an unsigned little-endian integer of 'bit_length' bits to bit offset
- * 'bit_offset'.
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and no write occurs.
- */
-void tmsg_write_ule(tmsg_t *msg, size_t bit_offset, size_t bit_length, uint64_t value);
-
-/**
- * Write a signed little-endian integer of 'bit_length' bits to bit offset
- * 'bit_offset'.
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and no write occurs.
- */
-void tmsg_write_le(tmsg_t *msg, size_t bit_offset, size_t bit_length, int64_t value);
-
-/**
- * Read an unsigned big-endian integer of 'bit_length' bits from bit offset
- * 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and 0 is returned.
- */
-uint64_t tmsg_read_ube(tmsg_t *msg, size_t bit_offset, size_t bit_length);
-
-/**
- * Read a signed big-endian integer of 'bit_length' bits from bit offset
- * 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and 0 is returned.
- */
-int64_t tmsg_read_be(tmsg_t *msg, size_t bit_offset, size_t bit_length);
-
-/**
- * Write an unsigned big-endian integer of 'bit_length' bits to bit offset
- * 'bit_offset'.
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and no write occurs.
- */
-void tmsg_write_ube(tmsg_t *msg, size_t bit_offset, size_t bit_length, uint64_t value);
-
-/**
- * Write a signed big-endian integer of 'bit_length' bits to bit offset
- * 'bit_offset'.
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and no write occurs.
- */
-void tmsg_write_be(tmsg_t *msg, size_t bit_offset, size_t bit_length, int64_t value);
-
-/**
- * Read a 32-bit IEEE float stored in little-endian format (bit 31: sign,
- * bits 30-23: exponent, bits 22-0: mantissa) from bit offset 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and 0 is returned.
- */
-float tmsg_read_float_le(tmsg_t *msg, size_t offset);
-
-/**
- * Write a 32-bit IEEE float in little-endian format (bit 31: sign,
- * bits 30-23: exponent, bits 22-0: mantissa) to bit offset 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and no write occurs.
- */
-void tmsg_write_float_le(tmsg_t *msg, size_t offset, float x);
-
-/**
- * Read a 32-bit IEEE float stored in big-endian format (bit 31: sign,
- * bits 30-23: exponent, bits 22-0: mantissa) from bit offset 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and 0 is returned.
- */
-float tmsg_read_float_be(tmsg_t *msg, size_t offset);
-
-/**
- * Write a 32-bit IEEE float in big-endian format (bit 31: sign,
- * bits 30-23: exponent, bits 22-0: mantissa) to bit offset 'bit_offset'
- * If the specified field is out of range for the buffer, tmsg_fail is called
- * and no write occurs.
- */
-void tmsg_write_float_be(tmsg_t *msg, size_t offset, float x);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "sfsource.h"
-#include "serialpacket.h"
-#include "serialprotocol.h"
-
-void hexprint(uint8_t *packet, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- printf("%02x ", packet[i]);
-}
-
-int main(int argc, char **argv)
-{
- int fd;
-
- if (argc != 3)
- {
- fprintf(stderr, "Usage: %s <host> <port> - dump packets from a serial forwarder\n", argv[0]);
- exit(2);
- }
- fd = open_sf_source(argv[1], atoi(argv[2]));
- if (fd < 0)
- {
- fprintf(stderr, "Couldn't open serial forwarder at %s:%s\n",
- argv[1], argv[2]);
- exit(1);
- }
- for (;;)
- {
- int len, i;
- uint8_t *packet = read_sf_packet(fd, &len);
-
- if (!packet)
- exit(0);
-
- if (len >= 1 + SPACKET_SIZE &&
- packet[0] == SERIAL_TOS_SERIAL_ACTIVE_MESSAGE_ID)
- {
- tmsg_t *msg = new_tmsg(packet + 1, len - 1);
-
- if (!msg)
- exit(0);
-
- printf("dest %u, src %u, length %u, group %u, type %u\n ",
- spacket_header_dest_get(msg),
- spacket_header_src_get(msg),
- spacket_header_length_get(msg),
- spacket_header_group_get(msg),
- spacket_header_type_get(msg));
- hexprint((uint8_t *)tmsg_data(msg) + spacket_data_offset(0),
- tmsg_length(msg) - spacket_data_offset(0));
-
- free(msg);
- }
- else
- {
- printf("non-AM packet: ");
- hexprint(packet, len);
- }
- putchar('\n');
- fflush(stdout);
- free((void *)packet);
- }
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "serialsource.h"
-
-static char *msgs[] = {
- "unknown_packet_type",
- "ack_timeout" ,
- "sync" ,
- "too_long" ,
- "too_short" ,
- "bad_sync" ,
- "bad_crc" ,
- "closed" ,
- "no_memory" ,
- "unix_error"
-};
-
-void stderr_msg(serial_source_msg problem)
-{
- fprintf(stderr, "Note: %s\n", msgs[problem]);
-}
-
-int main(int argc, char **argv)
-{
- serial_source src;
-
- if (argc != 3)
- {
- fprintf(stderr, "Usage: %s <device> <rate> - dump packets from a serial port\n", argv[0]);
- exit(2);
- }
- src = open_serial_source(argv[1], platform_baud_rate(argv[2]), 0, stderr_msg);
- if (!src)
- {
- fprintf(stderr, "Couldn't open serial port at %s:%s\n",
- argv[1], argv[2]);
- exit(1);
- }
- for (;;)
- {
- int len, i;
- const unsigned char *packet = read_serial_packet(src, &len);
-
- if (!packet)
- exit(0);
- for (i = 0; i < len; i++)
- printf("%02x ", packet[i]);
- putchar('\n');
- free((void *)packet);
- }
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "serialsource.h"
-
-static char *msgs[] = {
- "unknown_packet_type",
- "ack_timeout" ,
- "sync" ,
- "too_long" ,
- "too_short" ,
- "bad_sync" ,
- "bad_crc" ,
- "closed" ,
- "no_memory" ,
- "unix_error"
-};
-
-void stderr_msg(serial_source_msg problem)
-{
- fprintf(stderr, "Note: %s\n", msgs[problem]);
-}
-
-void send_packet(serial_source src, char **bytes, int count)
-{
- int i;
- unsigned char *packet;
-
- packet = malloc(count);
- if (!packet)
- exit(2);
-
- for (i = 0; i < count; i++)
- packet[i] = strtol(bytes[i], NULL, 0);
-
- fprintf(stderr,"Sending ");
- for (i = 0; i < count; i++)
- fprintf(stderr, " %02x", packet[i]);
- fprintf(stderr, "\n");
-
- if (write_serial_packet(src, packet, count) == 0)
- printf("ack\n");
- else
- printf("noack\n");
-}
-
-int main(int argc, char **argv)
-{
- serial_source src;
-
- if (argc < 3)
- {
- fprintf(stderr, "Usage: %s <device> <rate> <bytes> - send a raw packet to a serial port\n", argv[0]);
- exit(2);
- }
- src = open_serial_source(argv[1], platform_baud_rate(argv[2]), 0, stderr_msg);
- if (!src)
- {
- fprintf(stderr, "Couldn't open serial port at %s:%s\n",
- argv[1], argv[2]);
- exit(1);
- }
-
- send_packet(src, argv + 3, argc - 3);
-}
+++ /dev/null
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <termios.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/time.h>
-#include <stdio.h>
-#ifdef __CYGWIN__
-#include <windows.h>
-#include <io.h>
-#else
-#include <stdint.h>
-#endif
-
-/* C implementation of the mote serial protocol. See
- net.tinyos.packet.Packetizer for more details */
-
-#undef DEBUG
-
-#include "serialsource.h"
-#include "serialprotocol.h"
-
-typedef int bool;
-
-enum {
-#ifndef __CYGWIN__
- FALSE = 0,
- TRUE = 1,
-#endif
- BUFSIZE = 256,
- MTU = 256,
- ACK_TIMEOUT = 1000000, /* in us */
- SYNC_BYTE = SERIAL_HDLC_FLAG_BYTE,
- ESCAPE_BYTE = SERIAL_HDLC_CTLESC_BYTE,
-
- P_ACK = SERIAL_SERIAL_PROTO_ACK,
- P_PACKET_ACK = SERIAL_SERIAL_PROTO_PACKET_ACK,
- P_PACKET_NO_ACK = SERIAL_SERIAL_PROTO_PACKET_NOACK,
- P_UNKNOWN = SERIAL_SERIAL_PROTO_PACKET_UNKNOWN
-};
-
-struct packet_list
-{
- uint8_t *packet;
- int len;
- struct packet_list *next;
-};
-
-struct serial_source {
- int fd;
- bool non_blocking;
- void (*message)(serial_source_msg problem);
-
- /* Receive state */
- struct {
- uint8_t buffer[BUFSIZE];
- int bufpos, bufused;
- uint8_t packet[MTU];
- bool in_sync, escaped;
- int count;
- struct packet_list *queue[256]; // indexed by protocol
- } recv;
- struct {
- uint8_t seqno;
- uint8_t *escaped;
- int escapeptr;
- uint16_t crc;
- } send;
-};
-
-static tcflag_t parse_baudrate(int requested)
-{
- int baudrate;
-
- switch (requested)
- {
-#ifdef B50
- case 50: baudrate = B50; break;
-#endif
-#ifdef B75
- case 75: baudrate = B75; break;
-#endif
-#ifdef B110
- case 110: baudrate = B110; break;
-#endif
-#ifdef B134
- case 134: baudrate = B134; break;
-#endif
-#ifdef B150
- case 150: baudrate = B150; break;
-#endif
-#ifdef B200
- case 200: baudrate = B200; break;
-#endif
-#ifdef B300
- case 300: baudrate = B300; break;
-#endif
-#ifdef B600
- case 600: baudrate = B600; break;
-#endif
-#ifdef B1200
- case 1200: baudrate = B1200; break;
-#endif
-#ifdef B1800
- case 1800: baudrate = B1800; break;
-#endif
-#ifdef B2400
- case 2400: baudrate = B2400; break;
-#endif
-#ifdef B4800
- case 4800: baudrate = B4800; break;
-#endif
-#ifdef B9600
- case 9600: baudrate = B9600; break;
-#endif
-#ifdef B19200
- case 19200: baudrate = B19200; break;
-#endif
-#ifdef B38400
- case 38400: baudrate = B38400; break;
-#endif
-#ifdef B57600
- case 57600: baudrate = B57600; break;
-#endif
-#ifdef B115200
- case 115200: baudrate = B115200; break;
-#endif
-#ifdef B230400
- case 230400: baudrate = B230400; break;
-#endif
-#ifdef B460800
- case 460800: baudrate = B460800; break;
-#endif
-#ifdef B500000
- case 500000: baudrate = B500000; break;
-#endif
-#ifdef B576000
- case 576000: baudrate = B576000; break;
-#endif
-#ifdef B921600
- case 921600: baudrate = B921600; break;
-#endif
-#ifdef B1000000
- case 1000000: baudrate = B1000000; break;
-#endif
-#ifdef B1152000
- case 1152000: baudrate = B1152000; break;
-#endif
-#ifdef B1500000
- case 1500000: baudrate = B1500000; break;
-#endif
-#ifdef B2000000
- case 2000000: baudrate = B2000000; break;
-#endif
-#ifdef B2500000
- case 2500000: baudrate = B2500000; break;
-#endif
-#ifdef B3000000
- case 3000000: baudrate = B3000000; break;
-#endif
-#ifdef B3500000
- case 3500000: baudrate = B3500000; break;
-#endif
-#ifdef B4000000
- case 4000000: baudrate = B4000000; break;
-#endif
- default:
- baudrate = 0;
- }
- return baudrate;
-}
-
-#ifdef DEBUG
-static void dump(const char *msg, unsigned char *packet, int len)
-{
- int i;
-
- printf("%s", msg);
- for (i = 0; i < len; i++)
- printf(" %02x", packet[i]);
- putchar('\n');
-}
-#endif
-
-static void message(serial_source src, serial_source_msg msg)
-{
- if (src->message)
- src->message(msg);
-}
-
-static int serial_read(serial_source src, int non_blocking, void *buffer, int n)
-{
- fd_set fds;
- int cnt;
-
- if (non_blocking)
- {
- cnt = read(src->fd, buffer, n);
-
- /* Work around buggy usb serial driver (returns 0 when no data
- is available). Mac OS X seems to like to do this too (at
- least with a Keyspan 49WG).
- */
- if (cnt == 0)
- {
- cnt = -1;
- errno = EAGAIN;
- }
- return cnt;
- }
- else
- for (;;)
- {
- FD_ZERO(&fds);
- FD_SET(src->fd, &fds);
- cnt = select(src->fd + 1, &fds, NULL, NULL, NULL);
- if (cnt < 0)
- return -1;
-
- cnt = read(src->fd, buffer, n);
- if (cnt != 0)
- return cnt;
- }
-}
-
-serial_source open_serial_source(const char *device, int baud_rate,
- int non_blocking,
- void (*message)(serial_source_msg problem))
-/* Effects: opens serial port device at specified baud_rate. If non_blocking
- is true, read_serial_packet calls will be non-blocking (writes are
- always blocking, for now at least)
- Returns: descriptor for serial forwarder at host:port, or
- NULL for failure (bad device or bad baud rate)
- */
-{
- struct termios newtio;
- int fd;
- tcflag_t baudflag = parse_baudrate(baud_rate);
-
- if (!baudflag)
- return NULL;
-
- fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
- if (fd < 0)
- return NULL;
-
-#ifdef __CYGWIN__
- /* For some very mysterious reason, this incantation is necessary to make
- the serial port work under some windows machines */
- HANDLE handle = (HANDLE)get_osfhandle(fd);
- DCB dcb;
- if (!(GetCommState(handle, &dcb) && SetCommState(handle, &dcb)))
- {
- close(fd);
- return NULL;
- }
-#endif
- /* Serial port setting */
- memset(&newtio, 0, sizeof(newtio));
- newtio.c_cflag = CS8 | CLOCAL | CREAD;
- newtio.c_iflag = IGNPAR | IGNBRK;
- cfsetispeed(&newtio, baudflag);
- cfsetospeed(&newtio, baudflag);
-
- /* Raw output_file */
- newtio.c_oflag = 0;
-
- if (tcflush(fd, TCIFLUSH) >= 0 &&
- tcsetattr(fd, TCSANOW, &newtio) >= 0)
- {
- serial_source src = malloc(sizeof *src);
-
- if (src)
- {
- memset(src, 0, sizeof *src);
- src->fd = fd;
- src->non_blocking = non_blocking;
- src->message = message;
- src->send.seqno = 37;
-
- return src;
- }
- }
- close(fd);
-
- return NULL;
-}
-
-int serial_source_fd(serial_source src)
-/* Returns: the file descriptor used by serial source src (useful when
- non-blocking reads were requested)
-*/
-{
- return src->fd;
-}
-
-int close_serial_source(serial_source src)
-/* Effects: closes serial source src
- Returns: 0 if successful, -1 if some problem occured (but source is
- considered closed anyway)
- */
-{
- int ok = close(src->fd);
-
- free(src);
-
- return ok;
-}
-
-static int source_wait(serial_source src, struct timeval *deadline)
-/* Effects: waits until deadline for some data on source. deadline
- can be NULL for indefinite waiting.
- Returns: 0 if data is available, -1 if the deadline expires
-*/
-{
- struct timeval tv;
- fd_set fds;
- int cnt;
-
- if (src->recv.bufpos < src->recv.bufused)
- return 0;
-
- for (;;)
- {
- if (deadline)
- {
- gettimeofday(&tv, NULL);
- tv.tv_sec = deadline->tv_sec - tv.tv_sec;
- tv.tv_usec = deadline->tv_usec - tv.tv_usec;
- if (tv.tv_usec < 0)
- {
- tv.tv_usec += 1000000;
- tv.tv_sec--;
- }
- if (tv.tv_sec < 0)
- return -1;
- }
-
- FD_ZERO(&fds);
- FD_SET(src->fd, &fds);
- cnt = select(src->fd + 1, &fds, NULL, NULL, deadline ? &tv : NULL);
- if (cnt < 0)
- {
- if (errno == EINTR)
- continue;
- message(src, msg_unix_error);
- return -1;
- }
- if (cnt == 0)
- return -1;
- return 0;
- }
-}
-
-static int source_write(serial_source src, const void *buffer, int count)
-{
- int actual = 0;
-
- if (fcntl(src->fd, F_SETFL, 0) < 0)
- {
- message(src, msg_unix_error);
- return -1;
- }
- while (count > 0)
- {
- int n = write(src->fd, buffer, count);
-
- if (n < 0 && errno == EINTR)
- continue;
- if (n < 0)
- {
- message(src, msg_unix_error);
- actual = -1;
- break;
- }
-
- count -= n;
- actual += n;
- buffer += n;
- }
- if (fcntl(src->fd, F_SETFL, O_NONBLOCK) < 0)
- {
- message(src, msg_unix_error);
- /* We're in trouble, but there's no obvious fix. */
- }
- return actual;
-}
-
-static void push_protocol_packet(serial_source src,
- uint8_t type, uint8_t *packet, uint8_t len)
-{
- /* I'm assuming short queues */
- struct packet_list *entry = malloc(sizeof *entry), **last;
-
- if (!entry)
- {
- message(src, msg_no_memory);
- free(packet);
- return;
- }
-
- entry->packet = packet;
- entry->len = len;
- entry->next = NULL;
-
- last = &src->recv.queue[type];
- while (*last)
- last = &(*last)->next;
- *last = entry;
-}
-
-static struct packet_list *pop_protocol_packet(serial_source src, uint8_t type)
-{
- struct packet_list *entry = src->recv.queue[type];
-
- if (entry)
- src->recv.queue[type] = entry->next;
-
- return entry;
-}
-
-static bool packet_available(serial_source src, uint8_t type)
-{
- return src->recv.queue[type] != NULL;
-}
-
-int serial_source_empty(serial_source src)
-/* Returns: true if serial source does not contain any pending data, i.e.,
- if the result is true and there is no data available on the source's
- file descriptor, then read_serial_packet will:
- - return NULL if the source is non-blocking
- - block if it is blocking
-
- (Note: the presence of this calls allows the serial_source to do some
- internal buffering)
-*/
-{
- return src->recv.bufpos >= src->recv.bufused &&
- !packet_available(src, P_PACKET_NO_ACK);
-}
-
-/* Slow implementation of crc function */
-static uint16_t crc_byte(uint16_t crc, uint8_t b)
-{
- uint8_t i;
-
- crc = crc ^ b << 8;
- i = 8;
- do
- if (crc & 0x8000)
- crc = crc << 1 ^ 0x1021;
- else
- crc = crc << 1;
- while (--i);
-
- return crc;
-}
-
-static uint16_t crc_packet(uint8_t *data, int len)
-{
- uint16_t crc = 0;
-
- while (len-- > 0)
- crc = crc_byte(crc, *data++);
-
- return crc;
-}
-
-static int read_byte(serial_source src, int non_blocking)
-/* Returns: next byte (>= 0), or -1 if no data available and non-blocking is true.
-*/
-{
- if (src->recv.bufpos >= src->recv.bufused)
- {
- for (;;)
- {
- int n = serial_read(src, non_blocking, src->recv.buffer, sizeof src->recv.buffer);
-
- if (n == 0) /* Can't occur because of serial_read bug workaround */
- {
- message(src, msg_closed);
- return -1;
- }
- if (n > 0)
- {
-#ifdef DEBUG
- dump("raw", src->recv.buffer, n);
-#endif
- src->recv.bufpos = 0;
- src->recv.bufused = n;
- break;
- }
- if (errno == EAGAIN)
- return -1;
- if (errno != EINTR)
- message(src, msg_unix_error);
- }
- }
- //printf("in %02x\n", src->recv.buffer[src->recv.bufpos]);
- return src->recv.buffer[src->recv.bufpos++];
-}
-
-static void process_packet(serial_source src, uint8_t *packet, int len);
-static int write_framed_packet(serial_source src,
- uint8_t packet_type, uint8_t first_byte,
- const uint8_t *packet, int count);
-
-static void read_and_process(serial_source src, int non_blocking)
-/* Effects: reads and processes up to one packet.
-*/
-{
- uint8_t *packet = src->recv.packet;
-
- for (;;)
- {
- int byte = read_byte(src, non_blocking);
-
- if (byte < 0)
- return;
-
- if (!src->recv.in_sync)
- {
- if (byte == SYNC_BYTE)
- {
- src->recv.in_sync = TRUE;
- message(src, msg_sync);
- src->recv.count = 0;
- src->recv.escaped = FALSE;
- }
- continue;
- }
- if (src->recv.count >= MTU)
- {
- message(src, msg_too_long);
- src->recv.in_sync = FALSE;
- continue;
- }
- if (src->recv.escaped)
- {
- if (byte == SYNC_BYTE)
- {
- /* sync byte following escape is an error, resync */
- message(src, msg_bad_sync);
- src->recv.in_sync = FALSE;
- continue;
- }
- byte ^= 0x20;
- src->recv.escaped = FALSE;
- }
- else if (byte == ESCAPE_BYTE)
- {
- src->recv.escaped = TRUE;
- continue;
- }
- else if (byte == SYNC_BYTE)
- {
- int count = src->recv.count;
- uint8_t *received;
- uint16_t read_crc, computed_crc;
-
- src->recv.count = 0; /* ready for next packet */
-
- if (count < 4)
- /* frames that are too small are ignored */
- continue;
-
- received = malloc(count - 2);
- if (!received)
- {
- message(src, msg_no_memory);
- continue;
- }
- memcpy(received, packet, count - 2);
-
- read_crc = packet[count - 2] | packet[count - 1] << 8;
- computed_crc = crc_packet(received, count - 2);
-
-#ifdef DEBUG
- dump("received", packet, count);
- printf(" crc %x comp %x\n", read_crc, computed_crc);
-#endif
- if (read_crc == computed_crc)
- {
- process_packet(src, received, count - 2);
- return; /* give rest of world chance to do something */
- }
- else
- {
- message(src, msg_bad_crc);
- free(received);
- /* We don't lose sync here. If we did, garbage on the line
- at startup will cause loss of the first packet. */
- continue;
- }
- }
- packet[src->recv.count++] = byte;
- }
-}
-
-static void process_packet(serial_source src, uint8_t *packet, int len)
-{
- int packet_type = packet[0], offset = 1;
-
- if (packet_type == P_PACKET_ACK)
- {
- /* send ack */
- write_framed_packet(src, P_ACK, packet[1], NULL, 0);
- /* And merge with un-acked packets */
- packet_type = P_PACKET_NO_ACK;
- offset = 2;
- }
- /* packet must remain a valid pointer to pass to free. So we move the
- data rather than pass an internal pointer */
- memmove(packet, packet + offset, len - offset);
- push_protocol_packet(src, packet_type, packet, len - offset);
-}
-
-void *read_serial_packet(serial_source src, int *len)
-/* Effects: Read the serial source src. If a packet is available, return it.
- If in blocking mode and no packet is available, wait for one.
- Returns: the packet read (in newly allocated memory), with *len is
- set to the packet length, or NULL if no packet is yet available and
- the serial source is in non-blocking mode
-*/
-{
- read_and_process(src, TRUE);
- for (;;)
- {
- struct packet_list *entry;
-
- entry = pop_protocol_packet(src, P_PACKET_NO_ACK);
- if (entry)
- {
- uint8_t *packet = entry->packet;
-
- *len = entry->len;
- free(entry);
-
- return packet;
- }
- if (src->non_blocking && serial_source_empty(src))
- return NULL;
- source_wait(src, NULL);
- read_and_process(src, src->non_blocking);
- }
-}
-
-/* The escaper does the sync bytes+escape-like encoding+crc of packets */
-
-static void escape_add(serial_source src, uint8_t b)
-{
- src->send.escaped[src->send.escapeptr++] = b;
-}
-
-static int init_escaper(serial_source src, int count)
-{
- src->send.escaped = malloc(count * 2 + 2);
- if (!src->send.escaped)
- {
- message(src, msg_no_memory);
- return -1;
- }
- src->send.escapeptr = 0;
- src->send.crc = 0;
-
- escape_add(src, SYNC_BYTE);
-
- return 0;
-}
-
-static void terminate_escaper(serial_source src)
-{
- escape_add(src, SYNC_BYTE);
-}
-
-static void escape_byte(serial_source src, uint8_t b)
-{
- src->send.crc = crc_byte(src->send.crc, b);
- if (b == SYNC_BYTE || b == ESCAPE_BYTE)
- {
- escape_add(src, ESCAPE_BYTE);
- escape_add(src, b ^ 0x20);
- }
- else
- escape_add(src, b);
-}
-
-static void free_escaper(serial_source src)
-{
- free(src->send.escaped);
-}
-
-// Write a packet of type 'packetType', first byte 'firstByte'
-// and bytes 2..'count'+1 in 'packet'
-static int write_framed_packet(serial_source src,
- uint8_t packet_type, uint8_t first_byte,
- const uint8_t *packet, int count)
-{
- int i, crc;
-
-#ifdef DEBUG
- printf("writing %02x %02x", packet_type, first_byte);
- dump("", packet, count);
-#endif
-
- if (init_escaper(src, count + 4) < 0)
- return -1;
-
- escape_byte(src, packet_type);
- escape_byte(src, first_byte);
- for (i = 0; i < count; i++)
- escape_byte(src, packet[i]);
-
- crc = src->send.crc;
- escape_byte(src, crc & 0xff);
- escape_byte(src, crc >> 8);
-
- terminate_escaper(src);
-
-#ifdef DEBUG
- dump("encoded", src->send.escaped, src->send.escapeptr);
-#endif
-
- if (source_write(src, src->send.escaped, src->send.escapeptr) < 0)
- {
- free_escaper(src);
- return -1;
- }
- free_escaper(src);
- return 0;
-}
-
-static void add_timeval(struct timeval *tv, long us)
-/* Specialised for this app */
-{
- tv->tv_sec += us / 1000000;
- tv->tv_usec += us % 1000000;
- if (tv->tv_usec > 1000000)
- {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
- }
-}
-
-int write_serial_packet(serial_source src, const void *packet, int len)
-/* Effects: writes len byte packet to serial source src
- Returns: 0 if packet successfully written, 1 if successfully written
- but not acknowledged, -1 otherwise
-*/
-{
- struct timeval deadline;
-
- src->send.seqno++;
- if (write_framed_packet(src, P_PACKET_ACK, src->send.seqno, packet, len) < 0)
- return -1;
-
- gettimeofday(&deadline, NULL);
- add_timeval(&deadline, ACK_TIMEOUT);
- for (;;)
- {
- struct packet_list *entry;
-
- read_and_process(src, TRUE);
- entry = pop_protocol_packet(src, P_ACK);
- if (entry)
- {
- uint8_t acked = entry->packet[0];
-
- free(entry->packet);
- free(entry);
- if (acked == src->send.seqno)
- return 0;
- }
- else if (source_wait(src, &deadline) < 0)
- return 1;
- }
-}
-
-/* This somewhat convoluted code allows us to use a common baudrate table
- with the Java code. This could be improved if we generated the Java
- code from a common table.
-*/
-
-struct pargs {
- char *name;
- int rate;
-};
-
-static void padd(struct pargs *args, const char *name, int baudrate)
-{
- if (!strcmp(args->name, name))
- args->rate = baudrate;
-}
-
-static void init(void) { }
-
-int platform_baud_rate(char *platform_name)
-/* Returns: The baud rate of the specified platform, or -1 for unknown
- platforms
-*/
-{
- /* The Java code looks like Platform.add(Platform.x, "name", baudrate);
- Fake up some C stuff which will make that work right. */
- struct pargs args;
- struct {
- void (*add)(struct pargs *args, const char *name, int baudrate);
- struct pargs *x;
- } Platform = { padd, &args };
- static struct {
- struct {
- int packet;
- } tinyos;
- } net;
-
- if (isdigit(platform_name[0]))
- return atoi(platform_name);
-
- args.name = platform_name;
- args.rate = -1;
-
-#define class
-#define BaudRate
-#define static
-#define void
-#define throws ;
-#define Exception
-#define package
-#include "../java/net/tinyos/packet/BaudRate.java"
-
- return args.rate;
-}
+++ /dev/null
-#ifndef SERIALSOURCE_H
-#define SERIALSOURCE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct serial_source *serial_source;
-
-typedef enum {
- msg_unknown_packet_type, /* packet of unknown type received */
- msg_ack_timeout, /* ack not received within timeout */
- msg_sync, /* sync achieved */
- msg_too_long, /* greater than MTU (256 bytes) */
- msg_too_short, /* less than 4 bytes */
- msg_bad_sync, /* unexpected sync byte received */
- msg_bad_crc, /* received packet has bad crc */
- msg_closed, /* serial port closed itself */
- msg_no_memory, /* malloc failed */
- msg_unix_error /* check errno for details */
-} serial_source_msg;
-
-serial_source open_serial_source(const char *device, int baud_rate,
- int non_blocking,
- void (*message)(serial_source_msg problem));
-/* Effects: opens serial port device at specified baud_rate. If non_blocking
- is true, read_serial_packet calls will be non-blocking (writes are
- always blocking, for now at least)
- If non-null, message will be called to signal various problems during
- execution.
- Returns: descriptor for serial forwarder at host:port, or
- NULL for failure
- */
-
-int serial_source_fd(serial_source src);
-/* Returns: the file descriptor used by serial source src (useful when
- non-blocking reads were requested)
-*/
-
-int serial_source_empty(serial_source src);
-/* Returns: true if serial source does not contain any pending data, i.e.,
- if the result is true and there is no data available on the source's
- file descriptor, then read_serial_packet will:
- - return NULL if the source is non-blocking
- - block if it is blocking
-
- (Note: the presence of this calls allows the serial_source to do some
- internal buffering)
-*/
-
-int close_serial_source(serial_source src);
-/* Effects: closes serial source src
- Returns: 0 if successful, -1 if some problem occured (but source is
- considered closed anyway)
- */
-
-void *read_serial_packet(serial_source src, int *len);
-/* Effects: Read the serial source src. If a packet is available, return it.
- If in blocking mode and no packet is available, wait for one.
- Returns: the packet read (in newly allocated memory), with *len is
- set to the packet length, or NULL if no packet is yet available and
- the serial source is in non-blocking mode
-*/
-
-int write_serial_packet(serial_source src, const void *packet, int len);
-/* Effects: writes len byte packet to serial source src
- Returns: 0 if packet successfully written, 1 if successfully written
- but not acknowledged, -1 otherwise
-*/
-
-int platform_baud_rate(char *platform_name);
-/* Returns: The baud rate of the specified platform, or -1 for unknown
- platforms. If platform_name starts with a digit, just return
- atoi(platform_name).
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "sfsource.h"
-#include "serialsource.h"
-
-serial_source src;
-int server_socket;
-int packets_read, packets_written, num_clients;
-
-struct client_list
-{
- struct client_list *next;
- int fd;
-} *clients;
-
-int unix_check(const char *msg, int result)
-{
- if (result < 0)
- {
- perror(msg);
- exit(2);
- }
-
- return result;
-}
-
-void *xmalloc(size_t s)
-{
- void *p = malloc(s);
-
- if (!p)
- {
- fprintf(stderr, "out of memory\n");
- exit(2);
- }
- return p;
-}
-
-void fd_wait(fd_set *fds, int *maxfd, int fd)
-{
- if (fd > *maxfd)
- *maxfd = fd;
- FD_SET(fd, fds);
-}
-
-void pstatus(void)
-{
- printf("clients %d, read %d, wrote %d\n", num_clients, packets_read,
- packets_written);
-}
-
-void forward_packet(const void *packet, int len);
-
-
-void add_client(int fd)
-{
- struct client_list *c = xmalloc(sizeof *c);
-
- c->next = clients;
- clients = c;
- num_clients++;
- pstatus();
-
- c->fd = fd;
-}
-
-void rem_client(struct client_list **c)
-{
- struct client_list *dead = *c;
-
- *c = dead->next;
- num_clients--;
- pstatus();
- close(dead->fd);
- free(dead);
-}
-
-void new_client(int fd)
-{
- fcntl(fd, F_SETFL, 0);
- if (init_sf_source(fd) < 0)
- close(fd);
- else
- add_client(fd);
-}
-
-void check_clients(fd_set *fds)
-{
- struct client_list **c;
-
- for (c = &clients; *c; )
- {
- int next = 1;
-
- if (FD_ISSET((*c)->fd, fds))
- {
- int len;
- const void *packet = read_sf_packet((*c)->fd, &len);
-
- if (packet)
- {
- forward_packet(packet, len);
- free((void *)packet);
- }
- else
- {
- rem_client(c);
- next = 0;
- }
- }
- if (next)
- c = &(*c)->next;
- }
-}
-
-void wait_clients(fd_set *fds, int *maxfd)
-{
- struct client_list *c;
-
- for (c = clients; c; c = c->next)
- fd_wait(fds, maxfd, c->fd);
-}
-
-void dispatch_packet(const void *packet, int len)
-{
- struct client_list **c;
-
- for (c = &clients; *c; )
- if (write_sf_packet((*c)->fd, packet, len) >= 0)
- c = &(*c)->next;
- else
- rem_client(c);
-}
-
-void open_server_socket(int port)
-{
- struct sockaddr_in me;
- int opt;
-
- server_socket = unix_check("socket", socket(AF_INET, SOCK_STREAM, 0));
- unix_check("socket", fcntl(server_socket, F_SETFL, O_NONBLOCK));
- memset(&me, 0, sizeof me);
- me.sin_family = AF_INET;
- me.sin_port = htons(port);
-
- opt = 1;
- unix_check("setsockopt", setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,
- (char *)&opt, sizeof(opt)));
-
- unix_check("bind", bind(server_socket, (struct sockaddr *)&me, sizeof me));
- unix_check("listen", listen(server_socket, 5));
-}
-
-void check_new_client(void)
-{
- int clientfd = accept(server_socket, NULL, NULL);
-
- if (clientfd >= 0)
- new_client(clientfd);
-}
-
-
-
-
-
-void stderr_msg(serial_source_msg problem)
-{
- static char *msgs[] = {
- "unknown_packet_type",
- "ack_timeout" ,
- "sync" ,
- "too_long" ,
- "too_short" ,
- "bad_sync" ,
- "bad_crc" ,
- "closed" ,
- "no_memory" ,
- "unix_error"
- };
-
- fprintf(stderr, "Note: %s\n", msgs[problem]);
-}
-
-void open_serial(const char *dev, int baud)
-{
- char ldev[80];
-#ifdef __CYGWIN__
- int portnum;
- if (strncasecmp(dev, "COM", 3) == 0)
- {
- fprintf(stderr, "Warning: you're attempting to open a Windows rather that a Cygwin device. Retrying with ");
- portnum=atoi(dev+3);
- sprintf(ldev, "/dev/ttyS%d",portnum-1);
- fprintf(stderr,ldev);
- fprintf(stderr, "\n");
- }
- else
-#endif
- strcpy(ldev, dev);
-
- src = open_serial_source(ldev, baud, 1, stderr_msg);
- if (!src)
- {
- fprintf(stderr, "Couldn't open serial port at %s:%d\n", dev, baud);
- exit(1);
- }
-}
-
-void check_serial(void)
-{
- int len;
- const unsigned char *packet = read_serial_packet(src, &len);
-
- if (packet)
- {
- packets_read++;
- dispatch_packet(packet, len);
- free((void *)packet);
- }
-}
-
-void forward_packet(const void *packet, int len)
-{
- int ok = write_serial_packet(src, packet, len);
-
- packets_written++;
- if (ok < 0)
- exit(2);
- if (ok > 0)
- fprintf(stderr, "Note: write failed\n");
-}
-
-int main(int argc, char **argv)
-{
- int serfd;
-
- if (argc != 4)
- {
- fprintf(stderr,
- "Usage: %s <port> <device> <rate> - act as a serial forwarder on <port>\n"
- "(listens to serial port <device> at baud rate <rate>)\n" ,
- argv[0]);
- exit(2);
- }
-
- if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
- fprintf(stderr, "Warning: failed to ignore SIGPIPE.\n");
-
- open_serial(argv[2], platform_baud_rate(argv[3]));
- serfd = serial_source_fd(src);
- open_server_socket(atoi(argv[1]));
-
- for (;;)
- {
- fd_set rfds;
- int maxfd = -1;
- struct timeval zero;
- int serial_empty;
- int ret;
-
- zero.tv_sec = zero.tv_usec = 0;
-
- FD_ZERO(&rfds);
- fd_wait(&rfds, &maxfd, serfd);
- fd_wait(&rfds, &maxfd, server_socket);
- wait_clients(&rfds, &maxfd);
-
- serial_empty = serial_source_empty(src);
- if (serial_empty)
- ret = select(maxfd + 1, &rfds, NULL, NULL, NULL);
- else
- {
- ret = select(maxfd + 1, &rfds, NULL, NULL, &zero);
- check_serial();
- }
- if (ret >= 0)
- {
- if (FD_ISSET(serfd, &rfds))
- check_serial();
-
- if (FD_ISSET(server_socket, &rfds))
- check_new_client();
-
- check_clients(&rfds);
- }
- }
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "sfsource.h"
-
-int main(int argc, char **argv)
-{
- int fd;
-
- if (argc != 3)
- {
- fprintf(stderr, "Usage: %s <host> <port> - dump packets from a serial forwarder\n", argv[0]);
- exit(2);
- }
- fd = open_sf_source(argv[1], atoi(argv[2]));
- if (fd < 0)
- {
- fprintf(stderr, "Couldn't open serial forwarder at %s:%s\n",
- argv[1], argv[2]);
- exit(1);
- }
- for (;;)
- {
- int len, i;
- const unsigned char *packet = read_sf_packet(fd, &len);
-
- if (!packet)
- exit(0);
- for (i = 0; i < len; i++)
- printf("%02x ", packet[i]);
- putchar('\n');
- fflush(stdout);
- free((void *)packet);
- }
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "sfsource.h"
-
-void send_packet(int fd, char **bytes, int count)
-{
- int i;
- unsigned char *packet;
-
- packet = malloc(count);
- if (!packet)
- exit(2);
-
- for (i = 0; i < count; i++)
- packet[i] = strtol(bytes[i], NULL, 0);
-
- fprintf(stderr,"Sending ");
- for (i = 0; i < count; i++)
- fprintf(stderr, " %02x", packet[i]);
- fprintf(stderr, "\n");
-
- write_sf_packet(fd, packet, count);
-}
-
-int main(int argc, char **argv)
-{
- int fd;
-
- if (argc < 4)
- {
- fprintf(stderr, "Usage: %s <host> <port> <bytes> - send a raw packet to a serial forwarder\n", argv[0]);
- exit(2);
- }
- fd = open_sf_source(argv[1], atoi(argv[2]));
- if (fd < 0)
- {
- fprintf(stderr, "Couldn't open serial forwarder at %s:%s\n",
- argv[1], argv[2]);
- exit(1);
- }
-
- send_packet(fd, argv + 3, argc - 3);
-
- close(fd);
-}
+++ /dev/null
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sfsource.h"
-
-int saferead(int fd, void *buffer, int count)
-{
- int actual = 0;
-
- while (count > 0)
- {
- int n = read(fd, buffer, count);
-
- if (n == -1 && errno == EINTR)
- continue;
- if (n == -1)
- return -1;
- if (n == 0)
- return actual;
-
- count -= n;
- actual += n;
- buffer = (char*)buffer + n;
- }
- return actual;
-}
-
-int safewrite(int fd, const void *buffer, int count)
-{
- int actual = 0;
-
- while (count > 0)
- {
- int n = write(fd, buffer, count);
-
- if (n == -1 && errno == EINTR)
- continue;
- if (n == -1)
- return -1;
-
- count -= n;
- actual += n;
- buffer = (char*)buffer + n;
- }
- return actual;
-}
-
-int open_sf_source(const char *host, int port)
-/* Returns: file descriptor for serial forwarder at host:port
- */
-{
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- struct hostent *entry;
- struct sockaddr_in addr;
-
- if (fd < 0)
- return fd;
-
- entry = gethostbyname(host);
- if (!entry)
- {
- close(fd);
- return -1;
- }
-
- addr.sin_family = entry->h_addrtype;
- memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
- addr.sin_port = htons(port);
- if (connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0)
- {
- close(fd);
- return -1;
- }
-
- if (init_sf_source(fd) < 0)
- {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-int init_sf_source(int fd)
-/* Effects: Checks that fd is following the TinyOS 2.0 serial forwarder
- protocol. Use this if you obtain your file descriptor from some other
- source than open_sf_source (e.g., you're a server)
- Returns: 0 if it is, -1 otherwise
- */
-{
- char check[2], us[2];
- int version;
-
- /* Indicate version and check if a TinyOS 2.0 serial forwarder on the
- other end */
- us[0] = 'U'; us[1] = ' ';
- if (safewrite(fd, us, 2) != 2 ||
- saferead(fd, check, 2) != 2 ||
- check[0] != 'U')
- return -1;
-
- version = check[1];
- if (us[1] < version)
- version = us[1];
-
- /* Add other cases here for later protocol versions */
- switch (version)
- {
- case ' ': break;
- default: return -1; /* not a valid version */
- }
-
- return 0;
-}
-
-void *read_sf_packet(int fd, int *len)
-/* Effects: reads packet from serial forwarder on file descriptor fd
- Returns: the packet read (in newly allocated memory), and *len is
- set to the packet length, or NULL for failure
-*/
-{
- unsigned char l;
- void *packet;
-
- if (saferead(fd, &l, 1) != 1)
- return NULL;
-
- packet = malloc(l);
- if (!packet)
- return NULL;
-
- if (saferead(fd, packet, l) != l)
- {
- free(packet);
- return NULL;
- }
- *len = l;
-
- return packet;
-}
-
-int write_sf_packet(int fd, const void *packet, int len)
-/* Effects: writes len byte packet to serial forwarder on file descriptor
- fd
- Returns: 0 if packet successfully written, -1 otherwise
-*/
-{
- unsigned char l = len;
-
- if (safewrite(fd, &l, 1) != 1 ||
- safewrite(fd, packet, l) != l)
- return -1;
-
- return 0;
-}
+++ /dev/null
-#ifndef SFSOURCE_H
-#define SFSOURCE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int open_sf_source(const char *host, int port);
-/* Returns: file descriptor for TinyOS 2.0 serial forwarder at host:port, or
- -1 for failure
- */
-
-int init_sf_source(int fd);
-/* Effects: Checks that fd is following the TinyOS 2.0 serial forwarder
- protocol. Use this if you obtain your file descriptor from some other
- source than open_sf_source (e.g., you're a server)
- Returns: 0 if it is, -1 otherwise
- */
-
-void *read_sf_packet(int fd, int *len);
-/* Effects: reads packet from serial forwarder on file descriptor fd
- Returns: the packet read (in newly allocated memory), and *len is
- set to the packet length
-*/
-
-int write_sf_packet(int fd, const void *packet, int len);
-/* Effects: writes len byte packet to serial forwarder on file descriptor
- fd
- Returns: 0 if packet successfully written, -1 otherwise
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif