Commit 17292559 authored by Timothy Stack's avatar Timothy Stack

Made a pass over the mtp directory:

	* GNUmakerules: Add a "check" target that runs the executables
	listed in the "TESTS" variable.

	* robots/GNUmakefile.in: Add "mtp" to the list of SUBDIRS.

	* robots/mtp/GNUmakefile.in: Testbed-friendly makefile.

	* robots/mtp/mtp.h, robots/mtp.c: Tweaks and bug fixes.

	* robots/mtp/mtp_test.c: Test case for mtp stuff.
parent 997c5542
......@@ -68,3 +68,17 @@ vpath % $(SRCDIR) $(MOSTLY_SRCDIRS)
%: %.in
@echo "Regenerating $@"
cd $(OBJDIR) && CONFIG_FILES=$(SUBDIR)/$@ ./config.status
ifeq ($(TESTS),)
.PHONY: check
else
check: $(TESTS)
@for tst in $<; do \
if test `basename $$tst .sh` != `basename $$tst`; then \
tst="sh $$tst"; \
fi; \
if $$tst; then \
echo "PASS: $$tst"; \
fi \
done
endif
......@@ -11,9 +11,10 @@ SUBDIR = robots
include $(OBJDIR)/Makeconf
SUBDIRS = emc rmcd vmcd
SUBDIRS = mtp emc rmcd vmcd
all: all-subdirs
check: check-subdirs
include $(TESTBED_SRCDIR)/GNUmakerules
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2004 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../..
SUBDIR = robots/mtp
include $(OBJDIR)/Makeconf
MTPLIBS = libmtp.a
MTPPROGS = mtp_test
TESTS = mtp_test
all: $(MTPLIBS) $(MTPPROGS)
include $(TESTBED_SRCDIR)/GNUmakerules
OBJS = mtp.o
CFLAGS += -O -g -Wall -I${OBJDIR} -I/usr/local/include
libmtp.a: $(OBJS)
$(AR) crv $@ $<
$(RANLIB) $@
mtp.o: mtp.h
mtp_test.o: mtp.h
mtp_test: mtp_test.o $(MTPLIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ mtp_test.o -L. -lmtp
install: $(addprefix $(INSTALL_LIBDIR), $(MTPLIBS))
clean:
/bin/rm -f *.o *.a $(MTPPROGS)
#include "mtp.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <netinet/in.h>
#include "mtp.h"
static int readall(int fd,char *buffer,unsigned int len)
{
int rc, off = 0, retval;
assert(fd >= 0);
assert(buffer != NULL);
while ((rc = read(fd,&buffer[off],len - off)) > 0) {
off += rc;
}
if (rc < 0) {
retval = rc;
}
else {
retval = off;
}
return retval;
}
int mtp_receive_packet(int fd,struct mtp_packet **packet) {
unsigned int length;
char clength[4];
uint32_t clength;
char *buf = NULL;
int i;
int retval;
if (packet == NULL) {
return MTP_PP_ERROR_ARGS;
}
retval = read(fd,(void*)(&clength),4);
retval = readall(fd,&clength,4);
if (retval == -1) {
return MTP_PP_ERROR_READ;
}
else {
int remaining_length;
/* length is currently in bytes 0,1,2,and 3, in network byte order */
length = ntohl((uint32_t)(clength));
length = ntohl(clength);
if (length > MTP_PACKET_MAXLEN) {
return MTP_PP_ERROR_LENGTH;
}
/* read the rest of the packet into buf */
int remaining_length = length - 4;
remaining_length = length - 4;
buf = (char*)malloc(sizeof(char)*(length+1));
if (buf == NULL) {
return MTP_PP_ERROR_MALLOC;
}
// copy the header bytes to the new buf
for (i = 0; i < 4; ++i) {
buf[i] = clength[i];
}
memcpy(buf,&clength,4);
retval = read(fd,(void*)(buf+sizeof(char)*MTP_PACKET_HEADER_LEN),remaining_length);
retval = readall(fd,(void*)&buf[MTP_PACKET_HEADER_OFFSET_OPCODE],remaining_length);
if (retval == -1) {
free(buf);
return MTP_PP_ERROR_READ;
......@@ -56,10 +80,10 @@ int mtp_receive_packet(int fd,struct mtp_packet **packet) {
int mtp_encode_packet(char **buf_ptr,struct mtp_packet *packet) {
char *buf;
int i,j,k;
int i,j;
int buf_size;
if (packet == NULL || buf == NULL) {
if (packet == NULL || buf_ptr == NULL) {
return MTP_PP_ERROR_ARGS;
}
......@@ -94,13 +118,9 @@ int mtp_encode_packet(char **buf_ptr,struct mtp_packet *packet) {
// write code field
*((int *)(buf+i)) = htonl(data->code);
i += 4;
// write msg field, and null-term it
for (j = 0; j < strlen(data->msg); ++j) {
buf[i] = data->msg[j];
++i;
}
buf[i] = '\0';
// write msg field
strcpy(&buf[i],data->msg);
i += strlen(&buf[i]) + 1;
}
else if (packet->opcode == MTP_CONFIG_RMC) {
struct mtp_config_rmc *data = packet->data.config_rmc;
......@@ -127,13 +147,8 @@ int mtp_encode_packet(char **buf_ptr,struct mtp_packet *packet) {
*((int *)(buf+i)) = htonl(data->robots[j].id);
i += 4;
// write the hostname field
int len = strlen(data->robots[j].hostname);
for (k = 0; k < len; ++k) {
buf[i] = data->robots[j].hostname[k];
++i;
}
buf[i] = '\0';
++i;
strcpy(&buf[i],data->robots[j].hostname);
i += strlen(&buf[i]) + 1;
}
// now write the global_bound data
*((int *)(buf+i)) = htonl(data->box.horizontal);
......@@ -166,13 +181,8 @@ int mtp_encode_packet(char **buf_ptr,struct mtp_packet *packet) {
*((int *)(buf+i)) = htonl(data->robots[j].id);
i += 4;
// write the hostname field
int len = strlen(data->robots[j].hostname);
for (k = 0; k < len; ++k) {
buf[i] = data->robots[j].hostname[k];
++i;
}
buf[i] = '\0';
++i;
strcpy(&buf[i],data->robots[j].hostname);
i += strlen(&buf[i]) + 1;
}
}
......@@ -338,7 +348,7 @@ int mtp_encode_packet(char **buf_ptr,struct mtp_packet *packet) {
int mtp_decode_packet(char *buf,struct mtp_packet **packet_ptr) {
struct mtp_packet *packet;
int i,j,k;
int i,j;
int len;
if (buf == NULL) {
......@@ -392,9 +402,11 @@ int mtp_decode_packet(char *buf,struct mtp_packet **packet_ptr) {
return MTP_PP_ERROR_MALLOC;
}
for (j = 0; j < data->num_robots; ++j) {
int len;
data->robots[j].id = ntohl(*((int *)(buf+i)));
i += 4;
int len = strlen(buf+i) + 1;
len = strlen(buf+i) + 1;
data->robots[j].hostname = (char *)malloc(sizeof(char)*len);
memcpy(data->robots[j].hostname,buf+i,len);
i += len;
......@@ -419,9 +431,11 @@ int mtp_decode_packet(char *buf,struct mtp_packet **packet_ptr) {
return MTP_PP_ERROR_MALLOC;
}
for (j = 0; j < data->num_robots; ++j) {
int len;
data->robots[j].id = ntohl(*((int *)(buf+i)));
i += 4;
int len = strlen(buf+i) + 1;
len = strlen(buf+i) + 1;
data->robots[j].hostname = (char *)malloc(sizeof(char)*len);
memcpy(data->robots[j].hostname,buf+i,len);
i += len;
......@@ -523,20 +537,20 @@ int mtp_decode_packet(char *buf,struct mtp_packet **packet_ptr) {
}
int mtp_send_packet(int fd,struct mtp_packet *packet) {
char **buf;
char *buf;
int retval;
if (packet == NULL) {
return MTP_PP_ERROR;
}
retval = mtp_encode_packet(buf,packet);
retval = mtp_encode_packet(&buf,packet);
if (retval < MTP_PP_SUCCESS) {
return retval;
}
// now we can write the buffer out the socket.
retval = write(fd,*buf,retval);
retval = write(fd,buf,retval);
if (retval != -1) {
return MTP_PP_SUCCESS;
}
......@@ -612,7 +626,7 @@ struct mtp_packet *mtp_make_packet( unsigned char opcode,
int mtp_calc_size(int opcode,void *data) {
int retval = -1;
int i,j;
int i;
if (data == NULL) {
return retval;
......
......@@ -48,7 +48,7 @@
#define MTP_ROLE_RMC 1
#define MTP_ROLE_EMULAB 5
/* These are used in the status fields in MTP_POSITION_UPDATE packets */
/* These are used in the status fields in MTP_UPDATE_POSITION packets */
#define MTP_POSITION_STATUS_IDLE 1
#define MTP_POSITION_STATUS_MOVING 2
#define MTP_POSITION_STATUS_ERROR 3
......@@ -68,6 +68,18 @@
#define MTP_PACKET_HEADER_OFFSET_VERSION 5
#define MTP_PACKET_HEADER_OFFSET_ROLE 6
typedef union mtp_payload_t {
struct mtp_control *control;
struct mtp_config_rmc *config_rmc;
struct mtp_config_vmc *config_vmc;
struct mtp_request_position *request_position;
struct mtp_request_id *request_id;
struct mtp_update_position *update_position;
struct mtp_update_id *update_id;
struct mtp_command_goto *command_goto;
struct mtp_command_stop *command_stop;
} mtp_payload_t;
/* here is the protocol definition in terms of structures */
typedef struct mtp_packet {
/* length has no meaning for user applications -- it's just there to better
......@@ -78,17 +90,7 @@ typedef struct mtp_packet {
unsigned char version;
unsigned char role;
union {
struct mtp_control *control;
struct mtp_config_rmc *config_rmc;
struct mtp_config_vmc *config_vmc;
struct mtp_request_position *request_position;
struct mtp_request_id *request_id;
struct mtp_update_position *update_position;
struct mtp_update_id *update_id;
struct mtp_command_goto *command_goto;
struct mtp_command_stop *command_stop;
} data;
mtp_payload_t data;
} mtp_packet_t;
......
#include "config.h"
#define DEBUG
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include "mtp.h"
int main(int argc, char *argv[])
{
static struct mtp_control mc = {
42,
MTP_PP_ERROR_MALLOC,
"I've come undone"
};
static struct robot_config rcr[3] = {
{ 1, "node1" },
{ 2, "node2" },
{ 3, "node3" },
};
static struct mtp_config_rmc mcr = {
3,
rcr,
{ 10.0, 20.0 }
};
static struct robot_config rcv[3] = {
{ 4, "vnode4" },
{ 5, "vnode5" },
{ 6, "vnode6" },
};
static struct mtp_config_vmc mcv = {
3,
rcv
};
static struct mtp_request_position mrp = {
4
};
static struct mtp_update_position mup = {
3,
{ 5, 25, 76 },
MTP_POSITION_STATUS_IDLE,
56
};
static struct mtp_request_id mri = {
{ 3, 20, 69 },
169
};
static struct mtp_update_id mui = {
30
};
static struct mtp_command_goto mcg = {
5,
3,
{ 2, 13, 73 },
};
static struct mtp_command_goto mcs = {
4,
2,
};
int fd, retval = EXIT_SUCCESS;
if ((fd = open("mtp_stream.dat", O_CREAT | O_TRUNC | O_RDWR, 0666)) < 0) {
perror("Could not open 'mtp_stream.dat'?");
}
else {
struct mtp_packet *mp;
int lpc;
assert(mp = mtp_make_packet(MTP_CONTROL_ERROR, MTP_ROLE_EMC, &mc));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_CONFIG_RMC, MTP_ROLE_RMC, &mcr));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_CONFIG_VMC, MTP_ROLE_VMC, &mcv));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_REQUEST_POSITION, MTP_ROLE_VMC, &mrp));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_UPDATE_POSITION, MTP_ROLE_VMC, &mup));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_REQUEST_ID, MTP_ROLE_VMC, &mri));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_UPDATE_ID, MTP_ROLE_VMC, &mui));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_COMMAND_GOTO, MTP_ROLE_VMC, &mcg));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
assert(mp = mtp_make_packet(MTP_COMMAND_STOP, MTP_ROLE_VMC, &mcs));
assert(mtp_send_packet(fd,mp) == MTP_PP_SUCCESS);
lseek(fd,0,SEEK_SET);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_CONTROL_ERROR);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_EMC);
assert(mp->data.control->id == mc.id);
assert(mp->data.control->code == mc.code);
assert(strcmp(mp->data.control->msg, mc.msg) == 0);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_CONFIG_RMC);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_RMC);
assert(mp->data.config_rmc->num_robots == mcr.num_robots);
assert(mp->data.config_rmc->box.horizontal == mcr.box.horizontal);
assert(mp->data.config_rmc->box.vertical == mcr.box.vertical);
for (lpc = 0; lpc < mcr.num_robots; lpc++) {
assert(mp->data.config_rmc->robots[lpc].id == mcr.robots[lpc].id);
assert(strcmp(mp->data.config_rmc->robots[lpc].hostname,
mcr.robots[lpc].hostname) == 0);
}
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_CONFIG_VMC);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.config_vmc->num_robots == mcv.num_robots);
for (lpc = 0; lpc < mcv.num_robots; lpc++) {
assert(mp->data.config_vmc->robots[lpc].id == mcv.robots[lpc].id);
assert(strcmp(mp->data.config_vmc->robots[lpc].hostname,
mcv.robots[lpc].hostname) == 0);
}
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_REQUEST_POSITION);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.request_position->robot_id == mrp.robot_id);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_UPDATE_POSITION);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.update_position->robot_id == mup.robot_id);
assert(mp->data.update_position->position.x == mup.position.x);
assert(mp->data.update_position->position.y == mup.position.y);
assert(mp->data.update_position->position.theta == mup.position.theta);
assert(mp->data.update_position->status == mup.status);
assert(mp->data.update_position->timestamp == mup.timestamp);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_REQUEST_ID);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.request_id->position.x == mri.position.x);
assert(mp->data.request_id->position.y == mri.position.y);
assert(mp->data.request_id->position.theta == mri.position.theta);
assert(mp->data.request_id->timestamp == mri.timestamp);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_UPDATE_ID);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.update_id->robot_id == mui.robot_id);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_COMMAND_GOTO);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.command_goto->command_id == mcg.command_id);
assert(mp->data.command_goto->robot_id == mcg.robot_id);
assert(mp->data.command_goto->position.x == mcg.position.x);
assert(mp->data.command_goto->position.y == mcg.position.y);
assert(mp->data.command_goto->position.theta == mcg.position.theta);
assert(mtp_receive_packet(fd,&mp) == MTP_PP_SUCCESS);
assert(mp->opcode == MTP_COMMAND_STOP);
assert(mp->version == MTP_VERSION);
assert(mp->role == MTP_ROLE_VMC);
assert(mp->data.command_goto->command_id == mcs.command_id);
assert(mp->data.command_goto->robot_id == mcs.robot_id);
close(fd);
fd = -1;
}
return retval;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment