Browse Source

xpp: add all base libxtalk files

* Do not remove yet the old ones.
* So new files are built, but not used yet.
* Build as a "noinst_" convenience library.
* Also, compile with '-Wno-unknown-pragmas' because we use some pragmas.

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
master
Oron Peled 7 years ago
committed by Tzafrir Cohen
parent
commit
9c61e40187
  1. 6
      .gitignore
  2. 1
      configure.ac
  3. 2
      xpp/Makefile.am
  4. 84
      xpp/xtalk/Makefile.am
  5. 3
      xpp/xtalk/debug.c
  6. 38
      xpp/xtalk/include/xtalk/api_defs.h
  7. 53
      xpp/xtalk/include/xtalk/debug.h
  8. 40
      xpp/xtalk/include/xtalk/firmware_defs.h
  9. 186
      xpp/xtalk/include/xtalk/proto.h
  10. 76
      xpp/xtalk/include/xtalk/proto_raw.h
  11. 75
      xpp/xtalk/include/xtalk/proto_sync.h
  12. 32
      xpp/xtalk/include/xtalk/xlist.h
  13. 19
      xpp/xtalk/include/xtalk/xtalk_iface.h
  14. 115
      xpp/xtalk/include/xtalk/xusb.h
  15. 43
      xpp/xtalk/include/xtalk/xusb_iface.h
  16. 14
      xpp/xtalk/xlist.c
  17. 73
      xpp/xtalk/xlist_test.c
  18. 70
      xpp/xtalk/xtalk-xusb.c
  19. 353
      xpp/xtalk/xtalk_base.c
  20. 73
      xpp/xtalk/xtalk_base.h
  21. 221
      xpp/xtalk/xtalk_raw.c
  22. 207
      xpp/xtalk/xtalk_raw_test.c
  23. 49
      xpp/xtalk/xtalk_send.8
  24. 220
      xpp/xtalk/xtalk_send.c
  25. 290
      xpp/xtalk/xtalk_sync.c
  26. 199
      xpp/xtalk/xtalk_test.c
  27. 381
      xpp/xtalk/xusb_common.c
  28. 104
      xpp/xtalk/xusb_common.h
  29. 843
      xpp/xtalk/xusb_libusb.c
  30. 826
      xpp/xtalk/xusb_libusbx.c
  31. 124
      xpp/xtalk/xusb_test.c
  32. 76
      xpp/xtalk/xusb_test_bypath.c

6
.gitignore

@ -69,4 +69,10 @@ xpp/test_parse
xpp/twinstar.8
xpp/xpp_blink.8
xpp/xpp_sync.8
xpp/xtalk/xlist_test
xpp/xtalk/xtalk_raw_test
xpp/xtalk/xtalk_send
xpp/xtalk/xtalk_test
xpp/xtalk/xusb_test
xpp/xtalk/xusb_test_bypath
zonedata.lo

1
configure.ac

@ -372,6 +372,7 @@ AC_CONFIG_FILES([
hotplug/Makefile
ppp/Makefile
xpp/Makefile
xpp/xtalk/Makefile
xpp/oct612x/Makefile
xpp/perl_modules/Makefile
])

2
xpp/Makefile.am

@ -64,7 +64,7 @@ CLEANFILES = $(perl_checks) $(perl_mans)
if PBX_USB
SUBDIRS += oct612x
SUBDIRS += oct612x xtalk
if LIBUSBX
USB_CFLAGS = $(LIBUSBX_CFLAGS)

84
xpp/xtalk/Makefile.am

@ -0,0 +1,84 @@
VISIBILITY_DEFS = -DXTALK_DLL -DXTALK_DLL_EXPORTS
COMMON_CFLAGS = -Wall -Wno-unknown-pragmas -Werror $(VISIBILITY_DEFS) $(CFLAG_VISIBILITY)
AM_CFLAGS = $(COMMON_CFLAGS)
if LIBUSBX
USB_CFLAGS = $(LIBUSBX_CFLAGS)
USB_LIBS = $(LIBUSBX_LIBS)
USB_NAME = libusbx
else
if LIBUSB
USB_CFLAGS = $(LIBUSB_CFLAGS)
USB_LIBS = $(LIBUSB_LIBS)
USB_NAME = libusb
endif
endif
noinst_PROGRAMS = xlist_test xusb_test xusb_test_bypath xtalk_test xtalk_raw_test
sbin_PROGRAMS = xtalk_send
noinst_LTLIBRARIES = libxtalk.la
dist_noinst_HEADERS = \
debug.h \
xlist.h \
xtalk.h \
xtalk_base.h \
xtalk_defs.h \
xusb.h \
xusb_common.h \
include/xtalk/proto_raw.h \
include/xtalk/api_defs.h \
include/xtalk/xlist.h \
include/xtalk/proto_sync.h \
include/xtalk/xusb_iface.h \
include/xtalk/proto.h \
include/xtalk/debug.h \
include/xtalk/xusb.h \
include/xtalk/firmware_defs.h \
include/xtalk/xtalk_iface.h \
#
man_MANS = xtalk_send.8
libxtalk_la_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir) $(USB_CFLAGS)
libxtalk_la_LDFLAGS = #
libxtalk_la_LIBADD = $(USB_LIBS)
libxtalk_la_SOURCES = \
$(dist_noinst_HEADERS) \
xtalk_sync.c \
xtalk_raw.c \
xtalk_base.c \
xlist.c \
debug.c \
xtalk-xusb.c \
xusb_common.c
if LIBUSBX
libxtalk_la_SOURCES += xusb_libusbx.c
else
if LIBUSB
libxtalk_la_SOURCES += xusb_libusb.c
endif
endif
libxtalk_la_DEPENDENCIES = $(libxtalk_la_SOURCES)
xtalk_send_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
xtalk_send_LDADD = libxtalk.la $(USB_LIBS)
xtalk_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
xtalk_test_LDADD = libxtalk.la $(USB_LIBS)
xtalk_raw_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
xtalk_raw_test_LDADD = libxtalk.la $(USB_LIBS)
xusb_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
xusb_test_LDADD = libxtalk.la $(USB_LIBS)
xusb_test_bypath_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
xusb_test_bypath_LDADD = libxtalk.la $(USB_LIBS)
xlist_test_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/include -I$(srcdir)
xlist_test_LDADD = libxtalk.la $(USB_LIBS)
DISTCLEANFILES = xtalk.pc xtalk-uninstalled.pc
EXTRA_DIST = $(man_MANS)

3
xpp/xtalk/debug.c

@ -27,7 +27,8 @@
#include <stdarg.h>
#include <syslog.h>
#include <execinfo.h>
#include <debug.h>
#include <xtalk/debug.h>
#include <autoconfig.h>
int verbose = LOG_INFO;
int debug_mask;

38
xpp/xtalk/include/xtalk/api_defs.h

@ -0,0 +1,38 @@
#ifndef XTALK_API_DEFS_H
#define XTALK_API_DEFS_H
/*
* Visibility settings: taken from:
* http://gcc.gnu.org/wiki/Visibility
*/
/* Generic helper definitions for shared library support */
#if __GNUC__ >= 4
#define XTALK_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
#define XTALK_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
#define XTALK_HELPER_DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define XTALK_HELPER_DLL_IMPORT
#define XTALK_HELPER_DLL_EXPORT
#define XTALK_HELPER_DLL_LOCAL
#endif
/*
* Now we use the generic helper definitions above to define XTALK_API and XTALK_LOCAL.
* XTALK_API is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build)
* XTALK_LOCAL is used for non-api symbols.
*/
#ifdef XTALK_DLL /* defined if XTALK is compiled as a DLL */
#ifdef XTALK_DLL_EXPORTS /* defined if we are building the XTALK DLL (instead of using it) */
#define XTALK_API XTALK_HELPER_DLL_EXPORT
#else
#define XTALK_API XTALK_HELPER_DLL_IMPORT
#endif /* XTALK_DLL_EXPORTS */
#define XTALK_LOCAL XTALK_HELPER_DLL_LOCAL
#else /* XTALK_DLL is not defined: this means XTALK is a static lib. */
#define XTALK_API
#define XTALK_LOCAL
#endif /* XTALK_DLL */
#endif /* XTALK_API_DEFS_H */

53
xpp/xtalk/include/xtalk/debug.h

@ -0,0 +1,53 @@
#ifndef DEBUG_H
#define DEBUG_H
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2008, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <syslog.h>
#include <stdio.h>
#include <xtalk/api_defs.h>
/*
* Each module should define a unique DBG_MASK
*/
XTALK_API extern int verbose;
XTALK_API extern int debug_mask;
/*
* Logging
*/
XTALK_API void log_function(int level, int mask, const char *msg, ...)
__attribute__((format(printf, 3, 4)));
#define ERR(fmt, arg...) log_function(LOG_ERR, 0, "%s:%d: ERROR(%s): " fmt, \
__FILE__, __LINE__, __func__, ## arg)
#define WARN(fmt, arg...) log_function(LOG_WARNING, 0, "WARNING: " fmt, ## arg)
#define INFO(fmt, arg...) log_function(LOG_INFO, 0, "INFO: " fmt, ## arg)
#define DBG(fmt, arg...) log_function(LOG_DEBUG, DBG_MASK, \
"%s:%d: DBG(%s): " fmt, __FILE__, __LINE__, __func__, ## arg)
XTALK_API void dump_packet(int loglevel, int mask, const char *msg,
const char *buf, int len);
XTALK_API void print_backtrace(FILE *fp);
#endif /* DEBUG_H */

40
xpp/xtalk/include/xtalk/firmware_defs.h

@ -0,0 +1,40 @@
#ifndef XTALK_FIRMWARE_DEFS_H
#define XTALK_FIRMWARE_DEFS_H
#define MAX_OPS 256 /* single byte */
#define MAX_STATUS 256 /* single byte */
#define XTALK_REPLY_MASK 0x80 /* Every reply has this bit */
#define PRIVATE_OP_FIRST 0x05
#define PRIVATE_OP_LAST 0x7F
#define IS_PRIVATE_OP(x) ( \
(((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \
(((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \
)
#define XTALK_ACK 0x80
#define XTALK_PROTO_GET 0x01
#define XTALK_PROTO_GET_REPLY (XTALK_PROTO_GET | XTALK_REPLY_MASK)
#define XTALK_FWVERS_GET 0x11
#define XTALK_FWVERS_GET_REPLY (XTALK_FWVERS_GET | XTALK_REPLY_MASK)
#define XTALK_CAPS_GET 0x0E /* Get EEPROM table contents Product/Vendor Id ... */
#define XTALK_CAPS_GET_REPLY (XTALK_CAPS_GET | XTALK_REPLY_MASK)
/*------------- XTALK: statuses in ACK ---------------------------------------*/
#define STAT_OK 0x00 /* OK */
#define STAT_FAIL 0x01 /* last command failed */
#define STAT_RESET_FAIL 0x02 /* reset failed */
#define STAT_NODEST 0x03 /* No destination is selected */
#define STAT_MISMATCH 0x04 /* Data mismatch */
#define STAT_NOACCESS 0x05 /* No access */
#define STAT_BAD_CMD 0x06 /* Bad command */
#define STAT_TOO_SHORT 0x07 /* Packet is too short */
#define STAT_ERROFFS 0x08 /* Offset error (not used) */
#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */
#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */
#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */
#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */
#endif /* XTALK_FIRMWARE_DEFS_H */

186
xpp/xtalk/include/xtalk/proto.h

@ -0,0 +1,186 @@
#ifndef XTALK_PROTO_H
#define XTALK_PROTO_H
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2009, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* XTALK - Base protocol for our USB devices
* It is meant to provide a common base for layered
* protocols (dialects)
*/
#include <stdint.h>
#include <stdlib.h>
#include <xtalk/api_defs.h>
#include <xtalk/firmware_defs.h>
#ifdef __GNUC__
#define PACKED __attribute__((packed))
#else
#error "We do not know how your compiler packs structures"
#endif
struct xtalk_base;
struct xtalk_command_desc;
struct xtalk_command;
/*
* Callbacks should return negative errno's
* in case of errors.
* They are called from process_command() and their
* return values are propagated back.
*/
typedef int (*xtalk_cmd_callback_t)(
const struct xtalk_base *xtalk_base,
const struct xtalk_command_desc *cmd_desc,
struct xtalk_command *cmd);
/* Describe a single xtalk command */
struct xtalk_command_desc {
uint8_t op;
const char *name;
uint16_t len; /* Minimal length */
};
/* Define a complete protocol */
struct xtalk_protocol {
const char *name;
uint8_t proto_version;
struct xtalk_command_desc commands[MAX_OPS];
const char *ack_statuses[MAX_STATUS];
};
/*
* The common header of every xtalk command
* in every xtalk dialect.
*/
struct xtalk_header {
uint16_t len;
uint16_t seq;
uint8_t op; /* MSB: 0 - to device, 1 - from device */
} PACKED;
struct xtalk_command {
/* Common part */
struct xtalk_header header;
/* Each dialect has its own data members */
union private_data {
uint8_t raw_data[0];
} PACKED alt;
} PACKED;
/*
* Macros to unify access to protocol packets and fields:
* p - signify the dialect prefix (XTALK for base protocol)
* o - signify command op (e.g: ACK)
* cmd - A pointer to struct xtalk_command
* field - field name (e.g: raw_data)
*/
#define XTALK_STRUCT(p, o) p ## _struct_ ## o
#define XTALK_PDATA(o) xtalk_privdata_ ## o
#define XTALK_CMD_PTR(cmd, p) ((union XTALK_PDATA(p)*)&((cmd)->alt))
#define CMD_FIELD(cmd, p, o, field) \
(XTALK_CMD_PTR(cmd, p)->XTALK_STRUCT(p, o).field)
#define CMD_DEF(p, o, ...) struct XTALK_STRUCT(p, o) { \
__VA_ARGS__ \
} PACKED XTALK_STRUCT(p, o)
#define MEMBER(p, o) struct XTALK_STRUCT(p, o) XTALK_STRUCT(p, o)
#define XTALK_OP(p, o) (p ## _ ## o)
/* Wrappers for transport (xusb) functions */
struct xtalk_ops {
int (*send_func)(void *transport_priv, const char *data, size_t len,
int timeout);
int (*recv_func)(void *transport_priv, char *data, size_t maxlen,
int timeout);
int (*close_func)(void *transport_priv);
};
/*
* Base XTALK device. A pointer to this struct
* should be included in the struct representing
* the dialect.
*/
struct xtalk_base;
struct xusb_iface;
/* high-level */
XTALK_API struct xtalk_base *xtalk_base_new_on_xusb(struct xusb_iface *xusb_iface);
XTALK_API struct xtalk_base *xtalk_base_new(const struct xtalk_ops *ops,
size_t packet_size, void *priv);
XTALK_API void xtalk_base_delete(struct xtalk_base *xtalk_base);
XTALK_API struct xusb_iface *xusb_iface_of_xtalk_base(const struct xtalk_base *xtalk_base);
XTALK_API const char *xtalk_protocol_name(const struct xtalk_base *dev);
XTALK_API int xtalk_cmd_callback(struct xtalk_base *xtalk_base, int op,
xtalk_cmd_callback_t callback,
xtalk_cmd_callback_t *old_callback);
XTALK_API void xtalk_dump_command(struct xtalk_command *cmd);
XTALK_API int xtalk_set_timeout(struct xtalk_base *dev, int new_timeout);
/* low-level */
XTALK_API const char *ack_status_msg(const struct xtalk_protocol *xproto,
uint8_t status);
XTALK_API struct xtalk_command *new_command(
const struct xtalk_base *xtalk_base,
uint8_t op, uint16_t extra_data);
XTALK_API void free_command(struct xtalk_command *cmd);
/*
* Convenience macros to define entries in a protocol command table:
* p - signify the dialect prefix (XTALK for base protocol)
* o - signify command op (e.g: ACK)
*/
#define CMD_RECV(p, o) \
[p ## _ ## o | XTALK_REPLY_MASK] = { \
.op = (p ## _ ## o) | XTALK_REPLY_MASK, \
.name = (#o "_reply"), \
.len = \
sizeof(struct xtalk_header) + \
sizeof(struct XTALK_STRUCT(p, o)), \
}
#define CMD_SEND(p, o) \
[p ## _ ## o] = { \
.op = (p ## _ ## o), \
.name = (#o), \
.len = \
sizeof(struct xtalk_header) + \
sizeof(struct XTALK_STRUCT(p, o)), \
}
/*
* Convenience macro to define statuses:
* x - status code (e.g: OK)
* m - status message (const char *)
*/
#define ACK_STAT(x, m) [STAT_ ## x] = (m)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XTALK_PROTO_H */

76
xpp/xtalk/include/xtalk/proto_raw.h

@ -0,0 +1,76 @@
#ifndef XTALK_PROTO_RAW_H
#define XTALK_PROTO_RAW_H
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2009, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* XTALKSYNC - Base synchronous protocol for our USB devices
* It is meant to provide a common base for layered
* protocols (dialects)
*/
#include <stdint.h>
#include <stdlib.h>
#include <xtalk/api_defs.h>
#include <xtalk/proto.h>
#include <xtalk/firmware_defs.h>
#ifdef __GNUC__
#define PACKED __attribute__((packed))
#else
#error "We do not know how your compiler packs structures"
#endif
/*
* Base XTALK device. A pointer to this struct
* should be included in the struct representing
* the dialect.
*/
struct xtalk_raw;
struct xusb;
XTALK_API struct xtalk_raw *xtalk_raw_new(struct xtalk_base *xtalk_base);
XTALK_API void xtalk_raw_delete(struct xtalk_raw *xraw);
XTALK_API int xtalk_raw_set_protocol(struct xtalk_raw *xtalk_base,
const struct xtalk_protocol *xproto);
XTALK_API int xtalk_raw_cmd_recv(struct xtalk_raw *xraw,
struct xtalk_command **reply_ref);
XTALK_API int xtalk_raw_cmd_send(struct xtalk_raw *xraw, const char *buf, int len,
uint16_t *tx_seq);
/*
* These are low-level interfaces that receive/send arbitrary buffers
* Be carefull, as that allow to send illegal Xtalk packets
*/
XTALK_API int xtalk_raw_buffer_recv(struct xtalk_raw *xraw, char *buf, int len);
XTALK_API int xtalk_raw_buffer_send(struct xtalk_raw *xraw, const char *buf, int len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XTALK_PROTO_RAW_H */

75
xpp/xtalk/include/xtalk/proto_sync.h

@ -0,0 +1,75 @@
#ifndef XTALK_PROTO_SYNC_H
#define XTALK_PROTO_SYNC_H
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2009, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <xtalk/api_defs.h>
#include <xtalk/proto.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* XTALKSYNC - Base synchronous protocol for our USB devices
* It is meant to provide a common base for layered
* protocols (dialects)
*/
#include <stdint.h>
#include <stdlib.h>
#include <xtalk/firmware_defs.h>
#ifdef __GNUC__
#define PACKED __attribute__((packed))
#else
#error "We do not know how your compiler packs structures"
#endif
/*
* Base XTALK device. A pointer to this struct
* should be included in the struct representing
* the dialect.
*/
struct xtalk_sync;
struct xusb;
/* high-level */
XTALK_API struct xtalk_sync *xtalk_sync_new(struct xtalk_base *xtalk_base);
XTALK_API void xtalk_sync_delete(struct xtalk_sync *xtalk_sync);
XTALK_API int xtalk_sync_set_protocol(struct xtalk_sync *xtalk_base,
const struct xtalk_protocol *xproto);
XTALK_API int xtalk_proto_query(struct xtalk_sync *dev);
/* low-level */
XTALK_API int process_command(
struct xtalk_sync *dev,
struct xtalk_command *cmd,
struct xtalk_command **reply_ref,
uint16_t *sequence_number);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XTALK_PROTO_SYNC_H */

32
xpp/xtalk/include/xtalk/xlist.h

@ -0,0 +1,32 @@
#ifndef XLIST_H
#define XLIST_H
#include <xtalk/api_defs.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
struct xlist_node {
void *data;
struct xlist_node *next;
struct xlist_node *prev;
};
typedef void (*xlist_destructor_t)(void *data);
XTALK_API struct xlist_node *xlist_new(void *data);
XTALK_API void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor);
XTALK_API void xlist_append_list(struct xlist_node *list1, struct xlist_node *list2);
XTALK_API void xlist_append_item(struct xlist_node *list, struct xlist_node *item);
XTALK_API void xlist_remove_item(struct xlist_node *item);
XTALK_API struct xlist_node *xlist_shift(struct xlist_node *list);
XTALK_API int xlist_empty(const struct xlist_node *list);
XTALK_API size_t xlist_length(const struct xlist_node *list);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XLIST_H */

19
xpp/xtalk/include/xtalk/xtalk_iface.h

@ -0,0 +1,19 @@
/*
* Wrappers for swig/python integration
*/
struct Command {
struct xtalk_command *command;
};
struct Xtalksync {
struct xtalk_base *xtalk_base;
struct xtalk_sync *xtalk_sync;
struct XusbIface *py_xusb_iface;
};
struct Xtalkraw {
struct xtalk_base *xtalk_base;
struct xtalk_raw *xtalk_raw;
struct XusbIface *py_xusb_iface;
};

115
xpp/xtalk/include/xtalk/xusb.h

@ -0,0 +1,115 @@
#ifndef XUSB_H
#define XUSB_H
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2008, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <stdint.h>
#include <xtalk/api_defs.h>
#include <xtalk/xlist.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* Xorcom usb handling
*/
#define PACKET_SIZE 512
/*
* Specify the wanted device
*/
struct xusb_spec {
char *name; /* For debug/output purpose */
/* What we will actually use */
uint16_t vendor_id;
uint16_t product_id;
};
#define SPEC_HEAD(vendor_id_, product_id_, name_) \
{ \
.name = (name_), \
.vendor_id = (vendor_id_), \
.product_id = (product_id_), \
}
XTALK_API void xusb_init_spec(struct xusb_spec *xusb_spec,
char *name, uint16_t vendor_id, uint16_t product_id);
struct xusb_device;
struct xusb_iface;
/*
* Prototypes
*/
typedef int (*xusb_filter_t)(const struct xusb_device *xusb_device, void *data);
XTALK_API struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs,
int numspecs, xusb_filter_t filterfunc, void *data);
XTALK_API struct xusb_device *xusb_find_bypath(const char *path);
XTALK_API struct xusb_iface *xusb_open_one(const struct xusb_spec *specs, int numspecs,
int interface_num,
xusb_filter_t filterfunc, void *data);
/*
* A convenience filter
*/
XTALK_API int xusb_filter_bypath(const struct xusb_device *xusb_device, void *data);
/* Device management */
XTALK_API const struct xusb_spec *xusb_spec(const struct xusb_device *xusb_device);
XTALK_API void xusb_destroy(struct xusb_device *xusb_device);
XTALK_API size_t xusb_packet_size(const struct xusb_device *xusb_device);
XTALK_API void xusb_showinfo(const struct xusb_device *xusb_device);
XTALK_API const char *xusb_serial(const struct xusb_device *xusb_device);
XTALK_API const char *xusb_manufacturer(const struct xusb_device *xusb_device);
XTALK_API const char *xusb_product(const struct xusb_device *xusb_device);
XTALK_API uint16_t xusb_bus_num(const struct xusb_device *xusb_device);
XTALK_API uint16_t xusb_device_num(const struct xusb_device *xusb_device);
XTALK_API uint16_t xusb_vendor_id(const struct xusb_device *xusb_device);
XTALK_API uint16_t xusb_product_id(const struct xusb_device *xusb_device);
XTALK_API const char *xusb_devpath(const struct xusb_device *xusb_device);
XTALK_API const struct xusb_spec *xusb_device_spec(const struct xusb_device *xusb_device);
XTALK_API struct xusb_iface *xusb_find_iface(const char *devpath,
int iface_num,
int ep_out,
int ep_in,
struct xusb_spec *dummy_spec);
XTALK_API int xusb_claim(struct xusb_device *xusb_device, unsigned int interface_num,
struct xusb_iface **iface);
XTALK_API void xusb_release(struct xusb_iface *iface);
XTALK_API int xusb_is_claimed(struct xusb_iface *iface);
XTALK_API struct xusb_iface *xusb_interface_of(const struct xusb_device *dev, int num);
XTALK_API struct xusb_device *xusb_deviceof(struct xusb_iface *iface);
XTALK_API const char *xusb_interface_name(const struct xusb_iface *iface);
XTALK_API int xusb_interface_num(const struct xusb_iface *iface);
XTALK_API int xusb_send(struct xusb_iface *iface, const char *buf, int len, int timeout);
XTALK_API int xusb_recv(struct xusb_iface *iface, char *buf, size_t len, int timeout);
XTALK_API int xusb_flushread(struct xusb_iface *iface);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XUSB_H */

43
xpp/xtalk/include/xtalk/xusb_iface.h

@ -0,0 +1,43 @@
/*
* Wrappers for swig/python integration
*/
#ifdef SWIG
%feature("docstring", "Represents the specification of wanted USB device") Spec;
#endif
struct Spec {
#ifdef SWIG
%immutable spec;
%immutable ref_count;
#endif
struct xusb_spec *spec;
int ref_count;
};
#ifdef SWIG
%feature("docstring", "Represents a single USB device") XusbDev;
#endif
struct XusbDev {
#ifdef SWIG
%immutable spec;
%immutable xusb_device;
%immutable ref_count;
#endif
struct Spec *spec_wrapper;
struct xusb_device *xusb_device;
int ref_count;
};
#ifdef SWIG
%feature("docstring", "Represents a single USB interface") XusbIface;
#endif
struct XusbIface {
#ifdef SWIG
%immutable dev_wrapper;
%immutable iface;
#endif
struct XusbDev *dev_wrapper; /* for ref-counting */
struct xusb_iface *iface;
};

14
xpp/xtalk/xlist.c

@ -1,7 +1,8 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <xlist.h>
#include <xtalk/xlist.h>
#include <autoconfig.h>
struct xlist_node *xlist_new(void *data)
{
@ -36,6 +37,17 @@ void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor)
free(list);
}
void xlist_append_list(struct xlist_node *list1, struct xlist_node *list2)
{
struct xlist_node *curr;
assert(list1);
assert(list2);
while ((curr = xlist_shift(list2)) != NULL)
xlist_append_item(list1, curr);
}
void xlist_append_item(struct xlist_node *list, struct xlist_node *item)
{
assert(list);

73
xpp/xtalk/xlist_test.c

@ -0,0 +1,73 @@
#include <assert.h>
#include <stdio.h>
#include <xtalk/xlist.h>
#include <autoconfig.h>
void dump_list(const struct xlist_node *list)
{
struct xlist_node *curr;
const char *p;
int len;
len = xlist_length(list);
p = list->data;
printf("dumping list: %s[%d]\n", p, len);
for (curr = list->next; curr != list; curr = curr->next) {
p = curr->data;
printf("> %s\n", p);
}
}
void string_destructor(void *data)
{
const char *p = data;
printf("destroy: '%s'\n", p);
}
int main()
{
struct xlist_node *list1;
struct xlist_node *list2;
struct xlist_node *list3;
struct xlist_node *item1;
struct xlist_node *item2;
struct xlist_node *item3;
list1 = xlist_new("list1");
list2 = xlist_new("list2");
list3 = xlist_new("list3");
item1 = xlist_new("item1");
item2 = xlist_new("item2");
item3 = xlist_new("item3");
assert(xlist_empty(list1));
assert(xlist_empty(list2));
assert(xlist_empty(list3));
assert(xlist_empty(item1));
assert(xlist_empty(item2));
assert(xlist_empty(item3));
dump_list(list1);
dump_list(list2);
xlist_append_item(list1, item1);
assert(!xlist_empty(list1));
xlist_append_item(list1, item2);
xlist_append_item(list1, item3);
dump_list(list1);
xlist_remove_item(item2);
assert(!xlist_empty(list1));
xlist_append_item(list2, item2);
assert(!xlist_empty(list2));
dump_list(list1);
dump_list(list2);
xlist_shift(list1);
dump_list(list1);
xlist_append_list(list1, list2);
dump_list(list1);
xlist_append_item(list3, item1);
xlist_append_list(list1, list3);
dump_list(list1);
xlist_destroy(list1, string_destructor);
xlist_destroy(list2, string_destructor);
xlist_destroy(list3, string_destructor);
return 0;
}

70
xpp/xtalk/xtalk-xusb.c

@ -0,0 +1,70 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2012, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* Convenience wrappers for xtalk_base over xusb
*/
#include <assert.h>
#include <xtalk/debug.h>
#include <xtalk/xusb.h>
#include <autoconfig.h>
#include "xtalk_base.h"
static inline int close_func(void *priv)
{
struct xusb_iface *iface = (struct xusb_iface *)priv;
xusb_release(iface);
return 0;
}
static inline int send_func(void *priv, const char *data, size_t len, int timeout)
{
return xusb_send((struct xusb_iface *)priv, data, len, timeout);
}
static inline int recv_func(void *priv, char *data, size_t maxlen, int timeout)
{
return xusb_recv((struct xusb_iface *)priv, data, maxlen, timeout);
}
static struct xtalk_ops xtalk_ops = {
.send_func = send_func,
.recv_func = recv_func,
.close_func = close_func,
};
struct xtalk_base *xtalk_base_new_on_xusb(struct xusb_iface *xusb_iface)
{
struct xtalk_base *xtalk_base;
int packet_size;
assert(xusb_iface);
packet_size = xusb_packet_size(xusb_deviceof(xusb_iface));
xtalk_base = xtalk_base_new(&xtalk_ops, packet_size, xusb_iface);
if (!xtalk_base) {
ERR("Failed creating the xtalk device abstraction\n");
return NULL;
}
return xtalk_base;
}

353
xpp/xtalk/xtalk_base.c

@ -0,0 +1,353 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2009, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <arpa/inet.h>
#include <xtalk/debug.h>
#include <autoconfig.h>
#include "xtalk_base.h"
#define DBG_MASK 0x02
void free_command(struct xtalk_command *cmd)
{
if (!cmd)
return;
memset(cmd, 0, cmd->header.len);
free(cmd);
}
const struct xtalk_command_desc *get_command_desc(
const struct xtalk_protocol *xproto, uint8_t op)
{
const struct xtalk_command_desc *desc;
if (!xproto)
return NULL;
desc = &xproto->commands[op];
if (!desc->name)
return NULL;
#if 0
DBG("%s version=%d, op=0x%X (%s)\n",
xproto->name, xproto->proto_version,
op, desc->name);
#endif
return desc;
}
const char *ack_status_msg(const struct xtalk_protocol *xproto,
uint8_t status)
{
const char *ack_status;
if (!xproto)
return NULL;
ack_status = xproto->ack_statuses[status];
DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status);
return ack_status;
}
const char *xtalk_protocol_name(const struct xtalk_base *xtalk_base)
{
const struct xtalk_protocol *xproto;
xproto = &xtalk_base->xproto;
return (xproto) ? xproto->name : "";
}
int xtalk_set_protocol(struct xtalk_base *xtalk_base,
const struct xtalk_protocol *xproto_base,
const struct xtalk_protocol *xproto)
{
const char *protoname = (xproto) ? xproto->name : "GLOBAL";
int i;
DBG("%s\n", protoname);
memset(&xtalk_base->xproto, 0, sizeof(xtalk_base->xproto));
for (i = 0; i < MAX_OPS; i++) {
const struct xtalk_command_desc *desc;
desc = get_command_desc(xproto, i);
if (desc) {
if (!IS_PRIVATE_OP(i)) {
ERR("Bad op=0x%X "
"(should be in the range [0x%X-0x%X]\n",
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
return -EINVAL;
}
xtalk_base->xproto.commands[i] = *desc;
DBG("private: op=0x%X (%s)\n", i, desc->name);
} else {
if (!IS_PRIVATE_OP(i)) {
const char *name;
xtalk_base->xproto.commands[i] =
xproto_base->commands[i];
name = xtalk_base->xproto.commands[i].name;
if (name)
DBG("global: op=0x%X (%s)\n", i, name);
}
}
}
for (i = 0; i < MAX_STATUS; i++) {
const char *stat_msg;
stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL;
if (stat_msg) {
if (!IS_PRIVATE_OP(i)) {
ERR("Bad status=0x%X "
"(should be in the range [0x%X-0x%X]\n",
i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST);
return -EINVAL;
}
xtalk_base->xproto.ack_statuses[i] = stat_msg;
DBG("private: status=0x%X (%s)\n", i, stat_msg);
} else {
if (!IS_PRIVATE_OP(i)) {
const char *stat_msg;
xtalk_base->xproto.ack_statuses[i] =
xproto_base->ack_statuses[i];
stat_msg = xtalk_base->xproto.ack_statuses[i];
if (stat_msg)
DBG("global: status=0x%X (%s)\n",
i, stat_msg);
}
}
}
xtalk_base->xproto.name = protoname;
xtalk_base->xproto.proto_version = (xproto) ? xproto->proto_version : 0;
return 0;
}
int xtalk_cmd_callback(struct xtalk_base *xtalk_base, int op,
xtalk_cmd_callback_t callback,
xtalk_cmd_callback_t *old_callback)
{
const struct xtalk_protocol *xproto;
const struct xtalk_command_desc *desc;
xproto = &xtalk_base->xproto;
desc = get_command_desc(xproto, op);
if (!desc)
DBG("Unknown op=0x%X.\n", op);
if (old_callback)
*old_callback = xtalk_base->callbacks[op];
if (callback) {
xtalk_base->callbacks[op] = callback;
DBG("OP=0x%X [%s] -- set callback to %p\n",
op,
(desc) ? desc->name : "",
callback);
}
return 0;
}
struct xtalk_command *new_command(
const struct xtalk_base *xtalk_base,
uint8_t op, uint16_t extra_data)
{
const struct xtalk_protocol *xproto;
struct xtalk_command *cmd;
const struct xtalk_command_desc *desc;
uint16_t len;
xproto = &xtalk_base->xproto;
desc = get_command_desc(xproto, op);
if (!desc) {
ERR("Unknown op=0x%X.\n", op);
return NULL;
}
DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data);
len = desc->len + extra_data;
cmd = malloc(len);
if (!cmd) {
ERR("Out of memory\n");
return NULL;
}
if (extra_data) {
uint8_t *ptr = (uint8_t *)cmd;
DBG("clear extra_data (%d bytes)\n", extra_data);
memset(ptr + desc->len, 0, extra_data);
}
cmd->header.op = op;
cmd->header.len = len;
cmd->header.seq = 0; /* Overwritten in send_usb() */
return cmd;
}
void xtalk_dump_command(struct xtalk_command *cmd)
{
uint16_t len;
int i;
len = cmd->header.len;
if (len < sizeof(struct xtalk_header)) {
ERR("Command too short (%d)\n", len);
return;
}
INFO("DUMP: OP=0x%X len=%d seq=%d\n",
cmd->header.op, cmd->header.len, cmd->header.seq);
for (i = 0; i < len - sizeof(struct xtalk_header); i++)
INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]);
}
int xtalk_set_timeout(struct xtalk_base *dev, int new_timeout)
{
int old_timeout = dev->default_timeout;
dev->default_timeout = new_timeout;
return old_timeout;
}
int send_buffer(struct xtalk_base *xtalk_base, const char *buf, int len)
{
int ret;
void *priv = xtalk_base->transport_priv;
int timeout = xtalk_base->default_timeout;
ret = xtalk_base->ops.send_func(priv, buf, len, timeout);
if (ret < 0)
DBG("%s: failed ret=%d\n", __func__, ret);
return ret;
}
int recv_buffer(struct xtalk_base *xtalk_base, char *buf, int len)
{
void *priv = xtalk_base->transport_priv;
int timeout = xtalk_base->default_timeout;
int ret;
ret = xtalk_base->ops.recv_func(priv, buf, len, timeout);
if (ret < 0) {
DBG("Receive from usb failed (ret=%d)\n", ret);
goto out;
} else if (ret == 0) {
DBG("No reply\n");
goto out; /* No reply */
}
DBG("Received %d bytes\n", ret);
out:
return ret;
}
int send_command(struct xtalk_base *xtalk_base,
struct xtalk_command *cmd, uint16_t *tx_seq)
{
int ret;
int len;
len = cmd->header.len;
cmd->header.seq = xtalk_base->tx_sequenceno;
ret = send_buffer(xtalk_base, (const char *)cmd, len);
if (ret < 0)
DBG("%s: failed ret=%d\n", __func__, ret);
else if (tx_seq)
*tx_seq = xtalk_base->tx_sequenceno++;
return ret;
}
int recv_command(struct xtalk_base *xtalk_base,
struct xtalk_command **reply_ref)
{
struct xtalk_command *reply;
size_t psize = xtalk_base->packet_size;
int ret;
reply = malloc(psize);
if (!reply) {
ERR("Out of memory\n");
ret = -ENOMEM;
goto err;
}
reply->header.len = 0;
ret = recv_buffer(xtalk_base, (char *)reply, psize);
if (ret < 0) {
DBG("%s: calling recv_buffer() failed (ret=%d)\n", __func__, ret);
goto err;
} else if (ret == 0) {
goto err; /* No reply */
}
if (ret != reply->header.len) {
ERR("Wrong length received: got %d bytes, "
"but length field says %d bytes%s\n",
ret, reply->header.len,
(ret == 1) ? ". Old USB firmware?" : "");
goto err;
}
/* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */
*reply_ref = reply;
return ret;
err:
if (reply) {
memset(reply, 0, psize);
free_command(reply);
*reply_ref = NULL;
}
return ret;
}
/*
* Wrappers
*/
struct xtalk_base *xtalk_base_new(const struct xtalk_ops *ops,
size_t packet_size, void *priv)
{
struct xtalk_base *xtalk_base;
DBG("\n");
assert(ops != NULL);
xtalk_base = calloc(1, sizeof(*xtalk_base));
if (!xtalk_base) {
ERR("Allocating XTALK device memory failed\n");
return NULL;
}
memcpy((void *)&xtalk_base->ops, (const void *)ops,
sizeof(xtalk_base->ops));
xtalk_base->packet_size = packet_size;
xtalk_base->transport_priv = priv;
xtalk_base->tx_sequenceno = 1;
xtalk_base->default_timeout = 2000; /* millies */
return xtalk_base;
}
void xtalk_base_delete(struct xtalk_base *xtalk_base)
{
void *priv;
if (!xtalk_base)
return;
DBG("\n");
priv = xtalk_base->transport_priv;
assert(priv);
xtalk_base->tx_sequenceno = 0;
assert(&xtalk_base->ops != NULL);
assert(&xtalk_base->ops.close_func != NULL);
xtalk_base->ops.close_func(priv);
memset(xtalk_base, 0, sizeof(*xtalk_base));
free(xtalk_base);
}

73
xpp/xtalk/xtalk_base.h

@ -0,0 +1,73 @@
#ifndef XTALK_BASE_H
#define XTALK_BASE_H
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2009, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <xtalk/proto.h>
#include <xtalk/firmware_defs.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
* Base XTALK device. A pointer to this struct
* should be included in the struct representing
* the dialect.
*/
struct xtalk_base {
void *transport_priv; /* e.g: struct xusb */
struct xtalk_ops ops;
struct xtalk_protocol xproto;
xtalk_cmd_callback_t callbacks[MAX_OPS];
uint8_t xtalk_proto_version;
uint8_t status;
size_t packet_size;
uint16_t tx_sequenceno;
int default_timeout; /* in millies */
};
int xtalk_set_protocol(struct xtalk_base *xtalk_base,
const struct xtalk_protocol *xproto_base,
const struct xtalk_protocol *xproto);
const struct xtalk_command_desc *get_command_desc(
const struct xtalk_protocol *xproto, uint8_t op);
int send_command(struct xtalk_base *xtalk_base,
struct xtalk_command *cmd, uint16_t *tx_seq);
int recv_command(struct xtalk_base *xtalk_base,
struct xtalk_command **reply_ref);
/*
* These are low-level interfaces that receive/send arbitrary buffers
* Be carefull, as that allow to send illegal Xtalk packets
*/
int send_buffer(struct xtalk_base *xtalk_base, const char *buf, int len);
int recv_buffer(struct xtalk_base *xtalk_base, char *buf, int len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XTALK_BASE_H */

221
xpp/xtalk/xtalk_raw.c

@ -0,0 +1,221 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2009, Xorcom
*
* All rights reserved.
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <arpa/inet.h>
#include <xtalk/debug.h>
#include <xtalk/proto_raw.h>
#include <autoconfig.h>
#include "xtalk_base.h"
#define DBG_MASK 0x02
/*
* Base XTALK device. A pointer to this struct
* should be included in the struct representing
* the dialect.
*/
struct xtalk_raw {
struct xtalk_base *xtalk_base;
};
CMD_DEF(XTALK, ACK,
uint8_t stat;
);
union XTALK_PDATA(XTALK) {
MEMBER(XTALK, ACK);
} PACKED members;
const struct xtalk_protocol xtalk_raw_proto = {
.name = "XTALK-RAW",
.proto_version = 0,
.commands = {
CMD_RECV(XTALK, ACK),
},
.ack_statuses = {
ACK_STAT(OK, "Acknowledges previous command"),
ACK_STAT(FAIL, "Last command failed"),
ACK_STAT(RESET_FAIL, "reset failed"),
ACK_STAT(NODEST, "No destination is selected"),
ACK_STAT(MISMATCH, "Data mismatch"),
ACK_STAT(NOACCESS, "No access"),
ACK_STAT(BAD_CMD, "Bad command"),
ACK_STAT(TOO_SHORT, "Packet is too short"),
ACK_STAT(ERROFFS, "Offset error (not used)"),
ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"),
ACK_STAT(NO_EEPROM, "No EEPROM was found"),
ACK_STAT(WRITE_FAIL, "Writing to device failed"),
ACK_STAT(NOPWR_ERR, "No power on USB connector"),
}
};
struct xtalk_raw *xtalk_raw_new(struct xtalk_base *xtalk_base)
{
struct xtalk_raw *xtalk_raw;
int ret;
assert(xtalk_base);
xtalk_raw = calloc(1, sizeof(*xtalk_raw));
if (!xtalk_raw) {
ERR("Allocating XTALK device memory failed\n");
return NULL;
}
xtalk_raw->xtalk_base = xtalk_base;
ret = xtalk_set_protocol(xtalk_raw->xtalk_base, &xtalk_raw_proto, NULL);
if (ret < 0) {
ERR("GLOBAL Protocol registration failed: %d\n", ret);
goto err;
}
DBG("%s: xtalk_raw=%p\n", __func__, xtalk_raw);
return xtalk_raw;
err:
xtalk_raw_delete(xtalk_raw);
return NULL;
}
void xtalk_raw_delete(struct xtalk_raw *xtalk_raw)
{
if (xtalk_raw) {
memset(xtalk_raw, 0, sizeof(*xtalk_raw));
free(xtalk_raw);
}
}
int xtalk_raw_set_protocol(struct xtalk_raw *xtalk_raw,
const struct xtalk_protocol *xproto)
{
return xtalk_set_protocol(xtalk_raw->xtalk_base, &xtalk_raw_proto, xproto);
}
int xtalk_raw_cmd_send(struct xtalk_raw *xtalk_raw, const char *buf, int len,
uint16_t *tx_seq)
{
struct xtalk_command *cmd;
char *p;
int ret;
p = malloc(len);
if (!p) {
ERR("allocation failed (%d bytes)\n", len);
return -ENOMEM;
}
cmd = (struct xtalk_command *)p;
memcpy(p, buf, len);
cmd->header.len = len;
ret = send_command(xtalk_raw->xtalk_base, cmd, tx_seq);
if (ret < 0) {
DBG("%s: send_command(%d bytes) failed ret=%d\n",
__func__, len, ret);
goto out;
}
DBG("%s(%d bytes, tx_seq=%d)\n", __func__, len, *tx_seq);