[tuxdroid-svn] r791 - / tux_lib tux_lib/tux_usb tux_lib/tux_usb/trunk tux_lib/tux_usb/trunk/python
Status: Beta
Brought to you by:
ks156
From: remi <c2m...@c2...> - 2007-12-14 09:19:11
|
Author: remi Date: 2007-12-14 10:19:09 +0100 (Fri, 14 Dec 2007) New Revision: 791 Added: tux_lib/ tux_lib/tux_usb/ tux_lib/tux_usb/branches/ tux_lib/tux_usb/tags/ tux_lib/tux_usb/trunk/ tux_lib/tux_usb/trunk/Makefile tux_lib/tux_usb/trunk/python/ tux_lib/tux_usb/trunk/python/_TUX_USB.so tux_lib/tux_usb/trunk/python/test_tux_usb_with_callback.py tux_lib/tux_usb/trunk/python/test_tux_usb_without_callback.py tux_lib/tux_usb/trunk/python/tux_usb.py tux_lib/tux_usb/trunk/test.py tux_lib/tux_usb/trunk/tux_usb.c tux_lib/tux_usb/trunk/tux_usb.h Log: ADD: tux_lib base and tux_usb library Added: tux_lib/tux_usb/trunk/Makefile =================================================================== --- tux_lib/tux_usb/trunk/Makefile (rev 0) +++ tux_lib/tux_usb/trunk/Makefile 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,4 @@ +make: + gcc -c tux_usb.c -I"/usr/local/include" -I"/usr/include/glib-2.0" -I"/usr/lib/glib-2.0/include" + ld -shared tux_usb.o -o _TUX_USB.so -lusb -lglib-2.0 -lgthread-2.0 + rm tux_usb.o Added: tux_lib/tux_usb/trunk/python/_TUX_USB.so =================================================================== (Binary files differ) Property changes on: tux_lib/tux_usb/trunk/python/_TUX_USB.so ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + application/octet-stream Added: tux_lib/tux_usb/trunk/python/test_tux_usb_with_callback.py =================================================================== --- tux_lib/tux_usb/trunk/python/test_tux_usb_with_callback.py (rev 0) +++ tux_lib/tux_usb/trunk/python/test_tux_usb_with_callback.py 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,22 @@ +from tux_usb import * +import time + +def on_frame(data): + print 'RF status :', data[1],'frame count :', data[3] + +def on_dongle_disconnected(): + print 'dongle disconnected' + +def on_debug_message(level, message): + if level >= DEBUG_LEVEL_ERROR: + print DEBUG_STRINGS[level], ':', message + +TUX_USB_set_frame_callback(on_frame) +TUX_USB_set_disconnect_dongle_callback(on_dongle_disconnected) +TUX_USB_set_debug_msg_callback(on_debug_message) +TUX_USB_init() +if TUX_USB_start(): + time.sleep(1) + TUX_USB_write([0, 0x9A, 6, 25, 0]) + time.sleep(1) + TUX_USB_stop() Added: tux_lib/tux_usb/trunk/python/test_tux_usb_without_callback.py =================================================================== --- tux_lib/tux_usb/trunk/python/test_tux_usb_without_callback.py (rev 0) +++ tux_lib/tux_usb/trunk/python/test_tux_usb_without_callback.py 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,14 @@ +from tux_usb import * +import time + +def print_frame(data): + print 'RF status :', data[1],'frame count :', data[3] + +TUX_USB_init() +if TUX_USB_capture(): + TUX_USB_write([0, 0x9A, 6, 25, 0]) + for i in range(100): + data = TUX_USB_read() + print_frame(data) + time.sleep(0.1) + TUX_USB_release() Added: tux_lib/tux_usb/trunk/python/tux_usb.py =================================================================== --- tux_lib/tux_usb/trunk/python/tux_usb.py (rev 0) +++ tux_lib/tux_usb/trunk/python/tux_usb.py 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,193 @@ +# ----------------------------------------------------------------------------- +# Tux Droid - USB Interface +# Copyright (C) 2007 C2ME Sa <rem...@c2...> +# +# 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, 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., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# ----------------------------------------------------------------------------- + +from ctypes import * + +TUX_SEND_LENGTH = 5 +TUX_RECEIVE_LENGTH = 64 + +DEBUG_LEVEL_FRAME = 0 +DEBUG_LEVEL_DEBUG = 1 +DEBUG_LEVEL_INFO = 2 +DEBUG_LEVEL_WARNING = 3 +DEBUG_LEVEL_ERROR = 4 + +DEBUG_STRINGS = [ + "FRAME", + "DEBUG", + "INFO", + "WARNING ", + "ERROR" +] + +# ---------------------------------------------------------------------------- +# Library import +# ---------------------------------------------------------------------------- +lib = CDLL("./_TUX_USB.so") + +tux_usb_dongle_present = lib.tux_usb_dongle_present +tux_usb_dongle_present.restype = c_uint + +tux_usb_connected = lib.tux_usb_connected +tux_usb_connected.restype = c_uint + +tux_usb_init = lib.tux_usb_init +tux_usb_init.restype = None + +tux_usb_capture = lib.tux_usb_capture +tux_usb_capture.restype = c_uint + +tux_usb_release = lib.tux_usb_release +tux_usb_release.restype = c_uint + +tux_usb_start = lib.tux_usb_start +tux_usb_start.restype = c_uint + +tux_usb_stop = lib.tux_usb_stop +tux_usb_stop.restype = c_uint + +tux_usb_read = lib.tux_usb_read +tux_usb_read.restype = c_uint + +tux_usb_write = lib.tux_usb_write +tux_usb_write.restype = c_uint + +tux_usb_reset = lib.tux_usb_reset +tux_usb_reset.restype = None + +FRAME_CALLBACK = CFUNCTYPE(None, POINTER(c_uint8)) +set_frame_callback = lib.set_frame_callback +set_frame_callback.restype = None +set_frame_callback.argtypes = [FRAME_CALLBACK] + +DONGLE_DISCONNECT_CALLBACK = CFUNCTYPE(None) +set_disconnect_dongle_callback = lib.set_disconnect_dongle_callback +set_disconnect_dongle_callback.restype = None +set_disconnect_dongle_callback.argtypes = [DONGLE_DISCONNECT_CALLBACK] + +DEBUG_MSG_CALLBACK = CFUNCTYPE(None, c_int, c_char_p) +set_debug_msg_callback = lib.set_debug_msg_callback +set_debug_msg_callback.restype = None +set_debug_msg_callback.argtypes = [DEBUG_MSG_CALLBACK] + +# ---------------------------------------------------------------------------- +# Library wrapping +# ---------------------------------------------------------------------------- + +# =============================================== +def TUX_USB_dongle_present(): +# =============================================== + if tux_usb_dongle_present() == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_connected(): +# =============================================== + if tux_usb_connected() == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_init(): +# =============================================== + tux_usb_init() + +# =============================================== +def TUX_USB_capture(): +# =============================================== + if tux_usb_capture() == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_release(): +# =============================================== + if tux_usb_release() == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_start(): +# =============================================== + if tux_usb_start() == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_stop(): +# =============================================== + if tux_usb_stop() == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_read(): +# =============================================== + t = [0] * 64 + t_char = tuple(t) + data = (c_uint8 * len(t_char))(*t_char) + if tux_usb_read(data) == 0: + return t + else: + res = [] + for i in range(64): + res.append(data[i]) + return res + +# =============================================== +def TUX_USB_write(data = [0, 0x9A, 6, 25, 0]): +# =============================================== + if len(data) != TUX_SEND_LENGTH: + return False + for val in data: + if str(type(val)) != "<type 'int'>": + return False + t_char = tuple(data) + if tux_usb_write((c_uint8 * len(t_char))(*t_char)) == 0: + return False + else: + return True + +# =============================================== +def TUX_USB_reset(): +# =============================================== + tux_usb_reset() + +# =============================================== +def TUX_USB_set_frame_callback(funct): +# =============================================== + set_frame_callback(FRAME_CALLBACK(funct)) + +# =============================================== +def TUX_USB_set_disconnect_dongle_callback(funct): +# =============================================== + set_disconnect_dongle_callback(DONGLE_DISCONNECT_CALLBACK(funct)) + +# =============================================== +def TUX_USB_set_debug_msg_callback(funct): +# =============================================== + set_debug_msg_callback(DEBUG_MSG_CALLBACK(funct)) Added: tux_lib/tux_usb/trunk/test.py =================================================================== --- tux_lib/tux_usb/trunk/test.py (rev 0) +++ tux_lib/tux_usb/trunk/test.py 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,296 @@ +from ctypes import * +import time +import sys +import threading + +# ---------------------------------------------------------------------------- +# _TUX_USB.so library wrapping +# ---------------------------------------------------------------------------- +lib = CDLL("./_TUX_USB.so") + +usb_check_TuxDroid = lib.usb_check_TuxDroid +usb_check_TuxDroid.restype = c_uint + +usb_capture_TuxDroid = lib.usb_capture_TuxDroid +usb_capture_TuxDroid.restype = c_uint + +usb_write_TuxDroid = lib.usb_write_TuxDroid +usb_write_TuxDroid.restype = c_uint + +usb_read_TuxDroid = lib.usb_read_TuxDroid +usb_read_TuxDroid.restype = c_uint + +usb_close_TuxDroid = lib.usb_close_TuxDroid +usb_close_TuxDroid.restype = c_uint + +get_connected = lib.get_connected +get_connected.restype = c_uint + +set_connected = lib.set_connected +set_connected.restype = None + +library_init = lib.library_init +library_init.restype = None + +start = lib.start +start.restype = None + +stop = lib.stop +stop.restype = None + +FRAME_CALLBACK = CFUNCTYPE(None, POINTER(c_uint8)) +set_frame_callback = lib.set_frame_callback +set_frame_callback.restype = None +set_frame_callback.argtypes = [FRAME_CALLBACK] + +DONGLE_DISCONNECT_CALLBACK = CFUNCTYPE(None) +set_disconnect_dongle_callback = lib.set_disconnect_dongle_callback +set_disconnect_dongle_callback.restype = None +set_disconnect_dongle_callback.argtypes = [DONGLE_DISCONNECT_CALLBACK] + +def test_funct(test): + print test[3] + +def disconnected(): + print 'dongle disconnected' + +set_frame_callback(FRAME_CALLBACK(test_funct)) +set_disconnect_dongle_callback(DONGLE_DISCONNECT_CALLBACK(disconnected)) + +library_init() + +start() + +time.sleep(10) + +stop() +sys.exit(0) + +# ---------------------------------------------------------------------------- +# TUXUsbInterface constants +# ---------------------------------------------------------------------------- +CAPTURE_RETURN_NO_DONGLE = 0 +CAPTURE_RETURN_FIRMWARE_TO_OLD = 1 +CAPTURE_RETURN_DEVICE_NOT_HANDLED = 2 +CAPTURE_RETURN_SUCCESS = 3 +CLOSE_RETURN_INTERFACE_NOT_RELEASED = 0 +CLOSE_RETURN_DEVICE_NOT_CLOSED = 1 +CLOSE_RETURN_SUCCESS = 2 +DATA_WRITE_LENGTH = 5 +READ_LOOP_INTERVAL = 0.1 + +# ---------------------------------------------------------------------------- +# TUXUsbInterface class +# ---------------------------------------------------------------------------- +class TUXUsbInterface(object): + + def __init__(self): + self.__connected = False + self.__connected_mutex = threading.Lock() + self.__on_frame = None + self.__on_dongle_disconnect = None + self.__read_loop_thread = None + self.__debug = False + self.__read_write_mutex = threading.Lock() + self.__CallBack_mutex = threading.Lock() + self.__messages_mutex = threading.Lock() + + def destroy(self): + self.stop() + + def get_connected(self): + self.__connected_mutex.acquire() + connected = self.__connected + self.__connected_mutex.release() + return connected + + def __set_connected(self, value): + self.__connected_mutex.acquire() + self.__connected = value + self.__connected_mutex.release() + + def set_frame_CallBack(self, funct): + self.__CallBack_mutex.acquire() + self.__on_frame = funct + self.__CallBack_mutex.release() + + def __get_frame_CallBack(self): + self.__CallBack_mutex.acquire() + funct = self.__on_frame + self.__CallBack_mutex.release() + return funct + + def set_dongle_remove_CallBack(self, funct): + self.__CallBack_mutex.acquire() + self.__on_dongle_disconnect = funct + self.__CallBack_mutex.release() + + def __get_dongle_remove_CallBack(self): + self.__CallBack_mutex.acquire() + funct = self.__on_dongle_disconnect + self.__CallBack_mutex.release() + return funct + + def set_debug(self, value): + self.__debug = value + + def start(self): + if self.get_connected(): + return False + ret = usb_capture_TuxDroid() + if ret == CAPTURE_RETURN_NO_DONGLE: + self.__print_warning('Dongle not found.') + return False + elif ret == CAPTURE_RETURN_FIRMWARE_TO_OLD: + self.__print_warning('Your dongle firmware is too old.') + return False + elif ret == CAPTURE_RETURN_DEVICE_NOT_HANDLED: + self.__print_warning("Device can't be handled.") + return False + else: + self.__print_debug('The interface is started.') + self.__set_connected(True) + t = threading.Thread(target = self.__read_loop) + t.start() + self.__read_loop_thread = t + time.sleep(0.1) + return True + + def stop(self): + if not self.get_connected(): + return True + self.__set_connected(False) + if self.__read_loop_thread != None: + if self.__read_loop_thread.isAlive(): + self.__read_loop_thread.join() + ret = usb_close_TuxDroid() + if ret == CLOSE_RETURN_INTERFACE_NOT_RELEASED: + self.__print_warning("The interface can't be released.") + return False + elif ret == CLOSE_RETURN_DEVICE_NOT_CLOSED: + self.__print_warning("The device can't be closed.") + return False + else: + self.__print_debug('The interface is stopped.') + return True + + def dongle_present(self): + if usb_check_TuxDroid() == 0: + value = False + self.__connected_mutex.acquire() + self.__connected = value + self.__connected_mutex.release() + else: + value = True + return value + + def write(self, data = [0, 0x9A, 6, 25, 0]): + if not self.get_connected(): + return False + if len(data) != DATA_WRITE_LENGTH: + self.__print_warning("Write : Bad data length.") + return False + for val in data: + if str(type(val)) != "<type 'int'>": + self.__print_warning("Write : Bad data type.") + return False + t_char = tuple(data) + self.__read_write_mutex.acquire() + ret = usb_write_TuxDroid((c_uint8 * len(t_char))(*t_char), DATA_WRITE_LENGTH) + self.__read_write_mutex.release() + if ret != DATA_WRITE_LENGTH: + self.__print_warning("Write : Usb error.") + return False + else: + self.__print_debug('Write ok.') + return True + + def __write(self, data = [0, 0x9A, 6, 25, 0]): + if not self.get_connected(): + return False + if len(data) != DATA_WRITE_LENGTH: + self.__print_warning("Write : Bad data length.") + return False + for val in data: + if str(type(val)) != "<type 'int'>": + self.__print_warning("Write : Bad data type.") + return False + t_char = tuple(data) + ret = usb_write_TuxDroid((c_uint8 * len(t_char))(*t_char), DATA_WRITE_LENGTH) + if ret != DATA_WRITE_LENGTH: + self.__print_warning("Write : Usb error.") + return False + else: + self.__print_debug('Write ok.') + return True + + def __read(self): + t = [0] * 64 + t_char = tuple(t) + data = (c_uint8 * len(t_char))(*t_char) + if not self.get_connected(): + return t + self.__read_write_mutex.acquire() + if not self.__write([1, 1, 0, 0, 0]): + self.__read_write_mutex.release() + return t + ret = usb_read_TuxDroid(data) + self.__read_write_mutex.release() + res = [] + for i in range(64): + res.append(data[i]) + return res + + def __read_loop(self): + time.sleep(0.01) + check_counter = 0 + initial_timeout = time.time() + current_timeout = initial_timeout + while True: + current_timeout += READ_LOOP_INTERVAL + if not self.get_connected(): + self.__print_debug('End of read loop.') + break + if check_counter >= 9: + if not self.dongle_present(): + self.__print_debug('End of read loop.') + if self.__get_dongle_remove_CallBack() != None: + t = threading.Thread(target = self.__get_dongle_remove_CallBack()) + t.start() + break + check_counter = 0 + else: + check_counter += 1 + data = self.__read() + if self.__get_frame_CallBack() != None: + t = threading.Thread(target = self.__get_frame_CallBack(), args = (data, )) + t.start() + while time.time() < current_timeout: + time.sleep(0.005) + + def __print_debug(self, msg): + self.__messages_mutex.acquire() + if self.__debug: + print 'TUXUsbInterface [DEBUG] : %s' % msg + self.__messages_mutex.release() + + def __print_warning(self, msg): + self.__messages_mutex.acquire() + print 'TUXUsbInterface [WARNING] : %s' % msg + self.__messages_mutex.release() + + +def frame_CallBack(data): + print 'packet number :', data[3] + +def dongle_remove_CallBack(): + print 'Dongle is removed !' + +ti = TUXUsbInterface() +ti.set_frame_CallBack(frame_CallBack) +ti.set_dongle_remove_CallBack(dongle_remove_CallBack) +ti.set_debug(True) +ti.start() +time.sleep(5) +ti.write() +ti.stop() Added: tux_lib/tux_usb/trunk/tux_usb.c =================================================================== --- tux_lib/tux_usb/trunk/tux_usb.c (rev 0) +++ tux_lib/tux_usb/trunk/tux_usb.c 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,428 @@ +/* + * Tux Droid - USB Interface + * Copyright (C) 2007 C2ME Sa <rem...@c2...> + * + * 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, 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +/*_____________________ I N C L U D E S_____________________________________*/ +#include <stdio.h> +#include <stdlib.h> +#include <usb.h> +#include <sys/poll.h> +#include <glib.h> +#include <glib-object.h> +#include <sys/time.h> +#include "tux_usb.h" +/*_____________________ V A R I A B L E S __________________________________*/ +usb_dev_handle *tux_handle = NULL; +struct usb_device *tux_device = NULL; +static pthread_mutex_t __connected_mutex; +static pthread_mutex_t __read_write_mutex; +static pthread_mutex_t __callback_mutex; +static int usb_connected = 0; +GThread *read_loop_thread; +GError *error=NULL; +frame_callback_t frame_callback_function; +dongle_disconnect_callback_t dongle_disconnect_function; +msg_callback_t debug_msg_function; +/*_____________________ F U N C T I O N S __________________________________*/ + +void set_debug_msg_callback(msg_callback_t funct) +{ + pthread_mutex_lock(&__callback_mutex); + debug_msg_function = funct; + pthread_mutex_unlock(&__callback_mutex); +} + +void send_debug_msg(int level, char *msg) +{ + if(debug_msg_function) + debug_msg_function(level, msg); +} + +void set_frame_callback(frame_callback_t funct) +{ + pthread_mutex_lock(&__callback_mutex); + frame_callback_function = funct; + pthread_mutex_unlock(&__callback_mutex); +} + +void set_disconnect_dongle_callback(dongle_disconnect_callback_t funct) +{ + pthread_mutex_lock(&__callback_mutex); + dongle_disconnect_function = funct; + pthread_mutex_unlock(&__callback_mutex); +} + +void tux_usb_init(void) +{ + pthread_mutex_init(&__connected_mutex, NULL); + pthread_mutex_init(&__read_write_mutex, NULL); + pthread_mutex_init(&__callback_mutex, NULL); + if(!g_thread_supported()) + { + g_thread_init(NULL); + }else{ + send_debug_msg(DEBUG_LEVEL_ERROR, "G_thread NOT supported"); + } +} + +int tux_usb_connected(void) +{ + int ret = 0; + pthread_mutex_lock(&__connected_mutex); + ret = usb_connected; + pthread_mutex_unlock(&__connected_mutex); + return ret; +} + +void set_connected(int value) +{ + pthread_mutex_lock(&__connected_mutex); + usb_connected = value; + pthread_mutex_unlock(&__connected_mutex); +} + +int tux_usb_dongle_present(void) +{ + struct usb_bus *bus; + struct usb_device *tux_dev; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_busses; bus; bus = bus->next) + for (tux_dev = bus->devices; tux_dev; tux_dev = tux_dev->next) + if (tux_dev->descriptor.idVendor == TUX_VID + && tux_dev->descriptor.idProduct == TUX_PID) + return 1; + + return 0; +} + +struct usb_device *usb_find_TuxDroid(void) +{ + struct usb_bus *bus; + struct usb_device *tux_dev; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_busses; bus; bus = bus->next) + for (tux_dev = bus->devices; tux_dev; tux_dev = tux_dev->next) + if (tux_dev->descriptor.idVendor == TUX_VID + && tux_dev->descriptor.idProduct == TUX_PID) + { + send_debug_msg(DEBUG_LEVEL_DEBUG, "Fux found"); + return tux_dev; + } + send_debug_msg(DEBUG_LEVEL_ERROR, "Fux not found"); + return NULL; +} + +static struct usb_dev_handle *usb_open_TuxDroid(struct usb_device *tux_dev) +{ + usb_dev_handle *tux_hdl; + int error; + + /* Open usb device */ + tux_hdl = usb_open(tux_dev); + + if (!tux_hdl) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Can't open device"); + return NULL; + } + + /* Setting configuration is normally not necessary as the snd-usb-audio + * will already have that done at this point. But in case we don't have usb + * sound support, it may help to set the configuration. */ + if (usb_set_configuration(tux_hdl, 1) < 0) + { + send_debug_msg(DEBUG_LEVEL_DEBUG, "Couldn't set config 1:\n"\ + " Another module may have claimed an interface "\ + "already, see dmesg|tail."); + } + + /* Claim device interface */ + error = usb_claim_interface(tux_hdl, TUX_INTERFACE); + if (error != 0) + { + /*usb_detach_kernel_driver_np(tux_hdl, TUX_INTERFACE); */ + error = usb_claim_interface(tux_hdl, TUX_INTERFACE); + if (error != 0) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Can't claim interface"); + return NULL; + } + } + return tux_hdl; +} + +int tux_usb_capture(void) +{ + send_debug_msg(DEBUG_LEVEL_DEBUG, "Capturing USB device"); + + tux_device = usb_find_TuxDroid(); + if (!tux_device) + return 0; + + /* Old firmware should be discarded here */ + if (tux_device->descriptor.bcdDevice < 0x030) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Can't claim interface"); + return 0; + } + + send_debug_msg(DEBUG_LEVEL_DEBUG, "Fux found on the USB bus"); + + /* Get Device handle */ + tux_handle = usb_open_TuxDroid(tux_device); + if (tux_handle == NULL) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "You must load the daemon in root mode"); + return 0; + } + + send_debug_msg(DEBUG_LEVEL_DEBUG, "Fux USB device opened"); + + set_connected(1); + return 1; +} + +int tux_usb_release(void) +{ + if (usb_release_interface(tux_handle, TUX_INTERFACE) < 0) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Failed releasing USB interface"); + return 0; + } + + if (usb_close(tux_handle) < 0) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Failed closing USB device"); + return 0; + } + + set_connected(0); + return 1; +} + +int usb_write_TuxDroid(const void *buf, int size) +{ + return usb_interrupt_write(tux_handle, TUX_WRITE_EP, (char *)buf, size, + TUX_WRITE_TIMEOUT); +} + +int usb_read_TuxDroid(void *buf) +{ + return usb_interrupt_read(tux_handle, TUX_READ_EP, (char *)buf, TUX_RECEIVE_LENGTH, + TUX_READ_TIMEOUT); +} + +int tux_usb_write(const void *buff) +{ + int ret; + char frame_msg[256]; + void *buf2; + unsigned char dest; + unsigned char cmd; + unsigned char param1; + unsigned char param2; + unsigned char param3; + + if (!tux_usb_connected()) + return 0; + + pthread_mutex_lock(&__read_write_mutex); + ret = usb_write_TuxDroid(buff, TUX_SEND_LENGTH); + pthread_mutex_unlock(&__read_write_mutex); + + buf2 = buff; + dest = *(unsigned char *)buf2++; + cmd = *(unsigned char *)buf2++; + param1 = *(unsigned char *)buf2++; + param2 = *(unsigned char *)buf2++; + param3 = *(unsigned char *)buf2++; + sprintf(frame_msg, "WRITE [Dest: 0x%.2x Cmd: 0x%.2x Param1 : 0x%.2x Param2 : 0x%.2x Param3 : 0x%.2x]", + dest, + cmd, + param1, + param2, + param3); + send_debug_msg(DEBUG_LEVEL_DEBUG, frame_msg); + + return 1; +} + +int tux_usb_read(void *buf) +{ + int ret; + char data_send[5] = {1, 1, 0, 0, 0}; + char frame_msg[256]; + void *buf2; + unsigned char rf_state; + unsigned char cmd_state; + unsigned char fc_state; + + if (!tux_usb_connected()) + return 0; + + pthread_mutex_lock(&__read_write_mutex); + ret = usb_write_TuxDroid(data_send, TUX_SEND_LENGTH); + if (!ret) + { + pthread_mutex_unlock(&__read_write_mutex); + send_debug_msg(DEBUG_LEVEL_ERROR, "Failed to write on USB device."); + return 0; + } + + ret = usb_read_TuxDroid((char *)buf); + pthread_mutex_unlock(&__read_write_mutex); + if (!ret) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Failed to read on USB device."); + return 0; + } + buf2 = buf; + buf2++; + rf_state = *(unsigned char *)buf2++; + cmd_state = *(unsigned char *)buf2++; + fc_state = *(unsigned char *)buf2++; + sprintf(frame_msg, "READ [RF_st: %d CMD_st: %d NB_frames : %d idx : %d]", + rf_state, + cmd_state, + fc_state, + ret); + send_debug_msg(DEBUG_LEVEL_FRAME, frame_msg); + return 1; +} + +double get_time(void) +{ + double result; + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + result = ((float)tv.tv_usec / 1000000) + (float)tv.tv_sec; + return result; +} + +void read_usb_loop(void) +{ + int check_counter = 0; + double initial_timeout = 0.0; + double current_timeout = 0.0; + unsigned char data[64] = { [0 ... 63] = 0 }; + + initial_timeout = get_time(); + current_timeout = initial_timeout; + + while (1) + { + current_timeout += TUX_READ_LOOP_INTERVAL; + + if (!tux_usb_connected()) + break; + + if (check_counter >= 9) + { + if (!tux_usb_dongle_present()) + { + set_connected(0); + tux_usb_release(); + // Disconnect CallBack + send_debug_msg(DEBUG_LEVEL_WARNING, "Fux is disconnected"); + pthread_mutex_lock(&__callback_mutex); + if (dongle_disconnect_function) + dongle_disconnect_function(); + pthread_mutex_unlock(&__callback_mutex); + break; + } + check_counter = 0; + }else{ + check_counter++; + } + + tux_usb_read(data); + // Frame CallBack + pthread_mutex_lock(&__callback_mutex); + if (frame_callback_function) + frame_callback_function(data); + pthread_mutex_unlock(&__callback_mutex); + + while (get_time() < current_timeout) + usleep(1000); + } + + send_debug_msg(DEBUG_LEVEL_DEBUG, "End of read loop"); +} + +void start_loop(void) +{ + if ((read_loop_thread = g_thread_create((GThreadFunc)read_usb_loop, NULL, TRUE, &error)) == NULL ) + { + send_debug_msg(DEBUG_LEVEL_ERROR, "Thread creation failed. Read loop can't start"); + } +} + +int tux_usb_start(void) +{ + if (tux_usb_connected()) + { + send_debug_msg(DEBUG_LEVEL_INFO, "Tux usb is already started"); + return 0; + } + + if (!tux_usb_capture()) + { + send_debug_msg(DEBUG_LEVEL_INFO, "Tux usb can't start"); + return 0; + } + + start_loop(); + usleep(100000); + send_debug_msg(DEBUG_LEVEL_INFO, "Tux usb start"); + return 1; +} + +int tux_usb_stop(void) +{ + if (!tux_usb_connected()) + return 1; + + set_connected(0); + + usleep(500000); + + if (!tux_usb_release()) + { + send_debug_msg(DEBUG_LEVEL_INFO, "Tux usb can't stop"); + return 0; + } + + send_debug_msg(DEBUG_LEVEL_INFO, "Tux usb stop"); + return 1; +} + +void tux_usb_reset(void) +{ + usb_reset(tux_handle); +} Added: tux_lib/tux_usb/trunk/tux_usb.h =================================================================== --- tux_lib/tux_usb/trunk/tux_usb.h (rev 0) +++ tux_lib/tux_usb/trunk/tux_usb.h 2007-12-14 09:19:09 UTC (rev 791) @@ -0,0 +1,61 @@ +/* + * Tux Droid - USB Interface + * Copyright (C) 2007 C2ME Sa <rem...@c2...> + * + * 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, 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +/*_____________________ D E F I N E S ______________________________________*/ +#define TUX_PID 0xFF07 +#define TUX_VID 0x03EB +#define TUX_INTERFACE 0x03 +#define TUX_SEND_LENGTH 0x05 +#define TUX_RECEIVE_LENGTH 64 +#define TUX_WRITE_EP 0x05 +#define TUX_READ_EP 0x84 +#define TUX_WRITE_TIMEOUT 1000 +#define TUX_READ_TIMEOUT 1000 +#define TUX_READ_LOOP_INTERVAL 0.1 +/*Debug level messages*/ +#define DEBUG_LEVEL_FRAME 0 +#define DEBUG_LEVEL_DEBUG 1 +#define DEBUG_LEVEL_INFO 2 +#define DEBUG_LEVEL_WARNING 3 +#define DEBUG_LEVEL_ERROR 4 +/*_____________________ T Y P E _ D E F ____________________________________*/ +typedef void(*dongle_disconnect_callback_t)(void); +typedef void(*frame_callback_t)(char *data); +typedef void(*msg_callback_t)(int, char *data); +/*_____________________ F U N C T I O N S __________________________________*/ +/* Library initialisation */ +extern void tux_usb_init(void); +/* Device capture and release */ +extern int tux_usb_capture(void); +extern int tux_usb_release(void); +/* Callback set*/ +extern void set_frame_callback(frame_callback_t funct); +extern void set_disconnect_dongle_callback(dongle_disconnect_callback_t funct); +extern void set_debug_msg_callback(msg_callback_t funct); +/* Read and write */ +extern int tux_usb_write(const void *buff); +extern int tux_usb_read(void *buf); +/* Frame callback loop (automatic capture and release of device) */ +extern int tux_usb_start(void); +extern int tux_usb_stop(void); +/* Misc */ +extern int tux_usb_connected(void); +extern int tux_usb_dongle_present(void); +extern void tux_usb_reset(void); |