178 lines
3.9 KiB
C
178 lines
3.9 KiB
C
|
#include <assert.h>
|
||
|
#include <errno.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <xtalk/debug.h>
|
||
|
#include <xtalk/xusb.h>
|
||
|
#include "mpptalk.h"
|
||
|
#include "astribank.h"
|
||
|
|
||
|
#define DBG_MASK 0x08
|
||
|
|
||
|
struct astribank {
|
||
|
struct xusb_device *xusb_device;
|
||
|
struct xusb_iface *xpp_iface;
|
||
|
struct xusb_iface *mpp_iface;
|
||
|
struct mpp_device *mpp;
|
||
|
char *path;
|
||
|
};
|
||
|
|
||
|
|
||
|
struct astribank *astribank_new(const char *path)
|
||
|
{
|
||
|
struct astribank *ab;
|
||
|
|
||
|
ab = calloc(sizeof(*ab), 1);
|
||
|
if (!ab) {
|
||
|
ERR("%s: Failed allocating Astribank device\n", path);
|
||
|
goto err;
|
||
|
}
|
||
|
ab->xusb_device = xusb_find_bypath(path);
|
||
|
if (!ab->xusb_device) {
|
||
|
ERR("%s: Cannot find Astribank\n", path);
|
||
|
goto err;
|
||
|
}
|
||
|
ab->path = strdup(path);
|
||
|
if (!ab->path) {
|
||
|
ERR("%s: Failed allocating Astribank path\n", path);
|
||
|
goto err;
|
||
|
}
|
||
|
return ab;
|
||
|
err:
|
||
|
astribank_destroy(ab);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void astribank_destroy(struct astribank *ab)
|
||
|
{
|
||
|
if (ab) {
|
||
|
if (ab->path)
|
||
|
free(ab->path);
|
||
|
if (ab->xpp_iface)
|
||
|
xusb_release(ab->xpp_iface);
|
||
|
if (ab->mpp) {
|
||
|
mpp_delete(ab->mpp); /* this also closes the underlying xusb */
|
||
|
ab->mpp = NULL;
|
||
|
}
|
||
|
if (ab->xusb_device) {
|
||
|
xusb_destroy(ab->xusb_device);
|
||
|
ab->xusb_device = NULL;
|
||
|
}
|
||
|
free(ab);
|
||
|
ab = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct xusb_iface *astribank_xpp_open(struct astribank *ab)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
ret = xusb_claim(ab->xusb_device, 0, &ab->xpp_iface);
|
||
|
if (ret < 0) {
|
||
|
ERR("%s: Cannot claim XPP interface\n", ab->path);
|
||
|
goto err;
|
||
|
}
|
||
|
DBG("%s: Claimed Astribank XPP interface\n", ab->path);
|
||
|
return ab->xpp_iface;
|
||
|
err:
|
||
|
if (ab->xpp_iface)
|
||
|
xusb_release(ab->xpp_iface);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
struct mpp_device *astribank_mpp_open(struct astribank *ab)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
ret = xusb_claim(ab->xusb_device, 1, &ab->mpp_iface);
|
||
|
if (ret < 0) {
|
||
|
ERR("%s: Cannot claim MPP interface\n", ab->path);
|
||
|
goto err;
|
||
|
}
|
||
|
DBG("%s: Claimed Astribank MPP interface\n", ab->path);
|
||
|
ab->mpp = mpp_new(ab->mpp_iface);
|
||
|
if (!ab->mpp) {
|
||
|
ERR("Failed initializing MPP protocol\n");
|
||
|
goto err;
|
||
|
}
|
||
|
ret = mpp_status_query(ab->mpp);
|
||
|
if (ret < 0) {
|
||
|
ERR("status query failed (ret=%d)\n", ret);
|
||
|
goto err;
|
||
|
}
|
||
|
return ab->mpp;
|
||
|
err:
|
||
|
if (ab->mpp) {
|
||
|
mpp_delete(ab->mpp); /* this also closes the underlying xusb */
|
||
|
ab->mpp = NULL;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
struct xusb_device *xusb_dev_of_astribank(const struct astribank *ab)
|
||
|
{
|
||
|
assert(ab->xusb_device);
|
||
|
return ab->xusb_device;
|
||
|
}
|
||
|
|
||
|
const char *astribank_devpath(const struct astribank *ab)
|
||
|
{
|
||
|
return xusb_devpath(ab->xusb_device);
|
||
|
}
|
||
|
|
||
|
const char *astribank_serial(const struct astribank *ab)
|
||
|
{
|
||
|
return xusb_serial(ab->xusb_device);
|
||
|
}
|
||
|
|
||
|
void show_astribank_info(const struct astribank *ab)
|
||
|
{
|
||
|
struct xusb_device *xusb_device;
|
||
|
|
||
|
assert(ab != NULL);
|
||
|
xusb_device = ab->xusb_device;
|
||
|
assert(xusb_device != NULL);
|
||
|
if(verbose <= LOG_INFO) {
|
||
|
xusb_showinfo(xusb_device);
|
||
|
} else {
|
||
|
const struct xusb_spec *spec;
|
||
|
|
||
|
spec = xusb_spec(xusb_device);
|
||
|
printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb_device));
|
||
|
printf("USB Firmware Type: [%s]\n", spec->name);
|
||
|
printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb_device));
|
||
|
printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb_device));
|
||
|
printf("USB iProduct: [%s]\n", xusb_product(xusb_device));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int astribank_send(struct astribank *ab, int interface_num, const char *buf, int len, int timeout)
|
||
|
{
|
||
|
struct xusb_iface *iface;
|
||
|
|
||
|
if (interface_num == 0)
|
||
|
iface = ab->xpp_iface;
|
||
|
else if (interface_num == 1)
|
||
|
iface = ab->mpp_iface;
|
||
|
else {
|
||
|
ERR("Unknown interface number (%d)\n", interface_num);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
return xusb_send(iface, buf, len, timeout);
|
||
|
}
|
||
|
|
||
|
int astribank_recv(struct astribank *ab, int interface_num, char *buf, size_t len, int timeout)
|
||
|
{
|
||
|
struct xusb_iface *iface;
|
||
|
|
||
|
if (interface_num == 0)
|
||
|
iface = ab->xpp_iface;
|
||
|
else if (interface_num == 1)
|
||
|
iface = ab->mpp_iface;
|
||
|
else {
|
||
|
ERR("Unknown interface number (%d)\n", interface_num);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
return xusb_recv(iface, buf, len, timeout);
|
||
|
}
|