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 1620 additions and 0 deletions
package labcommTCPtest.server;
/**
* The service object to be accessed remotely via a LabComm channel
*
*/
public class TestObject {
/**
* A test method. The matching LabComm description is in test.lc
*
* @param x
* @param y
* @param t
* @param d
*/
public void foo(int x, int y, long t, double d) {
System.out.format("TestObject.foo(%d, %d, %d, %f)\n", x, y, t, d);
}
}
package labcommTCPtest.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.EncoderChannel;
import labcommTCPtest.gen.FooSample;
import labcommTCPtest.gen.FooSample.Handler;
public class TestServer implements Handler {
private OutputStream out;
private InputStream in;
public static void main(String a[]) {
try {
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();
TestServer ts = new TestServer(s);
ts.runOne();
} catch (IOException e) {
e.printStackTrace();
}
}
public TestServer(Socket s) throws IOException {
out = s.getOutputStream();
in = s.getInputStream();
}
public void runOne() {
try {
DecoderChannel c = new DecoderChannel(in);
FooSample.register(c,this);
c.runOne();
} catch (Exception e) {
e.printStackTrace();
}
}
public void handle_FooSample(FooSample sample) throws Exception {
EncoderChannel e = new EncoderChannel(out );
FooSample.register(e);
System.out.println("TestServer.handle_FooSample: "+sample.s);
int tmp[] = new int[2*sample.a.length];
for (int i = 0; i < sample.a.length;i++) {
tmp[2*i] = tmp[2*i+1] = sample.a[i];
}
sample.s = "double!";
sample.x *= 2;
sample.y *= 2;
sample.a = tmp;
sample.t *= 2;
sample.d *= 2;
FooSample.encode(e, sample);
}
}
#!/bin/sh
PYTHONPATH=../../lib/python ./example_tcp_client_decoder.py $@
import socket
import types
def flush(self):
pass
socket.socket.write = socket.socket.send
socket.socket.read = socket.socket.recv
socket.socket.flush = flush
# class rwsocket(socket.socket):
# write=socket.socket.send
# read=socket.socket.recv
# def flush(self):
# pass
# def accept(self):
# sock, addr = super(rwsocket, self).accept()
# # sock.write = types.MethodType(self.write, sock, sock.__class__)
# # sock.read = types.MethodType(self.write, sock, sock.__class__)
# sock.__class__ = rwsocket
# return (sock, addr)
sample struct {
string s;
int x;
int y;
int a[_];
long t;
double d;
} FooSample;
gen
UNAME_S=$(shell uname -s)
TARGETS=client server
LABCOMM_JAR=../../compiler/labcomm2014_compiler.jar
LABCOMM=java -jar $(LABCOMM_JAR)
#include ../../lib/c/os_compat.mk
CFLAGS=-O3 -g -Wall -Werror -I../../lib/c/2014 -I. -Wno-unused-function
ifeq ($(UNAME_S),Darwin)
CFLAGS+=-DLABCOMM_COMPAT=\"labcomm2014_compat_osx.h\" -DLABCOMM_OS_DARWIN=1
else
CFLAGS+=-Wno-tautological-compare
endif
all: $(TARGETS:%=gen/%)
test: all
LD_LIBRARY_PATH=../../lib/c ./gen/server 2000 &
LD_LIBRARY_PATH=../../lib/c ./gen/client localhost 2000
gen/.dir:
mkdir -p $@
.PRECIOUS: gen/%.o
gen/%.o: gen/%.c | gen/.dir
$(CC) $(CFLAGS) -c -o $@ $<
gen/%.o: %.c | gen/.dir
$(CC) $(CFLAGS) -c -o $@ $<
.PRECIOUS: gen/%.c gen/%.h
gen/%.c gen/%.h: %.lc | gen/.dir
$(LABCOMM) --c=gen/$*.c --h=gen/$*.h $<
gen/client: client.c
$(CC) -o $@ $(CFLAGS) $^ -lpthread \
-L../../lib/c -llabcomm2014
gen/server: server.c
$(CC) -o $@ $(CFLAGS) $^ -lpthread \
-L../../lib/c -llabcomm2014
.PHONY: clean distclean
clean distclean:
rm -rf gen
gen/decimating.o: decimating.h
gen/decimating.o: gen/decimating_messages.h
gen/introspecting.o: introspecting.h
gen/introspecting.o: gen/introspecting_messages.h
gen/client.o: decimating.h
gen/client.o: gen/types.h
gen/client: gen/decimating.o
gen/client: gen/decimating_messages.o
gen/client: gen/introspecting.o
gen/client: gen/introspecting_messages.o
gen/client: gen/types.o
gen/server: gen/types.o
gen/server: gen/decimating.o
gen/server: gen/decimating_messages.o
gen/server: gen/introspecting.o
gen/server: gen/introspecting_messages.o
/*
client.c -- LabComm example of using stacked readers/writers.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <arpa/inet.h>
#ifndef LABCOMM_OS_DARWIN
#include <linux/tcp.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif
#include <netdb.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <labcomm2014.h>
#include <labcomm2014_fd_reader.h>
#include <labcomm2014_fd_writer.h>
#include <labcomm2014_default_error_handler.h>
#include <labcomm2014_default_memory.h>
#include <labcomm2014_pthread_scheduler.h>
#include "decimating.h"
#include "introspecting.h"
#include "gen/types.h"
static void handle_Sum(int32_t *value, void *context)
{
printf("A+B=%d ", *value);
}
static void handle_Diff(int32_t *value, void *context)
{
printf("A-B=%d ", *value);
}
static void handle_Product(int32_t *value, void *context)
{
printf("A*B=%d ", *value);
}
static void *run_decoder(void *context)
{
struct labcomm2014_decoder *decoder = context;
int result;
labcomm2014_decoder_register_types_Sum(decoder, handle_Sum, NULL);
labcomm2014_decoder_register_types_Diff(decoder, handle_Diff, NULL);
do {
result = labcomm2014_decoder_decode_one(decoder);
} while (result >= 0);
return NULL;
}
int main(int argc, char *argv[])
{
int fd;
struct sockaddr_in adr;
int err;
struct hostent *host;
struct sockaddr_in to;
int nodelay;
struct decimating *decimating;
struct introspecting *introspecting;
char *hostname;
int port;
struct labcomm2014_scheduler *scheduler;
struct labcomm2014_decoder *decoder;
struct labcomm2014_encoder *encoder;
struct labcomm2014_time *next;
int32_t i, j;
hostname = argv[1];
port = atoi(argv[2]);
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "failed to create socket\n");
goto out;
}
adr.sin_family = AF_INET;
adr.sin_port = 0;
adr.sin_addr.s_addr = INADDR_ANY;
err = bind(fd, (struct sockaddr*)&adr, sizeof(adr));
if (err != 0) {
fprintf(stderr, "failed to bind socket\n");
goto out;
}
host = gethostbyname(hostname);
if (!host) {
fprintf(stderr, "failed to lookup %s\n", hostname);
goto out;
}
to.sin_family = AF_INET;
to.sin_port = htons(port);
bcopy((char*)host->h_addr, (char*)&to.sin_addr, host->h_length);
err = connect(fd, (struct sockaddr*)&to, sizeof(to));
if (err != 0) {
fprintf(stderr, "failed to connect %d@%s\n", port, hostname);
goto out;
}
nodelay = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
scheduler = labcomm2014_pthread_scheduler_new(labcomm2014_default_memory);
decimating = decimating_new(labcomm2014_fd_reader_new(labcomm2014_default_memory,
fd, 1),
labcomm2014_fd_writer_new(labcomm2014_default_memory,
fd, 0),
labcomm2014_default_error_handler,
labcomm2014_default_memory,
scheduler);
if (decimating == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
introspecting = introspecting_new(decimating->reader,
decimating->writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
scheduler);
if (introspecting == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
decoder = labcomm2014_decoder_new(introspecting->reader,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
scheduler);
encoder = labcomm2014_encoder_new(introspecting->writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
scheduler);
pthread_t rdt;
pthread_create(&rdt, NULL, run_decoder, decoder);
labcomm2014_encoder_register_types_A(encoder);
labcomm2014_encoder_register_types_B(encoder);
labcomm2014_encoder_register_types_Terminate(encoder);
err = labcomm2014_decoder_ioctl_types_Sum(decoder, SET_DECIMATION, 2);
err = labcomm2014_decoder_ioctl_types_Diff(decoder, SET_DECIMATION, 4);
next = labcomm2014_scheduler_now(scheduler);
for (i = 0 ; i < 4 ; i++) {
if (i == 2) {
labcomm2014_decoder_register_types_Product(decoder, handle_Product, NULL);
}
for (j = 0 ; j < 4 ; j++) {
printf("\nA=%d B=%d: ", i, j);
labcomm2014_encode_types_A(encoder, &i);
labcomm2014_encode_types_B(encoder, &j);
labcomm2014_time_add_usec(next, 100000);
labcomm2014_scheduler_sleep(scheduler, next);
}
}
printf("\n");
labcomm2014_encode_types_Terminate(encoder);
out:
return 0;
}
/*
decimating.c -- LabComm example of a twoway stacked decimation
reader/writer.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "labcomm2014_private.h"
#include "decimating.h"
#include "gen/decimating_messages.h"
struct decimating_private {
struct decimating decimating;
struct labcomm2014_error_handler *error;
struct labcomm2014_memory *memory;
struct labcomm2014_scheduler *scheduler;
int encoder_initialized;
struct labcomm2014_reader_action_context reader_action_context;
struct labcomm2014_writer_action_context writer_action_context;
LABCOMM_SIGNATURE_ARRAY_DEF(writer_decimation,
struct decimation {
int n;
int current;
});
LABCOMM_SIGNATURE_ARRAY_DEF(reader_decimation, int);
};
static void set_decimation(
decimating_messages_set_decimation *value,
void * context)
{
struct decimating_private *decimating = context;
struct decimation *decimation;
labcomm2014_scheduler_data_lock(decimating->scheduler);
decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
decimating->writer_decimation,
struct decimation,
value->signature_index);
decimation->n = value->decimation;
decimation->current = 0;
labcomm2014_scheduler_data_unlock(decimating->scheduler);
}
static int wrap_reader_alloc(
struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
struct decimating_private *decimating = action_context->context;
labcomm2014_decoder_register_decimating_messages_set_decimation(
r->decoder, set_decimation, decimating);
return labcomm2014_reader_alloc(r, action_context->next);
}
struct send_set_decimation {
struct decimating_private *decimating;
decimating_messages_set_decimation set_decimation;
};
static void send_set_decimation(void *arg)
{
struct send_set_decimation *msg = arg;
struct labcomm2014_memory *memory = msg->decimating->memory;
labcomm2014_encode_decimating_messages_set_decimation(
msg->decimating->decimating.writer->encoder, &msg->set_decimation);
labcomm2014_memory_free(memory, 1, msg);
}
static void enqueue_decimation(struct decimating_private *decimating,
int remote_index,
int amount)
{
struct send_set_decimation *msg;
msg = labcomm2014_memory_alloc(decimating->memory, 1, sizeof(*msg));
if (msg) {
msg->decimating = decimating;
msg->set_decimation.decimation = amount;
msg->set_decimation.signature_index = remote_index;
labcomm2014_scheduler_enqueue(decimating->scheduler, 0,
send_set_decimation, msg);
}
}
static int wrap_reader_start(
struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index, const struct labcomm2014_signature *signature,
void *value)
{
struct decimating_private *decimating = action_context->context;
if (value == NULL) {
int *decimation, amount;
labcomm2014_scheduler_data_lock(decimating->scheduler);
decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
decimating->reader_decimation,
int,
local_index);
amount = *decimation;
labcomm2014_scheduler_data_unlock(decimating->scheduler);
if (remote_index != 0 && amount != 0) {
enqueue_decimation(decimating, remote_index, amount);
}
}
return labcomm2014_reader_start(r, action_context->next,
local_index, remote_index, signature, value);
}
static int wrap_reader_ioctl(
struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index,
const struct labcomm2014_signature *signature,
uint32_t action, va_list args)
{
struct decimating_private *decimating = action_context->context;
if (action == SET_DECIMATION) {
va_list va;
int amount;
int *decimation;
va_copy(va, args);
amount = va_arg(va, int);
va_end(va);
labcomm2014_scheduler_data_lock(decimating->scheduler);
decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
decimating->reader_decimation,
int,
local_index);
*decimation = amount;
labcomm2014_scheduler_data_unlock(decimating->scheduler);
if (remote_index) {
enqueue_decimation(decimating, remote_index, amount);
}
} else {
return labcomm2014_reader_ioctl(r, action_context->next,
local_index, remote_index, signature,
action, args);
}
return 0;
}
struct labcomm2014_reader_action decimating_reader_action = {
.alloc = wrap_reader_alloc,
.free = NULL,
.start = wrap_reader_start,
.end = NULL,
.fill = NULL,
.ioctl = wrap_reader_ioctl
};
static void register_signatures(void *context)
{
struct decimating_private *decimating = context;
labcomm2014_encoder_register_decimating_messages_set_decimation(
decimating->decimating.writer->encoder);
}
static int wrap_writer_alloc(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
struct decimating_private *decimating = action_context->context;
labcomm2014_scheduler_enqueue(decimating->scheduler,
0, register_signatures, decimating);
return labcomm2014_writer_alloc(w, action_context->next);
}
static int wrap_writer_start(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
void *value)
{
struct decimating_private *decimating = action_context->context;
struct decimation *decimation;
int result;
if (index < LABCOMM_USER) {
result = 0;
} else {
labcomm2014_scheduler_data_lock(decimating->scheduler);
decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
decimating->writer_decimation,
struct decimation, index);
decimation->current++;
if (decimation->current < decimation->n) {
result = -EALREADY;
} else {
decimation->current = 0;
result = 0;
}
labcomm2014_scheduler_data_unlock(decimating->scheduler);
}
if (result == 0) {
result = labcomm2014_writer_start(w, action_context->next,
index, signature, value);
}
return result;
}
struct labcomm2014_writer_action decimating_writer_action = {
.alloc = wrap_writer_alloc,
.free = NULL,
.start = wrap_writer_start,
.end = NULL,
.flush = NULL,
.ioctl = NULL
};
struct decimating *decimating_new(
struct labcomm2014_reader *reader,
struct labcomm2014_writer *writer,
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler)
{
struct decimating_private *result;
result = malloc(sizeof(*result));
if (result == NULL) {
goto out_fail;
}
/* Wrap reader and writer */
result->reader_action_context.next = reader->action_context;
result->reader_action_context.action = &decimating_reader_action;
result->reader_action_context.context = result;
reader->action_context = &result->reader_action_context;
result->writer_action_context.next = writer->action_context;
result->writer_action_context.action = &decimating_writer_action;
result->writer_action_context.context = result;
writer->action_context = &result->writer_action_context;
/* Init visible result struct */
result->decimating.reader = reader;
result->decimating.writer = writer;
/* Init other fields */
result->error = error;
result->memory = memory;
result->scheduler = scheduler;
LABCOMM_SIGNATURE_ARRAY_INIT(result->writer_decimation, struct decimation);
LABCOMM_SIGNATURE_ARRAY_INIT(result->reader_decimation, int);
goto out_ok;
out_fail:
return NULL;
out_ok:
return &result->decimating;
}
#ifndef __DECIMATING_H__
#define __DECIMATING_H__
#include <labcomm2014.h>
#include <labcomm2014_ioctl.h>
struct decimating {
struct labcomm2014_reader *reader;
struct labcomm2014_writer *writer;
};
extern struct decimating *decimating_new(
struct labcomm2014_reader *reader,
struct labcomm2014_writer *writer,
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler);
#define SET_DECIMATION LABCOMM_IOSW('d',0,int)
#endif
sample struct {
int decimation;
int signature_index;
} set_decimation;
/*
introspecting.c -- LabComm example of a twoway stacked introspection
reader/writer.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "labcomm2014_private.h"
#include "introspecting.h"
#include "gen/introspecting_messages.h"
struct introspecting_private {
struct introspecting introspecting;
struct labcomm2014_error_handler *error;
struct labcomm2014_memory *memory;
struct labcomm2014_scheduler *scheduler;
struct labcomm2014_reader_action_context reader_action_context;
struct labcomm2014_writer_action_context writer_action_context;
LABCOMM_SIGNATURE_ARRAY_DEF(remote,
struct remote {
char *name;
int size;
uint8_t *signature;
});
LABCOMM_SIGNATURE_ARRAY_DEF(local,
struct local {
enum introspecting_status status;
const struct labcomm2014_signature *signature;
});
};
static struct local *get_local(struct introspecting_private *introspecting,
int index,
const struct labcomm2014_signature *signature)
{
/* Called with data_lock held */
struct local *local;
local = LABCOMM_SIGNATURE_ARRAY_REF(introspecting->memory,
introspecting->local,
struct local,
index);
if (local->signature == NULL) {
local->signature = signature;
local->status = introspecting_unknown;
}
if (local->status == introspecting_unknown) {
int i;
local->status = introspecting_unhandled;
LABCOMM_SIGNATURE_ARRAY_FOREACH(introspecting->remote, struct remote, i) {
struct remote *r;
r = LABCOMM_SIGNATURE_ARRAY_REF(introspecting->memory,
introspecting->remote, struct remote, i);
if (r->name &&
strcmp(signature->name, r->name) == 0 &&
r->size == signature->size &&
memcmp(signature->signature, r->signature, signature->size) == 0) {
local->status = introspecting_unregistered;
break;
}
}
}
return local;
}
static void handles_signature(
introspecting_messages_handles_signature *value,
void * context)
{
struct introspecting_private *introspecting = context;
struct remote *remote;
labcomm2014_scheduler_data_lock(introspecting->scheduler);
remote = LABCOMM_SIGNATURE_ARRAY_REF(introspecting->memory,
introspecting->remote,
struct remote,
value->index);
remote->name = strdup(value->name);
remote->signature = malloc(value->signature.n_0);
if (remote->signature) {
int i;
memcpy(remote->signature, value->signature.a, value->signature.n_0);
remote->size = value->signature.n_0;
LABCOMM_SIGNATURE_ARRAY_FOREACH(introspecting->local, struct local, i) {
struct local *l;
l = LABCOMM_SIGNATURE_ARRAY_REF(introspecting->memory,
introspecting->local, struct local, i);
if (l->signature &&
l->status == introspecting_unhandled &&
l->signature->name &&
strcmp(remote->name, l->signature->name) == 0 &&
remote->size == l->signature->size &&
memcmp(l->signature->signature, remote->signature,
l->signature->size) == 0) {
l->status = introspecting_unregistered;
}
}
}
labcomm2014_scheduler_data_unlock(introspecting->scheduler);
}
static int wrap_reader_alloc(
struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
struct introspecting_private *introspecting = action_context->context;
labcomm2014_decoder_register_introspecting_messages_handles_signature(
introspecting->introspecting.reader->decoder,
handles_signature, introspecting);
return labcomm2014_reader_alloc(r, action_context->next);
}
struct handles_signature {
struct introspecting_private *introspecting;
int index;
const struct labcomm2014_signature *signature;
};
static void send_handles_signature(void *arg)
{
struct handles_signature *h = arg;
introspecting_messages_handles_signature handles_signature;
handles_signature.index = h->index;
handles_signature.name = h->signature->name;
handles_signature.signature.n_0 = h->signature->size;
handles_signature.signature.a = h->signature->signature;
labcomm2014_encode_introspecting_messages_handles_signature(
h->introspecting->introspecting.writer->encoder, &handles_signature);
}
static int wrap_reader_start(
struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context,
int local_index, int remote_index, const struct labcomm2014_signature *signature,
void *value)
{
struct introspecting_private *introspecting = action_context->context;
if (value == NULL) {
struct handles_signature *handles_signature;
handles_signature = labcomm2014_memory_alloc(introspecting->memory, 1,
sizeof(*handles_signature));
handles_signature->introspecting = introspecting;
handles_signature->index = local_index;
handles_signature->signature = signature;
labcomm2014_scheduler_enqueue(introspecting->scheduler,
0, send_handles_signature, handles_signature);
}
return labcomm2014_reader_start(r, action_context->next,
local_index, remote_index, signature, value);
}
void encode_handles_signature(
struct labcomm2014_encoder *encoder,
void *context)
{
const struct labcomm2014_signature *signature = context;
introspecting_messages_handles_signature handles_signature;
int index = 0;
handles_signature.index = index;
handles_signature.name = signature->name;
handles_signature.signature.n_0 = signature->size;
handles_signature.signature.a = signature->signature;
labcomm2014_encode_introspecting_messages_handles_signature(
NULL, &handles_signature);
}
struct labcomm2014_reader_action introspecting_reader_action = {
.alloc = wrap_reader_alloc,
.free = NULL,
.start = wrap_reader_start,
.end = NULL,
.fill = NULL,
.ioctl = NULL
};
static void register_encoder_signatures(void *context)
{
struct introspecting_private *introspecting = context;
labcomm2014_encoder_register_introspecting_messages_handles_signature(
introspecting->introspecting.writer->encoder);
}
static int wrap_writer_alloc(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
struct introspecting_private *introspecting = action_context->context;
labcomm2014_scheduler_enqueue(introspecting->scheduler,
0, register_encoder_signatures, introspecting);
return labcomm2014_writer_alloc(w, action_context->next);
}
static int wrap_writer_start(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
void *value)
{
struct introspecting_private *introspecting = action_context->context;
if (index >= LABCOMM_USER && value == NULL) {
struct local *local;
labcomm2014_scheduler_data_lock(introspecting->scheduler);
local = get_local(introspecting, index, signature);
local->status = introspecting_registered;
labcomm2014_scheduler_data_unlock(introspecting->scheduler);
}
return labcomm2014_writer_start(w, action_context->next, index, signature, value);
}
static int wrap_writer_ioctl(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
uint32_t ioctl_action, va_list args)
{
struct introspecting_private *introspecting = action_context->context;
switch (ioctl_action) {
case HAS_SIGNATURE: {
struct local *local;
int result;
labcomm2014_scheduler_data_lock(introspecting->scheduler);
local = get_local(introspecting, index, signature);
result = local->status;
labcomm2014_scheduler_data_unlock(introspecting->scheduler);
return result;
}
default: {
return labcomm2014_writer_ioctl(w, action_context->next, index, signature,
ioctl_action, args);
} break;
}
}
struct labcomm2014_writer_action introspecting_writer_action = {
.alloc = wrap_writer_alloc,
.free = NULL,
.start = wrap_writer_start,
.end = NULL,
.flush = NULL,
.ioctl = wrap_writer_ioctl
};
extern struct introspecting *introspecting_new(
struct labcomm2014_reader *reader,
struct labcomm2014_writer *writer,
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler)
{
struct introspecting_private *result;
result = malloc(sizeof(*result));
if (result == NULL) {
goto out_fail;
}
/* Wrap reader and writer */
result->reader_action_context.next = reader->action_context;
result->reader_action_context.action = &introspecting_reader_action;
result->reader_action_context.context = result;
reader->action_context = &result->reader_action_context;
result->writer_action_context.next = writer->action_context;
result->writer_action_context.action = &introspecting_writer_action;
result->writer_action_context.context = result;
writer->action_context = &result->writer_action_context;
/* Init visible result struct */
result->introspecting.reader = reader;
result->introspecting.writer = writer;
/* Init other fields */
result->error = error;
result->memory = memory;
result->scheduler = scheduler;
LABCOMM_SIGNATURE_ARRAY_INIT(result->remote, struct remote);
LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct local);
goto out_ok;
out_fail:
return NULL;
out_ok:
return &result->introspecting;
}
/*
introspecting.h -- LabComm example of a twoway stacked introspection
reader/writer.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __INTROSPECTING_H__
#define __INTROSPECTING_H__
#include <labcomm2014.h>
#include <labcomm2014_ioctl.h>
#include <labcomm2014_fd_reader.h>
#include <labcomm2014_fd_writer.h>
struct introspecting {
struct labcomm2014_reader *reader;
struct labcomm2014_writer *writer;
};
extern struct introspecting *introspecting_new(
struct labcomm2014_reader *reader,
struct labcomm2014_writer *writer,
struct labcomm2014_error_handler *error,
struct labcomm2014_memory *memory,
struct labcomm2014_scheduler *scheduler);
#define HAS_SIGNATURE LABCOMM_IOS('i',2)
enum introspecting_status { introspecting_unknown,
introspecting_unhandled,
introspecting_unregistered,
introspecting_registered };
#endif
sample struct {
int index;
string name;
byte signature[_];
} handles_signature;
/*
server.c -- LabComm example of using stacked readers/writers.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <arpa/inet.h>
#ifndef LABCOMM_OS_DARWIN
#include <linux/tcp.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <labcomm2014_default_error_handler.h>
#include <labcomm2014_default_memory.h>
#include <labcomm2014_pthread_scheduler.h>
#include <labcomm2014_fd_reader.h>
#include <labcomm2014_fd_writer.h>
#include "decimating.h"
#include "introspecting.h"
#include "gen/types.h"
struct client {
int fd;
pthread_t main_thread;
pthread_t decoder_thread;
struct sockaddr_in adr;
unsigned int adrlen;
int32_t A, B, Sum, Diff, Product;
struct labcomm2014_decoder *decoder;
struct labcomm2014_encoder *encoder;
struct labcomm2014_scheduler *scheduler;
};
static void handle_A(int32_t *value, void *context)
{
struct client *client = context;
client->A = *value;
}
static void handle_B(int32_t *value, void *context)
{
struct client *client = context;
int status;
client->B = *value;
status = labcomm2014_encoder_ioctl_types_Product(client->encoder, HAS_SIGNATURE);
switch (status) {
case introspecting_unregistered:
labcomm2014_encoder_register_types_Product(client->encoder);
/* fall through */
case introspecting_registered:
client->Product = client->A * client->B;
labcomm2014_encode_types_Product(client->encoder, &client->Product);
break;
default:
break;
}
client->Sum = client->A + client->B;
client->Diff = client->A - client->B;
labcomm2014_encode_types_Sum(client->encoder, &client->Sum);
labcomm2014_encode_types_Diff(client->encoder, &client->Diff);
}
static void handle_Terminate(types_Terminate *value, void *context)
{
exit(0);
}
static void *run_decoder(void *arg)
{
struct client *client = arg;
int result;
labcomm2014_decoder_register_types_A(client->decoder, handle_A, client);
labcomm2014_decoder_register_types_B(client->decoder, handle_B, client);
labcomm2014_decoder_register_types_Terminate(client->decoder, handle_Terminate,
NULL);
do {
result = labcomm2014_decoder_decode_one(client->decoder);
} while (result >= 0);
labcomm2014_scheduler_wakeup(client->scheduler);
return NULL;
}
static void *run_client(void *arg)
{
struct client *client = arg;
struct decimating *decimating;
struct introspecting *introspecting;
printf("Client start\n");
client->A = 0;
client->B = 0;
client->scheduler = labcomm2014_pthread_scheduler_new(labcomm2014_default_memory);
decimating = decimating_new(labcomm2014_fd_reader_new(labcomm2014_default_memory,
client->fd, 1),
labcomm2014_fd_writer_new(labcomm2014_default_memory,
client->fd, 0),
labcomm2014_default_error_handler,
labcomm2014_default_memory,
client->scheduler);
if (decimating == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
introspecting = introspecting_new(decimating->reader,
decimating->writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
client->scheduler);
if (introspecting == NULL) {
/* Warning: might leak reader and writer at this point */
goto out;
}
client->decoder = labcomm2014_decoder_new(introspecting->reader,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
client->scheduler);
client->encoder = labcomm2014_encoder_new(introspecting->writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
client->scheduler);
pthread_t rdt;
pthread_create(&rdt, NULL, run_decoder, client);
labcomm2014_encoder_register_types_Sum(client->encoder);
labcomm2014_encoder_register_types_Diff(client->encoder);
labcomm2014_scheduler_sleep(client->scheduler, NULL);
printf("Awoken\n");
pthread_join(rdt, NULL);
out:
printf("Client end\n");
shutdown(client->fd, SHUT_RDWR);
close(client->fd);
free(client);
return NULL;
}
int main(int argc, char *argv[])
{
int fd;
int result = 0;
int reuse;
int port;
struct sockaddr_in adr;
port = atoi(argv[1]);
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) {
result = errno;
goto no_server_socket;
}
reuse = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
adr.sin_family = AF_INET;
adr.sin_port = htons(port);
adr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr*)&adr, sizeof(adr)) != 0) {
result = errno;
goto failed_to_bind;
}
if (listen(fd, 5) != 0) {
result = errno;
goto failed_to_listen;
}
while (1) {
struct client *client;
int nodelay;
client = malloc(sizeof(*client));
if (client == NULL) {
result = errno;
goto failed_to_alloc_client;
}
client->adr.sin_family = AF_INET;
client->adr.sin_port = 0;
client->adr.sin_addr.s_addr = INADDR_ANY;
client->adrlen = sizeof(client->adr);
client->fd = accept(fd, (struct sockaddr*)&client->adr, &client->adrlen);
if (client->fd < 0) {
result = errno;
goto failed_to_accept;
}
nodelay = 1;
setsockopt(client->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
pthread_create(&client->main_thread, NULL, run_client, client);
}
failed_to_alloc_client:
failed_to_accept:
failed_to_listen:
failed_to_bind:
close(fd);
no_server_socket:
return result;
}
sample int A;
sample int B;
sample int Sum;
sample int Diff;
sample int Product;
sample void Terminate;
gen
labcomm2014.dll
ExampleDecoder.exe
ExampleEncoder.exe
encoded_data_c
encoded_data_cs
encoded_data_j
encoded_data_p
example_decoder
example_encoder
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.TypeDef;
import se.lth.control.labcomm2014.TypeDefParser;
import se.lth.control.labcomm2014.SigTypeDef;
//import se.lth.control.labcomm2014.TypeBinding;
public class Decoder
implements twoLines.Handler,
// TypeDef.Handler,
// TypeBinding.Handler,
TypeDefParser.TypeDefListener,
twoInts.Handler,
theFirstInt.Handler,
theSecondInt.Handler,
doavoid.Handler,
intAndRef.Handler
{
private DecoderChannel decoder;
private TypeDefParser tdp;
public Decoder(InputStream in)
throws Exception
{
decoder = new DecoderChannel(in);
doavoid.register(decoder, this);
twoInts.register(decoder, this);
twoLines.register(decoder, this);
theFirstInt.register(decoder, this);
theSecondInt.register(decoder, this);
intAndRef.register(decoder, this);
doavoid.registerSampleRef(decoder);
this.tdp = TypeDefParser.registerTypeDefParser(decoder);
// TypeDef.register(decoder, this);
// TypeBinding.register(decoder, this);
tdp.addListener(this);
try {
System.out.println("Running decoder.");
decoder.run();
} catch (java.io.EOFException e) {
System.out.println("Decoder reached end of file.");
}
}
private String genPoint(point p) {
return "("+p.x.val+", "+p.y.val+")";
}
private String genLine(line l) {
return "Line from "+genPoint(l.start)+" to "+genPoint(l.end);
}
// public void handle_TypeDef(TypeDef d) throws java.io.IOException {
// System.out.println("Got TypeDef: "+d.getName()+"("+d.getIndex()+")");
// }
//
// public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
// System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+"");
// }
public void onTypeDef(SigTypeDef d) {
System.out.println("ontype_def: ");
if(d != null) {
System.out.print((d.isSampleDef()?"sample ":"typedef ")+d);
System.out.println(" "+d.getName()+";");
} else {
System.out.println(" null???");
}
//for(byte b: d.getSignature()) {
// System.out.print(Integer.toHexString(b)+" ");
//}
//System.out.println();
//try {
// tdp.parseSignature(d.getIndex());
//} catch(IOException ex) { ex.printStackTrace();}
}
public void handle_doavoid() throws java.io.IOException {
System.out.println("Got a void.");
}
public void handle_twoInts(twoInts d) throws java.io.IOException {
System.out.print("Got twoInts: ");
System.out.println(d.a +", "+d.b);
}
public void handle_theFirstInt(int d) throws java.io.IOException {
System.out.println("Got theFirstInt: "+d);
}
public void handle_theSecondInt(int d) throws java.io.IOException {
System.out.println("Got theSecondInt: "+d);
}
public void handle_intAndRef(intAndRef d) throws java.io.IOException {
System.out.println("Got intAndRef: "+d.x+", "+d.reference);
}
public void handle_twoLines(twoLines d) throws java.io.IOException {
System.out.print("Got twoLines: ");
System.out.println("Line l1: "+genLine(d.l1));
System.out.println(" Line l2: "+genLine(d.l2));
}
public static void main(String[] arg) throws Exception {
Decoder example = new Decoder(
new FileInputStream(new File(arg[0]))
);
}
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import se.lth.control.labcomm2014.EncoderChannel;
/**
* Simple encoder
*/
public class Encoder
{
EncoderChannel encoder;
public Encoder(OutputStream out)
throws Exception
{
encoder = new EncoderChannel(out);
doavoid.register(encoder);
twoInts.register(encoder);
twoLines.register(encoder);
theFirstInt.register(encoder);
theSecondInt.register(encoder);
intAndRef.register(encoder);
doavoid.registerSampleRef(encoder);
}
public void doEncode() throws java.io.IOException {
System.out.println("Encoding doavoid");
doavoid.encode(encoder);
intAndRef iar = new intAndRef();
iar.x = 17;
iar.reference = doavoid.class;
System.out.println("Encoding intAndRef");
intAndRef.encode(encoder, iar);
twoInts ti = new twoInts();
ti.a = 12;
ti.b = 21;
System.out.println("Encoding twoInts");
twoInts.encode(encoder, ti);
System.out.println("Encoding the Ints");
theFirstInt.encode(encoder, 71);
theSecondInt.encode(encoder, 24);
twoLines x = new twoLines();
line l1 = new line();
point p11 = new point();
coord c11x = new coord();
coord c11y = new coord();
c11x.val = 11;
c11y.val = 99;
p11.x = c11x;
p11.y = c11y;
l1.start = p11;
point p12 = new point();
coord c12x = new coord();
coord c12y = new coord();
c12x.val = 22;
c12y.val = 88;
p12.x = c12x;
p12.y = c12y;
l1.end = p12;
line l2 = new line();
point p21 = new point();
coord c21x = new coord();
coord c21y = new coord();
c21x.val = 17;
c21y.val = 42;
p21.x = c21x;
p21.y = c21y;
l2.start = p21;
point p22 = new point();
coord c22x = new coord();
coord c22y = new coord();
c22x.val = 13;
c22y.val = 37;
p22.x = c22x;
p22.y = c22y;
l2.end = p22;
foo f = new foo();
f.a = 10;
f.b = 20;
f.c = false;
x.l1 = l1;
x.l2 = l2;
x.f = f;
System.out.println("Encoding theTwoLines");
twoLines.encode(encoder, x);
}
public static void main(String[] arg) throws Exception {
FileOutputStream fos = new FileOutputStream(arg[0]);
Encoder example = new Encoder(fos);
example.doEncode();
fos.close();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using se.lth.control.labcomm2014;
namespace user_types
{
class Decoder : twoLines.Handler,
twoInts.Handler,
theFirstInt.Handler,
theSecondInt.Handler,
doavoid.Handler,
intAndRef.Handler
{
DecoderChannel dec;
public Decoder(Stream stream)
{
dec = new DecoderChannel(stream);
twoLines.register(dec, this);
twoInts.register(dec, this);
theFirstInt.register(dec, this);
theSecondInt.register(dec, this);
doavoid.register(dec, this);
intAndRef.register(dec, this);
doavoid.registerSampleRef(dec);
try
{
Console.WriteLine("Running decoder.");
dec.run();
}
catch (EndOfStreamException)
{
Console.WriteLine("EOF reached");
}
}
private string genPoint(point p)
{
return "(" + p.x.val + ", " + p.y.val + ")";
}
private String genLine(line l)
{
return "Line from " + genPoint(l.start) + " to " + genPoint(l.end);
}
public void handle(twoLines d)
{
Console.WriteLine("Got twoLines: ");
Console.WriteLine("Line l1: "+genLine(d.l1));
Console.WriteLine("Line l2: " + genLine(d.l2));
}
public void handle(twoInts d)
{
Console.WriteLine("Got twoInts: ");
Console.WriteLine("a: "+d.a);
Console.WriteLine("b: "+d.b);
}
void theFirstInt.Handler.handle(int d)
{
Console.WriteLine("Got theFirstInt: "+d);
}
void theSecondInt.Handler.handle(int d)
{
Console.WriteLine("Got theSecondInt: "+d);
}
void doavoid.Handler.handle()
{
Console.WriteLine("Got a void.");
}
void intAndRef.Handler.handle(intAndRef d)
{
Console.WriteLine("Got intAndRef: "+d.x+" : "+d.reference);
}
static void Main(string[] args)
{
new Decoder(new FileStream(args[0], FileMode.Open));
}
}
}