Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Show changes
Showing
with 749 additions and 455 deletions
/*
sample float data;
*/
import java.io.IOException;
import se.lth.control.labcomm.LabCommDecoder;
import se.lth.control.labcomm.LabCommDispatcher;
import se.lth.control.labcomm.LabCommEncoder;
import se.lth.control.labcomm.LabCommHandler;
import se.lth.control.labcomm.LabCommSample;
public class data implements LabCommSample {
public interface Handler extends LabCommHandler {
public void handle_data(float value) throws Exception;
}
public static void register(LabCommDecoder d, Handler h) throws IOException {
d.register(new Dispatcher(), h);
}
public static void register(LabCommEncoder e) throws IOException {
e.register(new Dispatcher());
}
private static class Dispatcher implements LabCommDispatcher {
public Class getSampleClass() {
return data.class;
}
public String getName() {
return "data";
}
public byte[] getSignature() {
return signature;
}
public void decodeAndHandle(LabCommDecoder d,
LabCommHandler h) throws Exception {
((Handler)h).handle_data(data.decode(d));
}
}
public static void encode(LabCommEncoder e, float value) throws IOException {
e.begin(data.class);
e.encodeFloat(value);
e.end(data.class);
}
public static float decode(LabCommDecoder d) throws IOException {
float result;
result = d.decodeFloat();
return result;
}
private static byte[] signature = new byte[] {
0, 0, 0, 37,
};
}
#include "labcomm.h"
#include "labcomm_private.h"
#include "example.h"
static unsigned char signature_bytes_log_message[] = {
// struct { 2 fields
0, 0, 0, 17,
0, 0, 0, 2,
// int 'sequence'
0, 0, 0, 8,
115, 101, 113, 117, 101, 110, 99, 101,
0, 0, 0, 35,
// array [_] 'line'
0, 0, 0, 4,
108, 105, 110, 101,
// array [_]
0, 0, 0, 16,
0, 0, 0, 1,
0, 0, 0, 0,
// struct { 2 fields
0, 0, 0, 17,
0, 0, 0, 2,
// boolean 'last'
0, 0, 0, 4,
108, 97, 115, 116,
0, 0, 0, 32,
// string 'data'
0, 0, 0, 4,
100, 97, 116, 97,
0, 0, 0, 39,
// }
// }
// }
};
labcomm_signature_t labcomm_signature_example_log_message = {
LABCOMM_SAMPLE, "log_message",
(int (*)(void *))labcomm_sizeof_example_log_message,
sizeof(signature_bytes_log_message),
signature_bytes_log_message
};
static unsigned char signature_bytes_data[] = {
0, 0, 0, 37,
};
labcomm_signature_t labcomm_signature_example_data = {
LABCOMM_SAMPLE, "data",
(int (*)(void *))labcomm_sizeof_example_data,
sizeof(signature_bytes_data),
signature_bytes_data
};
static void decode_log_message(
labcomm_decoder_t *d,
void (*handle)(
example_log_message *v,
void *context
),
void *context
)
{
example_log_message v;
v.sequence = labcomm_decode_int(d);
v.line.n_0 = labcomm_decode_int(d);
v.line.a = malloc(sizeof(v.line.a[0]) * v.line.n_0);
{
int i_0_0;
for (i_0_0 = 0 ; i_0_0 < v.line.n_0 ; i_0_0++) {
int i_0 = i_0_0;
v.line.a[i_0].last = labcomm_decode_boolean(d);
v.line.a[i_0].data = labcomm_decode_string(d);
}
}
handle(&v, context);
{
{
int i_0_0;
for (i_0_0 = 0 ; i_0_0 < v.line.n_0 ; i_0_0++) {
int i_0 = i_0_0;
free(v.line.a[i_0].data);
}
}
free(v.line.a);
}
}
void labcomm_decoder_register_example_log_message(
struct labcomm_decoder *d,
void (*handler)(
example_log_message *v,
void *context
),
void *context
)
{
labcomm_internal_decoder_register(
d,
&labcomm_signature_example_log_message,
(labcomm_decoder_typecast_t)decode_log_message,
(labcomm_handler_typecast_t)handler,
context
);
}
static void encode_log_message(
labcomm_encoder_t *e,
example_log_message *v
)
{
e->writer.write(&e->writer, labcomm_writer_start);
labcomm_encode_type_index(e, &labcomm_signature_example_log_message);
{
labcomm_encode_int(e, (*v).sequence);
labcomm_encode_int(e, (*v).line.n_0);
{
int i_0_0;
for (i_0_0 = 0 ; i_0_0 < (*v).line.n_0 ; i_0_0++) {
int i_0 = i_0_0;
labcomm_encode_boolean(e, (*v).line.a[i_0].last);
labcomm_encode_string(e, (*v).line.a[i_0].data);
}
}
}
e->writer.write(&e->writer, labcomm_writer_end);
}
void labcomm_encode_example_log_message(
labcomm_encoder_t *e,
example_log_message *v
)
{
labcomm_internal_encode(e, &labcomm_signature_example_log_message, v);
}
void labcomm_encoder_register_example_log_message(
struct labcomm_encoder *e
)
{
labcomm_internal_encoder_register(
e,
&labcomm_signature_example_log_message,
(labcomm_encode_typecast_t)encode_log_message
);
}
int labcomm_sizeof_example_log_message(example_log_message *v)
{
int result = 4;
{
int i_0_0;
for (i_0_0 = 0 ; i_0_0 < (*v).line.n_0 ; i_0_0++) {
int i_0 = i_0_0;
result += 4 + strlen((*v).line.a[i_0].data);
result += 1;
}
}
result += 4;
return result;
}
static void decode_data(
labcomm_decoder_t *d,
void (*handle)(
example_data *v,
void *context
),
void *context
)
{
example_data v;
v = labcomm_decode_float(d);
handle(&v, context);
}
void labcomm_decoder_register_example_data(
struct labcomm_decoder *d,
void (*handler)(
example_data *v,
void *context
),
void *context
)
{
labcomm_internal_decoder_register(
d,
&labcomm_signature_example_data,
(labcomm_decoder_typecast_t)decode_data,
(labcomm_handler_typecast_t)handler,
context
);
}
static void encode_data(
labcomm_encoder_t *e,
example_data *v
)
{
e->writer.write(&e->writer, labcomm_writer_start);
labcomm_encode_type_index(e, &labcomm_signature_example_data);
{
labcomm_encode_float(e, (*v));
}
e->writer.write(&e->writer, labcomm_writer_end);
}
void labcomm_encode_example_data(
labcomm_encoder_t *e,
example_data *v
)
{
labcomm_internal_encode(e, &labcomm_signature_example_data, v);
}
void labcomm_encoder_register_example_data(
struct labcomm_encoder *e
)
{
labcomm_internal_encoder_register(
e,
&labcomm_signature_example_data,
(labcomm_encode_typecast_t)encode_data
);
}
int labcomm_sizeof_example_data(example_data *v)
{
return 8;
}
File deleted
/* LabComm declarations:
sample struct {
int sequence;
struct {
boolean last;
string data;
} line[_];
} log_message;
sample float data;
*/
#ifndef __LABCOMM_example_H__
#define __LABCOMM_example_H__
#include "labcomm.h"
#ifndef PREDEFINED_example_log_message
typedef struct {
int sequence;
struct {
int n_0;
struct {
unsigned char last;
char* data;
} *a;
} line;
} example_log_message;
#endif
void labcomm_decoder_register_example_log_message(
struct labcomm_decoder *d,
void (*handler)(
example_log_message *v,
void *context
),
void *context
);
void labcomm_encoder_register_example_log_message(
struct labcomm_encoder *e);
void labcomm_encode_example_log_message(
struct labcomm_encoder *e,
example_log_message *v
);
extern int labcomm_sizeof_example_log_message(example_log_message *v);
#ifndef PREDEFINED_example_data
typedef float example_data;
#endif
void labcomm_decoder_register_example_data(
struct labcomm_decoder *d,
void (*handler)(
example_data *v,
void *context
),
void *context
);
void labcomm_encoder_register_example_data(
struct labcomm_encoder *e);
void labcomm_encode_example_data(
struct labcomm_encoder *e,
example_data *v
);
extern int labcomm_sizeof_example_data(example_data *v);
#define LABCOMM_FORALL_SAMPLES_example(func, sep) \
func(log_message, example_log_message) sep \
func(data, example_data)
#endif
#!/usr/bin/python
# Auto generated example
import labcomm
class log_message(object):
signature = labcomm.sample('log_message',
labcomm.struct([
('sequence', labcomm.INTEGER()),
('line', labcomm.array([0],
labcomm.struct([
('last', labcomm.BOOLEAN()),
('data', labcomm.STRING())])))]))
class data(object):
signature = labcomm.sample('data',
labcomm.FLOAT())
#!/usr/bin/python
import labcomm
import labcomm2014
import sys
class FileReader:
def __init__(self, name):
self.f = open(name)
def read(self, count):
s = self.f.read(count)
if len(s) == 0:
raise Exception("EOF")
return s
def mark(self, value, decl):
pass
if __name__ == "__main__":
d = labcomm.Decoder(FileReader(sys.argv[1]))
version = sys.argv[2] if len(sys.argv) == 3 else "LabComm2014"
d = labcomm2014.Decoder(labcomm2014.StreamReader(open(sys.argv[1])), version)
while True:
try:
data,decl = d.decode()
if data:
print data
except:
except Exception, e:
print e
break
......@@ -4,24 +4,24 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import se.lth.control.labcomm.LabCommDecoderChannel;
import se.lth.control.labcomm.LabCommEncoderChannel;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.EncoderChannel;
public class example_decoder_encoder
implements data.Handler, log_message.Handler
{
LabCommDecoderChannel decoder;
LabCommEncoderChannel encoder;
DecoderChannel decoder;
EncoderChannel encoder;
public example_decoder_encoder(InputStream in, OutputStream out)
throws Exception
{
decoder = new LabCommDecoderChannel(in);
decoder = new DecoderChannel(in);
log_message.register(decoder, this);
data.register(decoder, this);
encoder = new LabCommEncoderChannel(out);
encoder = new EncoderChannel(out);
log_message.register(encoder);
data.register(encoder);
......
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <labcomm_fd_reader_writer.h>
#include <labcomm2014.h>
#include <labcomm2014_default_memory.h>
#include <labcomm2014_fd_reader.h>
#include <labcomm2014_fd_writer.h>
#include "example.h"
int main(int argc, char *argv[]) {
int fd;
struct labcomm_encoder *encoder;
struct labcomm2014_encoder *encoder;
struct labcomm2014_writer *labcomm2014_fd_writer;
int i, j;
fd = open("example.encoded", O_WRONLY|O_CREAT|O_TRUNC, 0644);
encoder = labcomm_encoder_new(labcomm_fd_writer, &fd);
labcomm_encoder_register_example_log_message(encoder);
labcomm_encoder_register_example_data(encoder);
labcomm2014_fd_writer = labcomm2014_fd_writer_new(labcomm2014_default_memory, fd, 1);
encoder = labcomm2014_encoder_new(labcomm2014_fd_writer, NULL,
labcomm2014_default_memory, NULL);
labcomm2014_encoder_register_example_log_message(encoder);
labcomm2014_encoder_register_example_data(encoder);
for (i = 0 ; i < argc ; i++) {
example_log_message message;
......@@ -23,11 +29,12 @@ int main(int argc, char *argv[]) {
message.line.a[j].last = (j == message.line.n_0 - 1);
message.line.a[j].data = argv[j + 1];
}
labcomm_encode_example_log_message(encoder, &message);
labcomm2014_encode_example_log_message(encoder, &message);
free(message.line.a);
}
for (i = 0 ; i < argc ; i++) {
float f = i;
labcomm_encode_example_data(encoder, &f);
labcomm2014_encode_example_data(encoder, &f);
}
return 0;
}
#!/bin/sh
# Auto generate code from .lc file
java -jar ../../labComm.jar \
java -jar ../../compiler/labcomm2014_compiler.jar \
--c=example.c --h=example.h \
--java=. \
--cs=example.cs \
--python=example.py \
example.lc
example.lc || exit 1
# Compile executables
gcc -o example_encoder -I ../../lib/c/ \
example_encoder.c \
example.c \
../../lib/c/labcomm.c \
../../lib/c//labcomm_fd_reader_writer.c
javac -cp ../../lib/java:. *.java
(cd ../../lib/c; make all || exit 1)
gcc -Wall -Werror -o example_encoder -I../../lib/c/2014 \
example_encoder.c \
example.c \
../../lib/c/liblabcomm2014.a || exit 1
javac -cp ../../lib/java/labcomm2014.jar:. *.java || exit 1
# Run through all executables (c->java->Python)
./example_encoder one two
java -cp ../../lib/java:. example_decoder_encoder example.encoded example.javaencoded
PYTHONPATH=../../lib/python ./example_decoder.py example.javaencoded
./example_encoder one two || exit 1
java -cp ../../lib/java/labcomm2014.jar:. example_decoder_encoder example.encoded example.javaencoded || exit 1
PYTHONPATH=../../lib/python ./example_decoder.py example.javaencoded || exit 1
*** Java_CodeGen.old 2010-05-31 10:13:44.000000000 +0200
--- Java_CodeGen.jrag 2010-05-31 10:22:55.000000000 +0200
***************
*** 445,450 ****
--- 445,452 ----
String prefix = "";
for (int i = 0 ; i < getNumExp() ; i++) {
String limit = getExp(i).Java_emitEncoder(env, name + prefix);
+ env.println("{");
+ env.indent();
env.println("int i_" + (baseDepth + i) + "_max = " + limit + ";");
prefix = prefix + "[0]";
}
***************
*** 456,461 ****
--- 458,465 ----
for (int i = 0 ; i < getNumExp() ; i++) {
env.print_for_end();
}
+ env.unindent();
+ env.println("}");
}
public String Exp.Java_emitEncoder(Java_env env, String name) {
SUBDIRS=c csharp java python
.PHONY: all
all: $(SUBDIRS:%=make-%)
.PHONY: make-%
make-%:
$(MAKE) -C $*
.PHONY: test
test: $(SUBDIRS:%=test-%)
.PHONY: test-%
test-%:
$(MAKE) -C $* test
.PHONY: clean
clean: $(SUBDIRS:%=clean-%)
.PHONY: clean-%
clean-%:
$(MAKE) -C $* clean
.PHONY: distclean
distclean: clean $(SUBDIRS:%=distclean-%)
.PHONY: distclean-%
distclean-%:
$(MAKE) -C $* distclean
MODULE LabComm(SYSMODULE)
RECORD LabComm_Stream
socketdev soc;
ENDRECORD
RECORD LabComm_Decoder_Sample
string prefix;
string name;
num user_id;
string handler;
ENDRECORD
RECORD LabComm_Encoder_Sample
string prefix;
string name;
num user_id;
ENDRECORD
RECORD Decoder
num user_id;
ENDRECORD
RECORD Encoder
num next_user_id;
ENDRECORD
! LabComm constants
CONST string LabCommVersion := "LabComm2013";
CONST num SAMPLE_DECL:=2;
CONST num SAMPLE_DATA:=64;
CONST num STRUCT_TYPE := 17;
CONST num ARRAY_TYPE := 16;
CONST num BYTE_TYPE := 37;
CONST num BOOL_TYPE := 37;
CONST num SHORT_TYPE := 34;
CONST num INT_TYPE := 37;
CONST num LONG_TYPE := 37;
CONST num FLOAT_TYPE := 37;
! Error declarations
CONST errnum INCORRECT_LABCOMM_VERSION := 50;
CONST errnum UNKNOWN_PACKET_TYPE := 51;
CONST errnum UNKNOWN_SAMPLE_TYPE := 52;
CONST errnum INCORRECT_SAMPLE_SIGNATURE := 53;
CONST errnum SAMPLE_TYPE_NOT_REGISTERED := 54;
CONST errnum IMPLEMENTATION_LIMIT_REACHED := 55;
PROC Decode_Packed(VAR LabComm_Stream s, VAR num v, \ VAR rawbytes collect)
VAR rawbytes buffer;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=1;
UnpackRawBytes buffer,\Network,1,v,\IntX:=USINT;
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Packed(VAR LabComm_Stream s, num v)
VAR rawbytes buffer;
PackRawBytes v,buffer,\Network,1,\IntX:=USINT;
SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=1;
ERROR
RAISE ;
ENDPROC
PROC Decode_Boolean(VAR LabComm_Stream s, VAR bool v, \ VAR rawbytes collect)
VAR rawbytes buffer;
VAR num tmp;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=1;
UnpackRawBytes buffer,\Network,1,tmp,\IntX:=USINT;
IF tmp = 0 THEN
v := FALSE;
ELSE
v := TRUE;
ENDIF
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Boolean(VAR LabComm_Stream s, bool v)
VAR rawbytes buffer;
VAR num tmp;
IF v THEN
tmp := 1;
ELSE
tmp := 0;
ENDIF
PackRawBytes tmp,buffer,\Network,1,\IntX:=USINT;
SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=1;
ERROR
RAISE ;
ENDPROC
PROC Decode_Byte(VAR LabComm_Stream s, VAR byte v, \ VAR rawbytes collect)
VAR rawbytes buffer;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=1;
UnpackRawBytes buffer,\Network,1,v,\Hex1;
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Byte(VAR LabComm_Stream s, byte v)
VAR rawbytes buffer;
PackRawBytes v,buffer,\Network,1,\Hex1;
SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=1;
ERROR
RAISE ;
ENDPROC
PROC Decode_Short(VAR LabComm_Stream s,VAR num v, \ VAR rawbytes collect)
VAR rawbytes buffer;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=2;
UnpackRawBytes buffer,\Network,1,v,\IntX:=INT;
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Short(VAR LabComm_Stream s, num v)
VAR rawbytes buffer;
PackRawBytes v, buffer, \Network, 1, \IntX:=INT;
SocketSend s.soc, \RawData:=buffer, \NoOfBytes:=2;
ERROR
RAISE ;
ENDPROC
PROC Decode_Integer(VAR LabComm_Stream s, VAR num v, \ VAR rawbytes collect)
VAR rawbytes buffer;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=4;
UnpackRawBytes buffer,\Network,1,v,\IntX:=DINT;
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Integer(VAR LabComm_Stream s, num v)
VAR rawbytes buffer;
PackRawBytes v,buffer,\Network,1,\IntX:=DINT;
SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=4;
ERROR
RAISE ;
ENDPROC
PROC Decode_Long(VAR LabComm_Stream s, VAR dnum v, \ VAR rawbytes collect)
VAR rawbytes buffer;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=8;
UnpackRawBytes buffer,\Network,1,v,\IntX:=LINT;
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Long(VAR LabComm_Stream s, dnum v)
VAR rawbytes buffer;
PackRawBytes v,buffer,\Network,1,\IntX:=LINT;
SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=8;
ERROR
RAISE ;
ENDPROC
PROC Decode_Float(VAR LabComm_Stream s,VAR num v, \ VAR rawbytes collect)
VAR rawbytes buffer;
SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=4;
UnpackRawBytes buffer,\Network,1,v,\Float4;
IF Present(collect) THEN
CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_Float(VAR LabComm_Stream s, num v)
VAR rawbytes buffer;
PackRawBytes v, buffer,\Network,1,\Float4;
SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=4;
ERROR
RAISE ;
ENDPROC
PROC Decode_String(VAR LabComm_Stream st,VAR string s, \ VAR rawbytes collect)
VAR rawbytes buffer;
VAR num length;
IF Present(collect) THEN
Decode_Packed st, length, \collect:=collect;
ELSE
Decode_Packed st, length;
ENDIF
SocketReceive st.soc,\Str:=s,\ReadNoOfBytes:=length;
IF Present(collect) THEN
PackRawBytes s, collect, (RawBytesLen(collect)+1), \ASCII;
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Encode_String(VAR LabComm_Stream st, string s)
VAR rawbytes buffer;
VAR num length;
length := StrLen(s);
Encode_Packed st, length;
SocketSend st.soc,\Str:=s,\NoOfBytes:=length;
ERROR
RAISE ;
ENDPROC
PROC Encoder_Register_Sample(VAR Encoder e, VAR LabComm_Stream st, VAR LabComm_Encoder_Sample s)
s.user_id := e.next_user_id;
e.next_user_id := e.next_user_id + 1;
Encode_Packed st, SAMPLE_DECL;
Encode_Packed st, s.user_id;
Encode_String st, s.name;
% s.prefix + ":Encode_Signature_" + s.name % e, st;
ERROR
RAISE ;
ENDPROC
PROC Collect_Array(VAR LabComm_Stream s, VAR rawbytes sig)
VAR num num_dim;
VAR num dims;
Decode_Packed s, num_dim, \collect:=sig;
FOR i FROM 1 TO num_dim DO
Decode_Packed s, dims, \collect:=sig;
ENDFOR
Collect_Signature s, sig;
ERROR
RAISE ;
ENDPROC
PROC Collect_Struct(VAR LabComm_Stream s, VAR rawbytes sig)
VAR num num_elements;
VAR string tmp;
Decode_Packed s, num_elements, \collect:=sig;
FOR i FROM 1 TO num_elements DO
Decode_String s, tmp, \collect:=sig;
Collect_Signature s, sig;
ENDFOR
ERROR
RAISE ;
ENDPROC
PROC Collect_Signature(VAR LabComm_Stream s, VAR rawbytes sig)
VAR num type_id;
Decode_Packed s, type_id, \collect:=sig;
TEST type_id
CASE STRUCT_TYPE:
Collect_Struct s, sig;
CASE ARRAY_TYPE:
Collect_Array s, sig;
CASE BYTE_TYPE, BOOL_TYPE, SHORT_TYPE, INT_TYPE, LONG_TYPE, SHORT_TYPE:
DEFAULT:
RAISE IMPLEMENTATION_LIMIT_REACHED;
ENDTEST
ERROR
RAISE ;
ENDPROC
PROC Decode_One(VAR Decoder d, VAR LabComm_Stream s, VAR LabComm_Decoder_Sample samples{*})
VAR rawbytes buffer;
VAR num packet_type;
VAR num user_id;
VAR string type_name;
Decode_Packed s, packet_type;
WHILE packet_type = SAMPLE_DECL DO
Decode_Packed s, user_id;
Decode_String s, type_name;
Collect_Signature s, buffer;
FOR i FROM 1 TO Dim(samples, 1) DO
% samples{i}.prefix + ":Reg_If_Signature_Of_" + samples{i}.name % samples{i}, buffer, user_id;
ENDFOR
Decode_Packed s, packet_type;
ENDWHILE
IF packet_type >= SAMPLE_DATA THEN
FOR i FROM 1 TO Dim(samples, 1) DO
IF samples{i}.user_id = packet_type THEN
% samples{i}.prefix + ":Decode_And_Handle_" + samples{i}.name % d, s, samples{i};
ENDIF
ENDFOR
RETURN ;
ENDIF
RAISE UNKNOWN_PACKET_TYPE;
ERROR
RAISE ;
ENDPROC
PROC Init_Decoder(VAR Decoder d, VAR LabComm_Stream s)
VAR string version;
Decode_String s,version;
IF version<>LabCommVersion THEN
RAISE INCORRECT_LABCOMM_VERSION;
ENDIF
ERROR
RAISE ;
ENDPROC
PROC Init_Encoder(VAR Encoder e, VAR LabComm_Stream s)
Encode_String s, LabCommVersion;
e.next_user_id := SAMPLE_DATA;
ERROR
RAISE ;
ENDPROC
ENDMODULE
The implementation of LabComm in RAPID
Limitations of this implementation:
- The type double is not available due to limitations in RAPID. There is a
non-integer type with 64 bits but there is not marshalling utilities for it.
- Variable sized arrays is not available. There is no dynamic allocation,
possible solution is a max-size array (1024) and a integervalue denoting the
size.
- A RECORD (struct) cannot contain an array, but fixed size arrays are
available both in structs and stand alone. The current implementation creates
a RECORD with one member for each index in the array. Not an omptimal
solution, the alternativ would be a seperate variable.
- Decoding and encoding is done directly from a TCP socket.
- Every generated procedure is namespaced by declaring them LOCAL to the
generated module. They must be called by using runtime binding of procedure
names ( % proc_name % arg1, arg2, ...;). The generated types are not
declared local.
Usage:
# Declare a stream, LabComm_Stream:
$ VAR LabComm_Stream st;
This contains a socketdev wich must be created and connected or instatiated
through an accept.
$ SocketCreate st.soc;
$ SocketConnect st.soc, "127.0.0.1", 55555;
or
$ SocketAccept server_socket, st.soc;
# Initiate Encoder and/or Decoder with the stream:
$ VAR Decoder d;
$ Init_Decoder d, st;
$ VAR Encoder e;
$ Init_Encoder e, st;
This will read/write the version of LabComm to ensure compatibility, current
version is "LabComm2014".
# Initiate the labcomm samples:
LabComm trusts the application to manage each sample. It requests the samples,
as a list, when performing decoding or encoding.
This is done through the generated code which implies the procedures are LOCAL
and must be called with runtime bindings.
When initiating a decoder sample the name of the callback procedure to receive
such samples is suplied as a string.
$ PROC handle_samplename(prefix_samplename val)
$ ...
$ ENDPROC
$ VAR LabComm_Decoder_Sample ds{1};
$ % prefix:Dec_Reg_samplename % ds{1}, "handle_samplename";
NOTE: The callback must be of type procedure and not function. Functions cannot
be called with runtime bindings.
When initiating an encoder sample the stream must be supplied to let the
encoder send the sample signature.
$ VAR LabComm_Encoder_Sample es{1};
$ % prefix:Enc_Reg_samplename % e, st, es{1};
# Encode and/or decode samples:
$ Decode_One d, st, ds;
It returns as soon as any sample is decoded. The decoded sample is supplied as
argument to the callback procedure registered with the corresponding sample.
$ VAR prefix_samplename val;
$ <init val>
$ % prefix:Encode_samplename % e, st, es{1}, val;
# Complete example:
## LabComm definition:
example.lc >>
sample struct {
short sum;
short terms[2];
} foo;
<< EOF
## RAPID CODE
PROC handle_foo(example_foo val)
IF val.sum = val.terms.e1 + val.terms.e2 THEN
TPWrite "Verification successfull!";
ELSE
TPWrite "Verification failed!";
ENDIF
ENDPROC
PROC main()
VAR Decoder d;
VAR Encoder e;
VAR LabComm_Stream st;
VAR LabComm_Encoder_Sample es{1};
VAR LabComm_Decoder_Sample ds{1};
VAR example_foo val := [2,[1,1]];
SocketCreate st.soc;
SocketConnect st.soc, "127.0.0.1", 55555;
Init_Decoder d, st;
Init_Encoder e, st;
% "example:Enc_Reg_foo" % e, st, es{1};
% "example:Dec_Reg_foo" % ds{1}, "handle_foo";
% "example:Encode_foo" % e, st, es{1}, val;
Decode_One d, st, ds;
SocketClose st.soc;
ENDPROC
liblabcomm.a
liblabcomm.so
liblabcomm.so.1
liblabcomm2006.so.1
liblabcomm2006.so
liblabcomm2006.a
liblabcomm2014.so.1
liblabcomm2014.so
liblabcomm2014.a
## Macros
VERSION=2014
LIBVERSION=2014
include ../os_compat.mk
ALL_DEPS=../liblabcomm$(LIBVERSION).a ../liblabcomm$(LIBVERSION).so
# TODO: Support for Codesourcery ARM toolchain.
OBJS=labcomm$(VERSION).o \
labcomm$(VERSION)_memory.o \
labcomm$(VERSION)_error.o \
labcomm$(VERSION)_default_error_handler.o \
labcomm$(VERSION)_default_memory.o \
labcomm$(VERSION)_default_scheduler.o \
labcomm$(VERSION)_time.o \
labcomm$(VERSION)_scheduler.o \
labcomm$(VERSION)_encoder.o \
labcomm$(VERSION)_decoder.o \
labcomm$(VERSION)_dynamic_buffer_writer.o \
labcomm$(VERSION)_fd_reader.o \
labcomm$(VERSION)_type_signature.o \
labcomm$(VERSION)_fd_writer.o \
labcomm$(VERSION)_pthread_scheduler.o \
labcomm$(VERSION)_renaming.o \
labcomm$(VERSION)_renaming_registry.o \
labcomm$(VERSION)_renaming_encoder.o \
labcomm$(VERSION)_renaming_decoder.o
# Enable experimental objects by `make LABCOMM_EXPERIMENTAL=true`
ifeq ($(LABCOMM_EXPERIMENTAL),true)
OBJS += experimental/udp_hack.o experimental/ethaddr.o \
experimental/labcomm_thr_reader_writer.o \
experimental/ThrottleDrv/ethernet_drv.o \
experimental/ThrottleDrv/throttle_drv.o \
experimental/labcomm_udp_reader_writer.o
endif
# Enable experimental objects by `make LABCOMM_SIG_PARSER=true`
ifeq ($(LABCOMM_SIG_PARSER),true)
OBJS += experimental/labcomm2014_sig_parser.o
endif
LABCOMM_JAR=../../../compiler/labcomm$(LIBVERSION)_compiler.jar
LABCOMM=java -jar $(LABCOMM_JAR)
TESTS=test_labcomm_basic_type_encoding \
test_labcomm_generated_encoding \
test_signature_numbers \
test_labcomm \
test_labcomm_pthread_scheduler \
test_labcomm_copy \
test_labcomm_renaming_registry \
test_labcomm_renaming_encoder \
test_labcomm_renaming_decoder
#FIXME: test_labcomm_errors
TEST_DIR=test
## Targets
.PHONY: all
all: $(ALL_DEPS)
.PHONY: test
test: all $(TESTS:%=run-test-%)
.PHONY: clean
clean:
$(RM) *.o
$(RM) experimental/*.o
$(RM) experimental/ThrottleDrv/*.o
$(RM) test/*.o
$(RM) test/*.gch
$(RM) test/test_labcomm_errors
$(RM) test/testdata/gen/*.[cho]
$(RM) test/gen/*.[cho]
$(RM) -rf test/gen
.PHONY: distclean
distclean: clean
$(RM) ../liblabcomm$(LIBVERSION).so.1
$(RM) ../liblabcomm$(LIBVERSION).a
# rules invoked by 'all'
../liblabcomm$(LIBVERSION).so: ../liblabcomm$(LIBVERSION).so.1
if [ -h $@ ] ; then rm $@ ; fi
ln -s $(<:../%=%) $@
../liblabcomm$(LIBVERSION).so.1: $(OBJS:%.o=%.pic.o)
$(call MAKESHARED,$@,$(@:../%=%),$^)
../liblabcomm$(LIBVERSION).a: $(OBJS)
ar -r $@ $^
# Enable sig parser objects by `make labcomm2014_sig_PARSER=true`
ifeq ($(LABCOMM_SIG_PARSER),true)
experimental/test_sig_parser : experimental/labcomm2014_sig_parser.o experimental/test_sig_parser.c
endif
# compilation rules
%.pic.o: %.c
$(CC) -fPIC $(CFLAGS) -c -o $@ $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c -o $@ $<
# rules invoked by 'test'
.PHONY: run-test-%
run-test-%: $(TEST_DIR)/gen/% | $(TEST_DIR)/gen
$(VALGRIND) $<
.PRECIOUS: $(TEST_DIR)/gen/%
$(TEST_DIR)/gen/%: $(TEST_DIR)/gen/%.o | $(TEST_DIR)/gen
$(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(TEST_DIR)/gen/%.o: $(TEST_DIR)/%.c | $(TEST_DIR)/gen
$(CC) $(CFLAGS_TEST) -o $@ -c $<
.PRECIOUS: $(TEST_DIR)/gen/%.c
.PRECIOUS: $(TEST_DIR)/gen/%.h
$(TEST_DIR)/gen/%.c $(TEST_DIR)/gen/%.h: $(TEST_DIR)/%.lc | $(TEST_DIR)/gen
$(LABCOMM) \
--c=$(TEST_DIR)/gen/$*.c \
--h=$(TEST_DIR)/gen/$*.h \
$<
$(LABCOMM_JAR):
@echo "======Building LabComm compiler======"
cd $(shell dirname $(LABCOMM_JAR)); ant jar
@echo "======End building LabComm compiler======"
$(TEST_DIR)/gen:
mkdir -p $@
# Extra compilation dependencies
labcomm$(VERSION).o: \
labcomm$(VERSION).c \
labcomm$(VERSION).h \
labcomm$(VERSION)_private.h
labcomm$(VERSION)_fd_reader.o: \
labcomm$(VERSION)_private.h
labcomm$(VERSION)_fd_writer.o: \
labcomm$(VERSION)_private.h
labcomm$(VERSION)_dynamic_buffer_writer.o: \
labcomm$(VERSION)_private.h
$(TEST_DIR)/gen/test_labcomm_basic_type_encoding.o: \
labcomm$(VERSION)_private.h
$(TEST_DIR)/gen/test_labcomm_generated_encoding.o: \
labcomm$(VERSION)_private.h \
$(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/gen/test_labcomm_generated_encoding: \
$(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/gen/test_signature_numbers.c: \
$(TEST_DIR)/gen/another_encoding.h \
$(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/gen/test_signature_numbers: \
$(TEST_DIR)/gen/another_encoding.o \
$(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/gen/test_labcomm: \
$(TEST_DIR)/gen/test_sample.o
$(TEST_DIR)/gen/test_labcomm_copy: \
$(TEST_DIR)/gen/generated_encoding.o \
$(TEST_DIR)/gen/test_sample.o \
$(TEST_DIR)/gen/more_types.o
$(TEST_DIR)/gen/test_labcomm_renaming_registry: \
$(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/gen/test_labcomm_renaming_encoder: \
$(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/gen/test_labcomm_renaming_decoder: \
$(TEST_DIR)/gen/generated_encoding.o
#define PC_MODE
#ifdef PC_MODE
#include <stdio.h>
#define DISPLAY_ERR(s) perror(s);
// Some projects can not use stdio.h.
#ifndef LABCOMM_NO_STDIO
#include <stdio.h>
#endif
#else
#define DISPLAY_ERR(s) ;
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/if_arp.h>
#include <netinet/in.h>
//#include <linux/if_ether.h>
//#include <linux/if_packet.h>
//#include <linux/if_arp.h>
#include <net/if.h>
#include <netpacket/packet.h>
//#include <netinet/in.h>
#include "ethernet_drv.h"
#include "display.h"
// Some projects can not use stdio.h.
#ifndef LABCOMM_NO_STDIO
#include <stdio.h>
#endif
/** LOCAL FUNCTIONS **/
/* local type for the ethernet interface */
struct eth_int_t
{
unsigned char mac_adr[ETH_ALEN]; /* MAC address */
struct ether_addr mac_adr; /* MAC address */
int socket_id; /* socket file descriptor */
int index; /* index of the eth interface */
unsigned char validity;
......@@ -72,7 +77,7 @@ struct eth_int_t* eth_open(const char* eth_int_name)
else
{
/* copy the MAC address into the eth interface struct */
memcpy(tmp_eth->mac_adr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
memcpy(tmp_eth->mac_adr.ether_addr_octet, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
/*retrieve the Ethernet interface index*/
if (ioctl(tmp_eth->socket_id, SIOCGIFINDEX, &ifr) == -1)/* error during the retrieve of index */
......@@ -87,7 +92,7 @@ struct eth_int_t* eth_open(const char* eth_int_name)
/* copy the interface index into the eth interface struct */
tmp_eth->index = ifr.ifr_ifindex;
printf("Successfully got our MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
tmp_eth->mac_adr[0],tmp_eth->mac_adr[1],tmp_eth->mac_adr[2],tmp_eth->mac_adr[3],tmp_eth->mac_adr[4],tmp_eth->mac_adr[5]);
tmp_eth->mac_adr.ether_addr_octet[0],tmp_eth->mac_adr.ether_addr_octet[1],tmp_eth->mac_adr.ether_addr_octet[2],tmp_eth->mac_adr.ether_addr_octet[3],tmp_eth->mac_adr.ether_addr_octet[4],tmp_eth->mac_adr.ether_addr_octet[5]);
printf("Successfully got interface index for %s: %i\n",eth_int_name, tmp_eth->index);
}
}
......@@ -130,7 +135,7 @@ int eth_close(struct eth_int_t* eth_int)
/***
Returns the MAC address of the Ethernet Interface
***/
int eth_getMACadr(const struct eth_int_t* eth_int, unsigned char* mac_adr)
int eth_getMACadr(const struct eth_int_t* eth_int, struct ether_addr * mac_adr)
{
int ret = 0;
......@@ -143,7 +148,7 @@ int eth_getMACadr(const struct eth_int_t* eth_int, unsigned char* mac_adr)
else
{
/* TO-DO: introduce a validity flag to be check before accessing to eth_int (better a crc) */
memcpy(mac_adr, eth_int->mac_adr, ETH_ALEN);
memcpy(mac_adr, &eth_int->mac_adr, sizeof(mac_adr));
}
return(ret);
}
......@@ -170,11 +175,6 @@ int eth_send(const struct eth_int_t* eth_int, const unsigned char* eth_frame, un
/*prepare sockaddr_ll (address structure for PACKET_SOCKET) */
socket_address.sll_family = AF_PACKET;
socket_address.sll_protocol = htons(ETH_P_IP); /* Physical layer protocol */
socket_address.sll_ifindex = eth_int->index; /* Ethernet Interface index */
socket_address.sll_hatype = ARPHRD_ETHER; /* ARP hardware identifier: Ethernet */
socket_address.sll_pkttype = PACKET_OTHERHOST; /* Packet type: Another host */
socket_address.sll_halen = ETH_ALEN; /* Length of the MAC address */
socket_address.sll_addr[0] = eth_header->h_dest[0];
socket_address.sll_addr[1] = eth_header->h_dest[1];
socket_address.sll_addr[2] = eth_header->h_dest[2];
......@@ -183,6 +183,16 @@ int eth_send(const struct eth_int_t* eth_int, const unsigned char* eth_frame, un
socket_address.sll_addr[5] = eth_header->h_dest[5];
socket_address.sll_addr[6] = 0x00; /* not used */
socket_address.sll_addr[7] = 0x00; /* not used */
socket_address.sll_halen = ETH_ALEN; /* Length of the MAC address */
socket_address.sll_ifindex = eth_int->index; /* Ethernet Interface index */
// The rest should be zero for sending, and are set by the system for receiving.
socket_address.sll_hatype = 0;
socket_address.sll_protocol = 0;
socket_address.sll_pkttype = 0;
//socket_address.sll_protocol = htons(ETH_P_IP); /* Physical layer protocol */
//socket_address.sll_hatype = ARPHRD_ETHER; /* ARP hardware identifier: Ethernet */
//socket_address.sll_pkttype = PACKET_OTHERHOST; /* Packet type: Another host */
/*send the Ethernet frame */
ret = sendto(eth_int->socket_id, eth_frame, length, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
......
#ifndef _ETHERNET_DRV_H_
#define _ETHERNET_DRV_H_
#include <net/ethernet.h>
struct eth_int_t;
struct eth_int_t* eth_open(const char* eth_int_name);
int eth_close(struct eth_int_t* eth_int);
int eth_getMACadr(const struct eth_int_t* eth_int, unsigned char* mac_adr);
int eth_getMACadr(const struct eth_int_t* eth_int, struct ether_addr *mac_adr);
int eth_send(const struct eth_int_t* eth_int, const unsigned char* eth_frame, unsigned short length);
int eth_receive (const struct eth_int_t* eth_int, unsigned char* eth_frame, unsigned short length);
......
......@@ -5,10 +5,9 @@
#include "stdlib.h"
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
// #include <arpa/inet.h>
#define THROTTLENET_PROTO 0x544e
#define ETH_ADR_LEN 6
#define THR_DST_ADR_POS 0
#define THR_SRC_ADR_POS (THR_DST_ADR_POS + sizeof(((thr_header_t*)0)->dst_adr)) //6
......@@ -20,8 +19,8 @@
#define THR_PAYLOAD_POS (THR_FRAG_LEN_POS + sizeof(((thr_header_t*)0)->frag_len)) //21
#define THR_MSG_HEADER_LEN THR_PAYLOAD_POS
#define THR_MSG_DST_ADR(thr_msg) (unsigned char*)(&thr_msg[THR_DST_ADR_POS])
#define THR_MSG_SRC_ADR(thr_msg) (unsigned char*)(&thr_msg[THR_SRC_ADR_POS])
#define THR_MSG_DST_ADR(thr_msg) (struct ether_addr*)(&thr_msg[THR_DST_ADR_POS])
#define THR_MSG_SRC_ADR(thr_msg) (struct ether_addr*)(&thr_msg[THR_SRC_ADR_POS])
#define THR_MSG_ETH_TYP(thr_msg) *(unsigned short*)(&thr_msg[THR_ETH_TYP_POS])
#define THR_MSG_CHN_ID(thr_msg) *(unsigned char*)(&thr_msg[THR_CHN_ID_POS])
#define THR_MSG_FRAG_NUM(thr_msg) *(unsigned short*)(&thr_msg[THR_FRAG_NUM_POS])
......@@ -33,20 +32,21 @@
/* local type for the Throttle Channel structure */
struct thr_chn_t
{
unsigned char dst_adr[ETH_ADR_LEN];/* destination MAC address */
struct ether_addr dst_adr; /* destination MAC address */
unsigned char id; /* Channel id */
unsigned short frag_size; /* Fragment size */
unsigned short freq; /* Message transmission frequency */
thr_msg_handler_t funct; /* Callback function invoked at the reception */
unsigned short msg_length;
unsigned char* p_msg;
struct ether_addr last_sender_adr;/* src MAC address of last message */
};
/* Type for the Throttle message */
typedef struct
{
unsigned char dst_adr[ETH_ADR_LEN]; /* destination MAC address */
unsigned char src_adr[ETH_ADR_LEN]; /* source MAC address */
struct ether_addr dst_adr; /* destination MAC address */
struct ether_addr src_adr; /* source MAC address */
unsigned short eth_type; /* ethernet packet type */
unsigned char chn_id; /* channel identification */
unsigned short frag_num; /* fragment number */
......@@ -104,7 +104,7 @@ int thr_init(const char* eth_int_name)
* @retval struct thr_chn_t*: pointer to the Channel structure. NULL on error and errno is set appropriately.
*
*******************************************************************************/
struct thr_chn_t* thr_open_chn(const unsigned char* dst_adr, unsigned char chn_id, unsigned char frag_size, unsigned short freq, const thr_msg_handler_t funct)
struct thr_chn_t* thr_open_chn(const struct ether_addr* dst_adr, unsigned char chn_id, unsigned char frag_size, unsigned short freq, const thr_msg_handler_t funct)
{
struct thr_chn_t* tmp_chn = NULL; /* pointer to Channel structure */
......@@ -127,7 +127,7 @@ struct thr_chn_t* thr_open_chn(const unsigned char* dst_adr, unsigned char chn_i
else
{
/* Update the Channel structure */
memcpy(tmp_chn->dst_adr, dst_adr, sizeof(tmp_chn->dst_adr));
memcpy(&tmp_chn->dst_adr, dst_adr, sizeof(tmp_chn->dst_adr));
tmp_chn->id = chn_id;
tmp_chn->frag_size = frag_size;
tmp_chn->freq = freq;
......@@ -142,6 +142,9 @@ struct thr_chn_t* thr_open_chn(const unsigned char* dst_adr, unsigned char chn_i
return(tmp_chn);
}
void thr_close_chn(struct thr_chn_t* c){
free(c);
}
/**
* @fn int thr_send(const struct thr_chn_t* thr_chn, const char* data, unsigned int length)
......@@ -188,7 +191,7 @@ int thr_send(const struct thr_chn_t* thr_chn, const char* data, unsigned int len
else
{
/* Compose the Ethernet Frame to be sent */
memcpy(THR_MSG_DST_ADR(thr_msg), &thr_chn->dst_adr[0], ETH_ADR_LEN); /* Destiantion MAC Address */
memcpy(THR_MSG_DST_ADR(thr_msg), &thr_chn->dst_adr, sizeof(thr_chn->dst_adr)); /* Destiantion MAC Address */
eth_getMACadr(eth_int, THR_MSG_SRC_ADR(thr_msg)); /* Source MAC Address */
THR_MSG_ETH_TYP(thr_msg) = htons(THROTTLENET_PROTO); /* Ethernet Packet Type */
THR_MSG_CHN_ID(thr_msg) = thr_chn->id; /* Channel identification */
......@@ -317,6 +320,7 @@ int thr_receive(struct thr_chn_t* thr_chn, unsigned char* data, void* param)
#endif
thr_chn->msg_length = ret;
memcpy(thr_chn->p_msg, data, ret); /* copy the msg into the thr structure */
memcpy(&thr_chn->last_sender_adr, THR_MSG_SRC_ADR(thr_msg), 6); /* ... and the address of the sender */
#ifdef DEBUG
printf("thr_receive: calling %x\n", thr_chn->funct);
#endif
......@@ -395,3 +399,11 @@ int thr_read(struct thr_chn_t* thr_chn, unsigned char* data, int length)
}
return(ret);
}
struct ether_addr* get_sender_addr(struct thr_chn_t* ch) {
return &ch->last_sender_adr;
}
unsigned char get_channel(struct thr_chn_t* ch) {
return ch->id;
}
#ifndef _THROTTLE_DRV_H_
#define _THROTTLE_DRV_H_
#define ETH_ADR_SIZE 6
//#define ETH_ADR_SIZE 6
#include <net/ethernet.h>
/* typedef of the callback used to manage the received Ethernet Frame (the User Data)*/
typedef int (*thr_msg_handler_t)(void* data);
......@@ -9,9 +13,12 @@ struct thr_chn_t;
int thr_init(const char* eth_int);
struct thr_chn_t* thr_open_chn(const unsigned char* dst_adr, unsigned char chn_id, unsigned char frag_size, unsigned short freq, thr_msg_handler_t funct);
struct thr_chn_t* thr_open_chn(const struct ether_addr* dst_adr, unsigned char chn_id, unsigned char frag_size, unsigned short freq, thr_msg_handler_t funct);
void thr_close_chn(struct thr_chn_t* c);
int thr_receive (struct thr_chn_t* thr_chn, unsigned char* data, void* param);
int thr_send(const struct thr_chn_t* thr_chn, const char* data, unsigned int length);
int thr_read(struct thr_chn_t* thr_chn, unsigned char* data, int length);
struct ether_addr * get_sender_addr(struct thr_chn_t* ch);
unsigned char get_channel(struct thr_chn_t* ch);
#endif