1 /* picoproj - communication with AM7xxx based USB pico projectors
3 * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 * Examples of a packet headers:
30 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31 * +02|00|00|00|00|10|3e|10|01|00|00|00|20|03|00|00|e0|01|00|00|53|E8|00|00+
32 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
36 * +04|00|00|00|00|0c|ff|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00+
37 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 #define AM7x01_PACKET_TYPE_INIT 0x01
41 #define AM7x01_PACKET_TYPE_IMAGE 0x02
42 #define AM7x01_PACKET_TYPE_POWER 0x04
43 #define AM7x01_PACKET_TYPE_UNKNOWN 0x05
56 uint32_t payload_size;
64 static struct buffer *packet_allocate_buffer(struct packet *p)
66 struct buffer *buffer;
69 perror("packet NULL");
73 buffer = malloc(sizeof(*buffer));
75 perror("malloc buffer");
79 buffer->len = sizeof(p->header); /* + p->header.payload_size; */
81 buffer->data = malloc(buffer->len);
82 if (buffer->data == NULL) {
83 perror("malloc buffer->data");
90 static void packet_free_buffer(struct buffer *buffer)
97 static int packet_pack(struct packet *p, struct buffer *buffer)
102 if (p == NULL || buffer == NULL)
105 /* TODO: check for packet payload being NULL? */
106 if (buffer->data == NULL || buffer->len < sizeof(*p))
111 tmp = htole32(p->header.packet_type);
112 memcpy(buffer->data + offset, &tmp, sizeof(p->header.packet_type));
113 offset += sizeof(p->header.packet_type);
115 tmp = htole32(p->header.unknown1);
116 memcpy(buffer->data + offset, &tmp, sizeof(p->header.unknown1));
117 offset += sizeof(p->header.unknown1);
119 tmp = htole32(p->header.unknown2);
120 memcpy(buffer->data + offset, &tmp, sizeof(p->header.unknown2));
121 offset += sizeof(p->header.unknown2);
123 tmp = htole32(p->header.width);
124 memcpy(buffer->data + offset, &tmp, sizeof(p->header.width));
125 offset += sizeof(p->header.width);
127 tmp = htole32(p->header.height);
128 memcpy(buffer->data + offset, &tmp, sizeof(p->header.height));
129 offset += sizeof(p->header.height);
131 tmp = htole32(p->header.payload_size);
132 memcpy(buffer->data + offset, &tmp, sizeof(p->header.payload_size));
133 offset += sizeof(p->header.payload_size);
135 /* TODO memcpy payload of size */
140 static int packet_unpack(struct buffer *buffer, struct packet *p)
145 if (p == NULL || buffer == NULL)
148 /* TODO: check for packet payload being NULL? */
149 if (buffer->data == NULL || buffer->len < sizeof(*p))
154 memcpy(&tmp, buffer->data + offset, sizeof(p->header.packet_type));
155 p->header.packet_type = le32toh(tmp);
156 offset += sizeof(p->header.packet_type);
158 memcpy(&tmp, buffer->data + offset, sizeof(p->header.unknown1));
159 p->header.unknown1 = le32toh(tmp);
160 offset += sizeof(p->header.unknown1);
162 memcpy(&tmp, buffer->data + offset, sizeof(p->header.unknown2));
163 p->header.unknown2 = le32toh(tmp);
164 offset += sizeof(p->header.unknown2);
166 memcpy(&tmp, buffer->data + offset, sizeof(p->header.width));
167 p->header.width = le32toh(tmp);
168 offset += sizeof(p->header.width);
170 memcpy(&tmp, buffer->data + offset, sizeof(p->header.height));
171 p->header.height = le32toh(tmp);
172 offset += sizeof(p->header.height);
174 memcpy(&tmp, buffer->data + offset, sizeof(p->header.payload_size));
175 p->header.payload_size = le32toh(tmp);
176 offset += sizeof(p->header.payload_size);
178 /* malloc & memcpy payload of size p->header.payload_size */
183 static void packet_dump_header(struct packet *p)
188 printf("packet_type: 0x%08x (%u)\n", p->header.packet_type, p->header.packet_type);
189 printf("unknown1: 0x%08x (%u)\n", p->header.unknown1, p->header.unknown1);
190 printf("unknown2: 0x%08x (%u)\n", p->header.unknown2, p->header.unknown2);
191 printf("width: 0x%08x (%u)\n", p->header.width, p->header.width);
192 printf("height: 0x%08x (%u)\n", p->header.height, p->header.height);
193 printf("size: 0x%08x (%u)\n", p->header.payload_size, p->header.payload_size);
197 static void packet_dump_buffer(struct buffer *buffer)
204 if (buffer->data == NULL)
207 for (i = 0; i < buffer->len; i++) {
208 printf("%02hhX%c", buffer->data[i], (i < buffer->len - 1) ? ' ' : '\n');
217 .packet_type = AM7x01_PACKET_TYPE_IMAGE,
218 .unknown1 = le32toh(0x103e1000),
219 .unknown2 = le32toh(0x00000001),
222 .payload_size = 59475,
224 /* TODO initialize payload */
226 struct buffer *buffer = NULL;
230 packet_dump_header(&p1);
232 buffer = packet_allocate_buffer(&p1);
233 if (buffer == NULL) {
234 fprintf(stderr, "Cannot allocate the buffer.\n");
238 ret = packet_pack(&p1, buffer);
240 fprintf(stderr, "Cannot pack the packet.\n");
244 packet_dump_buffer(buffer);
246 ret = packet_unpack(buffer, &p2);
248 fprintf(stderr, "Cannot unpack the packet.\n");
252 packet_dump_header(&p2);
254 packet_free_buffer(buffer);