Initial import
authorAntonio Ospite <ospite@studenti.unina.it>
Fri, 6 Jan 2012 17:16:37 +0000 (18:16 +0100)
committerAntonio Ospite <ospite@studenti.unina.it>
Fri, 6 Jan 2012 17:17:06 +0000 (18:17 +0100)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
picoproj.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..1062ce4
--- /dev/null
@@ -0,0 +1,4 @@
+*~
+*.swp
+*.o
+picoproj
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..b8515ad
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,53 @@
+CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O2
+
+# Don't make pedantic checks errors,
+# as vanilla libusb-1.0.8 can't live with that
+#CFLAGS += -pedantic-errors
+
+# GCC >= 4.6
+#CFLAGS += -Wunused-but-set-variable
+
+CFLAGS += -fno-common \
+  -Wall \
+  -Wextra \
+  -Wformat=2 \
+  -Winit-self \
+  -Winline \
+  -Wpacked \
+  -Wp,-D_FORTIFY_SOURCE=2 \
+  -Wpointer-arith \
+  -Wlarger-than-65500 \
+  -Wmissing-declarations \
+  -Wmissing-format-attribute \
+  -Wmissing-noreturn \
+  -Wmissing-prototypes \
+  -Wnested-externs \
+  -Wold-style-definition \
+  -Wredundant-decls \
+  -Wsign-compare \
+  -Wstrict-aliasing=2 \
+  -Wstrict-prototypes \
+  -Wswitch-enum \
+  -Wundef \
+  -Wunreachable-code \
+  -Wunsafe-loop-optimizations \
+  -Wwrite-strings
+
+CFLAGS  += $(shell pkg-config --cflags libusb-1.0)
+LDLIBS += $(shell pkg-config --libs libusb-1.0)
+
+PREFIX ?= /usr/local
+bindir := $(PREFIX)/sbin
+
+all: picoproj
+
+CFLAGS += -D_BSD_SOURCE
+picoproj: picoproj.o
+
+
+install: picoproj
+       install -d $(DESTDIR)$(bindir)
+       install -m 755 picoproj $(DESTDIR)$(bindir)
+
+clean:
+       rm -rf *~ *.o picoproj
diff --git a/picoproj.c b/picoproj.c
new file mode 100644 (file)
index 0000000..f1c6a3b
--- /dev/null
@@ -0,0 +1,257 @@
+/* picoproj - communication with AM7xxx based USB pico projectors
+ *
+ * Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
+ *
+ * This program 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.
+ *
+ * This program 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <endian.h>
+#include <errno.h>
+
+/*
+ * Examples of a packet headers:
+ *
+ * Image widget:
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * +02|00|00|00|00|10|3e|10|01|00|00|00|20|03|00|00|e0|01|00|00|53|E8|00|00+
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ *
+ * Brightness widget:
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * +04|00|00|00|00|0c|ff|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00+
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+
+#define AM7x01_PACKET_TYPE_INIT           0x01
+#define AM7x01_PACKET_TYPE_IMAGE   0x02
+#define AM7x01_PACKET_TYPE_POWER   0x04
+#define AM7x01_PACKET_TYPE_UNKNOWN 0x05
+
+struct buffer {
+       unsigned int len;
+       uint8_t *data;
+};
+
+struct header{
+       uint32_t packet_type;
+       uint32_t unknown1;
+       uint32_t unknown2;
+       uint32_t width;
+       uint32_t height;
+       uint32_t payload_size;
+};
+
+struct packet {
+       struct header header;
+       uint8_t payload[];
+};
+
+static struct buffer *packet_allocate_buffer(struct packet *p)
+{
+       struct buffer *buffer;
+
+       if (p == NULL) {
+               perror("packet NULL");
+               return NULL;
+       }
+
+       buffer = malloc(sizeof(*buffer));
+       if (buffer == NULL) {
+               perror("malloc buffer");
+               return NULL;
+       }
+
+       buffer->len = sizeof(p->header); /* + p->header.payload_size; */
+
+       buffer->data = malloc(buffer->len);
+       if (buffer->data == NULL) {
+               perror("malloc buffer->data");
+               free(buffer);
+               return NULL;
+       }
+       return buffer;
+}
+
+static void packet_free_buffer(struct buffer *buffer)
+{
+       free(buffer->data);
+       free(buffer);
+       buffer = NULL;
+}
+
+static int packet_pack(struct packet *p, struct buffer *buffer)
+{
+       unsigned int offset;
+       uint32_t tmp;
+
+       if (p == NULL || buffer == NULL)
+               return -EINVAL;
+
+       /* TODO: check for packet payload being NULL? */
+       if (buffer->data == NULL || buffer->len < sizeof(*p))
+               return -EINVAL;
+
+       offset = 0;
+
+       tmp = htole32(p->header.packet_type);
+       memcpy(buffer->data + offset, &tmp, sizeof(p->header.packet_type));
+       offset += sizeof(p->header.packet_type);
+
+       tmp = htole32(p->header.unknown1);
+       memcpy(buffer->data + offset, &tmp, sizeof(p->header.unknown1));
+       offset += sizeof(p->header.unknown1);
+
+       tmp = htole32(p->header.unknown2);
+       memcpy(buffer->data + offset, &tmp, sizeof(p->header.unknown2));
+       offset += sizeof(p->header.unknown2);
+
+       tmp = htole32(p->header.width);
+       memcpy(buffer->data + offset, &tmp, sizeof(p->header.width));
+       offset += sizeof(p->header.width);
+
+       tmp = htole32(p->header.height);
+       memcpy(buffer->data + offset, &tmp, sizeof(p->header.height));
+       offset += sizeof(p->header.height);
+
+       tmp = htole32(p->header.payload_size);
+       memcpy(buffer->data + offset, &tmp, sizeof(p->header.payload_size));
+       offset += sizeof(p->header.payload_size);
+
+       /* TODO memcpy payload of size */
+
+       return 0;
+}
+
+static int packet_unpack(struct buffer *buffer, struct packet *p)
+{
+       unsigned int offset;
+       uint32_t tmp;
+
+       if (p == NULL || buffer == NULL)
+               return -EINVAL;
+
+       /* TODO: check for packet payload being NULL? */
+       if (buffer->data == NULL || buffer->len < sizeof(*p))
+               return -EINVAL;
+
+       offset = 0;
+
+       memcpy(&tmp, buffer->data + offset, sizeof(p->header.packet_type));
+       p->header.packet_type = le32toh(tmp);
+       offset += sizeof(p->header.packet_type);
+
+       memcpy(&tmp, buffer->data + offset, sizeof(p->header.unknown1));
+       p->header.unknown1 = le32toh(tmp);
+       offset += sizeof(p->header.unknown1);
+
+       memcpy(&tmp, buffer->data + offset, sizeof(p->header.unknown2));
+       p->header.unknown2 = le32toh(tmp);
+       offset += sizeof(p->header.unknown2);
+
+       memcpy(&tmp, buffer->data + offset, sizeof(p->header.width));
+       p->header.width = le32toh(tmp);
+       offset += sizeof(p->header.width);
+
+       memcpy(&tmp, buffer->data + offset, sizeof(p->header.height));
+       p->header.height = le32toh(tmp);
+       offset += sizeof(p->header.height);
+
+       memcpy(&tmp, buffer->data + offset, sizeof(p->header.payload_size));
+       p->header.payload_size = le32toh(tmp);
+       offset += sizeof(p->header.payload_size);
+
+       /* malloc & memcpy payload of size p->header.payload_size */
+
+       return 0;
+}
+
+static void packet_dump_header(struct packet *p)
+{
+       if (p == NULL)
+               return;
+
+       printf("packet_type: 0x%08x (%u)\n", p->header.packet_type, p->header.packet_type);
+       printf("unknown1:    0x%08x (%u)\n", p->header.unknown1, p->header.unknown1);
+       printf("unknown2:    0x%08x (%u)\n", p->header.unknown2, p->header.unknown2);
+       printf("width:       0x%08x (%u)\n", p->header.width, p->header.width);
+       printf("height:      0x%08x (%u)\n", p->header.height, p->header.height);
+       printf("size:        0x%08x (%u)\n", p->header.payload_size, p->header.payload_size);
+       fflush(stdout);
+}
+
+static void packet_dump_buffer(struct buffer *buffer)
+{
+       unsigned int i;
+
+       if (buffer == NULL)
+               return;
+
+       if (buffer->data == NULL)
+               return;
+
+       for (i = 0; i < buffer->len; i++) {
+               printf("%02hhX%c", buffer->data[i], (i < buffer->len - 1) ? ' ' : '\n');
+       }
+       fflush(stdout);
+}
+
+int main(void)
+{
+       struct packet p1  = {
+               .header = {
+                       .packet_type  = AM7x01_PACKET_TYPE_IMAGE,
+                       .unknown1     = le32toh(0x103e1000),
+                       .unknown2     = le32toh(0x00000001),
+                       .width        = 800,
+                       .height       = 480,
+                       .payload_size = 59475,
+               },
+               /* TODO initialize payload */
+       };
+       struct buffer *buffer = NULL;
+       struct packet p2;
+       int ret;
+
+       packet_dump_header(&p1);
+
+       buffer = packet_allocate_buffer(&p1);
+       if (buffer == NULL) {
+               fprintf(stderr, "Cannot allocate the buffer.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       ret = packet_pack(&p1, buffer);
+       if (ret < 0) {
+               fprintf(stderr, "Cannot pack the packet.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       packet_dump_buffer(buffer);
+
+       ret = packet_unpack(buffer, &p2);
+       if (ret < 0) {
+               fprintf(stderr, "Cannot unpack the packet.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       packet_dump_header(&p2);
+
+       packet_free_buffer(buffer);
+
+       exit(EXIT_SUCCESS);
+}