dahdi-tools/xpp/astribank.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);
}