/*
* libusb example to communicate with the TL-500
* Copyright (C) 2009 Kornelius Rohmeyer <kornl@gmx.de>
* based on the libusb example program to list devices on the bus
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <libusb.h>

uint16_t VENDOR = 1105; /* 0451 */
uint16_t PRODUCT = 12817; /* 3211 */

libusb_device_handle** find_tl500(libusb_device **devs) {
    libusb_device *dev;
    libusb_device_handle **handle;
    int i = 0;

    printf("Trying to find Arexx logging system.\n");
    while ((dev = devs[i++]) != NULL) {
        struct libusb_device_descriptor desc;
        int r = libusb_get_device_descriptor(dev, &desc);
        if (r < 0) {
            fprintf(stderr, "failed to get device descriptor");
            return NULL;
        }

        printf("%04x:%04x (bus %d, device %d)\n",
            desc.idVendor, desc.idProduct,
            libusb_get_bus_number(dev), libusb_get_device_address(dev));

        if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) {
            printf("Found Arexx TL-500.\n");
            libusb_open(dev, handle);
            return handle;
        }
    }

    return NULL;
}

int main() {
    libusb_device **devs;
    int r;
    ssize_t cnt;

    r = libusb_init(NULL);
    if (r < 0)
        return r;

    cnt = libusb_get_device_list(NULL, &devs);
    if (cnt < 0)
        return (int) cnt;

    libusb_device_handle **handle = find_tl500(devs);

    if (handle==NULL) {
        fprintf(stderr, "No logging system found.\n");
    }

    unsigned char ENDPOINT_DOWN = 0x1;
    unsigned char ENDPOINT_UP = 0x81;
    int actual_length;
    unsigned char dataUp[64];
    unsigned char dataDown[64];
    for(int j=0;j<64;j++) { dataDown[j] = 0; }
    dataDown[0] = 4;
    libusb_bulk_transfer(handle[0], ENDPOINT_DOWN, dataDown, sizeof(dataDown), &actual_length, 0);
    dataDown[0] = 3;
    for(int i=0; i<10000; i++) {
        r = libusb_bulk_transfer(handle[0], ENDPOINT_DOWN, dataDown,
                                 sizeof(dataDown), &actual_length, 0);
        r = libusb_bulk_transfer(handle[0], ENDPOINT_UP, dataUp,
                                 sizeof(dataUp), &actual_length, 1000);
        if (r == 0 && actual_length == sizeof(dataUp)) {
            if (dataUp[0]!=0 || dataUp[1]!=0) {
                printf("Data: ");
                for(int j=0;j<64;j++) {
                    printf("%02x ",dataUp[j]);
                }
                printf("\n");
            }
            sleep(1);
        } else {
            printf("Something went wrong (r == %i, actual_length == %i , sizeof(data) == %lu ).\n",
                   r, actual_length, sizeof(dataUp));
        }
    }

    libusb_free_device_list(devs, 1);

    libusb_exit(NULL);

    return 0;
}
