2
* Written by Oron Peled <oron@actcom.co.il>
3
* Copyright (C) 2009, Xorcom
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
#include <arpa/inet.h>
32
static const char rcsid[] = "$Id: xtalk.c 9825 2011-03-10 18:48:11Z tzafrir $";
39
* Base XTALK device. A pointer to this struct
40
* should be included in the struct representing
44
void *transport_priv; /* e.g: struct xusb */
46
struct xtalk_protocol xproto;
47
uint8_t xtalk_proto_version;
50
uint16_t tx_sequenceno;
57
CMD_DEF(XTALK, PROTO_GET,
58
uint8_t proto_version;
62
CMD_DEF(XTALK, PROTO_GET_REPLY,
63
uint8_t proto_version;
67
union XTALK_PDATA(XTALK) {
69
MEMBER(XTALK, PROTO_GET);
70
MEMBER(XTALK, PROTO_GET_REPLY);
73
struct xtalk_protocol xtalk_base = {
77
CMD_RECV(XTALK, ACK, NULL),
78
CMD_SEND(XTALK, PROTO_GET),
79
CMD_RECV(XTALK, PROTO_GET_REPLY, NULL),
82
ACK_STAT(OK, "Acknowledges previous command"),
83
ACK_STAT(FAIL, "Last command failed"),
84
ACK_STAT(RESET_FAIL, "reset failed"),
85
ACK_STAT(NODEST, "No destination is selected"),
86
ACK_STAT(MISMATCH, "Data mismatch"),
87
ACK_STAT(NOACCESS, "No access"),
88
ACK_STAT(BAD_CMD, "Bad command"),
89
ACK_STAT(TOO_SHORT, "Packet is too short"),
90
ACK_STAT(ERROFFS, "Offset error (not used)"),
91
ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"),
92
ACK_STAT(NO_EEPROM, "No EEPROM was found"),
93
ACK_STAT(WRITE_FAIL, "Writing to device failed"),
94
ACK_STAT(NOPWR_ERR, "No power on USB connector"),
98
void free_command(struct xtalk_command *cmd)
102
memset(cmd, 0, cmd->header.len);
106
static const struct xtalk_command_desc *get_command_desc(const struct xtalk_protocol *xproto, uint8_t op)
108
const struct xtalk_command_desc *desc;
112
desc = &xproto->commands[op];
116
DBG("%s version=%d, op=0x%X (%s)\n",
117
xproto->name, xproto->proto_version,
123
static const char *ack_status_msg(const struct xtalk_protocol *xproto, uint8_t status)
125
const char *ack_status;
129
ack_status = xproto->ack_statuses[status];
130
DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status);
134
int xtalk_set_protocol(struct xtalk_device *xtalk_dev, const struct xtalk_protocol *xproto)
136
const char *protoname = (xproto) ? xproto->name : "GLOBAL";
139
DBG("%s\n", protoname);
140
memset(&xtalk_dev->xproto, 0, sizeof(xtalk_dev->xproto));
141
for(i = 0; i < MAX_OPS; i++) {
142
const struct xtalk_command_desc *desc;
144
desc = get_command_desc(xproto, i);
146
if(!IS_PRIVATE_OP(i)) {
147
ERR("Bad op=0x%X (should be in the range [0x%X-0x%X]\n",
148
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
151
xtalk_dev->xproto.commands[i] = *desc;
152
DBG("private: op=0x%X (%s)\n", i, desc->name);
154
if(!IS_PRIVATE_OP(i)) {
157
xtalk_dev->xproto.commands[i] = xtalk_base.commands[i];
158
name = xtalk_dev->xproto.commands[i].name;
160
DBG("global: op=0x%X (%s)\n", i, name);
164
for(i = 0; i < MAX_STATUS; i++) {
165
const char *stat_msg;
167
stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL;
169
if(!IS_PRIVATE_OP(i)) {
170
ERR("Bad status=0x%X (should be in the range [0x%X-0x%X]\n",
171
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
174
xtalk_dev->xproto.ack_statuses[i] = stat_msg;
175
DBG("private: status=0x%X (%s)\n", i, stat_msg);
177
if(!IS_PRIVATE_OP(i)) {
178
const char *stat_msg;
180
xtalk_dev->xproto.ack_statuses[i] = xtalk_base.ack_statuses[i];
181
stat_msg = xtalk_dev->xproto.ack_statuses[i];
183
DBG("global: status=0x%X (%s)\n", i, stat_msg);
187
xtalk_dev->xproto.name = protoname;
188
xtalk_dev->xproto.proto_version = (xproto) ? xproto->proto_version : 0;
192
struct xtalk_command *new_command(
193
const struct xtalk_device *xtalk_dev,
194
uint8_t op, uint16_t extra_data)
196
const struct xtalk_protocol *xproto;
197
struct xtalk_command *cmd;
198
const struct xtalk_command_desc *desc;
201
xproto = &xtalk_dev->xproto;
202
desc = get_command_desc(xproto, op);
204
ERR("Unknown op=0x%X.\n", op);
207
DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data);
208
len = desc->len + extra_data;
209
if((cmd = malloc(len)) == NULL) {
210
ERR("Out of memory\n");
214
uint8_t *ptr = (uint8_t *)cmd;
216
DBG("clear extra_data (%d bytes)\n", extra_data);
217
memset(ptr + desc->len, 0, extra_data);
220
cmd->header.len = len;
221
cmd->header.seq = 0; /* Overwritten in send_usb() */
225
void xtalk_dump_command(struct xtalk_command *cmd)
230
len = cmd->header.len;
231
if(len < sizeof(struct xtalk_header)) {
232
ERR("Command too short (%d)\n", len);
235
INFO("DUMP: OP=0x%X len=%d seq=%d\n",
236
cmd->header.op, cmd->header.len, cmd->header.seq);
237
for(i = 0; i < len - sizeof(struct xtalk_header); i++) {
238
INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]);
242
static int send_command(struct xtalk_device *xtalk_dev, struct xtalk_command *cmd, int timeout)
247
void *priv = xtalk_dev->transport_priv;
249
len = cmd->header.len;
250
cmd->header.seq = xtalk_dev->tx_sequenceno;
253
//printf("%s: len=%d\n", __FUNCTION__, len);
259
fprintf(fp, "%05d:", cmd->header.seq);
260
for(i = 0; i < len; i++)
261
fprintf(fp, " %02X", (uint8_t)buf[i]);
265
ret = xtalk_dev->ops.send_func(priv, (char *)cmd, len, timeout);
267
DBG("send_func failed ret=%d\n", ret);
269
xtalk_dev->tx_sequenceno++;
273
static struct xtalk_command *recv_command(struct xtalk_device *xtalk_dev, int timeout)
275
struct xtalk_command *reply;
276
void *priv = xtalk_dev->transport_priv;
279
if((reply = malloc(xtalk_dev->packet_size)) == NULL) {
280
ERR("Out of memory\n");
283
reply->header.len = 0;
284
ret = xtalk_dev->ops.recv_func(priv, (char *)reply, xtalk_dev->packet_size, timeout);
286
ERR("Receive from usb failed.\n");
288
} else if(ret == 0) {
289
goto err; /* No reply */
291
if(ret != reply->header.len) {
292
ERR("Wrong length received: got %d bytes, but length field says %d bytes%s\n",
293
ret, reply->header.len,
294
(ret == 1)? ". Old USB firmware?": "");
297
//dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, (char *)reply, ret);
301
memset(reply, 0, xtalk_dev->packet_size);
308
__attribute__((warn_unused_result))
310
struct xtalk_device *xtalk_dev,
311
struct xtalk_command *cmd,
312
struct xtalk_command **reply_ref)
314
const struct xtalk_protocol *xproto;
315
struct xtalk_command *reply = NULL;
316
const struct xtalk_command_desc *reply_desc;
317
const struct xtalk_command_desc *expected;
318
const struct xtalk_command_desc *cmd_desc;
320
const char *protoname;
323
xproto = &xtalk_dev->xproto;
324
protoname = (xproto) ? xproto->name : "GLOBAL";
326
*reply_ref = NULL; /* So the caller knows if a reply was received */
327
reply_op = cmd->header.op | XTALK_REPLY_MASK;
328
cmd_desc = get_command_desc(xproto, cmd->header.op);
329
expected = get_command_desc(xproto, reply_op);
330
//printf("%s: len=%d\n", __FUNCTION__, cmd->header.len);
331
ret = send_command(xtalk_dev, cmd, TIMEOUT);
333
DBG("No reply requested\n");
337
ERR("send_command failed: %d\n", ret);
340
reply = recv_command(xtalk_dev, TIMEOUT);
342
ERR("recv_command failed\n");
347
if((reply->header.op & 0x80) != 0x80) {
348
ERR("Unexpected reply op=0x%02X, should have MSB set.\n", reply->header.op);
352
DBG("REPLY OP: 0x%X\n", reply->header.op);
353
reply_desc = get_command_desc(xproto, reply->header.op);
355
ERR("Unknown reply (proto=%s) op=0x%02X\n", protoname, reply->header.op);
359
DBG("REPLY NAME: %s\n", reply_desc->name);
360
if(reply->header.op == XTALK_ACK) {
361
int status = CMD_FIELD(reply, XTALK, ACK, stat);
364
ERR("Expected OP=0x%02X: Got ACK(%d): %s\n",
365
reply_op, status, ack_status_msg(xproto, status));
368
} else if(status != STAT_OK) {
370
ERR("Got ACK (for OP=0x%X [%s]): %d %s\n",
373
status, ack_status_msg(xproto, status));
377
fprintf(fp, "Got ACK(%d)\n", status);
383
/* Good expected ACK ... */
384
} else if(reply->header.op != reply_op) {
385
ERR("Expected OP=0x%02X: Got OP=0x%02X\n",
386
reply_op, reply->header.op);
390
if(expected && expected->len > reply->header.len) {
391
ERR("Expected len=%d: Got len=%d\n",
392
expected->len, reply->header.len);
396
if(cmd->header.seq != reply->header.seq) {
397
ERR("Expected seq=%d: Got seq=%d\n",
398
cmd->header.seq, reply->header.seq);
402
ret = reply->header.len; /* All good, return the length */
403
DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret);
406
if(!reply_ref && reply)
415
int xtalk_proto_query(struct xtalk_device *xtalk_dev)
417
struct xtalk_command *cmd;
418
struct xtalk_command *reply;
419
uint8_t proto_version;
423
assert(xtalk_dev != NULL);
424
proto_version = xtalk_dev->xproto.proto_version;
425
if((cmd = new_command(xtalk_dev, XTALK_PROTO_GET, 0)) == NULL) {
426
ERR("new_command failed\n");
429
CMD_FIELD(cmd, XTALK, PROTO_GET, proto_version) = proto_version; /* Protocol Version */
430
ret = process_command(xtalk_dev, cmd, &reply);
432
ERR("process_command failed: %d\n", ret);
435
xtalk_dev->xtalk_proto_version = CMD_FIELD(reply, XTALK, PROTO_GET_REPLY, proto_version);
436
if(xtalk_dev->xtalk_proto_version != proto_version) {
437
ERR("Got %s protocol version: 0x%02x (expected 0x%02x)\n",
438
xtalk_dev->xproto.name,
439
xtalk_dev->xtalk_proto_version,
441
ret = xtalk_dev->xtalk_proto_version;
444
DBG("Protocol version: %02x\n", xtalk_dev->xtalk_proto_version);
445
ret = xtalk_dev->xtalk_proto_version;
455
struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, size_t packet_size, void *priv)
457
struct xtalk_device *xtalk_dev;
462
if((xtalk_dev = malloc(sizeof(*xtalk_dev))) == NULL) {
463
ERR("Allocating XTALK device memory failed\n");
466
memset(xtalk_dev, 0, sizeof(*xtalk_dev));
467
memcpy((void *)&xtalk_dev->ops, (const void *)ops, sizeof(xtalk_dev->ops));
468
xtalk_dev->transport_priv = priv;
469
xtalk_dev->packet_size = packet_size;
470
xtalk_dev->tx_sequenceno = 1;
471
ret = xtalk_set_protocol(xtalk_dev, NULL);
473
ERR("GLOBAL Protocol registration failed: %d\n", ret);
480
xtalk_delete(xtalk_dev);
484
void xtalk_delete(struct xtalk_device *xtalk_dev)
491
priv = xtalk_dev->transport_priv;
493
xtalk_dev->tx_sequenceno = 0;
494
assert(&xtalk_dev->ops != NULL);
495
assert(&xtalk_dev->ops.close_func != NULL);
496
xtalk_dev->ops.close_func(priv);