David Gay wrote:
Sure, send them on.
please find the files attached...
the rest of the C code compiles fine on Visual Studio.
(disclaimer: I'm not a Windows fan by far - I was almost forced to do
this :)
#ifndef SERIALSOURCE_H
#define SERIALSOURCE_H
#ifdef _WIN32
#include <windows.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct serial_source_t *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
*/
#ifndef _WIN32
int serial_source_fd(serial_source src);
/* Returns: the file descriptor used by serial source src (useful when
non-blocking reads were requested)
*/
#endif
#ifdef _WIN32
HANDLE serial_source_handle(serial_source src);
/* Returns: the file descriptor used by serial source src (useful when
non-blocking reads were requested)
*/
#endif
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
#ifndef _WIN32
#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
#endif
#ifdef _WIN32
#include <windows.h>
#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__
#ifndef _WIN32
FALSE = 0,
TRUE = 1,
#endif
#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_t {
#ifndef _WIN32
int fd;
#else
HANDLE hComm;
#endif
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;
};
#ifndef _WIN32
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;
}
#endif
#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)
{
#ifndef _WIN32
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;
}
#else // _WIN32
int cnt;
if (non_blocking) {
ReadFile(src->hComm, buffer, n, &cnt, NULL);
return cnt;
} else {
for (;;) {
DWORD eventMask;
SetCommMask(src->hComm, EV_RXCHAR);
if (!WaitCommEvent(src->hComm, &eventMask, NULL)) {
return -1;
}
ReadFile(src->hComm, buffer, n, &cnt, NULL);
if (cnt != 0) {
return cnt;
}
}
}
#endif
}
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)
*/
{
#ifndef _WIN32
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;
#else // _WIN32
LPCTSTR ComName = (LPCTSTR)device;
HANDLE hComm;
DCB dcb;
serial_source src;
int buflen =
MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,0);
MultiByteToWideChar(CP_ACP,0,(PCSTR)device,-1,(LPWSTR)ComName,buflen);
//syncronize
hComm = CreateFile(ComName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hComm == INVALID_HANDLE_VALUE) {
return NULL;
}
PurgeComm(hComm, PURGE_RXCLEAR);
GetCommState(hComm, &dcb);
dcb.BaudRate = baud_rate;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.fParity = FALSE;
dcb.StopBits = ONESTOPBIT;
if (SetCommState(hComm, &dcb) == 0) {
return NULL;
}
src = malloc(sizeof *src);
if (src) {
memset(src, 0, sizeof *src);
src->hComm = hComm;
src->non_blocking = non_blocking;
src->message = message;
src->send.seqno = 37;
}
return src;
#endif // _WIN32
}
#ifndef _WIN32
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;
}
#endif
#ifdef _WIN32
HANDLE serial_source_handle(serial_source src)
/* Returns: the file descriptor used by serial source src (useful when
non-blocking reads were requested)
*/
{
return src->hComm;
}
#endif
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)
*/
{
#ifndef _WIN32
int ok = close(src->fd);
#else
int ok = CloseHandle(src->hComm);
#endif
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
*/
{
#ifndef _WIN32
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;
}
#else // _WIN32
// FIXME: the deadline is ignored here
DWORD eventMask;
SetCommMask(src->hComm, EV_RXCHAR);
if (!WaitCommEvent(src->hComm, &eventMask, NULL)) {
return -1;
}
return 0;
#endif
}
static int source_write(serial_source src, const void *buffer, int count)
{
#ifndef _WIN32
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;
#else // _WIN32
int actual = 0;
int n;
const unsigned char * b = buffer;
while (count > 0) {
if (!WriteFile(src->hComm, b, count, &n, NULL)) {
message(src, msg_unix_error);
actual = -1;
break;
}
count -= n;
actual += n;
b += n;
}
return actual;
#endif
}
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;
}
#ifndef _WIN32
if (errno == EAGAIN)
return -1;
if (errno != EINTR)
message(src, msg_unix_error);
#endif
}
}
//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;
// FIXME: the WIN32 implementation of source_wait()
// disregards the deadline parameter anyway
#ifndef _WIN32
gettimeofday(&deadline, NULL);
add_timeval(&deadline, ACK_TIMEOUT);
#endif
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
Platform.add(Platform.x, "mica", 19200);
Platform.add(Platform.x, "mica2", 57600);
Platform.add(Platform.x, "mica2dot", 19200);
Platform.add(Platform.x, "telos", 115200);
Platform.add(Platform.x, "telosb", 115200);
Platform.add(Platform.x, "tinynode", 115200);
Platform.add(Platform.x, "tmote", 115200);
Platform.add(Platform.x, "micaz", 57600);
Platform.add(Platform.x, "eyesIFX", 57600);
Platform.add(Platform.x, "intelmote2", 115200);
return args.rate;
}
_______________________________________________
Tinyos-help mailing list
[email protected]
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help