summaryrefslogtreecommitdiff
path: root/CDAL/CDAL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CDAL/CDAL.cpp')
-rwxr-xr-xCDAL/CDAL.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/CDAL/CDAL.cpp b/CDAL/CDAL.cpp
new file mode 100755
index 0000000..24ded12
--- /dev/null
+++ b/CDAL/CDAL.cpp
@@ -0,0 +1,223 @@
+/*
+ * CDAL.cpp
+ *
+ * Copyright (C) ST-Ericsson SA 2011
+ * Authors: Srimanta Panda <srimanta.panda@stericsson.com>,
+ * Ola Borgelin <ola.borgelin@stericsson.com>,
+ * Karin Hedlund <karin.hedlund@stericsson.com>,
+ * Markus Andersson <markus.m.andersson@stericsson.com> for ST-Ericsson.
+ * License terms: 3-clause BSD license
+ *
+ */
+
+#include "CDAL.h"
+#include "Debug.h"
+#include "CommDevice.h"
+#include "CommDeviceManager.h"
+#include "CommException.h"
+#include "Event.h"
+#include "Thread.h"
+#include "LibusbDevice.h"
+#include <libusb.h>
+#include <vector>
+#include <stdio.h>
+#include <stdlib.h>
+using namespace std;
+
+static int DUT_VENDOR_ID = 0x04cc;
+static int DUT_PRODUCT_ID = 0x8500;
+static libusb_context* context;
+static Thread* workerThread;
+static void* LibusbWorker(void* arg);
+bool shutdown = false;
+int error = 0;
+
+static EventCallback_t OnDeviceCallback = NULL;
+
+void usb_init_driver(const char* vendorId, const char* productId)
+{
+ if (vendorId != NULL && *vendorId != '\0') {
+ DUT_VENDOR_ID = strtol(vendorId, NULL, 16);
+ }
+
+ if (productId != NULL && *productId != '\0') {
+ DUT_PRODUCT_ID = strtol(productId, NULL, 16);
+ }
+
+ libusb_init(&context);
+ libusb_set_debug(context, 3);
+
+ workerThread = new Thread(LibusbWorker, 0);
+}
+
+void usb_set_listen_callback(EventCallback_t callback)
+{
+ OnDeviceCallback = callback;
+}
+
+void usb_deinit_driver()
+{
+ shutdown = true;
+ workerThread->wait();
+ delete workerThread;
+
+ CommDeviceManager::destroyAll();
+
+ libusb_exit(context);
+}
+
+void usb_destroy_device(Device_t device, int error_code)
+{
+ device->cancel();
+ error = error_code;
+}
+
+int comm_read(Device_t device, void* buffer, size_t size)
+{
+ return device->read(buffer, size);
+}
+
+int comm_read_nowait(void* buffer, size_t size, DataCallback_t cb, void* param)
+{
+ CommDevice* device = CommDeviceManager::getDevice<CommDevice>(param);
+
+ if (NULL != device) {
+ return device->readNoWait(buffer, size, cb, param);
+ } else {
+ return COMM_DEVICE_OBJECT_NOT_MAPPED;
+ }
+}
+
+int comm_write(Device_t device, void* buffer, size_t size)
+{
+ return device->write(buffer, size);
+}
+
+int comm_write_nowait(void* buffer, size_t size, DataCallback_t cb, void* param)
+{
+ CommDevice* device = CommDeviceManager::getDevice<CommDevice>(param);
+
+ if (NULL != device) {
+ return device->writeNoWait(buffer, size, cb, param);
+ } else {
+ return COMM_DEVICE_OBJECT_NOT_MAPPED;
+ }
+}
+
+int comm_cancel(void* param)
+{
+ CommDevice* device = CommDeviceManager::getDevice<CommDevice>(param);
+
+ if (NULL != device) {
+ return device->cancel();
+ } else {
+ return COMM_DEVICE_OBJECT_NOT_MAPPED;
+ }
+}
+
+unsigned long comm_get_physical_address(Device_t device)
+{
+ return device->getPhysicalAddress();
+}
+
+void** comm_get_object_storage(Device_t device)
+{
+ return device->getObjectStorage();
+}
+
+void comm_progress(void *Communication_p, unsigned long long totalbytes,
+ unsigned long long tranferedbytes)
+{
+ double precentage = (tranferedbytes * 100) / totalbytes;
+
+ printf("\r%.1f %% ", precentage);
+ fflush(stdout);
+}
+
+static void* LibusbWorker(void* arg __attribute__((unused)))
+{
+ timespec delay;
+ delay.tv_sec = 0;
+ delay.tv_nsec = 10 * 1000000; // 10ms
+ libusb_device** deviceList;
+ ssize_t deviceCount;
+ libusb_device_descriptor descriptor;
+
+ while (!shutdown) {
+ deviceCount = libusb_get_device_list(context, &deviceList);
+
+ if (deviceCount < 0) {
+ nanosleep(&delay, 0);
+ continue;
+ }
+
+ for (int i = 0; i != deviceCount; ++i) {
+ int status = libusb_get_device_descriptor(deviceList[i],
+ &descriptor);
+
+ if (status != LIBUSB_SUCCESS) {
+ Debug::error(
+ "Libusb worker: error while getting device descriptor for device %d from %d devices",
+ i, deviceCount);
+ continue;
+ }
+
+ if (descriptor.idVendor == DUT_VENDOR_ID && descriptor.idProduct
+ == DUT_PRODUCT_ID && (!shutdown)) {
+ LibusbDevice* device = CommDeviceManager::getDevice <
+ LibusbDevice, libusb_device* > (deviceList[i]);
+
+ if (0 == device) {
+ // new device found
+ try {
+ device = CommDeviceManager::createDevice < LibusbDevice,
+ libusb_device* > (deviceList[i]);
+ Debug::info("Libusb worker: Connected libusb device");
+ OnDeviceCallback(COMM_DEVICE_SUCCESS,
+ LIBUSB_DEVICE_CONNECTED, device);
+ } catch (CommException e) {
+ Debug::error("Libusb worker: %s", e.what());
+ OnDeviceCallback(e.getError(),
+ COMM_DEVICE_UNDEFINED_EVENT, 0);
+ }
+ }
+ }
+ }
+
+ vector<CommDevice*> devices = CommDeviceManager::getAllDevices();
+
+ for (vector<CommDevice*>::iterator i = devices.begin(); i
+ != devices.end(); ++i) {
+ LibusbDevice* device = dynamic_cast<LibusbDevice*>(*i);
+
+ if (0 == device) {
+ continue;
+ }
+
+ bool connected = false;
+
+ for (int j = 0; j != deviceCount; ++j) {
+ if (deviceList[j] == device->getPort()) {
+ if (error == 0)
+ connected = true;
+
+ break;
+ }
+ }
+
+ if (!connected) {
+ Debug::info("Libusb worker: Disconnected device with id %d", *i);
+ OnDeviceCallback(COMM_DEVICE_SUCCESS,
+ LIBUSB_DEVICE_DISCONNECTED, *i);
+ shutdown = true;
+ }
+ }
+
+ libusb_free_device_list(deviceList, 1);
+
+ nanosleep(&delay, 0);
+ }
+
+ return 0;
+}
+