Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Aguiar <alanjas@hotmail.com>2013-03-03 19:58:37 (GMT)
committer Alan Aguiar <alanjas@hotmail.com>2013-03-03 19:58:37 (GMT)
commitdb04ba167d5b83990418a9658ff82d50dc63eaf3 (patch)
treeead49a52f5a1fced38b3fc25ada078ff2d892fb8
parentae8181354bcfa55d38b5853595f819770f3370f7 (diff)
same changes that in gtk2 version: replace bobot by pybotgtk3
-rwxr-xr-xactivity.py4
-rwxr-xr-xbutiaAPI.py326
-rwxr-xr-xfollowme.py2
-rw-r--r--lib/support/bobot-server.lua227
-rw-r--r--lib/support/bobot.lua55
-rw-r--r--lib/support/bobot_server/bobot-server-http.lua211
-rw-r--r--lib/support/bobot_server/bobot-server-process.lua176
-rw-r--r--lib/support/bobot_server/bobot.pngbin10277 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/butia.htm17
-rw-r--r--lib/support/bobot_server/butia/butia_http.lua32
-rw-r--r--lib/support/bobot_server/butia/command.htm36
-rw-r--r--lib/support/bobot_server/butia/describeButia.htm88
-rw-r--r--lib/support/bobot_server/butia/header.htm10
-rw-r--r--lib/support/bobot_server/butia/images/btar_dn.gifbin303 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/images/btar_lft.gifbin279 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/images/btar_rgt.gifbin283 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/images/btar_up.gifbin312 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/images/butiaRobot3.pngbin80308 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/images/clase07.jpgbin20771 -> 0 bytes
-rw-r--r--lib/support/bobot_server/butia/sensors.htm40
-rw-r--r--lib/support/bobot_server/butia/view.htm10
-rw-r--r--lib/support/bobot_server/dumptemplate.txt11
-rw-r--r--lib/support/bobot_server/dumptemplate_descr.txt37
-rw-r--r--lib/support/bobot_server/dumptemplate_descr_row.txt20
-rw-r--r--lib/support/bobot_server/favicon.icobin1406 -> 0 bytes
-rw-r--r--lib/support/bobot_server/http-util.lua41
-rw-r--r--lib/support/bobot_server/indextemplate.txt16
-rw-r--r--lib/support/drivers/admin.lua11
-rw-r--r--lib/support/drivers/ax.lua118
-rw-r--r--lib/support/drivers/boot.lua11
-rw-r--r--lib/support/drivers/boton.lua19
-rw-r--r--lib/support/drivers/butia.lua39
-rw-r--r--lib/support/drivers/buzzer.lua51
-rw-r--r--lib/support/drivers/debug.lua39
-rw-r--r--lib/support/drivers/display.lua99
-rw-r--r--lib/support/drivers/dist.lua25
-rw-r--r--lib/support/drivers/dynamix.lua34
-rw-r--r--lib/support/drivers/gas.lua20
-rw-r--r--lib/support/drivers/grises.lua19
-rw-r--r--lib/support/drivers/hotplug/button.lua32
-rw-r--r--lib/support/drivers/hotplug/distanc.lua32
-rw-r--r--lib/support/drivers/hotplug/gpio.lua19
-rw-r--r--lib/support/drivers/hotplug/grey.lua32
-rw-r--r--lib/support/drivers/hotplug/light.lua32
-rw-r--r--lib/support/drivers/hotplug/port.lua19
-rw-r--r--lib/support/drivers/hotplug/tilt.lua19
-rw-r--r--lib/support/drivers/hotplug/vibra.lua19
-rw-r--r--lib/support/drivers/lback.lua21
-rw-r--r--lib/support/drivers/led.lua17
-rw-r--r--lib/support/drivers/ledA.lua46
-rw-r--r--lib/support/drivers/ledR.lua31
-rw-r--r--lib/support/drivers/ledV.lua31
-rw-r--r--lib/support/drivers/leds.lua43
-rw-r--r--lib/support/drivers/luz.lua21
-rw-r--r--lib/support/drivers/magnet.lua21
-rw-r--r--lib/support/drivers/motor.lua42
-rw-r--r--lib/support/drivers/motorTm.lua47
-rw-r--r--lib/support/drivers/motores.lua48
-rw-r--r--lib/support/drivers/motorin.lua28
-rw-r--r--lib/support/drivers/motors.lua70
-rw-r--r--lib/support/drivers/move.lua16
-rw-r--r--lib/support/drivers/pnp.lua0
-rw-r--r--lib/support/drivers/pote.lua16
-rw-r--r--lib/support/drivers/puerta.lua31
-rw-r--r--lib/support/drivers/sec.lua87
-rw-r--r--lib/support/drivers/sensor.lua52
-rw-r--r--lib/support/drivers/stmtr.lua46
-rw-r--r--lib/support/drivers/temp.lua28
-rw-r--r--lib/support/drivers/temp_lubot.lua20
-rw-r--r--lib/support/lib/bobot_baseboard.lua393
-rw-r--r--lib/support/lib/bobot_device.lua216
-rw-r--r--lib/support/lib/comms_chotox.lua39
-rw-r--r--lib/support/lib/comms_serial.lua94
-rw-r--r--lib/support/lib/comms_usb.lua99
-rwxr-xr-xlib/support/lib/libluausb.sobin17457 -> 0 bytes
-rwxr-xr-xlib/support/lib/lua_serialcomm.sobin11599 -> 0 bytes
-rwxr-xr-xlib/support/lib/mime/core.sobin12937 -> 0 bytes
-rwxr-xr-xlib/support/lib/socket/core.sobin44755 -> 0 bytes
-rwxr-xr-xlib/support/libluausb.sobin17457 -> 0 bytes
-rwxr-xr-xlib/support/luabin161497 -> 0 bytes
-rwxr-xr-xlib/support/lua_serialcomm.sobin11599 -> 0 bytes
-rw-r--r--lib/support/share/ltn12.lua292
-rw-r--r--lib/support/share/mime.lua87
-rw-r--r--lib/support/share/socket.lua133
-rw-r--r--lib/support/share/socket/ftp.lua281
-rw-r--r--lib/support/share/socket/http.lua350
-rw-r--r--lib/support/share/socket/smtp.lua251
-rw-r--r--lib/support/share/socket/tp.lua123
-rw-r--r--lib/support/share/socket/url.lua297
-rw-r--r--lib/support/socket.lua133
-rwxr-xr-xlib/support/socket/core.sobin44755 -> 0 bytes
-rwxr-xr-xmain.py2
-rwxr-xr-xpybot/__init__.py27
-rwxr-xr-xpybot/baseboard.py275
-rwxr-xr-xpybot/com_usb.py127
-rwxr-xr-xpybot/device.py154
-rw-r--r--pybot/drivers/admin.py19
-rw-r--r--pybot/drivers/butia.py19
-rw-r--r--pybot/drivers/hackp.py40
-rw-r--r--pybot/drivers/hotplug/button.py19
-rw-r--r--pybot/drivers/hotplug/distanc.py19
-rw-r--r--pybot/drivers/hotplug/grey.py19
-rw-r--r--pybot/drivers/hotplug/led.py19
-rw-r--r--pybot/drivers/hotplug/light.py19
-rw-r--r--pybot/drivers/hotplug/res.py19
-rw-r--r--pybot/drivers/hotplug/volt.py19
-rw-r--r--pybot/drivers/lback.py19
-rw-r--r--pybot/drivers/motors.py27
-rw-r--r--pybot/drivers/pnp.py11
-rwxr-xr-xpybot/pybot_server.py146
-rw-r--r--pybot/usb/__init__.py92
-rw-r--r--pybot/usb/_debug.py77
-rw-r--r--pybot/usb/_interop.py137
-rw-r--r--pybot/usb/backend/__init__.py368
-rw-r--r--pybot/usb/backend/libusb0.py586
-rw-r--r--pybot/usb/backend/libusb1.py670
-rw-r--r--pybot/usb/backend/openusb.py708
-rw-r--r--pybot/usb/control.py252
-rw-r--r--pybot/usb/core.py871
-rw-r--r--pybot/usb/legacy.py344
-rw-r--r--pybot/usb/util.py260
-rwxr-xr-xpybot/usb4butia.py375
-rwxr-xr-xrobot.py22
-rwxr-xr-xsugargame/__init__.py (renamed from lib/sugargame/__init__.py)0
-rwxr-xr-xsugargame/canvas.py (renamed from lib/sugargame/canvas.py)0
-rwxr-xr-xsugargame/event.py (renamed from lib/sugargame/event.py)0
126 files changed, 5745 insertions, 5614 deletions
diff --git a/activity.py b/activity.py
index 6a86d3a..aa78433 100755
--- a/activity.py
+++ b/activity.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# FollowMe Butia
-# Copyright (C) 2010, 2011, 2012
+# Copyright (C) 2010-2013
# This program was created to use with the robot Butia.
# Butia is a project from Facultad de Ingenieria - Uruguay
# Facultad de Ingenieria web site: <http://www.fing.edu.uy/>
@@ -27,8 +27,6 @@
# Rodrigo Dearmas <piegrande46@hotmail.com>
-import sys
-sys.path.insert(0, "lib")
import gi
from gi.repository import Gtk
from sugar3.activity import activity
diff --git a/butiaAPI.py b/butiaAPI.py
deleted file mode 100755
index 4bb6ca3..0000000
--- a/butiaAPI.py
+++ /dev/null
@@ -1,326 +0,0 @@
-#! /usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# ButiaAPI
-# Copyright (c) 2009, 2010, 2011, 2012 Butiá Team butia@fing.edu.uy
-# Butia is a free open plataform for robotics projects
-# www.fing.edu.uy/inco/proyectos/butia
-# Facultad de Ingenieria - Universidad de la República - Uruguay
-#
-# Implements abstractions for the comunications with the bobot-server
-#
-# 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 of the License, 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
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import socket
-import string
-import math
-import threading
-
-ERROR_SENSOR_READ = -1
-
-BUTIA_1 = 20
-
-BOBOT_HOST = 'localhost'
-BOBOT_PORT = 2009
-
-class robot:
-
-
- def __init__(self, host = BOBOT_HOST, port = BOBOT_PORT):
- """
- init the robot class
- """
- self.lock = threading.Lock()
- self.host = host
- self.port = port
- self.client = None
- self.fclient = None
- self.ver = BUTIA_1
- self.reconnect()
- self.getVersion()
-
-
- def doCommand(self, msg):
- """
- Executes a command in butia.
- @param msg message to be executed
- """
- msg = msg +'\n'
- ret = ERROR_SENSOR_READ
- self.lock.acquire()
- try:
- self.client.send(msg)
- ret = self.fclient.readline()
- ret = ret[:-1]
- except:
- ret = ERROR_SENSOR_READ # Doesn't return here to release the lock
- self.lock.release()
-
- if ((ret == 'nil value') or (ret == None) or (ret == 'fail') or (ret == 'missing driver')):
- ret = ERROR_SENSOR_READ
- return ret
-
- # connect o reconnect the bobot
- def reconnect(self):
- self.close()
- try:
- self.client = socket.socket()
- self.client.connect((self.host, self.port))
- self.fclient = self.client.makefile()
- msg = 'INIT'
- #bobot server instance is running, but we have to check for new or remove hardware
- self.doCommand(msg)
- except:
- return ERROR_SENSOR_READ
- return 0
-
- # ask bobot for refresh is state of devices connected
- def refresh(self):
- if (self.ver == BUTIA_1) or (self.ver == ERROR_SENSOR_READ):
- msg = 'INIT'
- else:
- msg = 'REFRESH'
- return self.doCommand(msg)
-
- # close the comunication with the bobot
- def close(self):
- try:
- if self.fclient != None:
- self.fclient.close()
- self.fclient = None
- if self.client != None:
- self.client.close()
- self.client = None
- except:
- return ERROR_SENSOR_READ
- return 0
-
- #######################################################################
- ### Operations to the principal module
- #######################################################################
-
-
- # call the module 'modulename'
- def callModule(self, modulename, function , params = ''):
- msg = 'CALL ' + modulename + ' ' + function
- if params != '' :
- msg += ' ' + params
- ret = self.doCommand(msg)
- try:
- ret = int(ret)
- except:
- ret = ERROR_SENSOR_READ
- return ret
-
- # Close bobot service
- def closeService(self):
- msg = 'QUIT'
- return self.doCommand(msg)
-
- #######################################################################
- ### Useful functions
- #######################################################################
-
- # returns if the module_name is present
- def isPresent(self, module_name):
- module_list = self.get_modules_list()
- return (module_name in module_list)
-
- # returns a list of modules
- def get_modules_list(self):
- msg = 'LIST'
- l = []
- ret = self.doCommand(msg)
- if not (ret == '' or ret == ERROR_SENSOR_READ):
- l = ret.split(',')
- return l
-
- # loopBack: send a message to butia and wait to recibe the same
- def loopBack(self, data):
- msg = 'lback send ' + data
- ret = self.doCommand(msg)
- if ret != -1 :
- msg = 'CALL lback read'
- return self.doCommand(msg)
- else:
- return ERROR_SENSOR_READ
-
-
- #######################################################################
- ### Operations for motores.lua driver
- #######################################################################
-
- def set2MotorSpeed(self, leftSense = '0', leftSpeed = '0', rightSense = '0', rightSpeed = '0'):
- msg = leftSense + ' ' + leftSpeed + ' ' + rightSense + ' ' + rightSpeed
- if self.ver == BUTIA_1:
- return self.callModule('motores', 'setvel2mtr', msg)
- else:
- return self.callModule('motors', 'setvel2mtr', msg)
-
- def setMotorSpeed(self, idMotor = '0', sense = '0', speed = '0'):
- msg = idMotor + ' ' + sense + ' ' + speed
- if self.ver == BUTIA_1:
- return self.callModule('motores', 'setvelmtr', msg)
- else:
- return self.callModule('motors', 'setvelmtr', msg)
-
- #######################################################################
- ### Operations for ax.lua driver
- #######################################################################
-
- def wheel_mode(self, idMotor = '0'):
- msg = idMotor
- if self.ver == BUTIA_1:
- return self.callModule('ax', 'wheel_mode', msg) ##TODO implement
- else:
- return self.callModule('ax', 'wheel_mode', msg)
-
- def joint_mode(self, idMotor = '0', min = '0', max = '1023'):
- msg = idMotor + ' ' + min + ' ' + max
- if self.ver == BUTIA_1:
- return self.callModule('ax', 'joint_mode', msg) ##TODO implement
- else:
- return self.callModule('ax', 'joint_mode', msg)
-
- def set_speed(self, idMotor = '0', speed = '0'):
- msg = idMotor + ' ' + speed
- if self.ver == BUTIA_1:
- return self.callModule('ax', 'set_speed', msg) ##TODO implement
- else:
- return self.callModule('ax', 'set_speed', msg)
-
- def set_position(self, idMotor = '0', pos = '0'):
- msg = idMotor + ' ' + pos
- if self.ver == BUTIA_1:
- return self.callModule('ax', 'set_position', msg) ##TODO implement
- else:
- return self.callModule('ax', 'set_position', msg)
-
- def get_position(self, idMotor = '0'):
- msg = idMotor
- if self.ver == BUTIA_1:
- return self.callModule('ax', 'get_position', msg) ##TODO implement
- else:
- return self.callModule('ax', 'get_position', msg)
-
-
-
- #######################################################################
- ### Operations for butia.lua driver
- #######################################################################
-
- def ping(self):
- return self.callModule('placa', 'ping')
-
- # returns the approximate charge of the battery
- def getBatteryCharge(self):
- return self.callModule('butia', 'get_volt')
-
- # returns the firmware version
- def getVersion(self):
- ver = self.callModule('butia', 'read_ver')
- if not(ver == ERROR_SENSOR_READ):
- self.ver = ver
- return ver
-
- # set de motor idMotor on determinate angle
- def setPosition(self, idMotor = 0, angle = 0):
- msg = str(idMotor) + ' ' + str(angle)
- return self.callModule('placa', 'setPosicion' , msg )
-
- # return the value of button: 1 if pressed, 0 otherwise
- def getButton(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('boton' + str(number), 'getValue')
- else:
- return self.callModule('button:' + str(number), 'getValue')
-
- # return the value en ambient light sensor
- def getAmbientLight(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('luz' + str(number), 'getValue')
- else:
- return self.callModule('light:' + str(number), 'getValue')
-
- # return the value of the distance sensor
- def getDistance(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('dist' + str(number), 'getValue')
- else:
- return self.callModule('distanc:' + str(number), 'getValue')
-
- # return the value of the grayscale sensor
- def getGrayScale(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('grises' + str(number), 'getValue')
- else:
- return self.callModule('grey:' + str(number), 'getValue')
-
- # return the value of the temperature sensor
- def getTemperature(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('temp' + str(number), 'getValue')
- else:
- return self.callModule('temp:' + str(number), 'getValue')
-
- # return the value of the vibration sensor
- def getVibration(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('vibra' + str(number), 'getValue')
- else:
- return self.callModule('vibra:' + str(number), 'getValue')
-
- # return the value of the resistance sensor
- def getResistance(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('resist' + str(number), 'getValue') #TODO implement
- else:
- return self.callModule('resist:' + str(number), 'getValue')
-
- # return the value of the tilt sensor
- def getTilt(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('tilt' + str(number), 'getValue')
- else:
- return self.callModule('tilt:' + str(number), 'getValue')
-
- # FIXME: the name of the module and the function...
- # return the value of the capacitive touch sensor
- def getCapacitive(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('capacitive' + str(number), 'getValue')
- else:
- return self.callModule('capacitive:' + str(number), 'getValue')
-
- # return the value of the magnetic induction sensor
- def getMagneticInduction(self, number=''):
- if self.ver == BUTIA_1:
- return self.callModule('magnet' + self.aux + str(number), 'getValue')
- else:
- return self.callModule('magnet:' + self.aux + str(number), 'getValue')
-
- # set the led intensity
- def setLed(self, nivel = 255, number= ''):
- if self.ver == BUTIA_1:
- return self.callModule('led' + self.aux + str(number), 'setLight', str(math.trunc(nivel)))
- else:
- return self.callModule('led:' + self.aux + str(number), 'setLight', str(math.trunc(nivel)))
-
- # FIXME: check the lenght of text?
- # write a text in LCD display
- def writeLCD(self, text):
- text = str(text)
- text = text.replace(' ', '_')
- self.callModule('display', 'escribir' , text)
-
diff --git a/followme.py b/followme.py
index 522d624..745e2af 100755
--- a/followme.py
+++ b/followme.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# FollowMe Butia - FollowMe
-# Copyright (C) 2010, 2011, 2012
+# Copyright (C) 2010-2013
# This program was created to use with the robot Butia.
# Butia is a project from Facultad de Ingenieria - Uruguay
# Facultad de Ingenieria web site: <http://www.fing.edu.uy/>
diff --git a/lib/support/bobot-server.lua b/lib/support/bobot-server.lua
deleted file mode 100644
index fcaa55b..0000000
--- a/lib/support/bobot-server.lua
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/lua
-
---[[
-
-Syntax
-
- # lua bobot-server.lua [DEBUG] [connection]*
-
-Parameters:
- DEBUG enables debug printing in bobot
- connection a list of connection services to attempt. Supported
- values in bobot (for now) are usb, serial and chotox
-
-If no connection services are provided, defaults to usb and serial.
-
-Examples:
- Start with debug disabled and the dummy chotox service, only:
- # lua bobot-server.lua chotox
-
- Start with debug enabled and the serial services only:
- # lua bobot-server.lua DEBUG serial
-
- Start with debug disabled and the usb and serial services (same as default):
- # lua bobot-server.lua usb serial
-
---]]
-
---package.path=package.path..";./bobot_server/?.lua"
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]] or "./"
-package.path=package.path..";"..my_path.."bobot_server/?.lua;"
- ..my_path.."lib/?.lua;"..my_path.."?.lua"
-
---tcp listening address
-local N_PROTOCOLS = 2
-local ADDRESS = "*"
-local PORT_B = 2009 --B is for bobot
-local PORT_H = 2010 --H is for http
-
-local TIMEOUT_REFRESH = 3
-
-local socket = require("socket")
-local process = require("bobot-server-process").process
-local http_serve = require("bobot-server-http").serve
-
-local bobot = require("bobot")
-
-local set_debug
-for i, v in ipairs(arg) do
- if v=="DEBUG" then
- set_debug=true
- table.remove(arg, i)
- break
- end
-end
-if set_debug then
- bobot.debugprint = print
- bobot.debugprint("Debugging messages enabled")
-else
- bobot.debugprint = function() end
-end
-
-
-local server_b = assert(socket.bind(ADDRESS, PORT_B))
-local server_h = assert(socket.bind(ADDRESS, PORT_H))
-
-local recvt={[1]=server_b, [2]=server_h}
-
-devices = {}
-
-local function get_device_name(d)
-
---print("DEVICENAME", d.module, d.hotplug, d.handler)
- local board_id, port_id = '', ''
- if #bobot.baseboards>1 then
- board_id='@'..d.baseboard.idBoard
- end
- if d.hotplug then
- port_id = ':'..d.handler
- end
-
- local n=d.module..board_id..port_id
-
- if not devices[n] then
- return n
- end
-
- local i=2
- local nn=n.."#"..i
- while devices[nn] do
- i=i+1
- nn=n.."#"..i
- end
-
- return nn
-end
-
-local function read_devices_list()
- bobot.debugprint("=Listing Devices")
- local bfound
- devices={}
- for _, bb in ipairs(bobot.baseboards) do
- bobot.debugprint("===board ", bb.idBoard)
- for _,d in ipairs(bb.devices) do
- local regname = get_device_name(d)
- devices[regname]=d
- devices[#devices+1]=d
- d.name=regname
- bobot.debugprint("=====module ",d.module," name",regname)
- end
- bfound = true
- end
- if not bfound then bobot.debugprint("ls:WARN: No Baseboard found.") end
-end
-
-local function split_words(s)
- local words={}
-
- for p in string.gmatch(s, "%S+") do
- words[#words+1]=p
- end
-
- return words
-end
-
-local socket_handlers = {}
-setmetatable(socket_handlers, { __mode = 'k' })
-socket_handlers[server_b]=function()
- local client, err=server_b:accept()
- if not client then return end
- bobot.debugprint ("bs:New bobot client", client, client:getpeername())
- table.insert(recvt,client)
- socket_handlers[client] = function ()
- local line,err = client:receive()
- if err=='closed' then
- bobot.debugprint ("bs:Closing bobot client", client)
- for k, v in ipairs(recvt) do
- if client==v then
- table.remove(recvt,k)
- return
- end
- end
- end
- if line then
- local words=split_words(line)
- local command=words[1]
- if not command then
- bobot.debugprint("bs:Error parsing line:", line, command)
- else
- if not process[command] then
- bobot.debugprint("bs:Command not supported:", command)
- else
- if command=="QUIT" and #recvt>N_PROTOCOLS+1 then
- client:send("server in use\n")
- return
- end
- local ret = process[command](words) or ""
- client:send(ret .. "\n")
- end
- end
- end
- end
-end
-
-socket_handlers[server_h]=function()
- local client, err=server_h:accept()
- if not client then return end
- bobot.debugprint ("bs:New http client", client, client:getpeername())
- client:setoption ("tcp-nodelay", true)
- --client:settimeout(5)
- table.insert(recvt,client)
- socket_handlers[client] = function ()
- local ret,err=http_serve(client)
- if err=='closed' then
- bobot.debugprint ("bs:Closing http client", client)
- for k, v in ipairs(recvt) do
- if client==v then
- table.remove(recvt,k)
- return
- end
- end
- end
- if ret then
- client:send(ret)
- end
- end
-end
-
-function server_refresh ()
- local refreshed
- for i, bb in ipairs(bobot.baseboards) do
- --if bb.refresh and not (bb.comms.type=='serial' and bb.devices) then
- if bb.refresh and bb.hotplug then
- if not bb:refresh() then
- bobot.baseboards[i]=nil
- end
- refreshed=true
- end
- end
- if refreshed then read_devices_list() end
-end
-
-function server_init ()
- bobot.init(arg)
- read_devices_list()
-end
-
-
-server_init()
-bobot.debugprint("Listening...")
--- loop forever waiting for clients
-
-while 1 do
- local recvt_ready, _, err=socket.select(recvt, nil, TIMEOUT_REFRESH)
- if err=='timeout' then
- if #bobot.baseboards==0 then
- server_init ()
- else
- server_refresh ()
- end
- else
- local skt=recvt_ready[1]
- socket_handlers[skt]()
- end
-end
-
-
-
diff --git a/lib/support/bobot.lua b/lib/support/bobot.lua
deleted file mode 100644
index c7dd062..0000000
--- a/lib/support/bobot.lua
+++ /dev/null
@@ -1,55 +0,0 @@
---[[
-bobot library
-
-Example usage:
- bobot=require("bobot")
- bobot.init()
-
-init() can receive a list of connectors to use. Supported values are "usb", "serial" and "chotox".
-For example, to only use de dummy chotox driver, use init({"chotox"})
-If no parameter is provided, behaves like init({"usb","serial"}).
-
---]]
-
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]] or "./"
-package.path=package.path..";"..my_path.."lib/?.lua"
-
-local socket=require('socket')
-
-local B = {}
-
-B.debugprint = print --function() end --do not print anything by default
-
---baseboards[iSerial] = BaseBoard
---B.baseboards = {}
-
---Returns number of baseboards detected.
-B.init = function ( comms )
- if not comms or #comms==0 then comms = {"usb","serial"} end
-
- B.baseboards={} --flush the baseboard because this function could be call after hardware remove or adition
-
- local n_boards, n_boards_total = {}, 0
- local start_time = os.time()
-
- repeat
- for _, comm in ipairs(comms) do
- B.debugprint ("Querying for baseboards:", comm)
- local comm_lib = require('comms_'..comm)
- if not comm_lib then
- B.debugprint("Could not open library:", comm)
- else
- comm_lib.type=comm
- n_boards[comm] = comm_lib.init(B.baseboards)
- n_boards_total = n_boards_total + n_boards[comm]
- end
- end
- if n_boards_total == 0 then socket.sleep(1) end
- until n_boards_total > 0 or os.time()-start_time > 3
-
- return n_boards_total
-end
-
---B.init()
-
-return B
diff --git a/lib/support/bobot_server/bobot-server-http.lua b/lib/support/bobot_server/bobot-server-http.lua
deleted file mode 100644
index efa239d..0000000
--- a/lib/support/bobot_server/bobot-server-http.lua
+++ /dev/null
@@ -1,211 +0,0 @@
-module(..., package.seeall);
-
-local bobot = require("bobot")
-
---local devices=devices
-local process = require("bobot-server-process").process
-local butia = require("butia/butia_http")
-local util = require("http-util")
-
-local parse_params = util.parse_params
-local load_template = util.load_file
-local find_page = util.find_page
-
---enable to cache in RAM
---[[
-local index_template=load_template('indextemplate.txt')
-local dump_template=load_template('dumptemplate.txt')
-local dump_template_descr=load_template('dumptemplate_descr.txt')
-local dump_template_descr_row=load_template('dumptemplate_descr_row.txt')
---]]
-
-local function check_open_device(d, ep1, ep2)
- if not d then return end
- if d.handler then return true end
- -- if the device is not open, then open the device
- bobot.debugprint ("Opening", d.name, d.handler)
- return d:open(ep1 or 1, ep2 or 1) --TODO asignacion de ep?
-end
-
-local html_list_devices = function (params)
- local ret,comma = "", ""
- local dsel=params['dsel']
- for d_name, d in pairs(devices) do
- local broken=""
- if not check_open_device(d, ep1, ep2) then
- broken=" (failed to open)"
- bobot.debugprint ("bs: WARN! Failure opening", d_name)
- end
- if dsel==d_name then
- ret = ret .. comma .. '<strong>' .. d_name .. broken .. '</strong>'
- else
- ret = ret .. comma .. '<a href="/dump.htm?dsel='..d_name..'">'..d_name..broken..'</a>'
- end
- comma=", "
- end
- return ret
-end
-
-local html_describe_device = function (params)
- --borrar
- dump_template_descr_row=load_template('dumptemplate_descr_row.txt')
-
- local dsel=params['dsel']
- local command=params['command']
- if not dsel then return "" end
-
- local device=devices[dsel]
-
- if not device then return "<TR><TD>Missing Device!</TD></TR>" end
- if not device.api then return "<TR><TD>Missing Driver for Device!</TD></TR>" end
-
- local ret = ""
- for fname, fdef in pairs(device.api) do
- local row=dump_template_descr_row
-
- local result,ok
- --print ("::",command,fname)
- if command==fname then
- --preparar parametros
- local fparams={}
- for i,param in ipairs(fdef.parameters) do
- local rname=param['rname']
- local rtype=param['rtype']
- if rtype=="int" or rtype=="number" or rtype=="numeric" then
- fparams[i]=tonumber(params[rname])
- else
- fparams[i]=params[rname]
- end
- end
-
- --ejecutar
- ok, result= pcall( fdef.call, unpack(fparams) )
- if not ok then bobot.debugprint ("Error calling", ret) end
- --imprimir
- bobot.debugprint ("::::",result)
- end
-
- local returns=''
- local comma=''
- for i,rets in ipairs(fdef.returns) do
- returns = returns..comma..rets['rtype']..'&nbsp;'..rets['rname']
- comma=','
- end
- local formfields=''
- local parameters=''
- local comma=''
- for i,rets in ipairs(fdef.parameters) do
- local rname=rets['rname']
- formfields=formfields..rname..': <INPUT TYPE="text" NAME="'..rname..'" /><br>'
- parameters = parameters..comma..rets['rtype']..'&nbsp;'..rname
- comma=','
- end
-
- local rep = {
- ['COMMAND'] = fname,
- ['RETURNS'] = returns,
- ['PARAMETERS'] = parameters,
- ['RESULT'] = result,
- ['MODULENAME'] = dsel,
- ['FORMFIELDS'] = formfields,
- }
- local generated_row=string.gsub(row, '<!%-%-(%w+)%-%->', rep)
-
- ret=ret..generated_row
-
- end
-
- return ret
-end
-
-local get_page={}
-setmetatable(get_page, {__index = function(_,page) bobot.debugprint ("======", page);return find_page(page) end})
-get_page["/index.htm"] = function (p)
- local index_template=load_template('indextemplate.txt')
-
- local params=parse_params(p)
- local rep = {
- ['DATA1'] = params['campo'],
- ['DATA2'] = tostring(params['unboton'])..', '..tostring(params['otroboton']),
- }
- local page=string.gsub(index_template, '<!%-%-(%w+)%-%->', rep)
- return "HTTP/1.1 200/OK\r\nContent-Type:text/html\r\nContent-Length: "..#page.."\r\n\r\n"..page
-end
-get_page["/"]=get_page["/index.htm"]
-get_page["/dump.htm"] = function (p)
- --remove this
- dump_template=load_template('dumptemplate.txt')
- dump_template_descr=load_template('dumptemplate_descr.txt')
-
- local params=parse_params(p)
- local dsel=params['dsel']
-
- local usetemplate
- if dsel then
- usetemplate=dump_template_descr
- else
- usetemplate=dump_template
- end
-
- local rep = {
- ['LIST'] = html_list_devices(params),
- ['MODULENAME'] = dsel or "(empty dsel)",
- ['ROWS'] = html_describe_device(params),
- }
- local page=string.gsub(usetemplate, '<!%-%-(%w+)%-%->', rep)
- return "HTTP/1.1 200/OK\r\nContent-Type:text/html\r\nContent-Length: "..#page.."\r\n\r\n"..page
-end
-get_page["/favicon.ico"] = function ()
- local served, err = io.open('bobot_server/favicon.ico', "rb")
- if served ~= nil then
- local content = served:read("*all")
- return "HTTP/1.1 200/OK\r\nContent-Type:image/x-icon\r\nContent-Length: "
- ..#content.."\r\n\r\n" .. content
- else
- bobot.debugprint("Error opening favicon:", err)
- return default_page()
- end
-end
-get_page["/bobot.png"] = function ()
- local served, err = io.open('bobot_server/bobot.png', "rb")
- if served ~= nil then
- local content = served:read("*all")
- return "HTTP/1.1 200/OK\r\nContent-Type:image/png\r\nContent-Length: "
- ..#content.."\r\n\r\n" .. content
- else
- bobot.debugprint("Error opening logo:", err)
- return default_page()
- end
-end
-butia.init(get_page)
-
-function serve(skt)
- local line,err = skt:receive('*l') --read first line, must be GET or POST
- if err then return nil, err end
-
- local f,p=string.match(line, '^GET ([%/%.%d%w%-_]+)[%?]?(.-) HTTP/1.1$')
- if f then
- repeat
- --skip headers we don't care
- line,err=skt:receive()
- until line=='' or line==nil
- if err then return end
- local s=get_page[f](p)
- return(s..'\r\n')
- end
-
- local f,p=string.match(line, '^POST ([%/%.%d%w%-_]+) HTTP/1.1$')
- if f then
- local length
- repeat
- --skip headers we don't care
- line,err=skt:receive()
- length=length or string.match(line, '^Content%-Length%: (%d+)$')
- until line=='' or line==nil
- if err then return end
- local p=skt:receive(tonumber(length))
- local s=get_page[f](p)
- return(s..'\r\n')
- end
-end
-
diff --git a/lib/support/bobot_server/bobot-server-process.lua b/lib/support/bobot_server/bobot-server-process.lua
deleted file mode 100644
index 18231cb..0000000
--- a/lib/support/bobot_server/bobot-server-process.lua
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/lua
-
-module(..., package.seeall);
-
-local bobot = require("bobot")
-
---local devices=devices
---local DEBUG = false
-
-local function check_open_device(d, ep1, ep2)
- if not d then return end
- if d.handler or d.name=='pnp' then return true end
-
- -- if the device is not open, then open the device
- bobot.debugprint ("Opening", d.name, d.handler)
- return d:open(ep1 or 1, ep2 or 1) --TODO asignacion de ep?
-end
-
-process = {}
-
-process["INIT"] = function () --to check the new state of hardware on the fly
- server_init()
-end
-process["REFRESH"] = function () --to check the new state of hardware on the fly
- --for _, bb in ipairs(bobot.baseboards) do
- -- bb:refresh()
- --end
- server_refresh()
- return 'ok'
-end
-
-
-process["LIST"] = function ()
- local ret,comma = "", ""
- for _, d in ipairs(devices) do
- ret = ret .. comma .. d.name
- comma=","
- end
- return ret
-end
-
-
-process["LISTI"] = function ()
- if bobot.baseboards then
- bobot.debugprint("listing instanced modules...")
- for _, bb in ipairs(bobot.baseboards) do
- local handler_size=bb:get_handler_size()
- for i=1, handler_size do
- t_handler = bb:get_handler_type(i)
- bobot.debugprint("handler=", i-1 ," type=" ,t_handler)
- end
- end
- end
-end
-
-
-process["OPEN"] = function (parameters)
- local d = parameters[2]
- local ep1= tonumber(parameters[3])
- local ep2= tonumber(parameters[4])
-
- if not d then
- bobot.debugprint("ls:Missing 'device' parameter")
- return
- end
-
- local device = devices[d]
- if check_open_device(device, ep1, ep2) then
- return "ok"
- else
- return "fail"
- end
-end
-process["DESCRIBE"] = function (parameters)
- local d = parameters[2]
- local ep1= tonumber(parameters[3])
- local ep2= tonumber(parameters[4])
-
- if not d then
- bobot.debugprint("ls:Missing \"device\" parameter")
- return
- end
-
- local device = devices[d]
- if not check_open_device(device, ep1, ep2) then
- return "fail"
- end
- if not device.api then
- return "missing driver"
- end
-
- local ret = "{"
- for fname, fdef in pairs(device.api) do
- ret = ret .. fname .. "={"
- ret = ret .. " parameters={"
- for i,pars in ipairs(fdef.parameters) do
- ret = ret .. "[" ..i.."]={"
- for k, v in pairs(pars) do
- ret = ret .."['".. k .."']='"..tostring(v).."',"
- end
- ret = ret .. "},"
- end
- ret = ret .. "}, returns={"
- for i,rets in ipairs(fdef.returns) do
- ret = ret .. "[" ..i.."]={"
- for k, v in pairs(rets) do
- ret = ret .."['".. k .."']='"..tostring(v).."',"
- end
- ret = ret .. "},"
- end
- ret = ret .. "}},"
- end
- ret=ret.."}"
-
- return ret
-end
-process["CALL"] = function (parameters)
- local d = parameters[2]
- local call = parameters[3]
-
- if not (d and call) then
- bobot.debugprint("ls:Missing parameters", d, call)
- return
- end
-
- local device = devices[d]
- if not check_open_device(device, nil, nil) then
- return "fail"
- end
-
- if not device.api then return "missing driver" end
- local api_call=device.api[call];
- if not api_call then return "missing call" end
-
- if api_call.call then
- --local tini=socket.gettime()
- local ok, ret = pcall (api_call.call, unpack(parameters,4))
- if not ok then bobot.debugprint ("Error calling", ret) end
- --print ('%%%%%%%%%%%%%%%% bobot-server',socket.gettime()-tini)
- return ret
- end
-end
-process["CLOSEALL"] = function ()
- if bobot.baseboards then
- for _, bb in ipairs(bobot.baseboards) do
- --this command closes all the open user modules
- --it does not have sense with plug and play
- bb:force_close_all() --modif andrew
- end
- end
- return "ok"
-end
-process["BOOTLOADER"] = function ()
- if bobot.baseboards then
- for _, bb in ipairs(bobot.baseboards) do
- bb:switch_to_bootloader()
- end
- end
- return "ok"
-end
-process["DEBUG"] = function (parameters) --disable debug mode Andrew code!
- local debug = parameters[2]
- if not debug then return "missing parameter" end
- if debug=="ON" then
- bobot.debugprint = print --function(...) print (...) end --enable printing
- elseif debug=="OFF" then
- bobot.debugprint = function() end --do not print anything
- end
- return "ok"
-end
-process["QUIT"] = function ()
- bobot.debugprint("Requested EXIT...")
- os.exit()
- return "ok"
-end
-
diff --git a/lib/support/bobot_server/bobot.png b/lib/support/bobot_server/bobot.png
deleted file mode 100644
index 2de1124..0000000
--- a/lib/support/bobot_server/bobot.png
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/butia.htm b/lib/support/bobot_server/butia/butia.htm
deleted file mode 100644
index ca86673..0000000
--- a/lib/support/bobot_server/butia/butia.htm
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
-<HEAD>
- <TITLE>Robot Butia</TITLE>
-</HEAD>
-<frameset rows="25%,50%,25%">
-
- <frame src="header.htm" />
- <frameset cols="25%,75%">
- <frame src="command.htm" />
- <frame src="view.htm" />
- </frameset>
-<frame src="sensors.htm" />
-
-</frameset>
-
-</html>
-
diff --git a/lib/support/bobot_server/butia/butia_http.lua b/lib/support/bobot_server/butia/butia_http.lua
deleted file mode 100644
index 6a0b1ff..0000000
--- a/lib/support/bobot_server/butia/butia_http.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-module(..., package.seeall);
-
---local devices=devices
-local process = require("bobot-server-process").process
-local util = require("http-util")
-
-local parse_params = util.parse_params
-local load_template = util.load_file
-
-local butia_template=load_template('butia/butia.htm') or "Error loading template butia.htm"
-local header_template=load_template('butia/header.htm') or "Error loading template header.htm"
-
-function init (get_page)
- get_page["/butia.htm"] = function (p)
- local params=parse_params(p)
- local rep = {
- ['DATA1'] = params['campo'],
- ['DATA2'] = tostring(params['unboton'])..', '..tostring(params['otroboton']),
- }
- local page=string.gsub(butia_template, '<!%-%-(%w+)%-%->', rep)
- return "HTTP/1.1 200/OK\r\nContent-Type:text/html\r\nContent-Length: "..#page.."\r\n\r\n"..page
- end
-
- get_page["/header.htm"] = function (p)
- local params=parse_params(p)
- local rep = {
- }
- local page=string.gsub(header_template, '<!%-%-(%w+)%-%->', rep)
- return "HTTP/1.1 200/OK\r\nContent-Type:text/html\r\nContent-Length: "..#page.."\r\n\r\n"..page
- end
-
-end
diff --git a/lib/support/bobot_server/butia/command.htm b/lib/support/bobot_server/butia/command.htm
deleted file mode 100644
index 9cec722..0000000
--- a/lib/support/bobot_server/butia/command.htm
+++ /dev/null
@@ -1,36 +0,0 @@
-<HTML>
-
-<BODY BGCOLOR="#bfbfbf" TEXT="#000000" VLINK="#000099" LINK="#9900ff" ALINK="#FFFF00">
-<CENTER>
-<h1 style="color: rgb(0, 153, 0);">Haz click en los botones para dirigir el robot</h1>
-<hr>
-<BR>
-<TABLE BORDER=1 WIDTH="95%" CELLSPACING=3 CELLPADDING=3>
-<TR>
- <TD ALIGN="center" VALIGN="top">
- <TABLE BORDER=1 WIDTH="95%" CELLSPACING=3 CELLPADDING=3>
- <TR>
- <TD ALIGN="center"></TD>
- <TD ALIGN="center"><A HREF="up.htm"><IMG SRC="images/btar_up.gif" BORDER=0 WIDTH=20 HEIGHT=20></A></TD>
- <TD ALIGN="center"></TD>
- </TR>
- <TR>
- <TD ALIGN="center"><A HREF="left.htm"><IMG SRC="images/btar_lft.gif" BORDER=0 WIDTH=20 HEIGHT=20></A></TD>
- <TD ALIGN="center"></TD>
- <TD ALIGN="center"><A HREF="right.htm"><IMG SRC="images/btar_rgt.gif" BORDER=0 WIDTH=20 HEIGHT=20></A></TD>
- </TR>
- <TR>
- <TD ALIGN="center"></TD>
- <TD ALIGN="center"><A HREF="down.htm"><IMG SRC="images/btar_dn.gif" BORDER=0 WIDTH=20 HEIGHT=20></A></TD>
- <TD ALIGN="center"></TD>
- </TR>
- </TABLE>
- </TD>
-</TR>
-</TABLE>
-<P>
-
-</CENTER>
-</BODY>
-</HTML>
-
diff --git a/lib/support/bobot_server/butia/describeButia.htm b/lib/support/bobot_server/butia/describeButia.htm
deleted file mode 100644
index b147468..0000000
--- a/lib/support/bobot_server/butia/describeButia.htm
+++ /dev/null
@@ -1,88 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<HTML>
-<HEAD>
-<TITLE>
-butia (Describe)
-</TITLE>
-</HEAD>
-
-<BODY BGCOLOR="white" >
-<HR>
-<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
-<TR>
-<TD COLSPAN=2 BGCOLOR="#EEEEFF" >
-<A NAME="navbar_top_firstrow"><!-- --></A>
-<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
- <TR ALIGN="center" VALIGN="top">
- <TD BGCOLOR="#EEEEFF" > &nbsp;<FONT ><B>DESCRIBE butia</B></FONT>&nbsp;</TD>
- <TD BGCOLOR="#EEEEFF" > <A HREF="lback.htm"><FONT><B>DESCRIBE lback</B></FONT></A>&nbsp;</TD>
- <TD BGCOLOR="#FFFFFF" > <A HREF="dist.htm"><FONT ><B>DESCRIBE dist</B></FONT></A>&nbsp;</TD>
-
- </TR>
-</TABLE>
-</TD>
-<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
-<b>Butia<br>Robot&nbsp;Educativo</b></EM>
-</TD>
-</TR>
-</TABLE>
-<HR>
-<H2>
-<FONT SIZE="-1">
-Funciones disponibles en </FONT>
-<BR>
-butia</H2>
-
-<HR>
-
-<P>
-A continuaci&oacute;n se lista las funciones disponibles en este m&oacute;dulo.
-<br>
-Puedes invocar la funci&oacute;n ingresando los datos necesarios y presionando el bot&oacute;n Submit.
-<p>
-
-<P>
-
-<A NAME="method_summary"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#CCCCFF" >
-<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
-<B>Resumen de Funciones</B></FONT></TH>
-</TR>
-
-
-<TR BGCOLOR="white" >
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;data&nbsp;(String)</CODE></FONT></TD>
-<TD><CODE><B>read_ver</B>(data&nbsp;number)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-<FORM METHOD="POST" ACTION="evaluate_function.do">
-<HIDDEN VALUE="read_ver"/>
-data: <INPUT TYPE="text" NAME="data" />
-<INPUT TYPE="submit" VALUE="Submit" />
-</FORM>
-</TD>
-</TR>
-
-<TR BGCOLOR="white" >
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>&nbsp;data&nbsp;(String)</CODE></FONT></TD>
-<TD><CODE><B>get_volt</B>()</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-<FORM METHOD="POST" ACTION="evaluate_function.do">
-<HIDDEN VALUE="get_volt"/>
-<INPUT TYPE="submit" VALUE="Submit" />
-</FORM>
-</TD>
-</TR>
-
-</TABLE>
-&nbsp;
-<P>
-
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/lib/support/bobot_server/butia/header.htm b/lib/support/bobot_server/butia/header.htm
deleted file mode 100644
index 7d64136..0000000
--- a/lib/support/bobot_server/butia/header.htm
+++ /dev/null
@@ -1,10 +0,0 @@
-<HTML>
-
-<BODY BGCOLOR="#bfbfbf" TEXT="#000000" VLINK="#000099" LINK="#9900ff" ALINK="#FFFF00">
-<CENTER>
-<H1>ROBOT BUTIA</H1>
-<IMG SRC="butia/images/butiaRobot3.png" style="width: 152px; height: 113px;" ALT="Butia" align="middle"><P>
-<HR SIZE=1 NOSHADE>
-</CENTER>
-</BODY>
-</HTML>
diff --git a/lib/support/bobot_server/butia/images/btar_dn.gif b/lib/support/bobot_server/butia/images/btar_dn.gif
deleted file mode 100644
index 7f6b4f3..0000000
--- a/lib/support/bobot_server/butia/images/btar_dn.gif
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/images/btar_lft.gif b/lib/support/bobot_server/butia/images/btar_lft.gif
deleted file mode 100644
index e104fe4..0000000
--- a/lib/support/bobot_server/butia/images/btar_lft.gif
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/images/btar_rgt.gif b/lib/support/bobot_server/butia/images/btar_rgt.gif
deleted file mode 100644
index 4cc5ae0..0000000
--- a/lib/support/bobot_server/butia/images/btar_rgt.gif
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/images/btar_up.gif b/lib/support/bobot_server/butia/images/btar_up.gif
deleted file mode 100644
index e3180df..0000000
--- a/lib/support/bobot_server/butia/images/btar_up.gif
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/images/butiaRobot3.png b/lib/support/bobot_server/butia/images/butiaRobot3.png
deleted file mode 100644
index f7e74cf..0000000
--- a/lib/support/bobot_server/butia/images/butiaRobot3.png
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/images/clase07.jpg b/lib/support/bobot_server/butia/images/clase07.jpg
deleted file mode 100644
index acc498f..0000000
--- a/lib/support/bobot_server/butia/images/clase07.jpg
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/butia/sensors.htm b/lib/support/bobot_server/butia/sensors.htm
deleted file mode 100644
index dca9244..0000000
--- a/lib/support/bobot_server/butia/sensors.htm
+++ /dev/null
@@ -1,40 +0,0 @@
-<HTML>
-
-<BODY >
-<CENTER>
-
-<table cellspacing="0" cellpadding="5" border="1" align="top">
-<tr>
-<th> Sensor Name
-</th><th> Type (A/D)
-</th><th> Value
-</th><th> Other
-</th></tr>
-<tr>
-<td> Temperature
-</td><td> D
-</td><td> 23
-</td><td> C
-</td></tr>
-<tr>
-<td> Pote
-</td><td> A
-</td><td> 100
-</td><td>
-</td></tr>
-<tr>
-<td> Gas
-</td><td> A
-</td><td> 15
-</td><td>
-</td></tr>
-<tr>
-<td> Button
-</td><td> D
-</td><td> 1
-</td><td> Pressed
-</td></tr>
-
-</CENTER>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/lib/support/bobot_server/butia/view.htm b/lib/support/bobot_server/butia/view.htm
deleted file mode 100644
index 0fda3dc..0000000
--- a/lib/support/bobot_server/butia/view.htm
+++ /dev/null
@@ -1,10 +0,0 @@
-<HTML>
-
-<BODY BGCOLOR="#bfbfbf" TEXT="#000000" VLINK="#000099" LINK="#9900ff" ALINK="#FFFF00">
-<CENTER>
-
-<IMG SRC="images/clase07.jpg" WIDTH=100% HEIGHT=100% ALT="Butia"><P>
-
-</CENTER>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/lib/support/bobot_server/dumptemplate.txt b/lib/support/bobot_server/dumptemplate.txt
deleted file mode 100644
index b1c1dfa..0000000
--- a/lib/support/bobot_server/dumptemplate.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-<head><title>Bobot dump</title></head>
-<body>
-<h2>Bobot</h2>
-<a href="/index.htm">home</a> | modules
-<hr>
-Modules: <!--LIST--><br>
-
-<hr>
-</body>
-</html>
diff --git a/lib/support/bobot_server/dumptemplate_descr.txt b/lib/support/bobot_server/dumptemplate_descr.txt
deleted file mode 100644
index e34df38..0000000
--- a/lib/support/bobot_server/dumptemplate_descr.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-<html>
-<head><title>Bobot dump</title></head>
-<body>
-<h2>Bobot dump</h2>
-<a href="/index.htm">home</a> | dump
-<hr>
-Modules: <!--LIST--><br>
-
-<HR>
-<H2>
-<FONT SIZE="-1">
-Funciones disponibles en </FONT>
-<BR>
-<!--MODULENAME--></H2>
-
-<HR>
-
-<P>
-A continuaci&oacute;n se lista las funciones disponibles en este m&oacute;dulo.
-<br>
-Puedes invocar la funci&oacute;n ingresando los datos necesarios y presionando el bot&oacute;n Submit.
-<p>
-
-<P>
-
-<A NAME="method_summary"><!-- --></A>
-<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
-<TR BGCOLOR="#CCCCFF" >
-<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
-<B>Resumen de Funciones</B></FONT></TH>
-</TR>
-
-
-<!--ROWS--><br>
-<hr>
-</body>
-</html>
diff --git a/lib/support/bobot_server/dumptemplate_descr_row.txt b/lib/support/bobot_server/dumptemplate_descr_row.txt
deleted file mode 100644
index ade4736..0000000
--- a/lib/support/bobot_server/dumptemplate_descr_row.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-<TR BGCOLOR="white" >
-<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
-<CODE>(<!--RETURNS-->)</CODE></FONT></TD>
-<TD><CODE><B><!--COMMAND--></B>(<!--PARAMETERS-->)</CODE>
-
-<BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-<FORM METHOD="POST" ACTION="/dump.htm">
-<INPUT TYPE=HIDDEN NAME="command" VALUE="<!--COMMAND-->"/>
-<INPUT TYPE=HIDDEN NAME="dsel" VALUE="<!--MODULENAME-->"/>
-<!--FORMFIELDS-->
-<INPUT TYPE="submit" VALUE="Submit" />
-</FORM>
-
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-<!--RESULT-->
-
-</TD>
-</TR>
-
diff --git a/lib/support/bobot_server/favicon.ico b/lib/support/bobot_server/favicon.ico
deleted file mode 100644
index 3834805..0000000
--- a/lib/support/bobot_server/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/lib/support/bobot_server/http-util.lua b/lib/support/bobot_server/http-util.lua
deleted file mode 100644
index c8b9a6c..0000000
--- a/lib/support/bobot_server/http-util.lua
+++ /dev/null
@@ -1,41 +0,0 @@
-module(..., package.seeall);
-
-local bobot = require("bobot")
-
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]]
-
---local devices=devices
-function load_file (filename)
- local served, err = io.open(my_path..filename, "r")
- if served then
- return served:read("*all")
- else
- bobot.debugprint("Error opening", my_path..filename,":", err)
- end
-end
-
-function parse_params(s)
- local params={}
- for k,v in string.gmatch(s, '([%w%%%_%-]+)=([%w%%%_%-]+)') do
- bobot.debugprint('param', k, v)
- params[k]=v
- end
- return params
-end
-
-local page404="<html><head><title>404 Not Found</title></head><body><h3>404 Not Found!</h3><hr><small>bobot</small></body></html>"
-local http404="HTTP/1.1 404 Not Found\r\nContent-Type:text/html\r\nContent-Length: "..#page404.."\r\n\r\n" .. page404
-page404=nil
-local function error_page()
- return http404
-end
-
-function find_page (page)
- local page=string.sub(page,2)
- local file=load_file(page)
- if file then
- return function() return file end
- else
- return error_page
- end
-end
diff --git a/lib/support/bobot_server/indextemplate.txt b/lib/support/bobot_server/indextemplate.txt
deleted file mode 100644
index 24b2245..0000000
--- a/lib/support/bobot_server/indextemplate.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-<html>
-<head><title>Bobot</title></head>
-<body>
-<h2>Bobot</h2>
-home | <a href="/dump.htm">modules</a>
-<hr>
-
-<img src="/bobot.png" alt="bobot logo" width="200" height="200" />
-<p>
-<a href="http://www.fing.edu.uy/inco/grupos/mina/">Grupo MINA</a><br>
-In.Co., Facultad de Ingenier&iacute;a<br>
-Universidad de la Rep&uacute;blica<br>
-Uruguay</p>
-<hr>
-</body>
-</html>
diff --git a/lib/support/drivers/admin.lua b/lib/support/drivers/admin.lua
deleted file mode 100644
index c3e3da9..0000000
--- a/lib/support/drivers/admin.lua
+++ /dev/null
@@ -1,11 +0,0 @@
-local device = _G
-local RESET = string.char(0xFF)
-
-api={}
-api.reset = {}
-api.reset.parameters = {}
-api.reset.returns = {}
-api.reset.call = function (data)
- device:send(RESET)
-end
-
diff --git a/lib/support/drivers/ax.lua b/lib/support/drivers/ax.lua
deleted file mode 100644
index d505511..0000000
--- a/lib/support/drivers/ax.lua
+++ /dev/null
@@ -1,118 +0,0 @@
-local device = _G
-local WRITE_INFO = 0x01
-local READ_INFO = 0x02
-local GET_RAW_POS = 0x03
-local char000 = string.char(0,0,0)
-local mode='wheel'
-
---byte id,byte regstart, int value
-api={}
-api.write_info = {}
-api.write_info.parameters = {[1]={rname="id", rtype="number", min=0, max=255},[2]={rname="regstart", rtype="number", min=0, max=255},[3]={rname="value", rtype="number", min=0, max=65536}} ----byte id,byte regstart, int value
-api.write_info.returns = {[1]={rname="write_info_return", rtype="number"}} --one return
-api.write_info.call = function (id, regstart, value)
- id, regstart, value = tonumber(id), tonumber(regstart), tonumber(value)
- local write_info_payload = string.char(WRITE_INFO, id, regstart, math.floor(value / 256),value % 256)
- device:send(write_info_payload)
- local write_info_response = device:read(2) or char000
- local raw_val = (string.byte(write_info_response, 2) or 0)
- return raw_val
-end
-
---- Set wheel mode.
---Set the motor to continuous rotation mode.
-api.wheel_mode = {}
-api.wheel_mode.parameters = {[1]={rname="id", rtype="number", min=0, max=255}}
-api.wheel_mode.returns = {}
-api.wheel_mode.call = function (id )
- id = tonumber(id)
- local ret = device:send(string.char(WRITE_INFO,id,0x06,0x00,0x00))
- local write_info_response = device:read(1) or string.char(0,0)
- local ret = device:send(string.char(WRITE_INFO,id,0x08,0x00,0x00))
- local write_info_response = device:read(1) or string.char(0,0)
- mode='wheel'
- end
-
---- Set joint mode.
--- Set the motor to joint mode. Angles are provided in degrees,
--- in the full servo coverage (0 - 300 degrees arc)
--- @param min the minimum joint angle (defaults to 0)
--- @param max the maximum joint angle (defaults to 300)
-api.joint_mode = {}
-api.joint_mode.parameters = {[1]={rname="id", rtype="number", min=0, max=255},[2]={rname="minimo", rtype="number", min=0, max=1023},[3]={rname="maximo", rtype="number", min=0, max=1023}}
-api.joint_mode.returns = {}
-api.joint_mode.call = function (id ,minimo, maximo)
- id = tonumber(id)
- minimo=tonumber(minimo)
- maximo=tonumber(maximo)
- local ret = device:send(string.char(WRITE_INFO,id,0x06,math.floor(minimo / 256),minimo % 256))
- local write_info_response = device:read(1) or string.char(0,0)
- local ret = device:send(string.char(WRITE_INFO,id,0x08,math.floor(maximo / 256),maximo % 256))
- local write_info_response = device:read(1) or string.char(0,0)
- mode='joint'
- end
-
-
---- Set motor position.
--- Set the target position for the motor's axle. Only works in
--- joint mode.
--- @param value Angle in degrees, in the 0 .. 300deg range.
-api.set_position = {}
-api.set_position.parameters = {[1]={rname="id", rtype="number", min=0, max=255},[2]={rname="pos", rtype="number", min=0, max=1023}}
-api.set_position.returns = {}
-api.set_position.call = function (id, pos )
- id = tonumber(id)
- pos = tonumber(pos)
- local ret = device:send(string.char(WRITE_INFO,id,0x1E,math.floor(pos / 256),pos % 256))
- local write_info_response = device:read(1) or string.char(0,0)
- end
-
-
---- Get motor position.
--- Read the axle position from the motor.
--- @return The angle in deg. The reading is only valid in the
--- 0 .. 300deg range
-api.get_position = {}
-api.get_position.parameters = {[1]={rname="id", rtype="number", min=0, max=255},[2]={rname="pos", rtype="number", min=0, max=1023}}
-api.get_position.returns = {[1]={rname="motor_position", rtype="number"}} --one return
-api.get_position.call = function(id)
- local send_response = device:send(string.char(GET_RAW_POS,id))
- local value = device:read(3) or string.char(0,0,0)
- local h_value = string.byte(value, 2)
- local l_value = string.byte(value, 3)
- local raw_angle = 256 * h_value + l_value
- local ang=0.29*(raw_angle) -- deg ?
- return raw_angle
-
- end
-
-
---- Set motor speed.
--- @param value If motor in joint mode, speed in deg/sec in the 1 .. 684 range
--- (0 means max available speed).
--- If in wheel mode, as a fraction of max torque (in the -1 .. 1 range).
-api.set_speed = {}
-api.set_speed.parameters = {[1]={rname="id", rtype="number", min=0, max=255},[2]={rname="speed", rtype="number", min=-1, max=684}}
-api.set_speed.returns = {} --no return
-api.set_speed.call = function(id, speed)
- --if mode=='joint' then
- -- 0 .. 684 deg/sec
- local vel=math.floor(speed * 1.496)
- local lowb = math.floor(vel/ 256)
- local highb = vel % 256
-
-
- --local lowb, highb = get2bytes_unsigned(vel)
- local ret = device:send(id,0x20,string.char(lowb,highb))
- print ("ret= ",ret, " lowb= ", lowb, " highb= ", highb)
- if ret then return ret:byte() end
- --else --mode=='wheel'
- -- -1 .. +1 max torque
- --local vel=math.floor(speed * 1023)
- --local lowb, highb = get2bytes_signed(vel)
- --local ret = device:send(id,0x20,string.char(lowb,highb))
- --if ret then return ret:byte() end
- --end
-end
-
-
diff --git a/lib/support/drivers/boot.lua b/lib/support/drivers/boot.lua
deleted file mode 100644
index 2471ab9..0000000
--- a/lib/support/drivers/boot.lua
+++ /dev/null
@@ -1,11 +0,0 @@
-local device = _G
-local RESET = string.char(0xFF)
-
-api={}
-api.reset = {}
-api.reset.parameters = {} --no parameters
-api.reset.returns = {} --no returns
-api.reset.call = function ()
- device:send(RESET)
-end
-
diff --git a/lib/support/drivers/boton.lua b/lib/support/drivers/boton.lua
deleted file mode 100644
index 4f846c9..0000000
--- a/lib/support/drivers/boton.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local device = _G
-
-local GET_VALUE=string.char(0x00)
-local string_byte=string.byte
-
--- description: lets us know button's current status
--- input: empty
--- output: button's current status. Possible status: 1 pressed - 0 not pressed
-api={}
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="state", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get button's status
- local sen_dig_response = device:read(2) -- 2 bytes to read (opcode, data)
- if not sen_dig_response or #sen_dig_response~=2 then return -1 end
- local raw_val = string_byte(sen_dig_response, 2) or 0 -- keep data
- return raw_val
-end
diff --git a/lib/support/drivers/butia.lua b/lib/support/drivers/butia.lua
deleted file mode 100644
index b29c9f1..0000000
--- a/lib/support/drivers/butia.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x02) -- lee la versión del firmware de la placa (Igual para 1.0 y 2.0)
-local GET_VOLT = string.char(0x03) -- obtiene el voltage de la batería (Igual para 1.0 y 2.0)
-
-api={}
-api.read_ver = {}
-api.read_ver.parameters = {}
-api.read_ver.returns = {[1]={rname="data", rtype="string"}}
-api.read_ver.call = function (data)
- device:send(RD_VERSION)
- local devolver = -1
- local ret = device:read(2)
- if ret then
- devolver = string.byte(ret , 2) --leo el segundo byte obtenido que tiene la versión (el primero tiene el opcode)
- end
- --local devolver = (string.byte(version_response,2) or 0) + (string.byte(version_response,3) or 0)* 256
- return devolver
-end
-
-api.get_volt = {}
-api.get_volt.parameters = {} -- no se envian parámetros
-api.get_volt.returns = {[1]={rname="volts", rtype="string"}} --nos devuelve el voltaje de las baterías
-api.get_volt.call = function ()
- device:send(GET_VOLT) --envío el código de operación
- local data_in = device:read(2) --leo 2 bytes, primero el código de operación y segundo el voltaje
- local voltaje = string.byte(data_in or "00000000" , 2) --leo el segundo byte obtenido que es el que tiene el voltaje
- --local resultado = string.char(math.floor(voltNum / 10),".",tonumber(volNum) % 256, " volts")
- return voltaje
-end
-
---[[
-function bytesToString(data)
- local data_hex = ""
- for i=1, string.len(data) do
- data_hex = data_hex .. string.format('%02X', (string.byte(data, i)))
- end
- return data_hex
-end
---]]
diff --git a/lib/support/drivers/buzzer.lua b/lib/support/drivers/buzzer.lua
deleted file mode 100644
index a2ede05..0000000
--- a/lib/support/drivers/buzzer.lua
+++ /dev/null
@@ -1,51 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local PRENDER = string.char(0x01)
-local APAGAR = string.char(0x02)
-local BUZZER_CORTO = string.char(0x03)
-local BUZZER_TRIPLE = string.char(0x04)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.prender = {}
-api.prender.parameters = {} --no parameters
-api.prender.returns = {} --no return
-api.prender.call = function ()
- local write_res, err = device:send(PRENDER)
- if write_res then return 1 else return 0 end
-end
-
-api.apagar = {}
-api.apagar.parameters = {} --no parameters
-api.apagar.returns = {} --no return
-api.apagar.call = function ()
- local write_res, err = device:send(APAGAR)
- if write_res then return 1 else return 0 end
-end
-
-api.buzzer_corto = {}
-api.buzzer_corto.parameters = {[1]={rname="num", rtype="number"}}
-api.buzzer_corto.returns = {} --no return
-api.buzzer_corto.call = function (num)
- local write_res, err = device:send(BUZZER_CORTO .. string.char(num))
- if write_res then return 1 else return 0 end
-end
-
-api.buzzer_triple = {}
-api.buzzer_triple.parameters = {[1]={rname="tiempo1", rtype="number"}, [2]={rname="tiempo2", rtype="number"}, [3]={rname="tiempo3", rtype="number"}}
-api.buzzer_triple.returns = {} --no return
-api.buzzer_triple.call = function (tiempo1, tiempo2, tiempo3)
- local write_res, err = device:send(BUZZER_TRIPLE .. string.char(tiempo1) .. string.char(tiempo2) .. string.char(tiempo3))
- if write_res then return 1 else return 0 end
-end
diff --git a/lib/support/drivers/debug.lua b/lib/support/drivers/debug.lua
deleted file mode 100644
index d8191ec..0000000
--- a/lib/support/drivers/debug.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local RD_DEBUG = string.char(0x01)
-local MESSAGE = string.char(0x02)
-
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- --return raw_val
- return version_response
-end
-
-api.rd_debug = {}
-api.rd_debug.parameters = {} --no parameters
-api.rd_debug.returns = {[1]={rname="data", rtype="string"}} --debug message
-api.rd_debug.call = function ()
- local write_res, err = device:send(RD_DEBUG)
- local len = 4
- local ret = device:read(len) or ""
- print("====",ret, string.len(ret))
- return ret
-end
-
-api.message = {}
-api.message.parameters = {} --no parameters
-api.message.returns = {}
-api.message.call = function ()
- local write_res, err = device:send(MESSAGE)
- return write_res
-end
-
diff --git a/lib/support/drivers/display.lua b/lib/support/drivers/display.lua
deleted file mode 100644
index 3629cb9..0000000
--- a/lib/support/drivers/display.lua
+++ /dev/null
@@ -1,99 +0,0 @@
-local device = _G
-
-local string_char=string.char
-
-local RD_VERSION = string_char(0x00)
-local ESCRIBIR = string_char(0x01)
-local PRUEBA = string_char(0x02)
-local BORRAR = string_char(0x03)
-local INICIAR = string_char(0x04)
-local PRENDER_BKL = string_char(0x08)
-local APAGAR_BKL = string_char(0x09)
-local AGENDAR_MSG = string_char(0x0A)
-local SET_TICKS = string_char(0x0B)
-local ESPACIO = string_char(0x20)
-
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- device:send(RD_VERSION)
- local version_response = device:read(2)
- local raw_val = string.byte(temperature_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.escribir = {}
-api.escribir.parameters = {[1]={rname="message", rtype="string"}}
-api.escribir.returns = {}
-api.escribir.call = function (str)
- local msg = ESCRIBIR .. str
- device:send(msg)
- --device:read()
-end
-
-api.prueba = {}
-api.prueba.parameters = {} --no parameters
-api.prueba.returns = {} --no return
-api.prueba.call = function ()
- device:send(PRUEBA)
-end
-
-api.borrar = {}
-api.borrar.parameters = {} --no parameters
-api.borrar.returns = {} --no return
-api.borrar.call = function ()
- device:send(BORRAR)
-end
-
-api.iniciar = {}
-api.iniciar.parameters = {} --no parameters
-api.iniciar.returns = {} --no return
-api.iniciar.call = function ()
- device:send(INICIAR)
-end
-
-api.prender_bkl = {}
-api.prender_bkl.parameters = {} --no parameters
-api.prender_bkl.returns = {} --no return
-api.prender_bkl.call = function ()
- device:send(PRENDER_BKL)
-end
-
-api.apagar_bkl = {}
-api.apagar_bkl.parameters = {} --no parameters
-api.apagar_bkl.returns = {} --no return
-api.apagar_bkl.call = function ()
- device:send(APAGAR_BKL)
-end
-
-api.set_ticks = {}
-api.set_ticks.parameters = {[1]={rname="cantTicks", rtype="numeric"}} --how many timmers ticks have to pass before display agendar_msg screen
-api.set_ticks.returns = {} --no return
-api.set_ticks.call = function (ticks)
- device:send(SET_TICKS .. string_char(ticks))
-end
-
-api.agendar_msg = {}
-api.agendar_msg.parameters = {
- [1]={rname="message", rtype="string"}, -- first parameter is the message
- [2]={rname="isCiclic", rtype="numeric"}, -- 1 in case of a ciclic message 0 elsewere
- [3]={rname="isEnd", rtype="numeric"}} -- 1 in case of end of message, so previously calls to agendar_msg could be concatenated
-api.agendar_msg.returns = {[1]={rname="isFull", rtype="boolean"}} --If it is no more space in the event buffer returns true, false elsewere
-api.agendar_msg.call = function (str, isCiclic, isEnd)
- device:send(AGENDAR_MSG .. string_char(32) .. string_char(isEnd) .. string_char(isCiclic) .. str)
- print("despues del send")
- local ret = device:read(3) or char0000 --el tercer byte recibido indica con un 1 si el buffer circuilar que se utiliza para mantener los mensajes esta lleno, 0 en caso controario
- print("despues del read")
- local error = (string.byte(ret,3) or 0)
- print("despues de capturar el 3er byte")
- if(error == 1) then
- print "error, buffer lleno"
- else
- print "ok"
- end
- return error
-end
diff --git a/lib/support/drivers/dist.lua b/lib/support/drivers/dist.lua
deleted file mode 100644
index 5b8a247..0000000
--- a/lib/support/drivers/dist.lua
+++ /dev/null
@@ -1,25 +0,0 @@
-local device = _G
-
-local GET_VALUE=string.char(0x00)
-local string_byte=string.byte
-
--- description: lets us know dist sensor's current value
--- input: empty
--- output: dist sensor's current value.
-api={}
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="par1", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get distance of object
- local sen_anl_response = device:read(3) -- operation code and data
- if not sen_anl_response or #sen_anl_response~=3 then return -1 end
- --local raw_val = (string_byte(sen_anl_response, 2) or 0) + (string_byte(sen_anl_response, 3) or 0)* 256
- raw_val = string.byte(sen_anl_response, 2)* 256 + string.byte(sen_anl_response, 3)
- raw_val = 1024 - raw_val
- return raw_val
-end
-
-
-
-
diff --git a/lib/support/drivers/dynamix.lua b/lib/support/drivers/dynamix.lua
deleted file mode 100644
index 52ea4ba..0000000
--- a/lib/support/drivers/dynamix.lua
+++ /dev/null
@@ -1,34 +0,0 @@
-local device = _G
-local WRITE_INFO = 0x01
-local SEND_BUS = 0x01
-local READ_INFO = 0x02
-local GET_RAW_POS = 0x03
-local char000 = string.char(0,0,0)
-
---byte id,byte regstart, int value
-api={}
-api.write_info = {}
-api.write_info.parameters = {[1]={rname="id", rtype="number", min=0, max=255},[2]={rname="regstart", rtype="number", min=0, max=255},[3]={rname="value", rtype="number", min=0, max=65536}} ----byte id,byte regstart, int value
-api.write_info.returns = {[1]={rname="write_info_return", rtype="number"}} --one return
-api.write_info.call = function (id, regstart, value)
- id, regstart, value = tonumber(id), tonumber(regstart), tonumber(value)
- local write_info_payload = string.char(WRITE_INFO, id, regstart, math.floor(value / 256),value % 256)
- device:send(write_info_payload)
- local write_info_response = device:read(2) or char000
- local raw_val = (string.byte(write_info_response, 2) or 0)
- return raw_val
-end
-
-api.pasarela = {}
-api.pasarela.parameters = {[1]={rname="packet", rtype="string", min=0, max=255}}
-api.pasarela.returns = {}
-api.pasarela.call = function (value)
- local valueN = tonumber(value)
- local checksum = 255 - ((0xfe + 0x04 + 0x03 + 0x19 +valueN)%256)
- print (checksum)
- local paquete = string.char(SEND_BUS, 0xff, 0xff,0xfe, 0x04, 0x03, 0x19, valueN, checksum)
- device:send(paquete)
-end
-
-
-
diff --git a/lib/support/drivers/gas.lua b/lib/support/drivers/gas.lua
deleted file mode 100644
index a056759..0000000
--- a/lib/support/drivers/gas.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-local device = _G
-local RD_GAS = string.char(0x01)
-local char000 = string.char(0,0,0)
-
-api={}
-api.get_gas = {}
-api.get_gas.parameters = {} --no parameter
-api.get_gas.returns = {[1]={rname="gas level", rtype="number"}} --one return
-api.get_gas.call = function ()
- local get_payload = RD_GAS
- device:send(get_payload)
- local response = device:read(3)
- if not response then
- print ('WARN: api.get_gas.call failure on device:read(3)')
- response=char000
- end
- local raw_val = string.byte(response, 2) + 255*string.byte(response, 3)
- return raw_val
-end
-
diff --git a/lib/support/drivers/grises.lua b/lib/support/drivers/grises.lua
deleted file mode 100644
index a680266..0000000
--- a/lib/support/drivers/grises.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local device = _G
-
-local GET_VALUE=string.char(0x00)
-local string_byte=string.byte
-
--- description: lets us know grey sensor's current value
--- input: empty
--- output: grey sensor's current value.
-api={}
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="par1", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get grey level
- local sen_anl_response = device:read(3) -- operation code and data
- if not sen_anl_response or #sen_anl_response~=3 then return -1 end
- local raw_val = math.floor(((string_byte(sen_anl_response, 2) or 0) + (string_byte(sen_anl_response, 3) or 0)* 256)/ 100)
- return raw_val
-end
diff --git a/lib/support/drivers/hotplug/button.lua b/lib/support/drivers/hotplug/button.lua
deleted file mode 100644
index 9ddba48..0000000
--- a/lib/support/drivers/hotplug/button.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-local device = _G
-
-local RD_VERSION=string.char(0x00)
-local GET_VALUE=string.char(0x01)
-local string_byte=string.byte
-
--- description: lets us know button module's version
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string_byte(version_response,2) or 0) + (string_byte(version_response,3) or 0)* 256
- return raw_val
-end
-
--- description: lets us know button's current status
--- input: empty
--- output: button's current status. Possible status: 1 pressed - 0 not pressed
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="state", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get button's status
- local sen_dig_response = device:read(2) -- 2 bytes to read (opcode, data)
- if not sen_dig_response or #sen_dig_response~=2 then return -1 end
- local raw_val = string_byte(sen_dig_response, 2) or 0 -- keep data
- return raw_val
-end
diff --git a/lib/support/drivers/hotplug/distanc.lua b/lib/support/drivers/hotplug/distanc.lua
deleted file mode 100644
index 2340796..0000000
--- a/lib/support/drivers/hotplug/distanc.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-local device = _G
-
-local RD_VERSION=string.char(0x00)
-local GET_VALUE=string.char(0x01)
-local string_byte=string.byte
-
--- description: lets us know dist module's version
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string_byte(version_response,2) or 0) + (string_byte(version_response,3) or 0)* 256
- return raw_val
-end
-
--- description: lets us know dist sensor's current value
--- input: empty
--- output: dist sensor's current value.
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="par1", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get distance of object
- local sen_anl_response = device:read(3) -- operation code and data
- if not sen_anl_response or #sen_anl_response~=3 then return -1 end
- local raw_val = (string_byte(sen_anl_response, 2) or 0) + (string_byte(sen_anl_response, 3) or 0)* 256
- return raw_val
-end
diff --git a/lib/support/drivers/hotplug/gpio.lua b/lib/support/drivers/hotplug/gpio.lua
deleted file mode 100644
index 331efb3..0000000
--- a/lib/support/drivers/hotplug/gpio.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local device = _G
-
-local RD_VERSION=string.char(0x00)
-local string_byte=string.byte
-
--- description: lets us know button module's version
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string_byte(version_response,2) or 0) + (string_byte(version_response,3) or 0)* 256
- return raw_val
-end
-
-
diff --git a/lib/support/drivers/hotplug/grey.lua b/lib/support/drivers/hotplug/grey.lua
deleted file mode 100644
index eb24f36..0000000
--- a/lib/support/drivers/hotplug/grey.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-local device = _G
-
-local RD_VERSION=string.char(0x00)
-local GET_VALUE=string.char(0x01)
-local string_byte=string.byte
-
--- description: lets us know grey module's version
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string_byte(version_response,2) or 0) + (string_byte(version_response,3) or 0)* 256
- return raw_val
-end
-
--- description: lets us know grey sensor's current value
--- input: empty
--- output: grey sensor's current value.
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="par1", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get grey level
- local sen_anl_response = device:read(3) -- operation code and data
- if not sen_anl_response or #sen_anl_response~=3 then return -1 end
- local raw_val = (string_byte(sen_anl_response, 2) or 0) + (string_byte(sen_anl_response, 3) or 0)* 256
- return raw_val
-end
diff --git a/lib/support/drivers/hotplug/light.lua b/lib/support/drivers/hotplug/light.lua
deleted file mode 100644
index ce953b2..0000000
--- a/lib/support/drivers/hotplug/light.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-local device = _G
-
-local RD_VERSION=string.char(0x00)
-local GET_VALUE=string.char(0x01)
-local string_byte=string.byte
-
--- description: lets us know light module's version
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string_byte(version_response,2) or 0) + (string_byte(version_response,3) or 0)* 256
- return raw_val
-end
-
--- description: lets us know light sensor's current value
--- input: empty
--- output: light sensor's current value.
-api.getValue = {}
-api.getValue.parameters = {} -- no input parameters
-api.getValue.returns = {[1]={rname="par1", rtype="int"}}
-api.getValue.call = function ()
- device:send(GET_VALUE) -- operation code 1 = get light level
- local sen_anl_response = device:read(3) -- operation code and data
- if not sen_anl_response or #sen_anl_response~=3 then return -1 end
- local raw_val = (string_byte(sen_anl_response, 2) or 0) + (string_byte(sen_anl_response, 3) or 0)* 256
- return raw_val
-end
diff --git a/lib/support/drivers/hotplug/port.lua b/lib/support/drivers/hotplug/port.lua
deleted file mode 100644
index 331efb3..0000000
--- a/lib/support/drivers/hotplug/port.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local device = _G
-
-local RD_VERSION=string.char(0x00)
-local string_byte=string.byte
-
--- description: lets us know button module's version
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string_byte(version_response,2) or 0) + (string_byte(version_response,3) or 0)* 256
- return raw_val
-end
-
-
diff --git a/lib/support/drivers/hotplug/tilt.lua b/lib/support/drivers/hotplug/tilt.lua
deleted file mode 100644
index 1076479..0000000
--- a/lib/support/drivers/hotplug/tilt.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local device = _G
-
-api={}
-api.getTilt = {}
-api.getTilt.parameters = {} -- -- no input parameters
-api.getTilt.returns = {[1]={rname="par1", rtype="int"}}
-api.getTilt.call = function ()
- device:send(string.char(0x00)) -- codigo de operacion 0
- local sen_dig_response = device:read(3)
- local raw_val
- if not sen_dig_response or string.byte(sen_dig_response or "00000000", 2) == nil or string.byte(sen_dig_response or "00000000", 3) == nil
- then
- raw_val = "nil value"
- else
- raw_val = string.byte(sen_dig_response, 3) % 2
- end
- return raw_val
-
-end
diff --git a/lib/support/drivers/hotplug/vibra.lua b/lib/support/drivers/hotplug/vibra.lua
deleted file mode 100644
index 0c3d985..0000000
--- a/lib/support/drivers/hotplug/vibra.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-local device = _G
-
-api={}
-api.getVibra = {}
-api.getVibra.parameters = {} -- -- no input parameters
-api.getVibra.returns = {[1]={rname="par1", rtype="int"}}
-api.getVibra.call = function ()
- device:send(string.char(0x00)) -- codigo de operacion 0
- local sen_dig_response = device:read(3)
- local raw_val
- if not sen_dig_response or string.byte(sen_dig_response or "00000000", 2) == nil or string.byte(sen_dig_response or "00000000", 3) == nil
- then
- raw_val = "nil value"
- else
- raw_val = string.byte(sen_dig_response, 3) % 2
- end
- return raw_val
-
-end
diff --git a/lib/support/drivers/lback.lua b/lib/support/drivers/lback.lua
deleted file mode 100644
index 9f903b1..0000000
--- a/lib/support/drivers/lback.lua
+++ /dev/null
@@ -1,21 +0,0 @@
-local device = _G
-
-api={}
-api.send = {}
-api.send.parameters = {[1]={rname="data", rtype="string"}}
-api.send.returns = {}
-api.send.call = function (data)
- --print("####", data, string.len(data))
- device:send(data)
-end
-
-api.read = {}
-api.read.parameters = {[1]={rname="len", rtype="int", default=64, min=0, max=255}}
-api.read.returns = {[1]={rname="data", rtype="string"}}
-api.read.call = function (len)
- local len = len or 64
- local ret = device:read(len)
--- print("====",ret, string.len(ret))
- return ret
-end
-
diff --git a/lib/support/drivers/led.lua b/lib/support/drivers/led.lua
deleted file mode 100644
index 1095d93..0000000
--- a/lib/support/drivers/led.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-local device = _G
-
-local string_char=string.char
-
-api={}
-api.setLight = {}
-api.setLight.parameters = {[1]={rname="message", rtype="string"}}
-api.setLight.returns = {}
-api.setLight.call = function (intensidad)
- intensidad=tonumber(intensidad)
- if (not intensidad) or intensidad<0 then intensidad=0
- elseif intensidad>255 then intensidad=255 end
-
- local msg = string_char(0x00) .. string_char(math.floor(intensidad)) -- entre 0 y 255
- device:send(msg)
- local version_response = device:read()
-end
diff --git a/lib/support/drivers/ledA.lua b/lib/support/drivers/ledA.lua
deleted file mode 100644
index f76b501..0000000
--- a/lib/support/drivers/ledA.lua
+++ /dev/null
@@ -1,46 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local PRENDER = string.char(0x01)
-local APAGAR = string.char(0x02)
-local BLINK = string.char(0x03)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.prender = {}
-api.prender.parameters = {} --no parameters
-api.prender.returns = {} --no return
-api.prender.call = function ()
- device:send(PRENDER)
--- local response = device:read(2)
--- print("[",string.byte(response, 1),",", string.byte(response, 2),"]")
--- print("-----------------------------------------------")
--- if (string.byte(response, 1) ~= nil or string.byte(response, 2) ~= nil) then
--- print("vino data")
--- end
-end
-
-api.apagar = {}
-api.apagar.parameters = {} --no parameters
-api.apagar.returns = {} --no return
-api.apagar.call = function ()
- device:send(APAGAR)
-end
-
-api.blink = {}
-api.blink.parameters = {[1]={rname="time", rtype="number"}, [2]={rname="blinks", rtype="number"}}
-api.blink.returns = {} --no return
-api.blink.call = function (time, blinks)
- local msg = BLINK .. string.char(time) .. string.char(blinks)
- device:send(msg)
-end
diff --git a/lib/support/drivers/ledR.lua b/lib/support/drivers/ledR.lua
deleted file mode 100644
index 1d3e726..0000000
--- a/lib/support/drivers/ledR.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local PRENDER = string.char(0x01)
-local APAGAR = string.char(0x02)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.prender = {}
-api.prender.parameters = {} --no parameters
-api.prender.returns = {} --no return
-api.prender.call = function ()
- device:send(PRENDER)
-end
-
-api.apagar = {}
-api.apagar.parameters = {} --no parameters
-api.apagar.returns = {} --no return
-api.apagar.call = function ()
- device:send(APAGAR)
-end
diff --git a/lib/support/drivers/ledV.lua b/lib/support/drivers/ledV.lua
deleted file mode 100644
index 1d3e726..0000000
--- a/lib/support/drivers/ledV.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local PRENDER = string.char(0x01)
-local APAGAR = string.char(0x02)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.prender = {}
-api.prender.parameters = {} --no parameters
-api.prender.returns = {} --no return
-api.prender.call = function ()
- device:send(PRENDER)
-end
-
-api.apagar = {}
-api.apagar.parameters = {} --no parameters
-api.apagar.returns = {} --no return
-api.apagar.call = function ()
- device:send(APAGAR)
-end
diff --git a/lib/support/drivers/leds.lua b/lib/support/drivers/leds.lua
deleted file mode 100644
index 7e55ce6..0000000
--- a/lib/support/drivers/leds.lua
+++ /dev/null
@@ -1,43 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local PRENDER = string.char(0x01)
-local APAGAR = string.char(0x02)
-local BLINK = string.char(0x03)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.prender = {}
-api.prender.parameters = {[1]={rname="numLed", rtype="number"}} --recibe the led number
-api.prender.returns = {} --no return
-api.prender.call = function (ledNumber)
- local write_res, err = device:send(PRENDER .. string.char(ledNumber))
- if write_res then return 1 else return 0 end
-end
-
-api.apagar = {}
-api.apagar.parameters = {[1]={rname="numLed", rtype="number"}} --recibe the led number
-api.apagar.returns = {} --no return
-api.apagar.call = function (ledNumber)
- local write_res, err = device:send(APAGAR .. string.char(ledNumber))
- if write_res then return 1 else return 0 end
-end
-
-api.blink = {}
-api.blink.parameters = {[1]={rname="time", rtype="number"}, [2]={rname="blinks", rtype="number"}, [3]={rname="numLed", rtype="number"}}
-api.blink.returns = {} --no return
-api.blink.call = function (time, blinks, ledNumber)
- local msg = BLINK .. string.char(time) .. string.char(blinks) .. string.char(ledNumber)
- local write_res, err = device:send(msg)
- if write_res then return 1 else return 0 end
-end
diff --git a/lib/support/drivers/luz.lua b/lib/support/drivers/luz.lua
deleted file mode 100644
index ed14e26..0000000
--- a/lib/support/drivers/luz.lua
+++ /dev/null
@@ -1,21 +0,0 @@
-local device = _G
-
-api={}
-api.getLuz = {}
-api.getLuz.parameters = {} -- -- no input parameters
-api.getLuz.returns = {[1]={rname="par1", rtype="int"}}
-api.getLuz.call = function ()
- device:send(string.char(0x00)) -- codigo de operacion 0
- local sen_anl_response = device:read(3)
- local raw_val
- if not sen_anl_response or string.byte(sen_anl_response or "00000000", 2) == nil or string.byte(sen_anl_response or "00000000", 3) == nil
- then
- raw_val = "nil value"
- else
- raw_val = string.byte(sen_anl_response, 2)* 256 + string.byte(sen_anl_response, 3)
- raw_val = 1024 - raw_val
-
- end
- return raw_val
-
-end
diff --git a/lib/support/drivers/magnet.lua b/lib/support/drivers/magnet.lua
deleted file mode 100644
index e70b69c..0000000
--- a/lib/support/drivers/magnet.lua
+++ /dev/null
@@ -1,21 +0,0 @@
-local device = _G
-
--- descripción: permite conocer el estado el botón en un momento dado.
--- entrada: no tiene.
--- salida: estado del botón. Posibles estados: 1 presionado, 0 libre.
-api={}
-api.getCampo = {}
-api.getCampo.parameters = {} -- no tiene parámetros de entrada
-api.getCampo.returns = {[1]={rname="par1", rtype="int"}} -- 1 = presionado, 0 = libre
-api.getCampo.call = function ()
- device:send(string.char(0x00)) -- codigo de operacion = 0
- local sen_dig_response = device:read(3) -- leo 2 bytes (opcode, data)
- local raw_val
- if not sen_dig_response or string.byte(sen_dig_response or "00000000", 2) == nil or string.byte(sen_dig_response or "00000000", 3) == nil
- then
- raw_val = "nil value"
- else
- raw_val = 1 - (string.byte(sen_dig_response, 3) % 2)
- end
- return raw_val
-end
diff --git a/lib/support/drivers/motor.lua b/lib/support/drivers/motor.lua
deleted file mode 100644
index c1a86d6..0000000
--- a/lib/support/drivers/motor.lua
+++ /dev/null
@@ -1,42 +0,0 @@
-local device = _G
-local SET_VEL_ADL = 0x00 -- código de op para mover el motor hacia adelante
-local SET_VEL_ATR = 0x01 -- código de op para mover el motor hacia atrás
-
-
-api={}
-api.setveladl = {}
-api.setveladl.parameters = {[1]={rname="id", rtype="int"}, [2]={rname="vel", rtype="int"}} --primer parametro id motor, segundo velocidad
-api.setveladl.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setveladl.call = function (id, vel)
- local msg = string.char(SET_VEL_ADL,id, math.floor(vel / 256),vel % 256)
- device:send(msg)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-api.setvelatr = {}
-api.setvelatr.parameters = {[1]={rname="id", rtype="int"}, [2]={rname="vel", rtype="int"}} --primer parametro id motor, segundo velocidad
-api.setvelatr.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvelatr.call = function (id, vel)
- local msg = string.char(SET_VEL_ATR,id, math.floor(vel / 256),vel % 256)
- device:send(msg)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-
-api.setvelatr2 = {}
-api.setvelatr2.parameters = {[1]={rname="id", rtype="int"}, [2]={rname="vel", rtype="int"}} --primer parametro id motor, segundo velocidad
-api.setvelatr2.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvelatr2.call = function (vel)
- local msg = string.char(SET_VEL_ATR,0, math.floor(vel / 256),vel % 256)
- device:send(msg)
- local msg = string.char(SET_VEL_ATR,1, math.floor(vel / 256),vel % 256)
- device:send(msg)
- local ret = device:read(1)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
diff --git a/lib/support/drivers/motorTm.lua b/lib/support/drivers/motorTm.lua
deleted file mode 100644
index 9343855..0000000
--- a/lib/support/drivers/motorTm.lua
+++ /dev/null
@@ -1,47 +0,0 @@
-local device = _G
-
-api={}
-api.step = {}
-api.step.parameters = {[1]={rname="step", rtype="int", min=0, max=65536}}
-api.step.returns = {}
-api.step.call = function (freq)
- local msg = string.char(0x02) .. string.char(math.floor(freq / 256)) .. string.char(freq % 256)
- device:send(msg)
- device:read(1)
-end
-
-api.steps = {}
-api.steps.parameters = {[1]={rname="number", rtype="int", min=0, max=65536}}
-api.steps.returns = {}
-api.steps.call = function (number)
- local msg = string.char(0x03) .. string.char(math.floor(number / 256)) .. string.char(number % 256)
- device:send(msg)
- device:read(1)
-end
-
-api.phasetype = {}
-api.phasetype.parameters = {[1]={rname="phasetype", rtype="int", min=0, max=2}}
-api.phasetype.returns = {}
-api.phasetype.call = function (phasetype)
- local msg = string.char(0x04) .. string.char(phasetype)
- device:send(msg)
-end
-
-api.power_on = {}
-api.power_on.parameters = {[1]={rname="power_on", rtype="int", min=0, max=1}}
-api.power_on.returns = {}
-api.power_on.call = function (on)
- local msg = string.char(0x06) .. string.char(on)
- device:send(msg)
-end
-
-api.direction = {}
-api.direction.parameters = {[1]={rname="direction", rtype="int", min=-1, max=1}}
-api.direction.returns = {}
-api.direction.call = function (dir)
- if dir==-1 then dir=2 end
- local msg = string.char(0x07) .. string.char(dir+1)
- device:send(msg)
-end
-
-
diff --git a/lib/support/drivers/motores.lua b/lib/support/drivers/motores.lua
deleted file mode 100644
index 45d2967..0000000
--- a/lib/support/drivers/motores.lua
+++ /dev/null
@@ -1,48 +0,0 @@
-local device = _G
-local SET_VEL_MTR = 0x00 -- código de op para mover un motor con vel y sentido
-local SET_VEL_2MTR = 0x01 -- código de op para mover dos motores con vel y sentido
-
-
-api={}
-api.setvelmtr = {}
-api.setvelmtr.parameters = {[1]={rname="id", rtype="int"},[2]={rname="sentido", rtype="int"},[3]={rname="vel", rtype="int"}} --parametros, id sentido vel
-api.setvelmtr.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvelmtr.call = function (id, sentido, vel)
- vel=tonumber(vel)
- if vel>1023 then vel=1023 end
- local msg = string.char(SET_VEL_MTR,id, sentido, math.floor(vel / 256),vel % 256)
- device:send(msg)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-api.setvel2mtr = {}
-api.setvel2mtr.parameters = {[1]={rname="sentido", rtype="int"},[2]={rname="vel", rtype="int"},[3]={rname="sentido", rtype="int"},[4]={rname="vel", rtype="int"}}
-api.setvel2mtr.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvel2mtr.call = function (sentido1, vel1, sentido2, vel2)
- vel1, vel2 = tonumber(vel1), tonumber(vel2)
- if vel1>1023 then vel1=1023 end
- if vel2>1023 then vel2=1023 end
- local msg = string.char(SET_VEL_2MTR,sentido1, math.floor(vel1 / 256),vel1 % 256, sentido2, math.floor(vel2 / 256),vel2 % 256)
- device:send(msg)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-
-api.setvelatr2 = {}
-api.setvelatr2.parameters = {[1]={rname="id", rtype="int"}, [2]={rname="vel", rtype="int"}} --primer parametro id motor, segundo velocidad
-api.setvelatr2.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvelatr2.call = function (vel)
- local vdiv, vmod = math.floor(vel / 256),vel % 256
- local msg = string.char(SET_VEL_ATR, 0, vdiv, vmod)
- device:send(msg)
- msg = string.char(SET_VEL_ATR, 1, vdiv, vmod)
- device:send(msg)
- local ret = device:read(1)
- ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
diff --git a/lib/support/drivers/motorin.lua b/lib/support/drivers/motorin.lua
deleted file mode 100644
index 042f3cc..0000000
--- a/lib/support/drivers/motorin.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-local device = _G
-
-api={}
-api.speed = {}
-api.speed.parameters = {[1]={rname="freq", rtype="int", min=0, max=65536}}
-api.speed.returns = {}
-api.speed.call = function (freq)
- local msg = string.char(0x02) .. string.char(math.floor(freq / 256)) .. string.char(freq % 256)
- device:send(msg)
- device:read(1)
-end
-
-api.steps = {}
-api.steps.parameters = {[1]={rname="number", rtype="int", min=0, max=65536}}
-api.steps.returns = {}
-api.steps.call = function (number)
- local msg = string.char(0x03) .. string.char(math.floor(number / 256)) .. string.char(number % 256)
- device:send(msg)
- device:read(1)
-end
-
-api.on = {}
-api.on.parameters = {[1]={rname="direction", rtype="int", min=-1, max=1}}
-api.on.returns = {}
-api.on.call = function (dir)
- local msg = string.char(0x01) .. string.char(dir+1)
- device:send(msg)
-end
diff --git a/lib/support/drivers/motors.lua b/lib/support/drivers/motors.lua
deleted file mode 100644
index a7c9a05..0000000
--- a/lib/support/drivers/motors.lua
+++ /dev/null
@@ -1,70 +0,0 @@
-local device = _G
-local RD_VERSION=string.char(0x00)
-local SET_VEL_2MTR=0x01 -- código de op para mover dos motores con vel y sentido
-local TEST_MOTORS=string.char(0x02)
-local SET_VEL_MTR = 0x01 -- código de op para mover un motor con vel y sentido
-
-api={}
-api.getVersion = {}
-api.getVersion.parameters = {} -- no input parameters
-api.getVersion.returns = {[1]={rname="version", rtype="int"}}
-api.getVersion.call = function ()
- device:send(RD_VERSION) -- operation code 0 = get version
- local version_response = device:read(3) -- 3 bytes to read (opcode, data)
- if not version_response or #version_response~=3 then return -1 end
- local raw_val = (string.byte(version_response,2) or 0) + (string.byte(version_response,3) or 0)* 256
- return raw_val
-end
-
-api.setvelmtr = {} -- no impl en firmware
-api.setvelmtr.parameters = {[1]={rname="id", rtype="int"},[2]={rname="sentido", rtype="int"},[3]={rname="vel", rtype="int"}} --parametros, id sentido vel
-api.setvelmtr.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvelmtr.call = function (id, sentido, vel)
- vel=tonumber(vel)
- if vel>1023 then vel=1023 end
- local msg = string.char(SET_VEL_MTR,id, sentido, math.floor(vel / 256),vel % 256)
- device:send(msg)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-api.setvel2mtr = {}
-api.setvel2mtr.parameters = {[1]={rname="sentido", rtype="int"},[2]={rname="vel", rtype="int"},[3]={rname="sentido", rtype="int"},[4]={rname="vel", rtype="int"}}
-api.setvel2mtr.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvel2mtr.call = function (sentido1, vel1, sentido2, vel2)
- vel1, vel2 = tonumber(vel1), tonumber(vel2)
- if vel1>1023 then vel1=1023 end
- if vel2>1023 then vel2=1023 end
- local msg = string.char(SET_VEL_2MTR,sentido1, math.floor(vel1 / 256),vel1 % 256, sentido2, math.floor(vel2 / 256),vel2 % 256)
- device:send(msg)
- local ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-api.setvelatr2 = {} -- no impl en firmware
-api.setvelatr2.parameters = {[1]={rname="id", rtype="int"}, [2]={rname="vel", rtype="int"}} --primer parametro id motor, segundo velocidad
-api.setvelatr2.returns = {[1]={rname="dato", rtype="int"}} --codigo de operación
-api.setvelatr2.call = function (vel)
- local vdiv, vmod = math.floor(vel / 256),vel % 256
- local msg = string.char(SET_VEL_ATR, 0, vdiv, vmod)
- device:send(msg)
- msg = string.char(SET_VEL_ATR, 1, vdiv, vmod)
- device:send(msg)
- local ret = device:read(1)
- ret = device:read(1)
- local raw_val = string.byte(ret or " ", 1)
- return raw_val
-end
-
-api.testMotors = {}
-api.testMotors.parameters = {} -- no input parameters
-api.testMotors.returns = {[1]={rname="dato", rtype="int"}}
-api.testMotors.call = function ()
- device:send(TEST_MOTORS) -- operation code 2 = test motors
- local ret = device:read(1) -- 1 byte to read (opcode)
- if not ret or #ret~=1 then return -1 end
- local ret = string.byte(ret, 1)
- return ret
-end
diff --git a/lib/support/drivers/move.lua b/lib/support/drivers/move.lua
deleted file mode 100644
index 7c361e3..0000000
--- a/lib/support/drivers/move.lua
+++ /dev/null
@@ -1,16 +0,0 @@
-local device = _G
-local GET_MOVE = string.char(0x01)
-local char000 = string.char(0,0,0)
-
-api={}
-api.get_move = {}
-api.get_move.parameters = {} --no parameter
-api.get_move.returns = {[1]={rname="digital_value", rtype="number"}} --one return
-api.get_move.call = function ()
- local get_move_payload = GET_MOVE
- device:send(get_move_payload)
- local move_response = device:read(2) or char000
- local raw_val = (string.byte(move_response, 2) or 0)
- return raw_val
-end
-
diff --git a/lib/support/drivers/pnp.lua b/lib/support/drivers/pnp.lua
deleted file mode 100644
index e69de29..0000000
--- a/lib/support/drivers/pnp.lua
+++ /dev/null
diff --git a/lib/support/drivers/pote.lua b/lib/support/drivers/pote.lua
deleted file mode 100644
index fac23cf..0000000
--- a/lib/support/drivers/pote.lua
+++ /dev/null
@@ -1,16 +0,0 @@
-local device = _G
-local RD_POTE = string.char(0x01)
-local char000 = string.char(0,0,0)
-
-api={}
-api.get_pote = {}
-api.get_pote.parameters = {} --no parameter
-api.get_pote.returns = {[1]={rname="analog_value", rtype="number"}} --one return
-api.get_pote.call = function ()
- local get_pote_payload = RD_POTE
- device:send(get_pote_payload)
- local pote_response = device:read(3) or char000
- local raw_val = (string.byte(pote_response, 2) or 0) + 255*(string.byte(pote_response, 3) or 0)
- return raw_val
-end
-
diff --git a/lib/support/drivers/puerta.lua b/lib/support/drivers/puerta.lua
deleted file mode 100644
index 1d3e726..0000000
--- a/lib/support/drivers/puerta.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local PRENDER = string.char(0x01)
-local APAGAR = string.char(0x02)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(2)
- local raw_val = string.byte(version_response, 2)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.prender = {}
-api.prender.parameters = {} --no parameters
-api.prender.returns = {} --no return
-api.prender.call = function ()
- device:send(PRENDER)
-end
-
-api.apagar = {}
-api.apagar.parameters = {} --no parameters
-api.apagar.returns = {} --no return
-api.apagar.call = function ()
- device:send(APAGAR)
-end
diff --git a/lib/support/drivers/sec.lua b/lib/support/drivers/sec.lua
deleted file mode 100644
index e89646b..0000000
--- a/lib/support/drivers/sec.lua
+++ /dev/null
@@ -1,87 +0,0 @@
-local device = _G
-local RD_VERSION = string.char(0x00)
-local GET_SEC = string.char(0X01)
-local INTRUSION = string.char(0x02)
-local RESET_FLAG = string.char(0x03)
-local CONT_INT = string.char(0x04)
-local MESS = string.char(0x05)
-local RESET = string.char(0xFF)
-
-api={}
-api.read_version = {}
-api.read_version.parameters = {} --no parameters
-api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
-api.read_version.call = function ()
- local get_read_version = RD_VERSION
- device:send(get_read_version)
- local version_response = device:read(4)
- local raw_val = string.byte(version_response, 3)
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return raw_val
-end
-
-api.get_sec = {}
-api.get_sec.parameters = {} --no parameters
---api.get_sec.returns = {[1]={rname="error", rtype="string"},[2]={rname="SecSensorValue_1", rtype="number"},[3]={rname="SecSensorValue_2", rtype="number"}}
-api.get_sec.returns = {[1]={rname="SecSensorValue_1", rtype="number"},[2]={rname="SecSensorValue_2", rtype="number"}}
-api.get_sec.call = function ()
- local send_res, err
- send_res, err = device:send(GET_SEC)
- local ret = device:read(3)
- local SecSensorValue_1 = (string.byte(ret,2) or 0)
- local SecSensorValue_2 = (string.byte(ret,3) or 0)
--- local SecSensorValue_1 = (string.byte(ret,2))
--- local SecSensorValue_2 = (string.byte(ret,3))
- if ((SecSensorValue_1 == 0) and (SecSensorValue_2 == 0)) then
- alarma = "00"
- elseif ((SecSensorValue_1 == 0) and (SecSensorValue_2 == 1)) then
- alarma = "01"
- elseif ((SecSensorValue_1 == 1) and (SecSensorValue_2 == 0)) then
- alarma = "10"
- else
- alarma = "11"
- end
- return alarma
- --if ret then return true, SecSensorValue_1, SecSensorValue_2 else return false end
-end
-
-api.intrusion = {}
-api.intrusion.parameters = {} --no parameters
-api.intrusion.returns = {[1]={rname="alarma", rtype="number"}} --one return
-api.intrusion.call = function ()
- local intrusion = INTRUSION
- device:send(intrusion)
- local alarma = device:read(1)
- if (alarma == string.char(0x00)) then
- alarma = 0
- else
- alarma = 1
- end
- return alarma
-end
-
-api.reset_flag = {}
-api.reset_flag.parameters = {} --no parameters
-api.reset_flag.returns = {[1]={rname="borrado", rtype="number"}} --one return
-api.reset_flag.call = function ()
- local reset_flag = RESET_FLAG
- device:send(reset_flag)
- local borrado = device:read(1)
- if (borrado == string.char(0x00)) then
- borrado = 0
- else
- borrado = 1
- end
-
- return borrado
-end
-
-api.cont_int = {}
-api.cont_int.parameters = {} --no parameters
-api.cont_int.returns = {[1]={rname="cantidad", rtype="number"}} --one return
-api.cont_int.call = function ()
- local cont_int = CONT_INT
- device:send(cont_int)
- local cantidad = device:read(1)
- return string.byte(cantidad)
-end
diff --git a/lib/support/drivers/sensor.lua b/lib/support/drivers/sensor.lua
deleted file mode 100644
index d4df8d4..0000000
--- a/lib/support/drivers/sensor.lua
+++ /dev/null
@@ -1,52 +0,0 @@
-local device = _G
-local SEN_DIG = string.char(0x03) -- consulta un sensor digital
-local SEN_ANL = string.char(0x00) -- consulta un sensor analogico
-local SEN_ I2C = string.char(0x02) -- consulta un sensor i2c
-
-api={}
-api.senanl = {}
-api.senanl.parameters = {[1]={rname="idPin", rtype="int"}} -- -- el parámetro indica el pin que queremos leer de la arduino
-api.senanl.returns = {[1]={rname="par1", rtype="int"}} --{[1]={rname="par1", rtype="int"}, [2]={rname="par2", rtype="int"}} --two return
-api.senanl.call = function (idPin)
- device:send(string.char(0x00, idPin)) -- codigo de operacion 0
- local sen_anl_response = device:read(3)
- local raw_val
- if not sen_anl_response or string.byte(sen_anl_response or "00000000", 2) == nil or string.byte(sen_anl_response or "00000000", 3) == nil
- then
- raw_val = "nil value"
- else
- raw_val = string.byte(sen_anl_response or "00000000", 2)* 256 + string.byte(sen_anl_response or "00000000", 3)
- end
- --local raw_val2 = string.byte(set_anl_response or " ", 3)
- return raw_val --string.char(raw_val ,raw_val2)
-end
-
-api.sendig = {}
-api.sendig.parameters = {[1]={rname="idPin", rtype="int"}} -- el parámetro indica el pin que queremos leer de la arduino
-api.sendig.returns = {[1]={rname="lecturaSensor", rtype="int"}}
-api.sendig.call = function (idPin)
- device:send(string.char(0x01, idPin)) -- codigo de operacion 1
- local sen_dig_response = device:read(3)
- local raw_val
- --if not sen_dig_response
- --then
- -- raw_val = "nil value"
- --else
- raw_val = string.byte(sen_dig_response or "0000", 2)* 256 + string.byte(sen_dig_response or "0000", 3) + 0
- --end
- return raw_val
-
-end
-
-
---api.seni2c = {}
---api.seni2c.parameters = {} -- no params
---api.seni2c.returns = {[1]={rname="par1", rtype="int"}, [2]={rname="par2", rtype="int"}} --two return
---api.seni2c.call = function ()
--- local get_sen_i2c = SET_I2C
--- device:send(get_sen_i2c)
--- local sen_i2c_response = device:read(2)
--- local raw_val = string.byte(set_i2c_response, 2)
--- return raw_val
---end
-
diff --git a/lib/support/drivers/stmtr.lua b/lib/support/drivers/stmtr.lua
deleted file mode 100644
index 9bd9b40..0000000
--- a/lib/support/drivers/stmtr.lua
+++ /dev/null
@@ -1,46 +0,0 @@
-local device = _G
-
-api={}
-api.rawspeed = {}
-api.rawspeed.parameters = {[1]={rname="speed1", rtype="int", min=-5, max=5}, [2]={rname="speed2", rtype="int", min=-5, max=5}}
-api.rawspeed.returns = {}
-api.rawspeed.call = function (speed1, speed2)
- local msg = string.char(0x02,speed1,speed2)
- device:send(msg)
- device:read()
-end
-
-api.t0cfg = {}
-api.t0cfg.parameters = {[1]={rname="t0_low", rtype="int", min=0, max=255}, [2]={rname="t0_high", rtype="int", min=0, max=255}}
-api.t0cfg.returns = {}
-api.t0cfg.call = function (t0_low, t0_high)
- local msg = string.char(0x01,t0_low,t0_high)
- device:send(msg)
- device:read()
-end
-
-api={}
-api.speed = {}
-api.speed.parameters = {[1]={rname="vel1", rtype="float", min=-127, max=127},
- [2]={rname="vel2", rtype="float", min=-127, max=127}}
-api.speed.returns = {}
-api.speed.call = function (vel1, vel2)
- vel1=tonumber(vel1)
- vel2=tonumber(vel2)
-
- local speed1, speed2
- if vel1>=0 then
- speed1=vel1
- else
- speed1=0xFF + vel1 + 1
- end
- if vel2>=0 then
- speed2=vel2
- else
- speed2=0xFF + vel2 + 1
- end
-
- local msg = string.char(0x02,speed1,speed2)
- device:send(msg)
- device:read()
-end
diff --git a/lib/support/drivers/temp.lua b/lib/support/drivers/temp.lua
deleted file mode 100644
index 09ffe9f..0000000
--- a/lib/support/drivers/temp.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-local device = _G
-
-api={}
-api.getTemp = {}
-api.getTemp.parameters = {} -- -- no input parameters
-api.getTemp.returns = {[1]={rname="par1", rtype="int"}}
-api.getTemp.call = function ()
- device:send(string.char(0x00)) -- codigo de operacion 0
- local sen_anl_response = device:read(3)
- local raw_val
- if not sen_anl_response or string.byte(sen_anl_response or "00000000", 2) == nil or string.byte(sen_anl_response or "00000000", 3) == nil
- then
- raw_val = "nil value"
- else
- raw_val = string.byte(sen_anl_response, 2)* 256 + string.byte(sen_anl_response, 3)
-
- local aux = (raw_val * 500) / 1024 --- obtengo la temperatura en grados
-
- if aux > 180 then
- raw_val = (raw_val * 45) / 1024
- else
- raw_val = aux
- end
-
- end
- return raw_val
-
-end
diff --git a/lib/support/drivers/temp_lubot.lua b/lib/support/drivers/temp_lubot.lua
deleted file mode 100644
index dd22fc4..0000000
--- a/lib/support/drivers/temp_lubot.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-local device = _G
-local RD_TEMP = string.char(0x34, 0x02)
-local char000 = string.char(0,0,0)
-
-
-api={}
-api.get_temperature = {}
-api.get_temperature.parameters = {} --no parameters
-api.get_temperature.returns = {[1]={rname="temperature", rtype="number"}} --one return
-api.get_temperature.call = function ()
- local get_temp_payload = RD_TEMP
- device:send(get_temp_payload)
- local temperature_response = device:read(3) or char000
- local raw_val = string.byte(temperature_response, 2) + (string.byte(temperature_response, 3) * 256)
- local raw_temp = raw_val / 8
- local deg_temp = raw_temp * 0.0625
- --print("rawval, deg_temp: ", raw_val, deg_temp)
- return deg_temp
-end
-
diff --git a/lib/support/lib/bobot_baseboard.lua b/lib/support/lib/bobot_baseboard.lua
deleted file mode 100644
index 757731a..0000000
--- a/lib/support/lib/bobot_baseboard.lua
+++ /dev/null
@@ -1,393 +0,0 @@
-#!/usr/bin/lua
-
---module(..., package.seeall);
-
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]]
-
-local bobot_device = require("bobot_device")
-local bobot = require("bobot")
-
-local NULL_BYTE = string.char(0x00)
-local DEFAULT_PACKET_SIZE = 0x04
-local GET_USER_MODULES_SIZE_COMMAND = string.char(0x05)
-local GET_USER_MODULE_LINE_COMMAND = string.char(0x06)
-local GET_HANDLER_SIZE_COMMAND = string.char(0x0A)
-local GET_HANDLER_TYPE_COMMAND = string.char(0x0B)
-local GET_LINES_RESPONSE_PACKET_SIZE = 5
-local GET_LINE_RESPONSE_PACKET_SIZE = 12
-local GET_HANDLER_TYPE_PACKET_SIZE = 5
-local GET_HANDLER_RESPONSE_PACKET_SIZE = 5 --
-local ADMIN_HANDLER_SEND_COMMAND = string.char(0x00)
-local ADMIN_MODULE_IN_ENDPOINT = 0x01
-local ADMIN_MODULE_OUT_ENDPOINT = 0x81
-local GET_USER_MODULE_LINE_PACKET_SIZE = 0x05
-local CLOSEALL_BASE_BOARD_COMMAND = string.char(0x07)
-local CLOSEALL_BASE_BOARD_RESPONSE_PACKET_SIZE = 5
-local TIMEOUT = 250 --ms
-local MAX_RETRY = 5
-
-local BaseBoard = {}
-
-
---executes s on the console and returns the output
-local function run_shell (s)
- local f = io.popen(s) -- runs command
- local l = f:read("*a") -- read output of command
- f:close()
- return l
-end
-
-openable = {}
-hotplug = {}
-
-local function parse_drivers()
- local driver_files=run_shell("sh -c 'ls "..my_path.."../drivers/*.lua 2> /dev/null'")
- for filename in driver_files:gmatch('drivers%/(%S+)%.lua') do
- --print ("Driver openable", filename)
- openable[filename] = true
- end
- driver_files=run_shell("sh -c 'ls "..my_path.."../drivers/hotplug/*.lua 2> /dev/null'")
- for filename in driver_files:gmatch('drivers%/hotplug%/(%S+)%.lua') do
- --print ("Driver hotplug", filename)
- hotplug[filename] = true
- end
-end
-parse_drivers()
-
-local function load_modules(bb)
- local retry = 0
- bb.modules = {}
-
- local n_modules=bb:get_user_modules_size()
- while n_modules == nil and retry < MAX_RETRY do
- n_modules=bb:get_user_modules_size()
- bobot.debugprint("u4b:the module list size returned a nil value, trying to recover...")
- retry = retry+1
- end
- if not n_modules then return nil end
- retry=0
- bobot.debugprint ("Reading modules:", n_modules)
- for i = 1, n_modules do
- local modulename=bb:get_user_module_line(i)
- while modulename == nil and retry < MAX_RETRY do
- bobot.debugprint("u4b:the module returned a nil value, trying to recover...")
- modulename=bb:get_handler_type(i)
- retry = retry+1
- end
- if not modulename then return nil end
- if openable[modulename] then
- bb.modules[i]=modulename
- local d = bobot_device:new({
- module=modulename,
- --name=module,
- baseboard=bb,
- hotplug=false,
- in_endpoint=0x01, out_endpoint=0x01,
- }) -- in_endpoint=0x01, out_endpoint=0x01})
- bb.devices[d]=true
- bb.devices[#bb.devices+1]=d
-
- bb.modules[modulename]=d
- elseif hotplug[modulename] then
- bb.modules[i]=modulename
- bb.modules[modulename]=true
- bb.hotplug = true -- bb has a hotplug module
- else
- bobot.debugprint("Loading modules: missing driver for",modulename)
- end
- end
- return true
-end
-
-local function load_module_handlers(bb)
- local retry = 0
-
- local n_module_handlers=bb:get_handler_size()
- while n_module_handlers == nil and retry < MAX_RETRY do
- n_module_handlers=bb:get_handler_size()
- bobot.debugprint("u4b:the module handler list size returned a nil value, trying to recover...")
- retry = retry+1
- end
- if (not n_module_handlers) or (n_module_handlers > 32) then return nil end
- retry=0
- bobot.debugprint ("Reading moduleshandlers:", n_module_handlers)
- for i=1, n_module_handlers do
- local t_handler = bb:get_handler_type(i)
- while(t_handler == nil and retry < MAX_RETRY) do
- bobot.debugprint("u4b:the module handler returned a nil value, trying to recover...")
- t_handler = bb:get_handler_type(i)
- retry = retry+1
- end
- if not t_handler then return nil end
- if t_handler<255 then
- local modulename=bb.modules[t_handler+1]
- local moduledev=bb.modules[modulename]
- if type(moduledev)=='table'
- and not moduledev.handler then
- moduledev.handler=i-1
- elseif moduledev==true then
- --name=name.."@"..(i-1)
- local d = bobot_device:new({
- handler=i-1,
- module=modulename,
- --name=name,
- baseboard=bb,
- hotplug=(hotplug[modulename]),
- in_endpoint=0x01, out_endpoint=0x01,
- }) -- in_endpoint=0x01, out_endpoint=0x01})
- if d then
- bb.devices[d]=true
- bb.devices[#bb.devices+1]=d
- end
- else
- bobot.debugprint ("No opened device!")
- end
- end
- end
- return true
-end
-
-
-function BaseBoard:refresh()
- self.devices = {}
-
- if not load_modules(self) then
- return nil,"failure reading modules"
- end
-
- if not load_module_handlers(self) then
- return nil,"failure reading module handlers"
- end
- return true
-end
-
---Instantiates BaseBoard object.
---Loads list of modules installed on baseboard
-function BaseBoard:new(bb)
- --parameters sanity check
- assert(type(bb)=="table")
- assert(type(bb.comms)=="table")
-
- --OO boilerplate
- setmetatable(bb, self)
- self.__index = self
-
- bb:refresh()
-
---bobot.debugprint ('----------------')
- --bb:force_close_all()
---bobot.debugprint ('================')
- return bb
-end
-
---Closes all modules opened on baseboard
-function BaseBoard:close()
- --state sanity check
- assert(type(self.devices)=="table")
-
- for _,d in ipairs(self.devices) do
- if type(d.handler)=="number" then
- bobot.debugprint ("closing", d.name, d.handler)
- d:close()
- end
- end
-
- --TODO actually close the baseboard
-end
-
---returns number of modules present on baseboard
-function BaseBoard:get_user_modules_size()
- --state sanity check
- assert(type(self.comms)=="table")
-
- local comms=self.comms
-
- -- In case of get_user_modules_size command is atended by admin module in handler 0 and send operation is 000
-
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. string.char(DEFAULT_PACKET_SIZE) .. NULL_BYTE
- local admin_packet = GET_USER_MODULES_SIZE_COMMAND
- local get_user_modules_size_packet = handler_packet .. admin_packet
-
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, get_user_modules_size_packet, TIMEOUT)
- if write_res then
- local data, err = comms.read(ADMIN_MODULE_OUT_ENDPOINT, GET_LINES_RESPONSE_PACKET_SIZE, TIMEOUT)
- if not data then
- bobot.debugprint("u4b:get_user_modules_size:comunication with I/O board read error", err)
- return 0
- else
- local user_modules_size = string.byte(data, 5)
- return user_modules_size
- end
- else
- bobot.debugprint("u4b:get_user_modules_size:comunication with I/O board write error", write_res)
- return 0
- end
-end
-
---returns thename of a given (by a 1-based index)module
-function BaseBoard:get_user_module_line(index)
- --state & parameter sanity check
- assert(type(index)=="number")
- assert(index>0)
- assert(type(self.comms)=="table")
-
-
- local comms=self.comms
-
- -- In case of get_user_module_line command is atended by admin module in handler 0 and send operation is 000
- local get_user_module_line_packet_length = string.char(GET_USER_MODULE_LINE_PACKET_SIZE)
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. get_user_module_line_packet_length .. NULL_BYTE
- local admin_packet = GET_USER_MODULE_LINE_COMMAND .. string.char(index-1)
- local get_user_module_line_packet = handler_packet .. admin_packet
-
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, get_user_module_line_packet, TIMEOUT)
- if write_res then
- local data, err = comms.read(ADMIN_MODULE_OUT_ENDPOINT, GET_LINE_RESPONSE_PACKET_SIZE, TIMEOUT)
- if not data then
- bobot.debugprint("u4b:get_user_modules_line:comunication with I/O board read error", err)
- return
- end
- --the name is between a header and a null
- local end_mark = string.find(data, "\000", GET_USER_MODULE_LINE_PACKET_SIZE, true)
- if not end_mark then
- bobot.debugprint ("u4b:get_user_module_line:Error parsing module name")
- return
- end
- local module_name = string.sub(data, GET_USER_MODULE_LINE_PACKET_SIZE, end_mark-1)
- return module_name
- else
- bobot.debugprint("u4b:get_user_module_line:comunication with I/O board write error", write_res)
- end
-end
-
-function BaseBoard:get_handler_size() ------ NEW LISTI ------
- --state sanity check
- assert(type(self.comms)=="table")
-
- local comms=self.comms
-
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. string.char(DEFAULT_PACKET_SIZE) .. NULL_BYTE
- local admin_packet = GET_HANDLER_SIZE_COMMAND
- local get_handler_size_packet = handler_packet .. admin_packet
-
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, get_handler_size_packet, TIMEOUT)
- if write_res then
- local data, err = comms.read(ADMIN_MODULE_OUT_ENDPOINT, GET_HANDLER_RESPONSE_PACKET_SIZE, TIMEOUT)
- if not data then
- bobot.debugprint("u4b:get_handler_size:comunication with I/O board read error", err)
- return 0
- else
- local handler_size = string.byte(data, 5)
- return handler_size
- end
- else
- bobot.debugprint("u4b:get_handler_type:comunication with I/O board write error", write_res)
- end
-end
-function BaseBoard:get_handler_type(index) ------ NEW LISTI ------
- --state & parameter sanity check
- assert(type(index)=="number")
- assert(index>0)
- assert(type(self.comms)=="table")
-
- local comms=self.comms
-
- -- In case of get_handler_type command is atended by admin module in handler 0 and send operation is 000
- local get_handler_type_packet_length = string.char(GET_HANDLER_TYPE_PACKET_SIZE) --GET_USER_MODULE_LINE_PACKET_SIZE
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. get_handler_type_packet_length .. NULL_BYTE
- local admin_packet = GET_HANDLER_TYPE_COMMAND .. string.char(index-1)
- local get_handler_type_packet = handler_packet .. admin_packet
-
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, get_handler_type_packet, TIMEOUT)
- if write_res then
- local data, err = comms.read(ADMIN_MODULE_OUT_ENDPOINT, GET_HANDLER_RESPONSE_PACKET_SIZE, TIMEOUT)
- if not data then
- bobot.debugprint("u4b:get_handler_type:comunication with I/O board read error", err)
- return 0
- else
- local handler_type = string.byte(data, 5)
- return handler_type
- end
- else
- bobot.debugprint("u4b:get_handler_type:comunication with I/O board write error", write_res)
- end
-end
-
--- resets the baseboard, after this operation the baseboard will claim reenumeration to the operative system
--- this function is deprecated by force_close_all
-function BaseBoard:close_all()
- for _,d in ipairs(self.devices) do
- --bobot.debugprint ("===", d.name,d.handler)
- if d.handler then d:close() end
- end
-end
-
--- switch the baseboard to the bootloader program implementend as a usb4all command to the admin module
-function BaseBoard:switch_to_bootloader()
- --state & parameter sanity check
- assert(type(self.comms)=="table")
-
- local comms=self.comms
- -- In case of reset_base_board command is atended by admin module in handler 0 and send operation is 000
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. string.char(DEFAULT_PACKET_SIZE) .. NULL_BYTE
- local admin_packet = string.char(0x09) --SWITCH_TO_BOOT_BASE_BOARD_COMMAND
- local boot_base_board_packet = handler_packet .. admin_packet
-
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, boot_base_board_packet, TIMEOUT)
- --from this moment the board is reseted, so there is nothing more to do
-end
-
-function BaseBoard:reset()
- --state & parameter sanity check
- assert(type(self.comms)=="table")
-
- local comms=self.comms
- -- In case of reset_base_board command is atended by admin module in handler 0 and send operation is 000
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. string.char(DEFAULT_PACKET_SIZE) .. NULL_BYTE
- local admin_packet = string.char(0xFF) --RESET_BASE_BOARD_COMMAND
- local reset_base_board_packet = handler_packet .. admin_packet
-
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, reset_base_board_packet, TIMEOUT)
- if write_res then
- -- no tego que leer respuesta porque se reseteo
- --libusb.close(libusb_handler)
- --self.libusb_handler=nil
- --for d_name,d in pairs(self.devices) do
- --bobot.debugprint ("===", d.name,d.handler)
- -- d.handler=nil
- --end
- else
- bobot.debugprint("u4b:reset:comunication with I/O board write error", write_res)
- end
-end
-
-function BaseBoard:force_close_all()
- --state & parameter sanity check
- assert(type(self.comms)=="table")
-
- local comms=self.comms
- -- In case of reset_base_board command is atended by admin module in handler 0 and send operation is 000
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. string.char(DEFAULT_PACKET_SIZE) .. NULL_BYTE
- local admin_packet = CLOSEALL_BASE_BOARD_COMMAND
- local reset_base_board_packet = handler_packet .. admin_packet
-
---bobot.debugprint ('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')
- local write_res = comms.send(ADMIN_MODULE_IN_ENDPOINT, reset_base_board_packet, TIMEOUT)
---bobot.debugprint ('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')
- if write_res then
- local data, err = comms.read(ADMIN_MODULE_OUT_ENDPOINT, CLOSEALL_BASE_BOARD_RESPONSE_PACKET_SIZE, TIMEOUT)
- if err then
- bobot.debugprint("u4b:force_close_all:comunication with I/O board read error",err)
- else
- --bobot.debugprint("u4b:force_close_all:libusb read",string.byte(data,1,string.len(data)))
- end
- for _,d in ipairs(self.devices) do
- --bobot.debugprint ("===", d.name,d.handler)
- d.handler=nil
- end
- else
- bobot.debugprint("u4b:force_close_all:comunication with I/O board write error", write_res)
- end
-end
-
-return BaseBoard
diff --git a/lib/support/lib/bobot_device.lua b/lib/support/lib/bobot_device.lua
deleted file mode 100644
index b560255..0000000
--- a/lib/support/lib/bobot_device.lua
+++ /dev/null
@@ -1,216 +0,0 @@
---module(..., package.seeall);
-
-local bobot = require("bobot")
-
-local string_char = string.char
-local string_len = string.len
-local string_byte = string.byte
-
-local OPEN_COMMAND = string_char(0x00)
-local CLOSE_COMMAND = string_char(0x01)
-local HEADER_PACKET_SIZE = 6
-local NULL_BYTE = string_char(0x00)
-local ADMIN_MODULE_IN_ENDPOINT = 0x01
-local ADMIN_MODULE_OUT_ENDPOINT = 0x81
-local ADMIN_HANDLER_SEND_COMMAND = string_char(0x00)
-local OPEN_RESPONSE_PACKET_SIZE = 5
-local CLOSE_RESPONSE_PACKET_SIZE = 2
-local TIMEOUT = 200 --ms
-
-local READ_HEADER_SIZE = 3
-
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]]
-
-local Device = {
- --some usefull stuff for the drivers to use
- string=string,
- print=bobot.debugprint,
- math=math,
- tonumber=tonumber,
- tostring=tostring
-}
-
-
-local drivers_cache = setmetatable({}, {__mode='kv'})
-local function load_driver(d)
- local modulename=d.module
- if drivers_cache[modulename] then return drivers_cache[modulename] end
-
- local drivername=string.match(modulename, '^(.-)%d*$')
- local f, err
- if d.hotplug then
- f, err = loadfile(my_path.."../drivers/hotplug/"..drivername..".lua")
- else
- f, err = loadfile(my_path.."../drivers/"..drivername..".lua")
- end
- drivers_cache[modulename] = f
- return f, err
-end
-
---Instantiates Device object.
---Attempts to load api from driver
-function Device:new(d)
- --parameters sanity check
- assert(type(d)=="table")
- --assert(type(d.name)=="string")
- assert(type(d.module)=="string")
- assert(type(d.baseboard)=="table")
- assert(type(d.baseboard.comms)=="table")
- assert(type(d.baseboard.comms.send)=="function")
- assert(type(d.baseboard.comms.read)=="function")
-
- --OO boilerplate
- setmetatable(d, self)
- self.__index = self
-
- --store locally, save 2 indirections
- d.comms_send = d.baseboard.comms.send
- d.comms_read = d.baseboard.comms.read
-
- --attempt to load api from driver
- local f, err = load_driver(d)
- if f then
- d._G=d
-
- setfenv(f, d) --the driver's environment is the device
- local status, err=pcall(f)
- if status then
- bobot.debugprint("u4d:new:Success loading driver:", d.module)
- else
- bobot.debugprint("u4d:new:Error initializing driver:", tostring(err))
- end
- else
- bobot.debugprint("u4d:new:Error loading driver:", err)
- return nil
- end
-
- return d
-end
-
---opens the device. must be done before sending / reading / etc.
---receives endpoints, which can be ommited if they were provided at Device creation
-function Device:open(in_endpoint, out_endpoint)
- --state & parameter sanity check
- assert(self.handler==nil)
- --assert(type(self.name)=="string")
- assert(type(in_endpoint)=="number" or type(self.in_endpoint)=="number")
- assert(type(self.comms_send)=="function")
- assert(type(self.comms_read)=="function")
- assert(type(out_endpoint)=="number" or type(self.out_endpoint)=="number")
-
- --save for later use
- if in_endpoint then self.in_endpoint = in_endpoint end
- if out_endpoint then self.out_endpoint = out_endpoint end
-
- local module_name=self.module .."\000" -- usb4all expect null terminated names
-
- local open_packet_length = string_char(HEADER_PACKET_SIZE + string_len(module_name))
-
- local module_in_endpoint = string_char(self.in_endpoint)
- local module_out_endpoint = string_char(self.out_endpoint)
-
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. open_packet_length .. NULL_BYTE
- local admin_packet = OPEN_COMMAND .. module_in_endpoint .. module_out_endpoint .. module_name
- local open_packet = handler_packet .. admin_packet
- local write_res = self.comms_send(ADMIN_MODULE_IN_ENDPOINT, open_packet, TIMEOUT)
-
- if not write_res then
- bobot.debugprint("u4d:open:comunication with I/O board write error", write_res)
- return false
- end
-
- local data, err = self.comms_read(ADMIN_MODULE_OUT_ENDPOINT, OPEN_RESPONSE_PACKET_SIZE, TIMEOUT)
- if not data then
- bobot.debugprint ("u4d:open:comunication with I/O boardread error", err)
- return false
- end
-
- local handler = string_byte(data, 5)
- --hander -1 meand error
- if handler==255 then
- bobot.debugprint ("u4d:open:Already open!",self.module,self.handler)
- return
- else
- bobot.debugprint ("u4d:open:Success!",self.module,handler)
- self.handler = handler --self.handler set means device is open
- return true
- end
-
-end
-
---closes the device
-function Device:close()
- if not self.handler then return end --already closed
-
- --state sanity check
- assert(type(self.handler)=="number")
- assert(type(self.comms_send)=="function")
- assert(type(self.comms_read)=="function")
-
- local close_packet_length = string_char(0x04) --string.char(HEADER_PACKET_SIZE + string.len(module_name))
- local handler_packet = ADMIN_HANDLER_SEND_COMMAND .. close_packet_length .. NULL_BYTE
- local admin_packet = CLOSE_COMMAND .. string_char(self.handler)
- local close_packet = handler_packet .. admin_packet
-
- local write_res = self.comms_send(ADMIN_MODULE_IN_ENDPOINT, close_packet, TIMEOUT)
- if not write_res then
- bobot.debugprint("u4d:close:comunication with I/O board write error", write_res)
- return
- end
- local data, err = self.comms_read(ADMIN_MODULE_OUT_ENDPOINT, CLOSE_RESPONSE_PACKET_SIZE, TIMEOUT)
-
- self.handler = nil
-end
-
---sends data (a string) to device
-function Device:send(data)
- --state & parameter sanity check
- data=tostring(data)
- assert(type(data)=="string")
- assert(type(self.handler)=="number")
- assert(type(self.in_endpoint)=="number")
- assert(type(self.comms_send)=="function")
- assert(type(self.comms_read)=="function")
-
- local len=string_len(data)
-
- local shifted_handler = self.handler * 8
- assert(shifted_handler<256, "u4d:send:shifted_handler vale " .. shifted_handler .. " excede el tamaño maximo representable en un byte (255)")
- local user_module_handler_send_command = string_char(shifted_handler)
- local send_packet_length = string_char(0x03 + len)
- local send_packet = user_module_handler_send_command .. send_packet_length .. NULL_BYTE .. data
-
- --local tini=socket.gettime()
- local write_res, err = self.comms_send(self.in_endpoint, send_packet, TIMEOUT)
- --bobot.debugprint ('%%%%%%%%%%%%%%%% device send',socket.gettime()-tini)
-
- if not write_res then
- bobot.debugprint("u4d:send:comunication with I/O board write error", err)
- end
-
- return write_res, err
-end
-
---read data (len bytes max) from device
-function Device:read(len)
- len = len or 255
- --state & parameter sanity check
- assert(type(len)=="number")
- assert(type(self.handler)=="number")
- assert(type(self.out_endpoint)=="number")
- assert(type(self.comms_send)=="function")
- assert(type(self.comms_read)=="function")
-
- local data, err = self.comms_read(self.out_endpoint, len+READ_HEADER_SIZE, TIMEOUT)
- if not data then
- bobot.debugprint("u4d:read:comunication with I/O board read error", err)
- return nil, err
- end
-
- local data_h = string.sub(data, READ_HEADER_SIZE+1, -1) --discard header
-
- return data_h, err
-end
-
-return Device
-
diff --git a/lib/support/lib/comms_chotox.lua b/lib/support/lib/comms_chotox.lua
deleted file mode 100644
index 18e02bf..0000000
--- a/lib/support/lib/comms_chotox.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-local bobot_device = require("bobot_device")
-
-local comms_chotox = {}
-
-function comms_chotox.send(endpoint, data, timeout)
-end
-
-function comms_chotox.read(endpoint, len, timeout)
-end
-
-
-function comms_chotox.init(baseboards)
- --parameters sanity check
- assert(type(baseboards)=="table")
-
- local n_boards=1
- --local bb = bobot_baseboard.BaseBoard:new({idBoard=iSerial, comms=comms_usb})
- local bb = {idBoard=1, comms=comms_chotox}
- local devices={}
- local is_hotplug= {button=true, led=true, grey=true, distanc=true}
- for i, name in ipairs({"button", "grey", "distanc","butia"}) do
- local dd={name=name, module=name, baseboard=bb, handler=i}
- dd.open = function() return true end
- dd.close = function() end
- dd.read = function() return "" end
- dd.send = function() return true end
- if is_hotplug[name] then dd.hotplug=true end
-
- local d = bobot_device:new(dd) -- in_endpoint=0x01, out_endpoint=0x01})
-
- devices[name]=true
- devices[#devices+1]=d
- end
- bb.devices=devices
- baseboards[1]=bb
- return n_boards
-end
-
-return comms_chotox
diff --git a/lib/support/lib/comms_serial.lua b/lib/support/lib/comms_serial.lua
deleted file mode 100644
index 4bd3bb0..0000000
--- a/lib/support/lib/comms_serial.lua
+++ /dev/null
@@ -1,94 +0,0 @@
---module(..., package.seeall);
-
---local socket=require("socket")
-
-local bobot_baseboard = require("bobot_baseboard")
-local bobot = require("bobot")
-
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]]
-assert(package.loadlib(my_path .. "lua_serialcomm.so","luaopen_serialcomm"))()
-local serialcomm=_G.serialcomm; _G.serialcomm=nil
-
-local serial_handler
-
---executes s on the console and returns the output
-local function run_shell (s)
- local f = io.popen(s) -- runs command
- local l = f:read("*a") -- read output of command
- f:close()
- return l
-end
-
-local function split_words(s)
- local words={}
- for p in string.gmatch(s, "%S+") do
- words[#words+1]=p
- end
- return words
-end
-
-local comms_serial = {}
-
-function comms_serial.send(endpoint, data, timeout)
- --parameters sanity check
- assert(type(serial_handler)=="number")
- --assert(type(endpoint)=="number")
- assert(type(data)=="string")
- assert(type(timeout)=="number")
-
- --local tini=socket.gettime()
- local ret = serialcomm.send_msg(serial_handler, data)
- --bobot.debugprint ('%%%%%%%%%%%%%%%% comms serial send',socket.gettime()-tini)
- return ret
-end
-
-function comms_serial.read(endpoint, len, timeout)
- --parameters sanity check
- assert(type(serial_handler)=="number")
- --assert(type(endpoint)=="number")
- --assert(type(len)=="number")
- --assert(type(timeout)=="number")
-
- return serialcomm.read_msg(serial_handler, len, timeout)
-end
-
-
-function comms_serial.init(baseboards)
- --parameters sanity check
- assert(type(baseboards)=="table")
-
- --FIXME leer ttyusbs...
- --local tty_s=run_shell("ls /dev/ttyUSB* ")
- local tty_s=run_shell("sh -c 'ls /dev/ttyUSB* 2> /dev/null'") --supress errors
- local tty_t=split_words(tty_s)
- local tty
- local err
- if (#tty_t == 0) then
- return 0,"no ttyUSB found"
- end
-
- -- tty="/dev/ttyUSB0"
- --for i=1, #tty_t do
- for _, ttyI in ipairs(tty_t) do
- bobot.debugprint ("Trying to connect to", ttyI)
- serial_handler, err = serialcomm.init(ttyI, 115200)
- if serial_handler then
- tty=ttyI
- break
- else
- bobot.debugprint("Error connecting:", err)
- end
- end
- if not serial_handler then
- bobot.debugprint("cs:", "no ttyUSB could be open")
- return 0, err
- end
- bobot.debugprint ("cs:", tty)
- local bb = bobot_baseboard:new({idBoard=tty, comms=comms_serial})
-
- baseboards[#baseboards+1]=bb
-
- return 1
-end
-
-return comms_serial
diff --git a/lib/support/lib/comms_usb.lua b/lib/support/lib/comms_usb.lua
deleted file mode 100644
index 91d64b5..0000000
--- a/lib/support/lib/comms_usb.lua
+++ /dev/null
@@ -1,99 +0,0 @@
---module(..., package.seeall);
-
-local bobot_baseboard = require("bobot_baseboard")
-local bobot = require("bobot")
-
-local my_path = debug.getinfo(1, "S").source:match[[^@?(.*[\/])[^\/]-$]]
-assert(package.loadlib(my_path .. "libluausb.so","luaopen_libusb"))()
-local libusb=_G.libusb; _G.libusb=nil
-
-local usb_bulk_write = libusb.bulk_write
-local usb_bulk_read = libusb.bulk_read
-
-local USB4ALL_VENDOR = 0x04d8
-local USB4ALL_PRODUCT = 0x000c
-local USB4ALL_CONFIGURATION = 1
-local USB4ALL_INTERFACE = 0
-
-local READ_HEADER_SIZE = 3
-
-local libusb_handler
-
-
-local comms_usb = {}
-
-function comms_usb.send(endpoint, data, timeout)
- --parameters sanity check
- assert(type(libusb_handler)=="userdata")
- assert(type(endpoint)=="number")
- assert(type(data)=="string")
- assert(type(timeout)=="number")
-
- return usb_bulk_write(libusb_handler, endpoint, data, timeout)
-end
-
-function comms_usb.read(endpoint, len, timeout)
- --parameters sanity check
- assert(type(libusb_handler)=="userdata")
- assert(type(endpoint)=="number")
- assert(type(len)=="number")
- assert(type(timeout)=="number")
-
- return usb_bulk_read(libusb_handler, endpoint, len+READ_HEADER_SIZE, timeout)
-end
-
-
-function comms_usb.init(baseboards)
- --parameters sanity check
- assert(type(baseboards)=="table")
-
-
- --refresh devices and buses
- libusb.find_busses()
- libusb.find_devices()
- local n_boards = 0
-
- local buses=libusb.get_busses()
- for dirname, bus in pairs(buses) do --iterate buses
- local devices=libusb.get_devices(bus)
- for filename, device in pairs(devices) do --iterate devices
- local descriptor = libusb.device_descriptor(device)
-
- --if device is baseboard...
- if ((descriptor.idVendor == USB4ALL_VENDOR) and (descriptor.idProduct == USB4ALL_PRODUCT)) then
- --try to intialize baseboard
- bobot.debugprint("Initializing Baseboard:", descriptor.idVendor, descriptor.idProduct)
- libusb_handler = libusb.open(device)
-
- if not libusb_handler then
- bobot.debugprint("Error opening device")
- break
- end
- if not libusb.set_configuration(libusb_handler, USB4ALL_CONFIGURATION) then
- bobot.debugprint("Error configuring device, retrying after a reset")
- libusb.reset(libusb_handler)
- if not libusb.set_configuration(libusb_handler, USB4ALL_CONFIGURATION) then
- bobot.debugprint("Error configuring device.")
- break
- end
- end
- if not libusb.claim_interface(libusb_handler, USB4ALL_INTERFACE) then
- bobot.debugprint("Error seting device interface")
- break
- end
-
- --success initializing, instantiate BaseBoard object and register
- local iSerial=descriptor.iSerialNumber
- local bb = bobot_baseboard:new({idBoard=iSerial, comms=comms_usb})
- --bb:force_close_all()
- --bobot.debugprint("Baseboard:", iSerial)
-
- baseboards[#baseboards+1]=bb
- n_boards = n_boards + 1
- end
- end
- end
- return n_boards
-end
-
-return comms_usb
diff --git a/lib/support/lib/libluausb.so b/lib/support/lib/libluausb.so
deleted file mode 100755
index a7c9406..0000000
--- a/lib/support/lib/libluausb.so
+++ /dev/null
Binary files differ
diff --git a/lib/support/lib/lua_serialcomm.so b/lib/support/lib/lua_serialcomm.so
deleted file mode 100755
index cb79295..0000000
--- a/lib/support/lib/lua_serialcomm.so
+++ /dev/null
Binary files differ
diff --git a/lib/support/lib/mime/core.so b/lib/support/lib/mime/core.so
deleted file mode 100755
index 696b7d9..0000000
--- a/lib/support/lib/mime/core.so
+++ /dev/null
Binary files differ
diff --git a/lib/support/lib/socket/core.so b/lib/support/lib/socket/core.so
deleted file mode 100755
index ddfc8c3..0000000
--- a/lib/support/lib/socket/core.so
+++ /dev/null
Binary files differ
diff --git a/lib/support/libluausb.so b/lib/support/libluausb.so
deleted file mode 100755
index a7c9406..0000000
--- a/lib/support/libluausb.so
+++ /dev/null
Binary files differ
diff --git a/lib/support/lua b/lib/support/lua
deleted file mode 100755
index a36f550..0000000
--- a/lib/support/lua
+++ /dev/null
Binary files differ
diff --git a/lib/support/lua_serialcomm.so b/lib/support/lua_serialcomm.so
deleted file mode 100755
index cb79295..0000000
--- a/lib/support/lua_serialcomm.so
+++ /dev/null
Binary files differ
diff --git a/lib/support/share/ltn12.lua b/lib/support/share/ltn12.lua
deleted file mode 100644
index b42689a..0000000
--- a/lib/support/share/ltn12.lua
+++ /dev/null
@@ -1,292 +0,0 @@
------------------------------------------------------------------------------
--- LTN12 - Filters, sources, sinks and pumps.
--- LuaSocket toolkit.
--- Author: Diego Nehab
--- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module
------------------------------------------------------------------------------
-local string = require("string")
-local table = require("table")
-local base = _G
-module("ltn12")
-
-filter = {}
-source = {}
-sink = {}
-pump = {}
-
--- 2048 seems to be better in windows...
-BLOCKSIZE = 2048
-_VERSION = "LTN12 1.0.1"
-
------------------------------------------------------------------------------
--- Filter stuff
------------------------------------------------------------------------------
--- returns a high level filter that cycles a low-level filter
-function filter.cycle(low, ctx, extra)
- base.assert(low)
- return function(chunk)
- local ret
- ret, ctx = low(ctx, chunk, extra)
- return ret
- end
-end
-
--- chains a bunch of filters together
--- (thanks to Wim Couwenberg)
-function filter.chain(...)
- local n = table.getn(arg)
- local top, index = 1, 1
- local retry = ""
- return function(chunk)
- retry = chunk and retry
- while true do
- if index == top then
- chunk = arg[index](chunk)
- if chunk == "" or top == n then return chunk
- elseif chunk then index = index + 1
- else
- top = top+1
- index = top
- end
- else
- chunk = arg[index](chunk or "")
- if chunk == "" then
- index = index - 1
- chunk = retry
- elseif chunk then
- if index == n then return chunk
- else index = index + 1 end
- else base.error("filter returned inappropriate nil") end
- end
- end
- end
-end
-
------------------------------------------------------------------------------
--- Source stuff
------------------------------------------------------------------------------
--- create an empty source
-local function empty()
- return nil
-end
-
-function source.empty()
- return empty
-end
-
--- returns a source that just outputs an error
-function source.error(err)
- return function()
- return nil, err
- end
-end
-
--- creates a file source
-function source.file(handle, io_err)
- if handle then
- return function()
- local chunk = handle:read(BLOCKSIZE)
- if not chunk then handle:close() end
- return chunk
- end
- else return source.error(io_err or "unable to open file") end
-end
-
--- turns a fancy source into a simple source
-function source.simplify(src)
- base.assert(src)
- return function()
- local chunk, err_or_new = src()
- src = err_or_new or src
- if not chunk then return nil, err_or_new
- else return chunk end
- end
-end
-
--- creates string source
-function source.string(s)
- if s then
- local i = 1
- return function()
- local chunk = string.sub(s, i, i+BLOCKSIZE-1)
- i = i + BLOCKSIZE
- if chunk ~= "" then return chunk
- else return nil end
- end
- else return source.empty() end
-end
-
--- creates rewindable source
-function source.rewind(src)
- base.assert(src)
- local t = {}
- return function(chunk)
- if not chunk then
- chunk = table.remove(t)
- if not chunk then return src()
- else return chunk end
- else
- table.insert(t, chunk)
- end
- end
-end
-
-function source.chain(src, f)
- base.assert(src and f)
- local last_in, last_out = "", ""
- local state = "feeding"
- local err
- return function()
- if not last_out then
- base.error('source is empty!', 2)
- end
- while true do
- if state == "feeding" then
- last_in, err = src()
- if err then return nil, err end
- last_out = f(last_in)
- if not last_out then
- if last_in then
- base.error('filter returned inappropriate nil')
- else
- return nil
- end
- elseif last_out ~= "" then
- state = "eating"
- if last_in then last_in = "" end
- return last_out
- end
- else
- last_out = f(last_in)
- if last_out == "" then
- if last_in == "" then
- state = "feeding"
- else
- base.error('filter returned ""')
- end
- elseif not last_out then
- if last_in then
- base.error('filter returned inappropriate nil')
- else
- return nil
- end
- else
- return last_out
- end
- end
- end
- end
-end
-
--- creates a source that produces contents of several sources, one after the
--- other, as if they were concatenated
--- (thanks to Wim Couwenberg)
-function source.cat(...)
- local src = table.remove(arg, 1)
- return function()
- while src do
- local chunk, err = src()
- if chunk then return chunk end
- if err then return nil, err end
- src = table.remove(arg, 1)
- end
- end
-end
-
------------------------------------------------------------------------------
--- Sink stuff
------------------------------------------------------------------------------
--- creates a sink that stores into a table
-function sink.table(t)
- t = t or {}
- local f = function(chunk, err)
- if chunk then table.insert(t, chunk) end
- return 1
- end
- return f, t
-end
-
--- turns a fancy sink into a simple sink
-function sink.simplify(snk)
- base.assert(snk)
- return function(chunk, err)
- local ret, err_or_new = snk(chunk, err)
- if not ret then return nil, err_or_new end
- snk = err_or_new or snk
- return 1
- end
-end
-
--- creates a file sink
-function sink.file(handle, io_err)
- if handle then
- return function(chunk, err)
- if not chunk then
- handle:close()
- return 1
- else return handle:write(chunk) end
- end
- else return sink.error(io_err or "unable to open file") end
-end
-
--- creates a sink that discards data
-local function null()
- return 1
-end
-
-function sink.null()
- return null
-end
-
--- creates a sink that just returns an error
-function sink.error(err)
- return function()
- return nil, err
- end
-end
-
--- chains a sink with a filter
-function sink.chain(f, snk)
- base.assert(f and snk)
- return function(chunk, err)
- if chunk ~= "" then
- local filtered = f(chunk)
- local done = chunk and ""
- while true do
- local ret, snkerr = snk(filtered, err)
- if not ret then return nil, snkerr end
- if filtered == done then return 1 end
- filtered = f(done)
- end
- else return 1 end
- end
-end
-
------------------------------------------------------------------------------
--- Pump stuff
------------------------------------------------------------------------------
--- pumps one chunk from the source to the sink
-function pump.step(src, snk)
- local chunk, src_err = src()
- local ret, snk_err = snk(chunk, src_err)
- if chunk and ret then return 1
- else return nil, src_err or snk_err end
-end
-
--- pumps all data from a source to a sink, using a step function
-function pump.all(src, snk, step)
- base.assert(src and snk)
- step = step or pump.step
- while true do
- local ret, err = step(src, snk)
- if not ret then
- if err then return nil, err
- else return 1 end
- end
- end
-end
-
diff --git a/lib/support/share/mime.lua b/lib/support/share/mime.lua
deleted file mode 100644
index 169eda2..0000000
--- a/lib/support/share/mime.lua
+++ /dev/null
@@ -1,87 +0,0 @@
------------------------------------------------------------------------------
--- MIME support for the Lua language.
--- Author: Diego Nehab
--- Conforming to RFCs 2045-2049
--- RCS ID: $Id: mime.lua,v 1.29 2007/06/11 23:44:54 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
------------------------------------------------------------------------------
-local base = _G
-local ltn12 = require("ltn12")
-local mime = require("mime.core")
-local io = require("io")
-local string = require("string")
-module("mime")
-
--- encode, decode and wrap algorithm tables
-encodet = {}
-decodet = {}
-wrapt = {}
-
--- creates a function that chooses a filter by name from a given table
-local function choose(table)
- return function(name, opt1, opt2)
- if base.type(name) ~= "string" then
- name, opt1, opt2 = "default", name, opt1
- end
- local f = table[name or "nil"]
- if not f then
- base.error("unknown key (" .. base.tostring(name) .. ")", 3)
- else return f(opt1, opt2) end
- end
-end
-
--- define the encoding filters
-encodet['base64'] = function()
- return ltn12.filter.cycle(b64, "")
-end
-
-encodet['quoted-printable'] = function(mode)
- return ltn12.filter.cycle(qp, "",
- (mode == "binary") and "=0D=0A" or "\r\n")
-end
-
--- define the decoding filters
-decodet['base64'] = function()
- return ltn12.filter.cycle(unb64, "")
-end
-
-decodet['quoted-printable'] = function()
- return ltn12.filter.cycle(unqp, "")
-end
-
-local function format(chunk)
- if chunk then
- if chunk == "" then return "''"
- else return string.len(chunk) end
- else return "nil" end
-end
-
--- define the line-wrap filters
-wrapt['text'] = function(length)
- length = length or 76
- return ltn12.filter.cycle(wrp, length, length)
-end
-wrapt['base64'] = wrapt['text']
-wrapt['default'] = wrapt['text']
-
-wrapt['quoted-printable'] = function()
- return ltn12.filter.cycle(qpwrp, 76, 76)
-end
-
--- function that choose the encoding, decoding or wrap algorithm
-encode = choose(encodet)
-decode = choose(decodet)
-wrap = choose(wrapt)
-
--- define the end-of-line normalization filter
-function normalize(marker)
- return ltn12.filter.cycle(eol, 0, marker)
-end
-
--- high level stuffing filter
-function stuff()
- return ltn12.filter.cycle(dot, 2)
-end
diff --git a/lib/support/share/socket.lua b/lib/support/share/socket.lua
deleted file mode 100644
index 211adcd..0000000
--- a/lib/support/share/socket.lua
+++ /dev/null
@@ -1,133 +0,0 @@
------------------------------------------------------------------------------
--- LuaSocket helper module
--- Author: Diego Nehab
--- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
------------------------------------------------------------------------------
-local base = _G
-local string = require("string")
-local math = require("math")
-local socket = require("socket.core")
-module("socket")
-
------------------------------------------------------------------------------
--- Exported auxiliar functions
------------------------------------------------------------------------------
-function connect(address, port, laddress, lport)
- local sock, err = socket.tcp()
- if not sock then return nil, err end
- if laddress then
- local res, err = sock:bind(laddress, lport, -1)
- if not res then return nil, err end
- end
- local res, err = sock:connect(address, port)
- if not res then return nil, err end
- return sock
-end
-
-function bind(host, port, backlog)
- local sock, err = socket.tcp()
- if not sock then return nil, err end
- sock:setoption("reuseaddr", true)
- local res, err = sock:bind(host, port)
- if not res then return nil, err end
- res, err = sock:listen(backlog)
- if not res then return nil, err end
- return sock
-end
-
-try = newtry()
-
-function choose(table)
- return function(name, opt1, opt2)
- if base.type(name) ~= "string" then
- name, opt1, opt2 = "default", name, opt1
- end
- local f = table[name or "nil"]
- if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
- else return f(opt1, opt2) end
- end
-end
-
------------------------------------------------------------------------------
--- Socket sources and sinks, conforming to LTN12
------------------------------------------------------------------------------
--- create namespaces inside LuaSocket namespace
-sourcet = {}
-sinkt = {}
-
-BLOCKSIZE = 2048
-
-sinkt["close-when-done"] = function(sock)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function(self, chunk, err)
- if not chunk then
- sock:close()
- return 1
- else return sock:send(chunk) end
- end
- })
-end
-
-sinkt["keep-open"] = function(sock)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function(self, chunk, err)
- if chunk then return sock:send(chunk)
- else return 1 end
- end
- })
-end
-
-sinkt["default"] = sinkt["keep-open"]
-
-sink = choose(sinkt)
-
-sourcet["by-length"] = function(sock, length)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function()
- if length <= 0 then return nil end
- local size = math.min(socket.BLOCKSIZE, length)
- local chunk, err = sock:receive(size)
- if err then return nil, err end
- length = length - string.len(chunk)
- return chunk
- end
- })
-end
-
-sourcet["until-closed"] = function(sock)
- local done
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function()
- if done then return nil end
- local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
- if not err then return chunk
- elseif err == "closed" then
- sock:close()
- done = 1
- return partial
- else return nil, err end
- end
- })
-end
-
-
-sourcet["default"] = sourcet["until-closed"]
-
-source = choose(sourcet)
-
diff --git a/lib/support/share/socket/ftp.lua b/lib/support/share/socket/ftp.lua
deleted file mode 100644
index 598f65d..0000000
--- a/lib/support/share/socket/ftp.lua
+++ /dev/null
@@ -1,281 +0,0 @@
------------------------------------------------------------------------------
--- FTP support for the Lua language
--- LuaSocket toolkit.
--- Author: Diego Nehab
--- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
------------------------------------------------------------------------------
-local base = _G
-local table = require("table")
-local string = require("string")
-local math = require("math")
-local socket = require("socket")
-local url = require("socket.url")
-local tp = require("socket.tp")
-local ltn12 = require("ltn12")
-module("socket.ftp")
-
------------------------------------------------------------------------------
--- Program constants
------------------------------------------------------------------------------
--- timeout in seconds before the program gives up on a connection
-TIMEOUT = 60
--- default port for ftp service
-PORT = 21
--- this is the default anonymous password. used when no password is
--- provided in url. should be changed to your e-mail.
-USER = "ftp"
-PASSWORD = "anonymous@anonymous.org"
-
------------------------------------------------------------------------------
--- Low level FTP API
------------------------------------------------------------------------------
-local metat = { __index = {} }
-
-function open(server, port, create)
- local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create))
- local f = base.setmetatable({ tp = tp }, metat)
- -- make sure everything gets closed in an exception
- f.try = socket.newtry(function() f:close() end)
- return f
-end
-
-function metat.__index:portconnect()
- self.try(self.server:settimeout(TIMEOUT))
- self.data = self.try(self.server:accept())
- self.try(self.data:settimeout(TIMEOUT))
-end
-
-function metat.__index:pasvconnect()
- self.data = self.try(socket.tcp())
- self.try(self.data:settimeout(TIMEOUT))
- self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
-end
-
-function metat.__index:login(user, password)
- self.try(self.tp:command("user", user or USER))
- local code, reply = self.try(self.tp:check{"2..", 331})
- if code == 331 then
- self.try(self.tp:command("pass", password or PASSWORD))
- self.try(self.tp:check("2.."))
- end
- return 1
-end
-
-function metat.__index:pasv()
- self.try(self.tp:command("pasv"))
- local code, reply = self.try(self.tp:check("2.."))
- local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
- self.try(a and b and c and d and p1 and p2, reply)
- self.pasvt = {
- ip = string.format("%d.%d.%d.%d", a, b, c, d),
- port = p1*256 + p2
- }
- if self.server then
- self.server:close()
- self.server = nil
- end
- return self.pasvt.ip, self.pasvt.port
-end
-
-function metat.__index:port(ip, port)
- self.pasvt = nil
- if not ip then
- ip, port = self.try(self.tp:getcontrol():getsockname())
- self.server = self.try(socket.bind(ip, 0))
- ip, port = self.try(self.server:getsockname())
- self.try(self.server:settimeout(TIMEOUT))
- end
- local pl = math.mod(port, 256)
- local ph = (port - pl)/256
- local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",")
- self.try(self.tp:command("port", arg))
- self.try(self.tp:check("2.."))
- return 1
-end
-
-function metat.__index:send(sendt)
- self.try(self.pasvt or self.server, "need port or pasv first")
- -- if there is a pasvt table, we already sent a PASV command
- -- we just get the data connection into self.data
- if self.pasvt then self:pasvconnect() end
- -- get the transfer argument and command
- local argument = sendt.argument or
- url.unescape(string.gsub(sendt.path or "", "^[/\\]", ""))
- if argument == "" then argument = nil end
- local command = sendt.command or "stor"
- -- send the transfer command and check the reply
- self.try(self.tp:command(command, argument))
- local code, reply = self.try(self.tp:check{"2..", "1.."})
- -- if there is not a a pasvt table, then there is a server
- -- and we already sent a PORT command
- if not self.pasvt then self:portconnect() end
- -- get the sink, source and step for the transfer
- local step = sendt.step or ltn12.pump.step
- local readt = {self.tp.c}
- local checkstep = function(src, snk)
- -- check status in control connection while downloading
- local readyt = socket.select(readt, nil, 0)
- if readyt[tp] then code = self.try(self.tp:check("2..")) end
- return step(src, snk)
- end
- local sink = socket.sink("close-when-done", self.data)
- -- transfer all data and check error
- self.try(ltn12.pump.all(sendt.source, sink, checkstep))
- if string.find(code, "1..") then self.try(self.tp:check("2..")) end
- -- done with data connection
- self.data:close()
- -- find out how many bytes were sent
- local sent = socket.skip(1, self.data:getstats())
- self.data = nil
- return sent
-end
-
-function metat.__index:receive(recvt)
- self.try(self.pasvt or self.server, "need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument = recvt.argument or
- url.unescape(string.gsub(recvt.path or "", "^[/\\]", ""))
- if argument == "" then argument = nil end
- local command = recvt.command or "retr"
- self.try(self.tp:command(command, argument))
- local code = self.try(self.tp:check{"1..", "2.."})
- if not self.pasvt then self:portconnect() end
- local source = socket.source("until-closed", self.data)
- local step = recvt.step or ltn12.pump.step
- self.try(ltn12.pump.all(source, recvt.sink, step))
- if string.find(code, "1..") then self.try(self.tp:check("2..")) end
- self.data:close()
- self.data = nil
- return 1
-end
-
-function metat.__index:cwd(dir)
- self.try(self.tp:command("cwd", dir))
- self.try(self.tp:check(250))
- return 1
-end
-
-function metat.__index:type(type)
- self.try(self.tp:command("type", type))
- self.try(self.tp:check(200))
- return 1
-end
-
-function metat.__index:greet()
- local code = self.try(self.tp:check{"1..", "2.."})
- if string.find(code, "1..") then self.try(self.tp:check("2..")) end
- return 1
-end
-
-function metat.__index:quit()
- self.try(self.tp:command("quit"))
- self.try(self.tp:check("2.."))
- return 1
-end
-
-function metat.__index:close()
- if self.data then self.data:close() end
- if self.server then self.server:close() end
- return self.tp:close()
-end
-
------------------------------------------------------------------------------
--- High level FTP API
------------------------------------------------------------------------------
-local function override(t)
- if t.url then
- local u = url.parse(t.url)
- for i,v in base.pairs(t) do
- u[i] = v
- end
- return u
- else return t end
-end
-
-local function tput(putt)
- putt = override(putt)
- socket.try(putt.host, "missing hostname")
- local f = open(putt.host, putt.port, putt.create)
- f:greet()
- f:login(putt.user, putt.password)
- if putt.type then f:type(putt.type) end
- f:pasv()
- local sent = f:send(putt)
- f:quit()
- f:close()
- return sent
-end
-
-local default = {
- path = "/",
- scheme = "ftp"
-}
-
-local function parse(u)
- local t = socket.try(url.parse(u, default))
- socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
- socket.try(t.host, "missing hostname")
- local pat = "^type=(.)$"
- if t.params then
- t.type = socket.skip(2, string.find(t.params, pat))
- socket.try(t.type == "a" or t.type == "i",
- "invalid type '" .. t.type .. "'")
- end
- return t
-end
-
-local function sput(u, body)
- local putt = parse(u)
- putt.source = ltn12.source.string(body)
- return tput(putt)
-end
-
-put = socket.protect(function(putt, body)
- if base.type(putt) == "string" then return sput(putt, body)
- else return tput(putt) end
-end)
-
-local function tget(gett)
- gett = override(gett)
- socket.try(gett.host, "missing hostname")
- local f = open(gett.host, gett.port, gett.create)
- f:greet()
- f:login(gett.user, gett.password)
- if gett.type then f:type(gett.type) end
- f:pasv()
- f:receive(gett)
- f:quit()
- return f:close()
-end
-
-local function sget(u)
- local gett = parse(u)
- local t = {}
- gett.sink = ltn12.sink.table(t)
- tget(gett)
- return table.concat(t)
-end
-
-command = socket.protect(function(cmdt)
- cmdt = override(cmdt)
- socket.try(cmdt.host, "missing hostname")
- socket.try(cmdt.command, "missing command")
- local f = open(cmdt.host, cmdt.port, cmdt.create)
- f:greet()
- f:login(cmdt.user, cmdt.password)
- f.try(f.tp:command(cmdt.command, cmdt.argument))
- if cmdt.check then f.try(f.tp:check(cmdt.check)) end
- f:quit()
- return f:close()
-end)
-
-get = socket.protect(function(gett)
- if base.type(gett) == "string" then return sget(gett)
- else return tget(gett) end
-end)
-
diff --git a/lib/support/share/socket/http.lua b/lib/support/share/socket/http.lua
deleted file mode 100644
index ad8db1e..0000000
--- a/lib/support/share/socket/http.lua
+++ /dev/null
@@ -1,350 +0,0 @@
------------------------------------------------------------------------------
--- HTTP/1.1 client support for the Lua language.
--- LuaSocket toolkit.
--- Author: Diego Nehab
--- RCS ID: $Id: http.lua,v 1.71 2007/10/13 23:55:20 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
--------------------------------------------------------------------------------
-local socket = require("socket")
-local url = require("socket.url")
-local ltn12 = require("ltn12")
-local mime = require("mime")
-local string = require("string")
-local base = _G
-local table = require("table")
-module("socket.http")
-
------------------------------------------------------------------------------
--- Program constants
------------------------------------------------------------------------------
--- connection timeout in seconds
-TIMEOUT = 60
--- default port for document retrieval
-PORT = 80
--- user agent field sent in request
-USERAGENT = socket._VERSION
-
------------------------------------------------------------------------------
--- Reads MIME headers from a connection, unfolding where needed
------------------------------------------------------------------------------
-local function receiveheaders(sock, headers)
- local line, name, value, err
- headers = headers or {}
- -- get first line
- line, err = sock:receive()
- if err then return nil, err end
- -- headers go until a blank line is found
- while line ~= "" do
- -- get field-name and value
- name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
- if not (name and value) then return nil, "malformed reponse headers" end
- name = string.lower(name)
- -- get next line (value might be folded)
- line, err = sock:receive()
- if err then return nil, err end
- -- unfold any folded values
- while string.find(line, "^%s") do
- value = value .. line
- line = sock:receive()
- if err then return nil, err end
- end
- -- save pair in table
- if headers[name] then headers[name] = headers[name] .. ", " .. value
- else headers[name] = value end
- end
- return headers
-end
-
------------------------------------------------------------------------------
--- Extra sources and sinks
------------------------------------------------------------------------------
-socket.sourcet["http-chunked"] = function(sock, headers)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function()
- -- get chunk size, skip extention
- local line, err = sock:receive()
- if err then return nil, err end
- local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
- if not size then return nil, "invalid chunk size" end
- -- was it the last chunk?
- if size > 0 then
- -- if not, get chunk and skip terminating CRLF
- local chunk, err, part = sock:receive(size)
- if chunk then sock:receive() end
- return chunk, err
- else
- -- if it was, read trailers into headers table
- headers, err = receiveheaders(sock, headers)
- if not headers then return nil, err end
- end
- end
- })
-end
-
-socket.sinkt["http-chunked"] = function(sock)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function(self, chunk, err)
- if not chunk then return sock:send("0\r\n\r\n") end
- local size = string.format("%X\r\n", string.len(chunk))
- return sock:send(size .. chunk .. "\r\n")
- end
- })
-end
-
------------------------------------------------------------------------------
--- Low level HTTP API
------------------------------------------------------------------------------
-local metat = { __index = {} }
-
-function open(host, port, create)
- -- create socket with user connect function, or with default
- local c = socket.try((create or socket.tcp)())
- local h = base.setmetatable({ c = c }, metat)
- -- create finalized try
- h.try = socket.newtry(function() h:close() end)
- -- set timeout before connecting
- h.try(c:settimeout(TIMEOUT))
- h.try(c:connect(host, port or PORT))
- -- here everything worked
- return h
-end
-
-function metat.__index:sendrequestline(method, uri)
- local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
- return self.try(self.c:send(reqline))
-end
-
-function metat.__index:sendheaders(headers)
- local h = "\r\n"
- for i, v in base.pairs(headers) do
- h = i .. ": " .. v .. "\r\n" .. h
- end
- self.try(self.c:send(h))
- return 1
-end
-
-function metat.__index:sendbody(headers, source, step)
- source = source or ltn12.source.empty()
- step = step or ltn12.pump.step
- -- if we don't know the size in advance, send chunked and hope for the best
- local mode = "http-chunked"
- if headers["content-length"] then mode = "keep-open" end
- return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step))
-end
-
-function metat.__index:receivestatusline()
- local status = self.try(self.c:receive(5))
- -- identify HTTP/0.9 responses, which do not contain a status line
- -- this is just a heuristic, but is what the RFC recommends
- if status ~= "HTTP/" then return nil, status end
- -- otherwise proceed reading a status line
- status = self.try(self.c:receive("*l", status))
- local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
- return self.try(base.tonumber(code), status)
-end
-
-function metat.__index:receiveheaders()
- return self.try(receiveheaders(self.c))
-end
-
-function metat.__index:receivebody(headers, sink, step)
- sink = sink or ltn12.sink.null()
- step = step or ltn12.pump.step
- local length = base.tonumber(headers["content-length"])
- local t = headers["transfer-encoding"] -- shortcut
- local mode = "default" -- connection close
- if t and t ~= "identity" then mode = "http-chunked"
- elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
- return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
- sink, step))
-end
-
-function metat.__index:receive09body(status, sink, step)
- local source = ltn12.source.rewind(socket.source("until-closed", self.c))
- source(status)
- return self.try(ltn12.pump.all(source, sink, step))
-end
-
-function metat.__index:close()
- return self.c:close()
-end
-
------------------------------------------------------------------------------
--- High level HTTP API
------------------------------------------------------------------------------
-local function adjusturi(reqt)
- local u = reqt
- -- if there is a proxy, we need the full url. otherwise, just a part.
- if not reqt.proxy and not PROXY then
- u = {
- path = socket.try(reqt.path, "invalid path 'nil'"),
- params = reqt.params,
- query = reqt.query,
- fragment = reqt.fragment
- }
- end
- return url.build(u)
-end
-
-local function adjustproxy(reqt)
- local proxy = reqt.proxy or PROXY
- if proxy then
- proxy = url.parse(proxy)
- return proxy.host, proxy.port or 3128
- else
- return reqt.host, reqt.port
- end
-end
-
-local function adjustheaders(reqt)
- -- default headers
- local lower = {
- ["user-agent"] = USERAGENT,
- ["host"] = reqt.host,
- ["connection"] = "close, TE",
- ["te"] = "trailers"
- }
- -- if we have authentication information, pass it along
- if reqt.user and reqt.password then
- lower["authorization"] =
- "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
- end
- -- override with user headers
- for i,v in base.pairs(reqt.headers or lower) do
- lower[string.lower(i)] = v
- end
- return lower
-end
-
--- default url parts
-local default = {
- host = "",
- port = PORT,
- path ="/",
- scheme = "http"
-}
-
-local function adjustrequest(reqt)
- -- parse url if provided
- local nreqt = reqt.url and url.parse(reqt.url, default) or {}
- -- explicit components override url
- for i,v in base.pairs(reqt) do nreqt[i] = v end
- if nreqt.port == "" then nreqt.port = 80 end
- socket.try(nreqt.host and nreqt.host ~= "",
- "invalid host '" .. base.tostring(nreqt.host) .. "'")
- -- compute uri if user hasn't overriden
- nreqt.uri = reqt.uri or adjusturi(nreqt)
- -- ajust host and port if there is a proxy
- nreqt.host, nreqt.port = adjustproxy(nreqt)
- -- adjust headers in request
- nreqt.headers = adjustheaders(nreqt)
- return nreqt
-end
-
-local function shouldredirect(reqt, code, headers)
- return headers.location and
- string.gsub(headers.location, "%s", "") ~= "" and
- (reqt.redirect ~= false) and
- (code == 301 or code == 302) and
- (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
- and (not reqt.nredirects or reqt.nredirects < 5)
-end
-
-local function shouldreceivebody(reqt, code)
- if reqt.method == "HEAD" then return nil end
- if code == 204 or code == 304 then return nil end
- if code >= 100 and code < 200 then return nil end
- return 1
-end
-
--- forward declarations
-local trequest, tredirect
-
-function tredirect(reqt, location)
- local result, code, headers, status = trequest {
- -- the RFC says the redirect URL has to be absolute, but some
- -- servers do not respect that
- url = url.absolute(reqt.url, location),
- source = reqt.source,
- sink = reqt.sink,
- headers = reqt.headers,
- proxy = reqt.proxy,
- nredirects = (reqt.nredirects or 0) + 1,
- create = reqt.create
- }
- -- pass location header back as a hint we redirected
- headers = headers or {}
- headers.location = headers.location or location
- return result, code, headers, status
-end
-
-function trequest(reqt)
- -- we loop until we get what we want, or
- -- until we are sure there is no way to get it
- local nreqt = adjustrequest(reqt)
- local h = open(nreqt.host, nreqt.port, nreqt.create)
- -- send request line and headers
- h:sendrequestline(nreqt.method, nreqt.uri)
- h:sendheaders(nreqt.headers)
- -- if there is a body, send it
- if nreqt.source then
- h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
- end
- local code, status = h:receivestatusline()
- -- if it is an HTTP/0.9 server, simply get the body and we are done
- if not code then
- h:receive09body(status, nreqt.sink, nreqt.step)
- return 1, 200
- end
- local headers
- -- ignore any 100-continue messages
- while code == 100 do
- headers = h:receiveheaders()
- code, status = h:receivestatusline()
- end
- headers = h:receiveheaders()
- -- at this point we should have a honest reply from the server
- -- we can't redirect if we already used the source, so we report the error
- if shouldredirect(nreqt, code, headers) and not nreqt.source then
- h:close()
- return tredirect(reqt, headers.location)
- end
- -- here we are finally done
- if shouldreceivebody(nreqt, code) then
- h:receivebody(headers, nreqt.sink, nreqt.step)
- end
- h:close()
- return 1, code, headers, status
-end
-
-local function srequest(u, b)
- local t = {}
- local reqt = {
- url = u,
- sink = ltn12.sink.table(t)
- }
- if b then
- reqt.source = ltn12.source.string(b)
- reqt.headers = {
- ["content-length"] = string.len(b),
- ["content-type"] = "application/x-www-form-urlencoded"
- }
- reqt.method = "POST"
- end
- local code, headers, status = socket.skip(1, trequest(reqt))
- return table.concat(t), code, headers, status
-end
-
-request = socket.protect(function(reqt, body)
- if base.type(reqt) == "string" then return srequest(reqt, body)
- else return trequest(reqt) end
-end)
diff --git a/lib/support/share/socket/smtp.lua b/lib/support/share/socket/smtp.lua
deleted file mode 100644
index 8f3cfcf..0000000
--- a/lib/support/share/socket/smtp.lua
+++ /dev/null
@@ -1,251 +0,0 @@
------------------------------------------------------------------------------
--- SMTP client support for the Lua language.
--- LuaSocket toolkit.
--- Author: Diego Nehab
--- RCS ID: $Id: smtp.lua,v 1.46 2007/03/12 04:08:40 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
------------------------------------------------------------------------------
-local base = _G
-local coroutine = require("coroutine")
-local string = require("string")
-local math = require("math")
-local os = require("os")
-local socket = require("socket")
-local tp = require("socket.tp")
-local ltn12 = require("ltn12")
-local mime = require("mime")
-module("socket.smtp")
-
------------------------------------------------------------------------------
--- Program constants
------------------------------------------------------------------------------
--- timeout for connection
-TIMEOUT = 60
--- default server used to send e-mails
-SERVER = "localhost"
--- default port
-PORT = 25
--- domain used in HELO command and default sendmail
--- If we are under a CGI, try to get from environment
-DOMAIN = os.getenv("SERVER_NAME") or "localhost"
--- default time zone (means we don't know)
-ZONE = "-0000"
-
----------------------------------------------------------------------------
--- Low level SMTP API
------------------------------------------------------------------------------
-local metat = { __index = {} }
-
-function metat.__index:greet(domain)
- self.try(self.tp:check("2.."))
- self.try(self.tp:command("EHLO", domain or DOMAIN))
- return socket.skip(1, self.try(self.tp:check("2..")))
-end
-
-function metat.__index:mail(from)
- self.try(self.tp:command("MAIL", "FROM:" .. from))
- return self.try(self.tp:check("2.."))
-end
-
-function metat.__index:rcpt(to)
- self.try(self.tp:command("RCPT", "TO:" .. to))
- return self.try(self.tp:check("2.."))
-end
-
-function metat.__index:data(src, step)
- self.try(self.tp:command("DATA"))
- self.try(self.tp:check("3.."))
- self.try(self.tp:source(src, step))
- self.try(self.tp:send("\r\n.\r\n"))
- return self.try(self.tp:check("2.."))
-end
-
-function metat.__index:quit()
- self.try(self.tp:command("QUIT"))
- return self.try(self.tp:check("2.."))
-end
-
-function metat.__index:close()
- return self.tp:close()
-end
-
-function metat.__index:login(user, password)
- self.try(self.tp:command("AUTH", "LOGIN"))
- self.try(self.tp:check("3.."))
- self.try(self.tp:command(mime.b64(user)))
- self.try(self.tp:check("3.."))
- self.try(self.tp:command(mime.b64(password)))
- return self.try(self.tp:check("2.."))
-end
-
-function metat.__index:plain(user, password)
- local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
- self.try(self.tp:command("AUTH", auth))
- return self.try(self.tp:check("2.."))
-end
-
-function metat.__index:auth(user, password, ext)
- if not user or not password then return 1 end
- if string.find(ext, "AUTH[^\n]+LOGIN") then
- return self:login(user, password)
- elseif string.find(ext, "AUTH[^\n]+PLAIN") then
- return self:plain(user, password)
- else
- self.try(nil, "authentication not supported")
- end
-end
-
--- send message or throw an exception
-function metat.__index:send(mailt)
- self:mail(mailt.from)
- if base.type(mailt.rcpt) == "table" then
- for i,v in base.ipairs(mailt.rcpt) do
- self:rcpt(v)
- end
- else
- self:rcpt(mailt.rcpt)
- end
- self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
-end
-
-function open(server, port, create)
- local tp = socket.try(tp.connect(server or SERVER, port or PORT,
- TIMEOUT, create))
- local s = base.setmetatable({tp = tp}, metat)
- -- make sure tp is closed if we get an exception
- s.try = socket.newtry(function()
- s:close()
- end)
- return s
-end
-
--- convert headers to lowercase
-local function lower_headers(headers)
- local lower = {}
- for i,v in base.pairs(headers or lower) do
- lower[string.lower(i)] = v
- end
- return lower
-end
-
----------------------------------------------------------------------------
--- Multipart message source
------------------------------------------------------------------------------
--- returns a hopefully unique mime boundary
-local seqno = 0
-local function newboundary()
- seqno = seqno + 1
- return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'),
- math.random(0, 99999), seqno)
-end
-
--- send_message forward declaration
-local send_message
-
--- yield the headers all at once, it's faster
-local function send_headers(headers)
- local h = "\r\n"
- for i,v in base.pairs(headers) do
- h = i .. ': ' .. v .. "\r\n" .. h
- end
- coroutine.yield(h)
-end
-
--- yield multipart message body from a multipart message table
-local function send_multipart(mesgt)
- -- make sure we have our boundary and send headers
- local bd = newboundary()
- local headers = lower_headers(mesgt.headers or {})
- headers['content-type'] = headers['content-type'] or 'multipart/mixed'
- headers['content-type'] = headers['content-type'] ..
- '; boundary="' .. bd .. '"'
- send_headers(headers)
- -- send preamble
- if mesgt.body.preamble then
- coroutine.yield(mesgt.body.preamble)
- coroutine.yield("\r\n")
- end
- -- send each part separated by a boundary
- for i, m in base.ipairs(mesgt.body) do
- coroutine.yield("\r\n--" .. bd .. "\r\n")
- send_message(m)
- end
- -- send last boundary
- coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
- -- send epilogue
- if mesgt.body.epilogue then
- coroutine.yield(mesgt.body.epilogue)
- coroutine.yield("\r\n")
- end
-end
-
--- yield message body from a source
-local function send_source(mesgt)
- -- make sure we have a content-type
- local headers = lower_headers(mesgt.headers or {})
- headers['content-type'] = headers['content-type'] or
- 'text/plain; charset="iso-8859-1"'
- send_headers(headers)
- -- send body from source
- while true do
- local chunk, err = mesgt.body()
- if err then coroutine.yield(nil, err)
- elseif chunk then coroutine.yield(chunk)
- else break end
- end
-end
-
--- yield message body from a string
-local function send_string(mesgt)
- -- make sure we have a content-type
- local headers = lower_headers(mesgt.headers or {})
- headers['content-type'] = headers['content-type'] or
- 'text/plain; charset="iso-8859-1"'
- send_headers(headers)
- -- send body from string
- coroutine.yield(mesgt.body)
-end
-
--- message source
-function send_message(mesgt)
- if base.type(mesgt.body) == "table" then send_multipart(mesgt)
- elseif base.type(mesgt.body) == "function" then send_source(mesgt)
- else send_string(mesgt) end
-end
-
--- set defaul headers
-local function adjust_headers(mesgt)
- local lower = lower_headers(mesgt.headers)
- lower["date"] = lower["date"] or
- os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE)
- lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
- -- this can't be overriden
- lower["mime-version"] = "1.0"
- return lower
-end
-
-function message(mesgt)
- mesgt.headers = adjust_headers(mesgt)
- -- create and return message source
- local co = coroutine.create(function() send_message(mesgt) end)
- return function()
- local ret, a, b = coroutine.resume(co)
- if ret then return a, b
- else return nil, a end
- end
-end
-
----------------------------------------------------------------------------
--- High level SMTP API
------------------------------------------------------------------------------
-send = socket.protect(function(mailt)
- local s = open(mailt.server, mailt.port, mailt.create)
- local ext = s:greet(mailt.domain)
- s:auth(mailt.user, mailt.password, ext)
- s:send(mailt)
- s:quit()
- return s:close()
-end)
diff --git a/lib/support/share/socket/tp.lua b/lib/support/share/socket/tp.lua
deleted file mode 100644
index 0683869..0000000
--- a/lib/support/share/socket/tp.lua
+++ /dev/null
@@ -1,123 +0,0 @@
------------------------------------------------------------------------------
--- Unified SMTP/FTP subsystem
--- LuaSocket toolkit.
--- Author: Diego Nehab
--- RCS ID: $Id: tp.lua,v 1.22 2006/03/14 09:04:15 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
------------------------------------------------------------------------------
-local base = _G
-local string = require("string")
-local socket = require("socket")
-local ltn12 = require("ltn12")
-module("socket.tp")
-
------------------------------------------------------------------------------
--- Program constants
------------------------------------------------------------------------------
-TIMEOUT = 60
-
------------------------------------------------------------------------------
--- Implementation
------------------------------------------------------------------------------
--- gets server reply (works for SMTP and FTP)
-local function get_reply(c)
- local code, current, sep
- local line, err = c:receive()
- local reply = line
- if err then return nil, err end
- code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
- if not code then return nil, "invalid server reply" end
- if sep == "-" then -- reply is multiline
- repeat
- line, err = c:receive()
- if err then return nil, err end
- current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
- reply = reply .. "\n" .. line
- -- reply ends with same code
- until code == current and sep == " "
- end
- return code, reply
-end
-
--- metatable for sock object
-local metat = { __index = {} }
-
-function metat.__index:check(ok)
- local code, reply = get_reply(self.c)
- if not code then return nil, reply end
- if base.type(ok) ~= "function" then
- if base.type(ok) == "table" then
- for i, v in base.ipairs(ok) do
- if string.find(code, v) then
- return base.tonumber(code), reply
- end
- end
- return nil, reply
- else
- if string.find(code, ok) then return base.tonumber(code), reply
- else return nil, reply end
- end
- else return ok(base.tonumber(code), reply) end
-end
-
-function metat.__index:command(cmd, arg)
- if arg then
- return self.c:send(cmd .. " " .. arg.. "\r\n")
- else
- return self.c:send(cmd .. "\r\n")
- end
-end
-
-function metat.__index:sink(snk, pat)
- local chunk, err = c:receive(pat)
- return snk(chunk, err)
-end
-
-function metat.__index:send(data)
- return self.c:send(data)
-end
-
-function metat.__index:receive(pat)
- return self.c:receive(pat)
-end
-
-function metat.__index:getfd()
- return self.c:getfd()
-end
-
-function metat.__index:dirty()
- return self.c:dirty()
-end
-
-function metat.__index:getcontrol()
- return self.c
-end
-
-function metat.__index:source(source, step)
- local sink = socket.sink("keep-open", self.c)
- local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
- return ret, err
-end
-
--- closes the underlying c
-function metat.__index:close()
- self.c:close()
- return 1
-end
-
--- connect with server and return c object
-function connect(host, port, timeout, create)
- local c, e = (create or socket.tcp)()
- if not c then return nil, e end
- c:settimeout(timeout or TIMEOUT)
- local r, e = c:connect(host, port)
- if not r then
- c:close()
- return nil, e
- end
- return base.setmetatable({c = c}, metat)
-end
-
diff --git a/lib/support/share/socket/url.lua b/lib/support/share/socket/url.lua
deleted file mode 100644
index 0e31d8a..0000000
--- a/lib/support/share/socket/url.lua
+++ /dev/null
@@ -1,297 +0,0 @@
------------------------------------------------------------------------------
--- URI parsing, composition and relative URL resolution
--- LuaSocket toolkit.
--- Author: Diego Nehab
--- RCS ID: $Id: url.lua,v 1.38 2006/04/03 04:45:42 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module
------------------------------------------------------------------------------
-local string = require("string")
-local base = _G
-local table = require("table")
-module("socket.url")
-
------------------------------------------------------------------------------
--- Module version
------------------------------------------------------------------------------
-_VERSION = "URL 1.0.1"
-
------------------------------------------------------------------------------
--- Encodes a string into its escaped hexadecimal representation
--- Input
--- s: binary string to be encoded
--- Returns
--- escaped representation of string binary
------------------------------------------------------------------------------
-function escape(s)
- return string.gsub(s, "([^A-Za-z0-9_])", function(c)
- return string.format("%%%02x", string.byte(c))
- end)
-end
-
------------------------------------------------------------------------------
--- Protects a path segment, to prevent it from interfering with the
--- url parsing.
--- Input
--- s: binary string to be encoded
--- Returns
--- escaped representation of string binary
------------------------------------------------------------------------------
-local function make_set(t)
- local s = {}
- for i,v in base.ipairs(t) do
- s[t[i]] = 1
- end
- return s
-end
-
--- these are allowed withing a path segment, along with alphanum
--- other characters must be escaped
-local segment_set = make_set {
- "-", "_", ".", "!", "~", "*", "'", "(",
- ")", ":", "@", "&", "=", "+", "$", ",",
-}
-
-local function protect_segment(s)
- return string.gsub(s, "([^A-Za-z0-9_])", function (c)
- if segment_set[c] then return c
- else return string.format("%%%02x", string.byte(c)) end
- end)
-end
-
------------------------------------------------------------------------------
--- Encodes a string into its escaped hexadecimal representation
--- Input
--- s: binary string to be encoded
--- Returns
--- escaped representation of string binary
------------------------------------------------------------------------------
-function unescape(s)
- return string.gsub(s, "%%(%x%x)", function(hex)
- return string.char(base.tonumber(hex, 16))
- end)
-end
-
------------------------------------------------------------------------------
--- Builds a path from a base path and a relative path
--- Input
--- base_path
--- relative_path
--- Returns
--- corresponding absolute path
------------------------------------------------------------------------------
-local function absolute_path(base_path, relative_path)
- if string.sub(relative_path, 1, 1) == "/" then return relative_path end
- local path = string.gsub(base_path, "[^/]*$", "")
- path = path .. relative_path
- path = string.gsub(path, "([^/]*%./)", function (s)
- if s ~= "./" then return s else return "" end
- end)
- path = string.gsub(path, "/%.$", "/")
- local reduced
- while reduced ~= path do
- reduced = path
- path = string.gsub(reduced, "([^/]*/%.%./)", function (s)
- if s ~= "../../" then return "" else return s end
- end)
- end
- path = string.gsub(reduced, "([^/]*/%.%.)$", function (s)
- if s ~= "../.." then return "" else return s end
- end)
- return path
-end
-
------------------------------------------------------------------------------
--- Parses a url and returns a table with all its parts according to RFC 2396
--- The following grammar describes the names given to the URL parts
--- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment>
--- <authority> ::= <userinfo>@<host>:<port>
--- <userinfo> ::= <user>[:<password>]
--- <path> :: = {<segment>/}<segment>
--- Input
--- url: uniform resource locator of request
--- default: table with default values for each field
--- Returns
--- table with the following fields, where RFC naming conventions have
--- been preserved:
--- scheme, authority, userinfo, user, password, host, port,
--- path, params, query, fragment
--- Obs:
--- the leading '/' in {/<path>} is considered part of <path>
------------------------------------------------------------------------------
-function parse(url, default)
- -- initialize default parameters
- local parsed = {}
- for i,v in base.pairs(default or parsed) do parsed[i] = v end
- -- empty url is parsed to nil
- if not url or url == "" then return nil, "invalid url" end
- -- remove whitespace
- -- url = string.gsub(url, "%s", "")
- -- get fragment
- url = string.gsub(url, "#(.*)$", function(f)
- parsed.fragment = f
- return ""
- end)
- -- get scheme
- url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
- function(s) parsed.scheme = s; return "" end)
- -- get authority
- url = string.gsub(url, "^//([^/]*)", function(n)
- parsed.authority = n
- return ""
- end)
- -- get query stringing
- url = string.gsub(url, "%?(.*)", function(q)
- parsed.query = q
- return ""
- end)
- -- get params
- url = string.gsub(url, "%;(.*)", function(p)
- parsed.params = p
- return ""
- end)
- -- path is whatever was left
- if url ~= "" then parsed.path = url end
- local authority = parsed.authority
- if not authority then return parsed end
- authority = string.gsub(authority,"^([^@]*)@",
- function(u) parsed.userinfo = u; return "" end)
- authority = string.gsub(authority, ":([^:]*)$",
- function(p) parsed.port = p; return "" end)
- if authority ~= "" then parsed.host = authority end
- local userinfo = parsed.userinfo
- if not userinfo then return parsed end
- userinfo = string.gsub(userinfo, ":([^:]*)$",
- function(p) parsed.password = p; return "" end)
- parsed.user = userinfo
- return parsed
-end
-
------------------------------------------------------------------------------
--- Rebuilds a parsed URL from its components.
--- Components are protected if any reserved or unallowed characters are found
--- Input
--- parsed: parsed URL, as returned by parse
--- Returns
--- a stringing with the corresponding URL
------------------------------------------------------------------------------
-function build(parsed)
- local ppath = parse_path(parsed.path or "")
- local url = build_path(ppath)
- if parsed.params then url = url .. ";" .. parsed.params end
- if parsed.query then url = url .. "?" .. parsed.query end
- local authority = parsed.authority
- if parsed.host then
- authority = parsed.host
- if parsed.port then authority = authority .. ":" .. parsed.port end
- local userinfo = parsed.userinfo
- if parsed.user then
- userinfo = parsed.user
- if parsed.password then
- userinfo = userinfo .. ":" .. parsed.password
- end
- end
- if userinfo then authority = userinfo .. "@" .. authority end
- end
- if authority then url = "//" .. authority .. url end
- if parsed.scheme then url = parsed.scheme .. ":" .. url end
- if parsed.fragment then url = url .. "#" .. parsed.fragment end
- -- url = string.gsub(url, "%s", "")
- return url
-end
-
------------------------------------------------------------------------------
--- Builds a absolute URL from a base and a relative URL according to RFC 2396
--- Input
--- base_url
--- relative_url
--- Returns
--- corresponding absolute url
------------------------------------------------------------------------------
-function absolute(base_url, relative_url)
- if base.type(base_url) == "table" then
- base_parsed = base_url
- base_url = build(base_parsed)
- else
- base_parsed = parse(base_url)
- end
- local relative_parsed = parse(relative_url)
- if not base_parsed then return relative_url
- elseif not relative_parsed then return base_url
- elseif relative_parsed.scheme then return relative_url
- else
- relative_parsed.scheme = base_parsed.scheme
- if not relative_parsed.authority then
- relative_parsed.authority = base_parsed.authority
- if not relative_parsed.path then
- relative_parsed.path = base_parsed.path
- if not relative_parsed.params then
- relative_parsed.params = base_parsed.params
- if not relative_parsed.query then
- relative_parsed.query = base_parsed.query
- end
- end
- else
- relative_parsed.path = absolute_path(base_parsed.path or "",
- relative_parsed.path)
- end
- end
- return build(relative_parsed)
- end
-end
-
------------------------------------------------------------------------------
--- Breaks a path into its segments, unescaping the segments
--- Input
--- path
--- Returns
--- segment: a table with one entry per segment
------------------------------------------------------------------------------
-function parse_path(path)
- local parsed = {}
- path = path or ""
- --path = string.gsub(path, "%s", "")
- string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
- for i = 1, table.getn(parsed) do
- parsed[i] = unescape(parsed[i])
- end
- if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
- if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
- return parsed
-end
-
------------------------------------------------------------------------------
--- Builds a path component from its segments, escaping protected characters.
--- Input
--- parsed: path segments
--- unsafe: if true, segments are not protected before path is built
--- Returns
--- path: corresponding path stringing
------------------------------------------------------------------------------
-function build_path(parsed, unsafe)
- local path = ""
- local n = table.getn(parsed)
- if unsafe then
- for i = 1, n-1 do
- path = path .. parsed[i]
- path = path .. "/"
- end
- if n > 0 then
- path = path .. parsed[n]
- if parsed.is_directory then path = path .. "/" end
- end
- else
- for i = 1, n-1 do
- path = path .. protect_segment(parsed[i])
- path = path .. "/"
- end
- if n > 0 then
- path = path .. protect_segment(parsed[n])
- if parsed.is_directory then path = path .. "/" end
- end
- end
- if parsed.is_absolute then path = "/" .. path end
- return path
-end
diff --git a/lib/support/socket.lua b/lib/support/socket.lua
deleted file mode 100644
index 211adcd..0000000
--- a/lib/support/socket.lua
+++ /dev/null
@@ -1,133 +0,0 @@
------------------------------------------------------------------------------
--- LuaSocket helper module
--- Author: Diego Nehab
--- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $
------------------------------------------------------------------------------
-
------------------------------------------------------------------------------
--- Declare module and import dependencies
------------------------------------------------------------------------------
-local base = _G
-local string = require("string")
-local math = require("math")
-local socket = require("socket.core")
-module("socket")
-
------------------------------------------------------------------------------
--- Exported auxiliar functions
------------------------------------------------------------------------------
-function connect(address, port, laddress, lport)
- local sock, err = socket.tcp()
- if not sock then return nil, err end
- if laddress then
- local res, err = sock:bind(laddress, lport, -1)
- if not res then return nil, err end
- end
- local res, err = sock:connect(address, port)
- if not res then return nil, err end
- return sock
-end
-
-function bind(host, port, backlog)
- local sock, err = socket.tcp()
- if not sock then return nil, err end
- sock:setoption("reuseaddr", true)
- local res, err = sock:bind(host, port)
- if not res then return nil, err end
- res, err = sock:listen(backlog)
- if not res then return nil, err end
- return sock
-end
-
-try = newtry()
-
-function choose(table)
- return function(name, opt1, opt2)
- if base.type(name) ~= "string" then
- name, opt1, opt2 = "default", name, opt1
- end
- local f = table[name or "nil"]
- if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
- else return f(opt1, opt2) end
- end
-end
-
------------------------------------------------------------------------------
--- Socket sources and sinks, conforming to LTN12
------------------------------------------------------------------------------
--- create namespaces inside LuaSocket namespace
-sourcet = {}
-sinkt = {}
-
-BLOCKSIZE = 2048
-
-sinkt["close-when-done"] = function(sock)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function(self, chunk, err)
- if not chunk then
- sock:close()
- return 1
- else return sock:send(chunk) end
- end
- })
-end
-
-sinkt["keep-open"] = function(sock)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function(self, chunk, err)
- if chunk then return sock:send(chunk)
- else return 1 end
- end
- })
-end
-
-sinkt["default"] = sinkt["keep-open"]
-
-sink = choose(sinkt)
-
-sourcet["by-length"] = function(sock, length)
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function()
- if length <= 0 then return nil end
- local size = math.min(socket.BLOCKSIZE, length)
- local chunk, err = sock:receive(size)
- if err then return nil, err end
- length = length - string.len(chunk)
- return chunk
- end
- })
-end
-
-sourcet["until-closed"] = function(sock)
- local done
- return base.setmetatable({
- getfd = function() return sock:getfd() end,
- dirty = function() return sock:dirty() end
- }, {
- __call = function()
- if done then return nil end
- local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
- if not err then return chunk
- elseif err == "closed" then
- sock:close()
- done = 1
- return partial
- else return nil, err end
- end
- })
-end
-
-
-sourcet["default"] = sourcet["until-closed"]
-
-source = choose(sourcet)
-
diff --git a/lib/support/socket/core.so b/lib/support/socket/core.so
deleted file mode 100755
index ddfc8c3..0000000
--- a/lib/support/socket/core.so
+++ /dev/null
Binary files differ
diff --git a/main.py b/main.py
index 5040560..8931938 100755
--- a/main.py
+++ b/main.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# FollowMe Butia - Main
-# Copyright (C) 2010, 2011, 2012
+# Copyright (C) 2010-2013
# This program was created to use with the robot Butia.
# Butia is a project from Facultad de Ingenieria - Uruguay
# Facultad de Ingenieria web site: <http://www.fing.edu.uy/>
diff --git a/pybot/__init__.py b/pybot/__init__.py
new file mode 100755
index 0000000..d908414
--- /dev/null
+++ b/pybot/__init__.py
@@ -0,0 +1,27 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2012-2013 Butiá Team butia@fing.edu.uy
+# Butia is a free and open robotic platform
+# www.fing.edu.uy/inco/proyectos/butia
+# Facultad de Ingeniería - Universidad de la República - Uruguay
+#
+# 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 of the License, 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
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+import os
+import sys
+# Make sure that can import all files
+sys.path.insert(0, os.path.dirname(__file__))
+
diff --git a/pybot/baseboard.py b/pybot/baseboard.py
new file mode 100755
index 0000000..fe5bba5
--- /dev/null
+++ b/pybot/baseboard.py
@@ -0,0 +1,275 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Baseboard abstraction for USB4butia
+#
+# Copyright (c) 2012-2013 Butiá Team butia@fing.edu.uy
+# Butia is a free and open robotic platform
+# www.fing.edu.uy/inco/proyectos/butia
+# Facultad de Ingeniería - Universidad de la República - Uruguay
+#
+# 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 of the License, 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
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+NULL_BYTE = 0x00
+DEFAULT_PACKET_SIZE = 0x04
+GET_USER_MODULES_SIZE_COMMAND = 0x05
+GET_USER_MODULE_LINE_COMMAND = 0x06
+GET_HANDLER_SIZE_COMMAND = 0x0A
+GET_HANDLER_TYPE_COMMAND = 0x0B
+ADMIN_HANDLER_SEND_COMMAND = 0x00
+CLOSEALL_BASE_BOARD_COMMAND = 0x07
+SWITCH_TO_BOOT_BASE_BOARD_COMMAND = 0x09
+RESET_BASE_BOARD_COMMAND = 0xFF
+
+ADMIN_MODULE_IN_ENDPOINT = 0x01
+ADMIN_MODULE_OUT_ENDPOINT = 0x81
+GET_USER_MODULE_LINE_PACKET_SIZE = 0x05
+
+GET_LINES_RESPONSE_PACKET_SIZE = 5
+GET_LINE_RESPONSE_PACKET_SIZE = 12
+GET_HANDLER_TYPE_PACKET_SIZE = 5
+GET_HANDLER_RESPONSE_PACKET_SIZE = 5
+CLOSEALL_BASE_BOARD_RESPONSE_PACKET_SIZE = 5
+
+ERROR = -1
+
+class Baseboard():
+
+ def __init__(self, dev, debug=False):
+ self.dev = dev
+ self.debug = debug
+ self.listi = {}
+ self.devices = {}
+ self.openables_loaded = []
+
+ def open_baseboard(self):
+ """
+ Open the baseboard
+ """
+ self.dev.open_device()
+
+ def close_baseboard(self):
+ """
+ Close the baseboard
+ """
+ self.dev.close_device()
+
+ def get_info(self):
+ """
+ Get baseboard info: manufacture..
+ """
+ return self.dev.get_info()
+
+ def add_device(self, handler, device):
+ """
+ Add a device with handler: handler to the dictionary
+ """
+ self.devices[handler] = device
+
+ def reset_device_list(self):
+ """
+ Cleans the device dictionary
+ """
+ self.devices = {}
+
+ def add_openable_loaded(self, name):
+ """
+ Add the name of device that was opened to prevent open twice
+ """
+ if not(name in self.openables_loaded):
+ self.openables_loaded.append(name)
+
+ def get_openables_loaded(self):
+ """
+ Get the list of modules that was openened (no pnp)
+ """
+ return self.openables_loaded
+
+ def reset_openables_loaded(self):
+ """
+ Reset the list of openables modules
+ """
+ self.openables_loaded = []
+
+ def add_to_listi(self, number, name):
+ """
+ Add a device to listi
+ """
+ self.listi[number] = name
+
+ def get_listi(self):
+ """
+ Get the listi: the list of modules present in the board that can be
+ opened (or pnp module opens)
+ """
+ if (self.listi == {}):
+ self.generate_listi()
+ return self.listi
+
+ def generate_listi(self):
+ """
+ Generate the listi: the list of modules present in the board that can be
+ opened (or pnp module opens)
+ """
+ self.listi = {}
+ try:
+ s = self.get_user_modules_size()
+ for m in range(s):
+ name = self.get_user_module_line(m)
+ self.listi[m] = name
+ except:
+ self.listi = {}
+ if self.debug:
+ print 'error listi'
+
+ def get_device_handler(self, name):
+ """
+ Get the handler of device with name: name
+ """
+ for e in self.devices:
+ if self.devices[e].name == name:
+ return e
+ return ERROR
+
+ def get_device_name(self, handler):
+ """
+ Get the name of device with handler: handler
+ """
+ if self.devices.has_key(handler):
+ return self.devices[handler].name
+ else:
+ return ''
+
+ def get_user_modules_size(self):
+ """
+ Get the size of the list of user modules (listi)
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(DEFAULT_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(GET_USER_MODULES_SIZE_COMMAND)
+ self.dev.write(w)
+
+ raw = self.dev.read(GET_USER_MODULE_LINE_PACKET_SIZE)
+
+ if self.debug:
+ print 'baseboard:get_user_modules_size return', raw
+
+ return raw[4]
+
+ def get_user_module_line(self, index):
+ """
+ Get the name of device with index: index (listi)
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(GET_USER_MODULE_LINE_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(GET_USER_MODULE_LINE_COMMAND)
+ w.append(index)
+ self.dev.write(w)
+
+ raw = self.dev.read(GET_LINE_RESPONSE_PACKET_SIZE)
+
+ if self.debug:
+ print 'baseboard:get_user_module_line return', raw
+
+ c = raw[4:len(raw)]
+ t = ''
+ for e in c:
+ if not(e == NULL_BYTE):
+ t = t + chr(e)
+
+ return t
+
+ def get_handler_size(self):
+ """
+ Get the number of handlers opened
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(DEFAULT_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(GET_HANDLER_SIZE_COMMAND)
+ self.dev.write(w)
+
+ raw = self.dev.read(GET_HANDLER_RESPONSE_PACKET_SIZE)
+
+ if self.debug:
+ print 'baseboard:get_handler_size return', raw
+
+ return raw[4]
+
+ def get_handler_type(self, index):
+ """
+ Get the type of the handler: index (return listi index)
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(GET_HANDLER_TYPE_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(GET_HANDLER_TYPE_COMMAND)
+ w.append(index)
+ self.dev.write(w)
+
+ raw = self.dev.read(GET_HANDLER_RESPONSE_PACKET_SIZE)
+
+ if self.debug:
+ print 'baseboard:get_handler_type return', raw
+
+ return raw[4]
+
+ def switch_to_bootloader(self):
+ """
+ Admin module command to switch to bootloader
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(DEFAULT_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(SWITCH_TO_BOOT_BASE_BOARD_COMMAND)
+ self.dev.write(w)
+
+ def reset(self):
+ """
+ Admin module command to reset the board
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(DEFAULT_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(RESET_BASE_BOARD_COMMAND)
+ self.dev.write(w)
+
+ def force_close_all(self):
+ """
+ Admin module command to force close all opened modules
+ """
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(DEFAULT_PACKET_SIZE)
+ w.append(NULL_BYTE)
+ w.append(CLOSEALL_BASE_BOARD_COMMAND)
+ self.dev.write(w)
+
+ raw = self.dev.read(CLOSEALL_BASE_BOARD_RESPONSE_PACKET_SIZE)
+
+ if self.debug:
+ print 'baseboard:force_close_all return', raw
+
+ return raw[4]
+
+
diff --git a/pybot/com_usb.py b/pybot/com_usb.py
new file mode 100755
index 0000000..54305ba
--- /dev/null
+++ b/pybot/com_usb.py
@@ -0,0 +1,127 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# USB comunication with USB4butia (USB4all) board
+#
+# Copyright (c) 2012-2013 Butiá Team butia@fing.edu.uy
+# Butia is a free and open robotic platform
+# www.fing.edu.uy/inco/proyectos/butia
+# Facultad de Ingeniería - Universidad de la República - Uruguay
+#
+# 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 of the License, 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
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+import usb
+
+USB4ALL_VENDOR = 0x04d8
+USB4ALL_PRODUCT = 0x000c
+USB4ALL_CONFIGURATION = 1
+USB4ALL_INTERFACE = 0
+
+ADMIN_MODULE_IN_ENDPOINT = 0x01
+ADMIN_MODULE_OUT_ENDPOINT = 0x81
+
+READ_HEADER_SIZE = 3
+
+TIMEOUT = 250
+
+ERROR = -1
+
+class usb_device():
+
+ def __init__(self, dev):
+ self.device = dev
+ self.handle = None
+ self.debug = True
+
+ def open_device(self):
+ """
+ Open the baseboard, configure the interface
+ """
+ try:
+ self.handle = self.device.open()
+ self.handle.setConfiguration(USB4ALL_CONFIGURATION)
+ self.handle.claimInterface(USB4ALL_INTERFACE)
+ except usb.USBError, err:
+ if self.debug:
+ print err
+ self.handle = None
+ raise
+ return self.handle
+
+ def close_device(self):
+ """
+ Close the comunication with the baseboard
+ """
+ try:
+ if self.handle:
+ self.handle.releaseInterface()
+ except Exception, err:
+ if self.debug:
+ print err
+ raise
+ self.handle = None
+ self.device = None
+
+ def read(self, length):
+ """
+ Read from the device length bytes
+ """
+ try:
+ return self.handle.bulkRead(ADMIN_MODULE_OUT_ENDPOINT, length, TIMEOUT)
+ except:
+ if self.debug:
+ print 'Exception in read usb'
+ raise
+
+ def write(self, data):
+ """
+ Write in the device: data
+ """
+ try:
+ return self.handle.bulkWrite(ADMIN_MODULE_IN_ENDPOINT, data, TIMEOUT)
+ except:
+ if self.debug:
+ print 'Exception in write usb'
+ raise
+
+ def get_info(self):
+ """
+ Get the device info such as manufacturer, etc
+ """
+ try:
+ names = self.handle.getString(1, 255)
+ copy = self.handle.getString(2, 255)
+ sn = self.handle.getString(3, 255)
+ return [names, copy, sn]
+ except Exception, err:
+ if self.debug:
+ print 'Exception in get_info', err
+ raise
+
+def find():
+ """
+ List all busses and returns a list of baseboards detected
+ """
+ l = []
+ try:
+ for bus in usb.busses():
+ for dev in bus.devices:
+ if dev.idVendor == USB4ALL_VENDOR and dev.idProduct == USB4ALL_PRODUCT:
+ l.append(usb_device(dev))
+ except Exception, err:
+ if self.debug:
+ print 'find gives the error:', err
+ return l
+
diff --git a/pybot/device.py b/pybot/device.py
new file mode 100755
index 0000000..81a9e57
--- /dev/null
+++ b/pybot/device.py
@@ -0,0 +1,154 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Device abstraction for USB4butia
+#
+# Copyright (c) 2012-2013 Butiá Team butia@fing.edu.uy
+# Butia is a free and open robotic platform
+# www.fing.edu.uy/inco/proyectos/butia
+# Facultad de Ingeniería - Universidad de la República - Uruguay
+#
+# 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 of the License, 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
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+NULL_BYTE = 0x00
+OPEN_COMMAND = 0x00
+CLOSE_COMMAND = 0x01
+HEADER_PACKET_SIZE = 0x06
+
+ADMIN_HANDLER_SEND_COMMAND = 0x00
+
+OPEN_RESPONSE_PACKET_SIZE = 5
+CLOSE_RESPONSE_PACKET_SIZE = 2
+
+READ_HEADER_SIZE = 3
+MAX_BYTES = 64
+
+ERROR = -1
+
+class Device():
+
+ def __init__(self, baseboard, name, handler=None):
+ self.baseboard = baseboard
+ self.name = name
+ self.handler = handler
+ if not(self.handler == None):
+ self.handler_tosend = self.handler * 8
+ self.functions = {}
+ self.debug = False
+
+ def add_functions(self, func_list):
+ """
+ Add the functions to current device
+ """
+ for f in func_list:
+ self.functions[f['name']] = f
+
+ def module_send(self, call, params_length, params):
+ """
+ Send to the device the specifiy call and parameters
+ """
+ if len(params) == 1:
+ if type(params[0]) == str:
+ params = to_ord(params[0])
+
+ send_packet_length = 0x04 + len(params)
+
+ w = []
+ w.append(self.handler_tosend)
+ w.append(send_packet_length)
+ w.append(NULL_BYTE)
+ w.append(call)
+ for p in params:
+ w.append(p)
+
+ self.baseboard.dev.write(w)
+
+ def module_read(self):
+ """
+ Read the device data
+ """
+ raw = self.baseboard.dev.read(MAX_BYTES)
+ if self.debug:
+ print 'device:module_rad return', raw
+ if raw[1] == 5:
+ if raw[4] == 255:
+ return -1
+ else:
+ return raw[4]
+ elif raw[1] == 6:
+ return raw[4] + raw[5] * 256
+ else:
+ ret = ''
+ for r in raw[4:]:
+ if not(r == 0):
+ ret = ret + chr(r)
+ return ret
+
+ def module_open(self):
+ """
+ Open this device. Return the handler
+ """
+ module_name = to_ord(self.name)
+ module_name.append(0)
+
+ open_packet_length = HEADER_PACKET_SIZE + len(module_name)
+
+ module_in_endpoint = 0x01
+ module_out_endpoint = 0x01
+
+ w = []
+ w.append(ADMIN_HANDLER_SEND_COMMAND)
+ w.append(open_packet_length)
+ w.append(NULL_BYTE)
+ w.append(OPEN_COMMAND)
+ w.append(module_in_endpoint)
+ w.append(module_out_endpoint)
+ w = w + module_name
+ self.baseboard.dev.write(w)
+
+ raw = self.baseboard.dev.read(OPEN_RESPONSE_PACKET_SIZE)
+
+ if self.debug:
+ print 'device:module_open return', raw
+
+ h = raw[4]
+ self.handler = h
+ self.handler_tosend = self.handler * 8
+ return h
+
+ def has_function(self, func):
+ """
+ Check if this device has func function
+ """
+ return self.functions.has_key(func)
+
+ def call_function(self, func, params):
+ """
+ Call specify func function with params parameters
+ """
+ self.module_send(self.functions[func]['call'], self.functions[func]['params'], params)
+ return self.module_read()
+
+def to_ord(string):
+ """
+ Useful function to convert characters into ordinal Unicode
+ """
+ s = []
+ for l in string:
+ o = ord(l)
+ if not(o == 0):
+ s.append(o)
+ return s
+
diff --git a/pybot/drivers/admin.py b/pybot/drivers/admin.py
new file mode 100644
index 0000000..5e4e192
--- /dev/null
+++ b/pybot/drivers/admin.py
@@ -0,0 +1,19 @@
+
+RESET = 0xFF
+GET_FIRMWARE_VERSION = 0xFE
+
+f1 = {
+ 'name': 'reset',
+ 'call': RESET,
+ 'params': 0,
+ 'read': 0
+}
+
+f2 = {
+ 'name': 'getVersion',
+ 'call': GET_FIRMWARE_VERSION,
+ 'params': 0,
+ 'read': 1
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/butia.py b/pybot/drivers/butia.py
new file mode 100644
index 0000000..74f6f0f
--- /dev/null
+++ b/pybot/drivers/butia.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x02
+GET_VOLT = 0x03
+
+f1 = {
+ 'name': 'read_ver',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 2
+}
+
+f2 = {
+ 'name': 'get_volt',
+ 'call': GET_VOLT,
+ 'params': 0,
+ 'read': 2
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hackp.py b/pybot/drivers/hackp.py
new file mode 100644
index 0000000..4e9c963
--- /dev/null
+++ b/pybot/drivers/hackp.py
@@ -0,0 +1,40 @@
+
+RD_VERSION = 0x00
+SET_MODE = 0x01
+READ = 0x02
+WRITE = 0x03
+WRITE_PORT = 0x04
+PORT_IN = 0x05
+PORT_OUT = 0x06
+
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'setMode',
+ 'call': SET_MODE,
+ 'params': 2,
+ 'read': 1
+}
+
+f3 = {
+ 'name': 'read',
+ 'call': READ,
+ 'params': 1,
+ 'read': 1
+}
+
+f4 = {
+ 'name': 'write',
+ 'call': WRITE,
+ 'params': 2,
+ 'read': 1
+}
+
+FUNCTIONS = [f1, f2, f3, f4]
+
diff --git a/pybot/drivers/hotplug/button.py b/pybot/drivers/hotplug/button.py
new file mode 100644
index 0000000..f714ecf
--- /dev/null
+++ b/pybot/drivers/hotplug/button.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+GET_VALUE = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'getValue',
+ 'call': GET_VALUE,
+ 'params': 0,
+ 'read': 2
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hotplug/distanc.py b/pybot/drivers/hotplug/distanc.py
new file mode 100644
index 0000000..db7e1c1
--- /dev/null
+++ b/pybot/drivers/hotplug/distanc.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+GET_VALUE = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'getValue',
+ 'call': GET_VALUE,
+ 'params': 0,
+ 'read': 3
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hotplug/grey.py b/pybot/drivers/hotplug/grey.py
new file mode 100644
index 0000000..db7e1c1
--- /dev/null
+++ b/pybot/drivers/hotplug/grey.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+GET_VALUE = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'getValue',
+ 'call': GET_VALUE,
+ 'params': 0,
+ 'read': 3
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hotplug/led.py b/pybot/drivers/hotplug/led.py
new file mode 100644
index 0000000..0703d54
--- /dev/null
+++ b/pybot/drivers/hotplug/led.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+TURN = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'turn',
+ 'call': TURN,
+ 'params': 1,
+ 'read': 1
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hotplug/light.py b/pybot/drivers/hotplug/light.py
new file mode 100644
index 0000000..db7e1c1
--- /dev/null
+++ b/pybot/drivers/hotplug/light.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+GET_VALUE = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'getValue',
+ 'call': GET_VALUE,
+ 'params': 0,
+ 'read': 3
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hotplug/res.py b/pybot/drivers/hotplug/res.py
new file mode 100644
index 0000000..db7e1c1
--- /dev/null
+++ b/pybot/drivers/hotplug/res.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+GET_VALUE = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'getValue',
+ 'call': GET_VALUE,
+ 'params': 0,
+ 'read': 3
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/hotplug/volt.py b/pybot/drivers/hotplug/volt.py
new file mode 100644
index 0000000..db7e1c1
--- /dev/null
+++ b/pybot/drivers/hotplug/volt.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+GET_VALUE = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'getValue',
+ 'call': GET_VALUE,
+ 'params': 0,
+ 'read': 3
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/lback.py b/pybot/drivers/lback.py
new file mode 100644
index 0000000..859eedb
--- /dev/null
+++ b/pybot/drivers/lback.py
@@ -0,0 +1,19 @@
+
+RD_VERSION = 0x00
+SEND_DATA = 0x01
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'send',
+ 'call': SEND_DATA,
+ 'params': 1,
+ 'read': 1
+}
+
+FUNCTIONS = [f1, f2]
diff --git a/pybot/drivers/motors.py b/pybot/drivers/motors.py
new file mode 100644
index 0000000..02421d9
--- /dev/null
+++ b/pybot/drivers/motors.py
@@ -0,0 +1,27 @@
+
+RD_VERSION = 0x00
+SET_VEL_2MTR = 0x01
+SET_VEL_MTR = 0x02
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+f2 = {
+ 'name': 'setvel2mtr',
+ 'call': SET_VEL_2MTR,
+ 'params': 6,
+ 'read': 1
+}
+
+f3 = {
+ 'name': 'setvelmtr',
+ 'call': SET_VEL_MTR,
+ 'params': 4,
+ 'read': 1
+}
+
+FUNCTIONS = [f1, f2, f3]
diff --git a/pybot/drivers/pnp.py b/pybot/drivers/pnp.py
new file mode 100644
index 0000000..3457126
--- /dev/null
+++ b/pybot/drivers/pnp.py
@@ -0,0 +1,11 @@
+
+RD_VERSION = 0x00
+
+f1 = {
+ 'name': 'getVersion',
+ 'call': RD_VERSION,
+ 'params': 0,
+ 'read': 3
+}
+
+FUNCTIONS = [f1]
diff --git a/pybot/pybot_server.py b/pybot/pybot_server.py
new file mode 100755
index 0000000..0b6000d
--- /dev/null
+++ b/pybot/pybot_server.py
@@ -0,0 +1,146 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Pybot server
+#
+# Copyright (c) 2012-2013 Butiá Team butia@fing.edu.uy
+# Butia is a free and open robotic platform
+# www.fing.edu.uy/inco/proyectos/butia
+# Facultad de Ingeniería - Universidad de la República - Uruguay
+#
+# 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 of the License, 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
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import sys
+import select
+import socket
+import usb4butia
+
+argv = sys.argv[:]
+
+PYBOT_HOST = 'localhost'
+PYBOT_PORT = 2009
+BUFSIZ = 1024
+MAX_CLIENTS = 4
+
+
+class Server():
+
+ def __init__(self, debug=False):
+ self.debug = debug
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ self.socket.bind((PYBOT_HOST, PYBOT_PORT))
+ self.socket.listen(MAX_CLIENTS)
+ self.clients = {}
+ self.robot = usb4butia.USB4Butia(self.debug)
+
+ def call_aux(self, modulename, board_number, number, function, params):
+ if modulename == 'lback':
+ par = params
+ else:
+ par = []
+ for e in params:
+ par.append(int(e))
+ return self.robot.callModule(modulename, board_number, number, function, par)
+
+ def init_server(self):
+
+ inputs = [self.socket]
+
+ run = True
+ while run:
+
+ try:
+ inputready,outputready,exceptready = select.select(inputs, [], [])
+ except Exception, err:
+ print 'Error in select', err
+ break
+
+ for s in inputready:
+ if s == self.socket:
+ client, addr = self.socket.accept()
+ print 'New client: ', str(addr)
+ inputs.append(client)
+ self.clients[client] = addr
+ else:
+ data = s.recv(BUFSIZ)
+ if data:
+ result = ''
+ # remove end line characters if become from telnet
+ r = data.replace('\r', '')
+ r = r.replace('\n', '')
+ r = r.split(' ')
+
+ #print 'split', r
+
+ if len(r) > 0:
+ if r[0] == 'QUIT':
+ result = 'BYE'
+ run = False
+ elif r[0] == 'CLIENTS':
+ first = True
+ for c in self.clients:
+ addr = self.clients[c]
+ if first:
+ result = result + str(addr[0]) + ', ' + str(addr[1])
+ first = False
+ else:
+ result = result + '\n' + str(addr[0]) + ', ' + str(addr[1])
+ elif r[0] == 'LIST':
+ l = self.robot.get_modules_list()
+ result = ','.join(l)
+ elif r[0] == 'REFRESH':
+ self.robot.refresh()
+ elif r[0] == 'BUTIA_COUNT':
+ result = self.robot.get_butia_count()
+ elif r[0] == 'CALL':
+ if len(r) >= 3:
+ board = 0
+ number = 0
+ mbn = r[1]
+ if mbn.count('@') > 0:
+ modulename, bn = mbn.split('@')
+ board, number = bn.split(':')
+ else:
+ if mbn.count(':') > 0:
+ modulename, number = mbn.split(':')
+ else:
+ modulename = mbn
+ function = r[2]
+ par = r[3:]
+ result = self.call_aux(modulename, int(board), int(number), function, par)
+
+ result = str(result)
+ try:
+ s.send(result + '\n')
+ except:
+ print 'Send fails'
+
+ else:
+ s.close()
+ inputs.remove(s)
+ self.clients.pop(s)
+
+ print 'Closing server'
+ self.socket.close()
+ self.robot.close()
+
+
+if __name__ == "__main__":
+ if 'DEBUG' in argv:
+ s = Server(True)
+ else:
+ s = Server()
+ s.init_server()
+
diff --git a/pybot/usb/__init__.py b/pybot/usb/__init__.py
new file mode 100644
index 0000000..8909cf2
--- /dev/null
+++ b/pybot/usb/__init__.py
@@ -0,0 +1,92 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+r"""PyUSB - Easy USB access in Python
+
+This package exports the following modules and subpackages:
+
+ core - the main USB implementation
+ legacy - the compatibility layer with 0.x version
+ backend - the support for backend implementations.
+
+Since version 1.0, main PyUSB implementation lives in the 'usb.core'
+module. New applications are encouraged to use it.
+"""
+
+import logging
+import os
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = ['legacy', 'core', 'backend', 'util']
+
+
+def _setup_log():
+ from usb import _debug
+ logger = logging.getLogger('usb')
+ debug_level = os.getenv('PYUSB_DEBUG_LEVEL')
+
+ if debug_level is not None:
+ _debug.enable_tracing(True)
+ filename = os.getenv('PYUSB_LOG_FILENAME')
+
+ LEVELS = {'debug': logging.DEBUG,
+ 'info': logging.INFO,
+ 'warning': logging.WARNING,
+ 'error': logging.ERROR,
+ 'critical': logging.CRITICAL}
+
+ level = LEVELS.get(debug_level, logging.CRITICAL + 10)
+ logger.setLevel(level = level)
+
+ try:
+ handler = logging.FileHandler(filename)
+ except:
+ handler = logging.StreamHandler()
+
+ fmt = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s')
+ handler.setFormatter(fmt)
+ logger.addHandler(handler)
+ else:
+ class NullHandler(logging.Handler):
+ def emit(self, record):
+ pass
+
+ # We set the log level to avoid delegation to the
+ # parent log handler (if there is one).
+ # Thanks to Chris Clark to pointing this out.
+ logger.setLevel(logging.CRITICAL + 10)
+
+ logger.addHandler(NullHandler())
+
+
+_setup_log()
+
+# We import all 'legacy' module symbols to provide compatility
+# with applications that use 0.x versions.
+from usb.legacy import *
diff --git a/pybot/usb/_debug.py b/pybot/usb/_debug.py
new file mode 100644
index 0000000..13b0ced
--- /dev/null
+++ b/pybot/usb/_debug.py
@@ -0,0 +1,77 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = ['methodtrace', 'functiontrace']
+
+import logging
+import usb._interop as _interop
+
+_enable_tracing = False
+
+def enable_tracing(enable):
+ global _enable_tracing
+ _enable_tracing = enable
+
+def _trace_function_call(logger, fname, *args, **named_args):
+ logger.debug(
+ # TODO: check if 'f' is a method or a free function
+ fname + '(' + \
+ ', '.join((str(val) for val in args)) + \
+ ', '.join((name + '=' + str(val) for name, val in named_args.items())) + ')'
+ )
+
+# decorator for methods calls tracing
+def methodtrace(logger):
+ def decorator_logging(f):
+ if not _enable_tracing:
+ return f
+ def do_trace(*args, **named_args):
+ # this if is just a optimization to avoid unecessary string formatting
+ if logging.DEBUG >= logger.getEffectiveLevel():
+ fn = type(args[0]).__name__ + '.' + f.__name__
+ _trace_function_call(logger, fn, *args[1:], **named_args)
+ return f(*args, **named_args)
+ _interop._update_wrapper(do_trace, f)
+ return do_trace
+ return decorator_logging
+
+# decorator for methods calls tracing
+def functiontrace(logger):
+ def decorator_logging(f):
+ if not _enable_tracing:
+ return f
+ def do_trace(*args, **named_args):
+ # this if is just a optimization to avoid unecessary string formatting
+ if logging.DEBUG >= logger.getEffectiveLevel():
+ _trace_function_call(logger, f.__name__, *args, **named_args)
+ return f(*args, **named_args)
+ _interop._update_wrapper(do_trace, f)
+ return do_trace
+ return decorator_logging
diff --git a/pybot/usb/_interop.py b/pybot/usb/_interop.py
new file mode 100644
index 0000000..d6d0a6c
--- /dev/null
+++ b/pybot/usb/_interop.py
@@ -0,0 +1,137 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+# All the hacks necessary to assure compatibility across all
+# supported versions come here.
+# Please, note that there is one version check for each
+# hack we need to do, this makes maintenance easier... ^^
+
+import sys
+import array
+
+__all__ = ['_reduce', '_set', '_next', '_groupby', '_sorted', '_update_wrapper']
+
+# we support Python >= 2.3
+assert sys.hexversion >= 0x020300f0
+
+# On Python 3, reduce became a functools module function
+try:
+ import functools
+ _reduce = functools.reduce
+except (ImportError, AttributeError):
+ _reduce = reduce
+
+# we only have the builtin set type since 2.5 version
+try:
+ _set = set
+except NameError:
+ import sets
+ _set = sets.Set
+
+# On Python >= 2.6, we have the builtin next() function
+# On Python 2.5 and before, we have to call the iterator method next()
+def _next(iter):
+ try:
+ return next(iter)
+ except NameError:
+ return iter.next()
+
+# groupby is available only since 2.4 version
+try:
+ import itertools
+ _groupby = itertools.groupby
+except (ImportError, AttributeError):
+ # stolen from Python docs
+ class _groupby(object):
+ # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
+ # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
+ def __init__(self, iterable, key=None):
+ if key is None:
+ key = lambda x: x
+ self.keyfunc = key
+ self.it = iter(iterable)
+ self.tgtkey = self.currkey = self.currvalue = object()
+ def __iter__(self):
+ return self
+ def next(self):
+ while self.currkey == self.tgtkey:
+ self.currvalue = _next(self.it) # Exit on StopIteration
+ self.currkey = self.keyfunc(self.currvalue)
+ self.tgtkey = self.currkey
+ return (self.currkey, self._grouper(self.tgtkey))
+ def _grouper(self, tgtkey):
+ while self.currkey == tgtkey:
+ yield self.currvalue
+ self.currvalue = _next(self.it) # Exit on StopIteration
+ self.currkey = self.keyfunc(self.currvalue)
+
+# builtin sorted function is only availale since 2.4 version
+try:
+ _sorted = sorted
+except NameError:
+ def _sorted(l, key=None, reverse=False):
+ # sort function on Python 2.3 does not
+ # support 'key' parameter
+ class KeyToCmp(object):
+ def __init__(self, K):
+ self.key = K
+ def __call__(self, x, y):
+ kx = self.key(x)
+ ky = self.key(y)
+ if kx < ky:
+ return reverse and 1 or -1
+ elif kx > ky:
+ return reverse and -1 or 1
+ else:
+ return 0
+ tmp = list(l)
+ tmp.sort(KeyToCmp(key))
+ return tmp
+
+try:
+ import functools
+ _update_wrapper = functools.update_wrapper
+except (ImportError, AttributeError):
+ def _update_wrapper(wrapper, wrapped):
+ wrapper.__name__ = wrapped.__name__
+ wrapper.__module__ = wrapped.__module__
+ wrapper.__doc__ = wrapped.__doc__
+ wrapper.__dict__ = wrapped.__dict__
+
+def as_array(data=None):
+ if data is None:
+ return array.array('B')
+ try:
+ return array.array('B', data)
+ except TypeError:
+ # When you pass a unicode string or a character sequence,
+ # you get a TypeError if first parameter does not match
+ a = array.array('B')
+ a.fromstring(data)
+ return a
+
diff --git a/pybot/usb/backend/__init__.py b/pybot/usb/backend/__init__.py
new file mode 100644
index 0000000..67ee00f
--- /dev/null
+++ b/pybot/usb/backend/__init__.py
@@ -0,0 +1,368 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+r"""usb.backend - Backend interface.
+
+This module exports:
+
+IBackend - backend interface.
+
+Backends are Python objects which implement the IBackend interface.
+The easiest way to do so is inherinting from IBackend.
+
+PyUSB already provides backends for libusb versions 0.1 and 1.0,
+and OpenUSB library. Backends modules included with PyUSB are required to
+export the get_backend() function, which returns an instance of a backend
+object. You can provide your own customized backend if you
+want to. Bellow you find a skeleton of a backend implementation module:
+
+import usb.backend
+
+class MyBackend(usb.backend.IBackend):
+ pass
+
+def get_backend():
+ return MyBackend()
+
+You can use your customized backend by passing it as the backend parameter of the
+usb.core.find() function. For example:
+
+import custom_backend
+import usb.core
+
+myidVendor = 0xfffe
+myidProduct = 0x0001
+
+mybackend = custom_backend.get_backend()
+
+dev = usb.core.find(backend = mybackend, idProduct=myidProduct,
+ idVendor=myidVendor)
+
+For custom backends, you are not required to supply the get_backend() function,
+since the application code will instantiate the backend.
+
+If you do not provide a backend to the find() function, it will use one of the
+defaults backend according to its internal rules. For details, consult the
+find() function documentation.
+"""
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = ['IBackend', 'libusb01', 'libusb10', 'openusb']
+
+def _not_implemented(func):
+ raise NotImplementedError(func.__name__)
+
+class IBackend(object):
+ r"""Backend interface.
+
+ IBackend is the basic interface for backend implementations. By default,
+ the methods of the interface raise a NotImplementedError exception. A
+ backend implementation should replace the methods to provide the funcionality
+ necessary.
+
+ As Python is a dynamic typed language, you are not obligated to inherit from
+ IBackend: everything that bahaves like an IBackend is an IBackend. But you
+ are strongly recommended to do so, inheriting from IBackend provides consistent
+ default behavior.
+ """
+ def enumerate_devices(self):
+ r"""This function is required to return an iterable object which
+ yields an implementation defined device identification for each
+ USB device found in the system.
+
+ The device identification object is used as argument to other methods
+ of the interface.
+ """
+ _not_implemented(self.enumerate_devices)
+
+ def get_device_descriptor(self, dev):
+ r"""Return the device descriptor of the given device.
+
+ The object returned is required to have all the Device Descriptor
+ fields accessible as member variables. They must be convertible (but
+ not required to be equal) to the int type.
+
+ dev is an object yielded by the iterator returned by the enumerate_devices()
+ method.
+ """
+ _not_implemented(self.get_device_descriptor)
+
+ def get_configuration_descriptor(self, dev, config):
+ r"""Return a configuration descriptor of the given device.
+
+ The object returned is required to have all the Configuration Descriptor
+ fields acessible as member variables. They must be convertible (but
+ not required to be equal) to the int type.
+
+ The dev parameter is the already described device identification object.
+ config is the logical index of the configuration (not the bConfigurationValue
+ field). By "logical index" we mean the relative order of the configurations
+ returned by the peripheral as a result of GET_DESCRIPTOR request.
+ """
+ _not_implemented(self.get_configuration_descriptor)
+
+ def get_interface_descriptor(self, dev, intf, alt, config):
+ r"""Return an interface descriptor of the given device.
+
+ The object returned is required to have all the Interface Descriptor
+ fields accessible as member variables. They must be convertible (but
+ not required to be equal) to the int type.
+
+ The dev parameter is the already described device identification object.
+ The intf parameter is the interface logical index (not the bInterfaceNumber field)
+ and alt is the alternate setting logical index (not the bAlternateSetting value).
+ Not every interface has more than one alternate setting. In this case, the alt
+ parameter should be zero. config is the configuration logical index (not the
+ bConfigurationValue field).
+ """
+ _not_implemented(self.get_interface_descriptor)
+
+ def get_endpoint_descriptor(self, dev, ep, intf, alt, config):
+ r"""Return an endpoint descriptor of the given device.
+
+ The object returned is required to have all the Endpoint Descriptor
+ fields acessible as member variables. They must be convertible (but
+ not required to be equal) to the int type.
+
+ The ep parameter is the endpoint logical index (not the bEndpointAddress
+ field) of the endpoint descriptor desired. intf, alt and config are the same
+ values already described in the get_interface_descriptor() method.
+ """
+ _not_implemented(self.get_endpoint_descriptor)
+
+ def open_device(self, dev):
+ r"""Open the device for data exchange.
+
+ This method opens the device identified by the dev parameter for communication.
+ This method must be called before calling any communication related method, such
+ as transfer methods.
+
+ It returns a handle identifying the communication instance. This handle must be
+ passed to the communication methods.
+ """
+ _not_implemented(self.open_device)
+
+ def close_device(self, dev_handle):
+ r"""Close the device handle.
+
+ This method closes the device communication channel and releases any
+ system resources related to it.
+ """
+ _not_implemented(self.close_device)
+
+ def set_configuration(self, dev_handle, config_value):
+ r"""Set the active device configuration.
+
+ This method should be called to set the active configuration
+ of the device. The dev_handle parameter is the value returned
+ by the open_device() method and the config_value parameter is the
+ bConfigurationValue field of the related configuration descriptor.
+ """
+ _not_implemented(self.set_configuration)
+
+ def get_configuration(self, dev_handle):
+ r"""Get the current active device configuration.
+
+ This method returns the bConfigurationValue of the currently
+ active configuration. Depending on the backend and the OS,
+ either a cached value may be returned or a control request may
+ be issued. The dev_handle parameter is the value returned by
+ the open_device method.
+ """
+ _not_implemented(self.get_configuration)
+
+ def set_interface_altsetting(self, dev_handle, intf, altsetting):
+ r"""Set the interface alternate setting.
+
+ This method should only be called when the interface has more than
+ one alternate setting. The dev_handle is the value returned by the
+ open_device() method. intf and altsetting are respectivelly the
+ bInterfaceNumber and bAlternateSetting fields of the related interface.
+ """
+ _not_implemented(self.set_interface_altsetting)
+
+ def claim_interface(self, dev_handle, intf):
+ r"""Claim the given interface.
+
+ Interface claiming is not related to USB spec itself, but it is
+ generally an necessary call of the USB libraries. It requests exclusive
+ access to the interface on the system. This method must be called
+ before using one of the transfer methods.
+
+ dev_handle is the value returned by the open_device() method and
+ intf is the bInterfaceNumber field of the desired interface.
+ """
+ _not_implemented(self.claim_interface)
+
+ def release_interface(self, dev_handle, intf):
+ r"""Release the claimed interface.
+
+ dev_handle and intf are the same parameters of the claim_interface
+ method.
+ """
+ _not_implemented(self.release_interface)
+
+ def bulk_write(self, dev_handle, ep, intf, data, timeout):
+ r"""Perform a bulk write.
+
+ dev_handle is the value returned by the open_device() method.
+ The ep parameter is the bEndpointAddress field whose endpoint
+ the data will be sent to. intf is the bInterfaceNumber field
+ of the interface containing the endpoint. The data parameter
+ is the data to be sent. It must be an instance of the array.array
+ class. The timeout parameter specifies a time limit to the operation
+ in miliseconds.
+
+ The method returns the number of bytes written.
+ """
+ _not_implemented(self.bulk_write)
+
+ def bulk_read(self, dev_handle, ep, intf, size, timeout):
+ r"""Perform a bulk read.
+
+ dev_handle is the value returned by the open_device() method.
+ The ep parameter is the bEndpointAddress field whose endpoint
+ the data will be received from. intf is the bInterfaceNumber field
+ of the interface containing the endpoint. The size parameter
+ is the number of bytes to be read. The timeout parameter specifies
+ a time limit to the operation in miliseconds.
+
+ The method returns an array.array object containing the data read.
+ """
+ _not_implemented(self.bulk_read)
+
+ def intr_write(self, dev_handle, ep, intf, data, timeout):
+ r"""Perform an interrupt write.
+
+ dev_handle is the value returned by the open_device() method.
+ The ep parameter is the bEndpointAddress field whose endpoint
+ the data will be sent to. intf is the bInterfaceNumber field
+ of the interface containing the endpoint. The data parameter
+ is the data to be sent. It must be an instance of the array.array
+ class. The timeout parameter specifies a time limit to the operation
+ in miliseconds.
+
+ The method returns the number of bytes written.
+ """
+ _not_implemented(self.intr_write)
+
+ def intr_read(self, dev_handle, ep, intf, size, timeout):
+ r"""Perform an interrut read.
+
+ dev_handle is the value returned by the open_device() method.
+ The ep parameter is the bEndpointAddress field whose endpoint
+ the data will be received from. intf is the bInterfaceNumber field
+ of the interface containing the endpoint. The size parameter
+ is the number of bytes to be read. The timeout parameter specifies
+ a time limit to the operation in miliseconds.
+
+ The method returns an array.array object containing the data read.
+ """
+ _not_implemented(self.intr_read)
+
+ def iso_write(self, dev_handle, ep, intf, data, timeout):
+ r"""Perform an isochronous write.
+
+ dev_handle is the value returned by the open_device() method.
+ The ep parameter is the bEndpointAddress field whose endpoint
+ the data will be sent to. intf is the bInterfaceNumber field
+ of the interface containing the endpoint. The data parameter
+ is the data to be sent.It must be an instance of the array.array
+ class. The timeout parameter specifies a time limit to the operation
+ in miliseconds.
+
+ The method returns the number of bytes written.
+ """
+ _not_implemented(self.iso_write)
+
+ def iso_read(self, dev_handle, ep, intf, size, timeout):
+ r"""Perform an isochronous read.
+
+ dev_handle is the value returned by the open_device() method.
+ The ep parameter is the bEndpointAddress field whose endpoint
+ the data will be received from. intf is the bInterfaceNumber field
+ of the interface containing the endpoint. The size parameter
+ is the number of bytes to be read. The timeout parameter specifies
+ a time limit to the operation in miliseconds.
+
+ The method returns an array.array object containing the data read.
+ """
+ _not_implemented(self.iso_read)
+
+ def ctrl_transfer(self,
+ dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ data_or_wLength,
+ timeout):
+ r"""Perform a control transfer on the endpoint 0.
+
+ The direction of the transfer is inferred from the bmRequestType
+ field of the setup packet.
+
+ dev_handle is the value returned by the open_device() method.
+ bmRequestType, bRequest, wValue and wIndex are the same fields
+ of the setup packet. data_or_wLength is either the payload to be sent
+ to the device, if any, as an array.array object (None there is no
+ payload) for OUT requests in the data stage or the wLength field
+ specifying the number of bytes to read for IN requests in the data
+ stage. The timeout parameter specifies a time limit to the operation
+ in miliseconds.
+
+ Return the number of bytes written (for OUT transfers) or the data
+ read (for IN transfers), as an array.array object.
+ """
+ _not_implemented(self.ctrl_transfer)
+
+ def reset_device(self, dev_handle):
+ r"""Reset the device."""
+ _not_implemented(self.reset_device)
+
+ def is_kernel_driver_active(self, dev_handle, intf):
+ r"""Determine if a kernel driver is active on an interface.
+
+ If a kernel driver is active, you cannot claim the interface,
+ and the backend will be unable to perform I/O.
+ """
+ _not_implemented(self.is_kernel_driver_active)
+
+ def detach_kernel_driver(self, dev_handle, intf):
+ r"""Detach a kernel driver from an interface.
+
+ If successful, you will then be able to claim the interface
+ and perform I/O.
+ """
+ _not_implemented(self.detach_kernel_driver)
+
+ def attach_kernel_driver(self, dev_handle, intf):
+ r"""Re-attach an interface's kernel driver, which was previously
+ detached using detach_kernel_driver()."""
+ _not_implemented(self.attach_kernel_driver)
diff --git a/pybot/usb/backend/libusb0.py b/pybot/usb/backend/libusb0.py
new file mode 100644
index 0000000..a9271c6
--- /dev/null
+++ b/pybot/usb/backend/libusb0.py
@@ -0,0 +1,586 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+from ctypes import *
+import ctypes.util
+import os
+import usb.backend
+import usb.util
+import sys
+from usb.core import USBError
+from usb._debug import methodtrace
+import usb._interop as _interop
+import logging
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = ['get_backend']
+
+_logger = logging.getLogger('usb.backend.libusb0')
+
+# usb.h
+
+_PC_PATH_MAX = 4
+
+if sys.platform.find('bsd') != -1 or sys.platform.find('mac') != -1 or \
+ sys.platform.find('darwin') != -1:
+ _PATH_MAX = 1024
+elif sys.platform == 'win32' or sys.platform == 'cygwin':
+ _PATH_MAX = 511
+else:
+ _PATH_MAX = os.pathconf('.', _PC_PATH_MAX)
+
+# libusb-win32 makes all structures packed, while
+# default libusb only does for some structures
+# _PackPolicy defines the structure packing according
+# to the platform.
+class _PackPolicy(object):
+ pass
+
+if sys.platform == 'win32' or sys.platform == 'cygwin':
+ _PackPolicy._pack_ = 1
+
+# Data structures
+
+class _usb_descriptor_header(Structure):
+ _pack_ = 1
+ _fields_ = [('blength', c_uint8),
+ ('bDescriptorType', c_uint8)]
+
+class _usb_string_descriptor(Structure):
+ _pack_ = 1
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('wData', c_uint16)]
+
+class _usb_endpoint_descriptor(Structure, _PackPolicy):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bEndpointAddress', c_uint8),
+ ('bmAttributes', c_uint8),
+ ('wMaxPacketSize', c_uint16),
+ ('bInterval', c_uint8),
+ ('bRefresh', c_uint8),
+ ('bSynchAddress', c_uint8),
+ ('extra', POINTER(c_uint8)),
+ ('extralen', c_int)]
+
+class _usb_interface_descriptor(Structure, _PackPolicy):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bInterfaceNumber', c_uint8),
+ ('bAlternateSetting', c_uint8),
+ ('bNumEndpoints', c_uint8),
+ ('bInterfaceClass', c_uint8),
+ ('bInterfaceSubClass', c_uint8),
+ ('bInterfaceProtocol', c_uint8),
+ ('iInterface', c_uint8),
+ ('endpoint', POINTER(_usb_endpoint_descriptor)),
+ ('extra', POINTER(c_uint8)),
+ ('extralen', c_int)]
+
+class _usb_interface(Structure, _PackPolicy):
+ _fields_ = [('altsetting', POINTER(_usb_interface_descriptor)),
+ ('num_altsetting', c_int)]
+
+class _usb_config_descriptor(Structure, _PackPolicy):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('wTotalLength', c_uint16),
+ ('bNumInterfaces', c_uint8),
+ ('bConfigurationValue', c_uint8),
+ ('iConfiguration', c_uint8),
+ ('bmAttributes', c_uint8),
+ ('bMaxPower', c_uint8),
+ ('interface', POINTER(_usb_interface)),
+ ('extra', POINTER(c_uint8)),
+ ('extralen', c_int)]
+
+class _usb_device_descriptor(Structure, _PackPolicy):
+ _pack_ = 1
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bcdUSB', c_uint16),
+ ('bDeviceClass', c_uint8),
+ ('bDeviceSubClass', c_uint8),
+ ('bDeviceProtocol', c_uint8),
+ ('bMaxPacketSize0', c_uint8),
+ ('idVendor', c_uint16),
+ ('idProduct', c_uint16),
+ ('bcdDevice', c_uint16),
+ ('iManufacturer', c_uint8),
+ ('iProduct', c_uint8),
+ ('iSerialNumber', c_uint8),
+ ('bNumConfigurations', c_uint8)]
+
+class _usb_device(Structure, _PackPolicy):
+ pass
+
+class _usb_bus(Structure, _PackPolicy):
+ pass
+
+_usb_device._fields_ = [('next', POINTER(_usb_device)),
+ ('prev', POINTER(_usb_device)),
+ ('filename', c_int8 * (_PATH_MAX + 1)),
+ ('bus', POINTER(_usb_bus)),
+ ('descriptor', _usb_device_descriptor),
+ ('config', POINTER(_usb_config_descriptor)),
+ ('dev', c_void_p),
+ ('devnum', c_uint8),
+ ('num_children', c_ubyte),
+ ('children', POINTER(POINTER(_usb_device)))]
+
+_usb_bus._fields_ = [('next', POINTER(_usb_bus)),
+ ('prev', POINTER(_usb_bus)),
+ ('dirname', c_char * (_PATH_MAX + 1)),
+ ('devices', POINTER(_usb_device)),
+ ('location', c_uint32),
+ ('root_dev', POINTER(_usb_device))]
+
+_usb_dev_handle = c_void_p
+
+class _DeviceDescriptor:
+ def __init__(self, dev):
+ desc = dev.descriptor
+ self.bLength = desc.bLength
+ self.bDescriptorType = desc.bDescriptorType
+ self.bcdUSB = desc.bcdUSB
+ self.bDeviceClass = desc.bDeviceClass
+ self.bDeviceSubClass = desc.bDeviceSubClass
+ self.bDeviceProtocol = desc.bDeviceProtocol
+ self.bMaxPacketSize0 = desc.bMaxPacketSize0
+ self.idVendor = desc.idVendor
+ self.idProduct = desc.idProduct
+ self.bcdDevice = desc.bcdDevice
+ self.iManufacturer = desc.iManufacturer
+ self.iProduct = desc.iProduct
+ self.iSerialNumber = desc.iSerialNumber
+ self.bNumConfigurations = desc.bNumConfigurations
+ self.address = dev.devnum
+ self.bus = dev.bus[0].location
+
+ self.port_number = None
+_lib = None
+
+def _load_library():
+ if sys.platform != 'cygwin':
+ candidates = ('usb-0.1', 'usb', 'libusb0')
+ for candidate in candidates:
+ libname = ctypes.util.find_library(candidate)
+ if libname is not None: break
+ else:
+ # corner cases
+ # cygwin predefines library names with 'cyg' instead of 'lib'
+ try:
+ return CDLL('cygusb0.dll')
+ except:
+ _logger.error('Libusb 0 could not be loaded in cygwin', exc_info=True)
+
+ raise OSError('USB library could not be found')
+ return CDLL(libname)
+
+def _setup_prototypes(lib):
+ # usb_dev_handle *usb_open(struct usb_device *dev);
+ lib.usb_open.argtypes = [POINTER(_usb_device)]
+ lib.usb_open.restype = _usb_dev_handle
+
+ # int usb_close(usb_dev_handle *dev);
+ lib.usb_close.argtypes = [_usb_dev_handle]
+
+ # int usb_get_string(usb_dev_handle *dev,
+ # int index,
+ # int langid,
+ # char *buf,
+ # size_t buflen);
+ lib.usb_get_string.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_int,
+ c_char_p,
+ c_size_t
+ ]
+
+ # int usb_get_string_simple(usb_dev_handle *dev,
+ # int index,
+ # char *buf,
+ # size_t buflen);
+ lib.usb_get_string_simple.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_char_p,
+ c_size_t
+ ]
+
+ # int usb_get_descriptor_by_endpoint(usb_dev_handle *udev,
+ # int ep,
+ # unsigned char type,
+ # unsigned char index,
+ # void *buf,
+ # int size);
+ lib.usb_get_descriptor_by_endpoint.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_ubyte,
+ c_ubyte,
+ c_void_p,
+ c_int
+ ]
+
+ # int usb_get_descriptor(usb_dev_handle *udev,
+ # unsigned char type,
+ # unsigned char index,
+ # void *buf,
+ # int size);
+ lib.usb_get_descriptor.argtypes = [
+ _usb_dev_handle,
+ c_ubyte,
+ c_ubyte,
+ c_void_p,
+ c_int
+ ]
+
+ # int usb_bulk_write(usb_dev_handle *dev,
+ # int ep,
+ # const char *bytes,
+ # int size,
+ # int timeout);
+ lib.usb_bulk_write.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_char_p,
+ c_int,
+ c_int
+ ]
+
+ # int usb_bulk_read(usb_dev_handle *dev,
+ # int ep,
+ # char *bytes,
+ # int size,
+ # int timeout);
+ lib.usb_bulk_read.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_char_p,
+ c_int,
+ c_int
+ ]
+
+ # int usb_interrupt_write(usb_dev_handle *dev,
+ # int ep,
+ # const char *bytes,
+ # int size,
+ # int timeout);
+ lib.usb_interrupt_write.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_char_p,
+ c_int,
+ c_int
+ ]
+
+ # int usb_interrupt_read(usb_dev_handle *dev,
+ # int ep,
+ # char *bytes,
+ # int size,
+ # int timeout);
+ lib.usb_interrupt_read.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_char_p,
+ c_int,
+ c_int
+ ]
+
+ # int usb_control_msg(usb_dev_handle *dev,
+ # int requesttype,
+ # int request,
+ # int value,
+ # int index,
+ # char *bytes,
+ # int size,
+ # int timeout);
+ lib.usb_control_msg.argtypes = [
+ _usb_dev_handle,
+ c_int,
+ c_int,
+ c_int,
+ c_int,
+ c_char_p,
+ c_int,
+ c_int
+ ]
+
+ # int usb_set_configuration(usb_dev_handle *dev, int configuration);
+ lib.usb_set_configuration.argtypes = [_usb_dev_handle, c_int]
+
+ # int usb_claim_interface(usb_dev_handle *dev, int interface);
+ lib.usb_claim_interface.argtypes = [_usb_dev_handle, c_int]
+
+ # int usb_release_interface(usb_dev_handle *dev, int interface);
+ lib.usb_release_interface.argtypes = [_usb_dev_handle, c_int]
+
+ # int usb_set_altinterface(usb_dev_handle *dev, int alternate);
+ lib.usb_set_altinterface.argtypes = [_usb_dev_handle, c_int]
+
+ # int usb_resetep(usb_dev_handle *dev, unsigned int ep);
+ lib.usb_resetep.argtypes = [_usb_dev_handle, c_int]
+
+ # int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
+ lib.usb_clear_halt.argtypes = [_usb_dev_handle, c_int]
+
+ # int usb_reset(usb_dev_handle *dev);
+ lib.usb_reset.argtypes = [_usb_dev_handle]
+
+ # char *usb_strerror(void);
+ lib.usb_strerror.argtypes = []
+ lib.usb_strerror.restype = c_char_p
+
+ # void usb_set_debug(int level);
+ lib.usb_set_debug.argtypes = [c_int]
+
+ # struct usb_device *usb_device(usb_dev_handle *dev);
+ lib.usb_device.argtypes = [_usb_dev_handle]
+ lib.usb_device.restype = POINTER(_usb_device)
+
+ # struct usb_bus *usb_get_busses(void);
+ lib.usb_get_busses.restype = POINTER(_usb_bus)
+
+def _check(retval):
+ if retval is None:
+ errmsg = _lib.usb_strerror()
+ else:
+ ret = int(retval)
+ if ret < 0:
+ errmsg = _lib.usb_strerror()
+ # No error means that we need to get the error
+ # message from the return code
+ # Thanks to Nicholas Wheeler to point out the problem...
+ # Also see issue #2860940
+ if errmsg.lower() == 'no error':
+ errmsg = os.strerror(-ret)
+ else:
+ return ret
+ raise USBError(errmsg, ret)
+
+# implementation of libusb 0.1.x backend
+class _LibUSB(usb.backend.IBackend):
+ @methodtrace(_logger)
+ def enumerate_devices(self):
+ _check(_lib.usb_find_busses())
+ _check(_lib.usb_find_devices())
+ bus = _lib.usb_get_busses()
+ while bool(bus):
+ dev = bus[0].devices
+ while bool(dev):
+ yield dev[0]
+ dev = dev[0].next
+ bus = bus[0].next
+
+ @methodtrace(_logger)
+ def get_device_descriptor(self, dev):
+ return _DeviceDescriptor(dev)
+
+ @methodtrace(_logger)
+ def get_configuration_descriptor(self, dev, config):
+ if config >= dev.descriptor.bNumConfigurations:
+ raise IndexError('Invalid configuration index ' + str(config))
+ return dev.config[config]
+
+ @methodtrace(_logger)
+ def get_interface_descriptor(self, dev, intf, alt, config):
+ cfgdesc = self.get_configuration_descriptor(dev, config)
+ if intf >= cfgdesc.bNumInterfaces:
+ raise IndexError('Invalid interface index ' + str(interface))
+ interface = cfgdesc.interface[intf]
+ if alt >= interface.num_altsetting:
+ raise IndexError('Invalid alternate setting index ' + str(alt))
+ return interface.altsetting[alt]
+
+ @methodtrace(_logger)
+ def get_endpoint_descriptor(self, dev, ep, intf, alt, config):
+ interface = self.get_interface_descriptor(dev, intf, alt, config)
+ if ep >= interface.bNumEndpoints:
+ raise IndexError('Invalid endpoint index ' + str(ep))
+ return interface.endpoint[ep]
+
+ @methodtrace(_logger)
+ def open_device(self, dev):
+ return _check(_lib.usb_open(dev))
+
+ @methodtrace(_logger)
+ def close_device(self, dev_handle):
+ _check(_lib.usb_close(dev_handle))
+
+ @methodtrace(_logger)
+ def set_configuration(self, dev_handle, config_value):
+ _check(_lib.usb_set_configuration(dev_handle, config_value))
+
+ @methodtrace(_logger)
+ def set_interface_altsetting(self, dev_handle, intf, altsetting):
+ _check(_lib.usb_set_altinterface(dev_handle, altsetting))
+
+ @methodtrace(_logger)
+ def get_configuration(self, dev_handle):
+ bmRequestType = usb.util.build_request_type(
+ usb.util.CTRL_IN,
+ usb.util.CTRL_TYPE_STANDARD,
+ usb.util.CTRL_RECIPIENT_DEVICE
+ )
+ return self.ctrl_transfer(dev_handle,
+ bmRequestType,
+ 0x08,
+ 0,
+ 0,
+ 1,
+ 100
+ )[0]
+
+
+ @methodtrace(_logger)
+ def claim_interface(self, dev_handle, intf):
+ _check(_lib.usb_claim_interface(dev_handle, intf))
+
+ @methodtrace(_logger)
+ def release_interface(self, dev_handle, intf):
+ _check(_lib.usb_release_interface(dev_handle, intf))
+
+ @methodtrace(_logger)
+ def bulk_write(self, dev_handle, ep, intf, data, timeout):
+ return self.__write(_lib.usb_bulk_write,
+ dev_handle,
+ ep,
+ intf,
+ data, timeout)
+
+ @methodtrace(_logger)
+ def bulk_read(self, dev_handle, ep, intf, size, timeout):
+ return self.__read(_lib.usb_bulk_read,
+ dev_handle,
+ ep,
+ intf,
+ size,
+ timeout)
+
+ @methodtrace(_logger)
+ def intr_write(self, dev_handle, ep, intf, data, timeout):
+ return self.__write(_lib.usb_interrupt_write,
+ dev_handle,
+ ep,
+ intf,
+ data,
+ timeout)
+
+ @methodtrace(_logger)
+ def intr_read(self, dev_handle, ep, intf, size, timeout):
+ return self.__read(_lib.usb_interrupt_read,
+ dev_handle,
+ ep,
+ intf,
+ size,
+ timeout)
+
+ @methodtrace(_logger)
+ def ctrl_transfer(self,
+ dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ data_or_wLength,
+ timeout):
+ if usb.util.ctrl_direction(bmRequestType) == usb.util.CTRL_OUT:
+ address, length = data_or_wLength.buffer_info()
+ length *= data_or_wLength.itemsize
+ return _check(_lib.usb_control_msg(
+ dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ cast(address, c_char_p),
+ length,
+ timeout
+ ))
+ else:
+ data = _interop.as_array((0,) * data_or_wLength)
+ read = int(_check(_lib.usb_control_msg(
+ dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ cast(data.buffer_info()[0],
+ c_char_p),
+ data_or_wLength,
+ timeout
+ )))
+ return data[:read]
+
+ @methodtrace(_logger)
+ def reset_device(self, dev_handle):
+ _check(_lib.usb_reset(dev_handle))
+
+ @methodtrace(_logger)
+ def detach_kernel_driver(self, dev_handle, intf):
+ _check(_lib.usb_detach_kernel_driver_np(dev_handle, intf))
+
+ def __write(self, fn, dev_handle, ep, intf, data, timeout):
+ address, length = data.buffer_info()
+ length *= data.itemsize
+ return int(_check(fn(
+ dev_handle,
+ ep,
+ cast(address, c_char_p),
+ length,
+ timeout
+ )))
+
+ def __read(self, fn, dev_handle, ep, intf, size, timeout):
+ data = _interop.as_array((0,) * size)
+ address, length = data.buffer_info()
+ length *= data.itemsize
+ ret = int(_check(fn(
+ dev_handle,
+ ep,
+ cast(address, c_char_p),
+ length,
+ timeout
+ )))
+ return data[:ret]
+
+def get_backend():
+ global _lib
+ try:
+ if _lib is None:
+ _lib = _load_library()
+ _setup_prototypes(_lib)
+ _lib.usb_init()
+ return _LibUSB()
+ except Exception:
+ _logger.error('Error loading libusb 0.1 backend', exc_info=True)
+ return None
diff --git a/pybot/usb/backend/libusb1.py b/pybot/usb/backend/libusb1.py
new file mode 100644
index 0000000..bd7d16f
--- /dev/null
+++ b/pybot/usb/backend/libusb1.py
@@ -0,0 +1,670 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+from ctypes import *
+import ctypes.util
+import usb.util
+import sys
+import logging
+from usb._debug import methodtrace
+import usb._interop as _interop
+import errno
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = [
+ 'get_backend',
+ 'LIBUSB_SUCESS',
+ 'LIBUSB_ERROR_IO',
+ 'LIBUSB_ERROR_INVALID_PARAM',
+ 'LIBUSB_ERROR_ACCESS',
+ 'LIBUSB_ERROR_NO_DEVICE',
+ 'LIBUSB_ERROR_NOT_FOUND',
+ 'LIBUSB_ERROR_BUSY',
+ 'LIBUSB_ERROR_TIMEOUT',
+ 'LIBUSB_ERROR_OVERFLOW',
+ 'LIBUSB_ERROR_PIPE',
+ 'LIBUSB_ERROR_INTERRUPTED',
+ 'LIBUSB_ERROR_NO_MEM',
+ 'LIBUSB_ERROR_NOT_SUPPORTED',
+ 'LIBUSB_ERROR_OTHER'
+ ]
+
+_logger = logging.getLogger('usb.backend.libusb1')
+
+# libusb.h
+
+# return codes
+
+LIBUSB_SUCCESS = 0
+LIBUSB_ERROR_IO = -1
+LIBUSB_ERROR_INVALID_PARAM = -2
+LIBUSB_ERROR_ACCESS = -3
+LIBUSB_ERROR_NO_DEVICE = -4
+LIBUSB_ERROR_NOT_FOUND = -5
+LIBUSB_ERROR_BUSY = -6
+LIBUSB_ERROR_TIMEOUT = -7
+LIBUSB_ERROR_OVERFLOW = -8
+LIBUSB_ERROR_PIPE = -9
+LIBUSB_ERROR_INTERRUPTED = -10
+LIBUSB_ERROR_NO_MEM = -11
+LIBUSB_ERROR_NOT_SUPPORTED = -12
+LIBUSB_ERROR_OTHER = -99
+
+# map return codes to strings
+_str_error = {
+ LIBUSB_SUCCESS:'Success (no error)',
+ LIBUSB_ERROR_IO:'Input/output error',
+ LIBUSB_ERROR_INVALID_PARAM:'Invalid parameter',
+ LIBUSB_ERROR_ACCESS:'Access denied (insufficient permissions)',
+ LIBUSB_ERROR_NO_DEVICE:'No such device (it may have been disconnected)',
+ LIBUSB_ERROR_NOT_FOUND:'Entity not found',
+ LIBUSB_ERROR_BUSY:'Resource busy',
+ LIBUSB_ERROR_TIMEOUT:'Operation timed out',
+ LIBUSB_ERROR_OVERFLOW:'Overflow',
+ LIBUSB_ERROR_PIPE:'Pipe error',
+ LIBUSB_ERROR_INTERRUPTED:'System call interrupted (perhaps due to signal)',
+ LIBUSB_ERROR_NO_MEM:'Insufficient memory',
+ LIBUSB_ERROR_NOT_SUPPORTED:'Operation not supported or unimplemented on this platform',
+ LIBUSB_ERROR_OTHER:'Unknown error'
+}
+
+# map return code to errno values
+_libusb_errno = {
+ LIBUSB_SUCCESS:None,
+ LIBUSB_ERROR_IO:errno.__dict__.get('EIO', None),
+ LIBUSB_ERROR_INVALID_PARAM:errno.__dict__.get('EINVAL', None),
+ LIBUSB_ERROR_ACCESS:errno.__dict__.get('EACCES', None),
+ LIBUSB_ERROR_NO_DEVICE:errno.__dict__.get('ENODEV', None),
+ LIBUSB_ERROR_NOT_FOUND:errno.__dict__.get('ENOENT', None),
+ LIBUSB_ERROR_BUSY:errno.__dict__.get('EBUSY', None),
+ LIBUSB_ERROR_TIMEOUT:errno.__dict__.get('ETIMEDOUT', None),
+ LIBUSB_ERROR_OVERFLOW:errno.__dict__.get('EOVERFLOW', None),
+ LIBUSB_ERROR_PIPE:errno.__dict__.get('EPIPE', None),
+ LIBUSB_ERROR_INTERRUPTED:errno.__dict__.get('EINTR', None),
+ LIBUSB_ERROR_NO_MEM:errno.__dict__.get('ENOMEM', None),
+ LIBUSB_ERROR_NOT_SUPPORTED:errno.__dict__.get('ENOSYS', None),
+ LIBUSB_ERROR_OTHER:None
+}
+
+# Data structures
+
+class _libusb_endpoint_descriptor(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bEndpointAddress', c_uint8),
+ ('bmAttributes', c_uint8),
+ ('wMaxPacketSize', c_uint16),
+ ('bInterval', c_uint8),
+ ('bRefresh', c_uint8),
+ ('bSynchAddress', c_uint8),
+ ('extra', POINTER(c_ubyte)),
+ ('extra_length', c_int)]
+
+class _libusb_interface_descriptor(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bInterfaceNumber', c_uint8),
+ ('bAlternateSetting', c_uint8),
+ ('bNumEndpoints', c_uint8),
+ ('bInterfaceClass', c_uint8),
+ ('bInterfaceSubClass', c_uint8),
+ ('bInterfaceProtocol', c_uint8),
+ ('iInterface', c_uint8),
+ ('endpoint', POINTER(_libusb_endpoint_descriptor)),
+ ('extra', POINTER(c_ubyte)),
+ ('extra_length', c_int)]
+
+class _libusb_interface(Structure):
+ _fields_ = [('altsetting', POINTER(_libusb_interface_descriptor)),
+ ('num_altsetting', c_int)]
+
+class _libusb_config_descriptor(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('wTotalLength', c_uint16),
+ ('bNumInterfaces', c_uint8),
+ ('bConfigurationValue', c_uint8),
+ ('iConfiguration', c_uint8),
+ ('bmAttributes', c_uint8),
+ ('bMaxPower', c_uint8),
+ ('interface', POINTER(_libusb_interface)),
+ ('extra', POINTER(c_ubyte)),
+ ('extra_length', c_int)]
+
+class _libusb_device_descriptor(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bcdUSB', c_uint16),
+ ('bDeviceClass', c_uint8),
+ ('bDeviceSubClass', c_uint8),
+ ('bDeviceProtocol', c_uint8),
+ ('bMaxPacketSize0', c_uint8),
+ ('idVendor', c_uint16),
+ ('idProduct', c_uint16),
+ ('bcdDevice', c_uint16),
+ ('iManufacturer', c_uint8),
+ ('iProduct', c_uint8),
+ ('iSerialNumber', c_uint8),
+ ('bNumConfigurations', c_uint8)]
+
+_lib = None
+_init = None
+
+_libusb_device_handle = c_void_p
+
+def _load_library():
+ if sys.platform != 'cygwin':
+ candidates = ('usb-1.0', 'libusb-1.0', 'usb')
+ for candidate in candidates:
+ libname = ctypes.util.find_library(candidate)
+ if libname is not None: break
+ else:
+ # corner cases
+ # cygwin predefines library names with 'cyg' instead of 'lib'
+ try:
+ return CDLL('cygusb-1.0.dll')
+ except Exception:
+ _logger.error('Libusb 1.0 could not be loaded in cygwin', exc_info=True)
+
+ raise OSError('USB library could not be found')
+ # Windows backend uses stdcall calling convention
+ if sys.platform == 'win32':
+ l = WinDLL(libname)
+ else:
+ l = CDLL(libname)
+ # On FreeBSD 8/9, libusb 1.0 and libusb 0.1 are in the same shared
+ # object libusb.so, so if we found libusb library name, we must assure
+ # it is 1.0 version. We just try to get some symbol from 1.0 version
+ if not hasattr(l, 'libusb_init'):
+ raise OSError('USB library could not be found')
+ return l
+
+def _setup_prototypes(lib):
+ # void libusb_set_debug (libusb_context *ctx, int level)
+ lib.libusb_set_debug.argtypes = [c_void_p, c_int]
+
+ # int libusb_init (libusb_context **context)
+ lib.libusb_init.argtypes = [POINTER(c_void_p)]
+
+ # void libusb_exit (struct libusb_context *ctx)
+ lib.libusb_exit.argtypes = [c_void_p]
+
+ # ssize_t libusb_get_device_list (libusb_context *ctx,
+ # libusb_device ***list)
+ lib.libusb_get_device_list.argtypes = [
+ c_void_p,
+ POINTER(POINTER(c_void_p))
+ ]
+
+ # void libusb_free_device_list (libusb_device **list,
+ # int unref_devices)
+ lib.libusb_free_device_list.argtypes = [
+ POINTER(c_void_p),
+ c_int
+ ]
+
+ # libusb_device *libusb_ref_device (libusb_device *dev)
+ lib.libusb_ref_device.argtypes = [c_void_p]
+ lib.libusb_ref_device.restype = c_void_p
+
+ # void libusb_unref_device(libusb_device *dev)
+ lib.libusb_unref_device.argtypes = [c_void_p]
+
+ # int libusb_open(libusb_device *dev, libusb_device_handle **handle)
+ lib.libusb_open.argtypes = [c_void_p, POINTER(_libusb_device_handle)]
+
+ # void libusb_close(libusb_device_handle *dev_handle)
+ lib.libusb_close.argtypes = [_libusb_device_handle]
+
+ # int libusb_set_configuration(libusb_device_handle *dev,
+ # int configuration)
+ lib.libusb_set_configuration.argtypes = [_libusb_device_handle, c_int]
+
+ # int libusb_get_configuration(libusb_device_handle *dev,
+ # int *config)
+ lib.libusb_get_configuration.argtypes = [_libusb_device_handle, POINTER(c_int)]
+
+ # int libusb_claim_interface(libusb_device_handle *dev,
+ # int interface_number)
+ lib.libusb_claim_interface.argtypes = [_libusb_device_handle, c_int]
+
+ # int libusb_release_interface(libusb_device_handle *dev,
+ # int interface_number)
+ lib.libusb_release_interface.argtypes = [_libusb_device_handle, c_int]
+
+ # int libusb_set_interface_alt_setting(libusb_device_handle *dev,
+ # int interface_number,
+ # int alternate_setting)
+ lib.libusb_set_interface_alt_setting.argtypes = [
+ _libusb_device_handle,
+ c_int,
+ c_int
+ ]
+
+ # int libusb_reset_device (libusb_device_handle *dev)
+ lib.libusb_reset_device.argtypes = [_libusb_device_handle]
+
+ # int libusb_kernel_driver_active(libusb_device_handle *dev,
+ # int interface)
+ lib.libusb_kernel_driver_active.argtypes = [
+ _libusb_device_handle,
+ c_int
+ ]
+
+ # int libusb_detach_kernel_driver(libusb_device_handle *dev,
+ # int interface)
+ lib.libusb_detach_kernel_driver.argtypes = [
+ _libusb_device_handle,
+ c_int
+ ]
+
+ # int libusb_attach_kernel_driver(libusb_device_handle *dev,
+ # int interface)
+ lib.libusb_attach_kernel_driver.argtypes = [
+ _libusb_device_handle,
+ c_int
+ ]
+
+ # int libusb_get_device_descriptor(
+ # libusb_device *dev,
+ # struct libusb_device_descriptor *desc
+ # )
+ lib.libusb_get_device_descriptor.argtypes = [
+ c_void_p,
+ POINTER(_libusb_device_descriptor)
+ ]
+
+ # int libusb_get_config_descriptor(
+ # libusb_device *dev,
+ # uint8_t config_index,
+ # struct libusb_config_descriptor **config
+ # )
+ lib.libusb_get_config_descriptor.argtypes = [
+ c_void_p,
+ c_uint8,
+ POINTER(POINTER(_libusb_config_descriptor))
+ ]
+
+ # void libusb_free_config_descriptor(
+ # struct libusb_config_descriptor *config
+ # )
+ lib.libusb_free_config_descriptor.argtypes = [
+ POINTER(_libusb_config_descriptor)
+ ]
+
+ # int libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
+ # uint8_t desc_index,
+ # unsigned char *data,
+ # int length)
+ lib.libusb_get_string_descriptor_ascii.argtypes = [
+ _libusb_device_handle,
+ c_uint8,
+ POINTER(c_ubyte),
+ c_int
+ ]
+
+ # int libusb_control_transfer(libusb_device_handle *dev_handle,
+ # uint8_t bmRequestType,
+ # uint8_t bRequest,
+ # uint16_t wValue,
+ # uint16_t wIndex,
+ # unsigned char *data,
+ # uint16_t wLength,
+ # unsigned int timeout)
+ lib.libusb_control_transfer.argtypes = [
+ _libusb_device_handle,
+ c_uint8,
+ c_uint8,
+ c_uint16,
+ c_uint16,
+ POINTER(c_ubyte),
+ c_uint16,
+ c_uint
+ ]
+
+ #int libusb_bulk_transfer(
+ # struct libusb_device_handle *dev_handle,
+ # unsigned char endpoint,
+ # unsigned char *data,
+ # int length,
+ # int *transferred,
+ # unsigned int timeout
+ # )
+ lib.libusb_bulk_transfer.argtypes = [
+ _libusb_device_handle,
+ c_ubyte,
+ POINTER(c_ubyte),
+ c_int,
+ POINTER(c_int),
+ c_uint
+ ]
+
+ # int libusb_interrupt_transfer(
+ # libusb_device_handle *dev_handle,
+ # unsigned char endpoint,
+ # unsigned char *data,
+ # int length,
+ # int *actual_length,
+ # unsigned int timeout
+ # );
+ lib.libusb_interrupt_transfer.argtypes = [
+ _libusb_device_handle,
+ c_ubyte,
+ POINTER(c_ubyte),
+ c_int,
+ POINTER(c_int),
+ c_uint
+ ]
+
+ # uint8_t libusb_get_bus_number(libusb_device *dev)
+ lib.libusb_get_bus_number.argtypes = [c_void_p]
+ lib.libusb_get_bus_number.restype = c_uint8
+
+ # uint8_t libusb_get_device_address(libusb_device *dev)
+ lib.libusb_get_device_address.argtypes = [c_void_p]
+ lib.libusb_get_device_address.restype = c_uint8
+ try:
+ # uint8_t libusb_get_port_number(libusb_device *dev)
+ lib.libusb_get_port_number.argtypes = [c_void_p]
+ lib.libusb_get_port_number.restype = c_uint8
+ except AttributeError:
+ pass
+
+# check a libusb function call
+def _check(retval):
+ if isinstance(retval, int):
+ retval = c_int(retval)
+ if isinstance(retval, c_int):
+ if retval.value < 0:
+ from usb.core import USBError
+ ret = retval.value
+ raise USBError(_str_error[ret], ret, _libusb_errno[ret])
+ return retval
+
+# wrap a device
+class _Device(object):
+ def __init__(self, devid):
+ self.devid = _lib.libusb_ref_device(devid)
+ def __del__(self):
+ _lib.libusb_unref_device(self.devid)
+
+# wrap a descriptor and keep a reference to another object
+# Thanks to Thomas Reitmayr.
+class _WrapDescriptor(object):
+ def __init__(self, desc, obj = None):
+ self.obj = obj
+ self.desc = desc
+ def __getattr__(self, name):
+ return getattr(self.desc, name)
+
+# wrap a configuration descriptor
+class _ConfigDescriptor(object):
+ def __init__(self, desc):
+ self.desc = desc
+ def __del__(self):
+ _lib.libusb_free_config_descriptor(self.desc)
+ def __getattr__(self, name):
+ return getattr(self.desc.contents, name)
+
+# initialize and finalize the library
+class _Initializer(object):
+ def __init__(self):
+ _check(_lib.libusb_init(None))
+ def __del__(self):
+ _lib.libusb_exit(None)
+
+
+# iterator for libusb devices
+class _DevIterator(object):
+ def __init__(self):
+ self.dev_list = POINTER(c_void_p)()
+ self.num_devs = _check(_lib.libusb_get_device_list(
+ None,
+ byref(self.dev_list))
+ ).value
+ def __iter__(self):
+ for i in range(self.num_devs):
+ yield _Device(self.dev_list[i])
+ def __del__(self):
+ _lib.libusb_free_device_list(self.dev_list, 1)
+
+# implementation of libusb 1.0 backend
+class _LibUSB(usb.backend.IBackend):
+ @methodtrace(_logger)
+ def enumerate_devices(self):
+ return _DevIterator()
+
+ @methodtrace(_logger)
+ def get_device_descriptor(self, dev):
+ dev_desc = _libusb_device_descriptor()
+ _check(_lib.libusb_get_device_descriptor(dev.devid, byref(dev_desc)))
+ dev_desc.bus = _lib.libusb_get_bus_number(dev.devid)
+ dev_desc.address = _lib.libusb_get_device_address(dev.devid)
+ #Only available i newer versions of libusb
+ try:
+ dev_desc.port_number = _lib.libusb_get_port_number(dev.devid)
+ except AttributeError:
+ dev_desc.port_number = None
+ return dev_desc
+
+ @methodtrace(_logger)
+ def get_configuration_descriptor(self, dev, config):
+ cfg = POINTER(_libusb_config_descriptor)()
+ _check(_lib.libusb_get_config_descriptor(dev.devid,
+ config, byref(cfg)))
+ return _ConfigDescriptor(cfg)
+
+ @methodtrace(_logger)
+ def get_interface_descriptor(self, dev, intf, alt, config):
+ cfg = self.get_configuration_descriptor(dev, config)
+ if intf >= cfg.bNumInterfaces:
+ raise IndexError('Invalid interface index ' + str(intf))
+ i = cfg.interface[intf]
+ if alt >= i.num_altsetting:
+ raise IndexError('Invalid alternate setting index ' + str(alt))
+ return _WrapDescriptor(i.altsetting[alt], cfg)
+
+ @methodtrace(_logger)
+ def get_endpoint_descriptor(self, dev, ep, intf, alt, config):
+ i = self.get_interface_descriptor(dev, intf, alt, config)
+ if ep > i.bNumEndpoints:
+ raise IndexError('Invalid endpoint index ' + str(ep))
+ return _WrapDescriptor(i.endpoint[ep], i)
+
+ @methodtrace(_logger)
+ def open_device(self, dev):
+ handle = _libusb_device_handle()
+ _check(_lib.libusb_open(dev.devid, byref(handle)))
+ return handle
+
+ @methodtrace(_logger)
+ def close_device(self, dev_handle):
+ _lib.libusb_close(dev_handle)
+
+ @methodtrace(_logger)
+ def set_configuration(self, dev_handle, config_value):
+ _check(_lib.libusb_set_configuration(dev_handle, config_value))
+
+ @methodtrace(_logger)
+ def get_configuration(self, dev_handle):
+ config = c_int()
+ _check(_lib.libusb_get_configuration(dev_handle, byref(config)))
+ return config.value
+
+ @methodtrace(_logger)
+ def set_interface_altsetting(self, dev_handle, intf, altsetting):
+ _check(_lib.libusb_set_interface_alt_setting(dev_handle,
+ intf,
+ altsetting))
+
+ @methodtrace(_logger)
+ def claim_interface(self, dev_handle, intf):
+ _check(_lib.libusb_claim_interface(dev_handle, intf))
+
+ @methodtrace(_logger)
+ def release_interface(self, dev_handle, intf):
+ _check(_lib.libusb_release_interface(dev_handle, intf))
+
+ @methodtrace(_logger)
+ def bulk_write(self, dev_handle, ep, intf, data, timeout):
+ return self.__write(_lib.libusb_bulk_transfer,
+ dev_handle,
+ ep,
+ intf,
+ data,
+ timeout)
+
+ @methodtrace(_logger)
+ def bulk_read(self, dev_handle, ep, intf, size, timeout):
+ return self.__read(_lib.libusb_bulk_transfer,
+ dev_handle,
+ ep,
+ intf,
+ size,
+ timeout)
+
+ @methodtrace(_logger)
+ def intr_write(self, dev_handle, ep, intf, data, timeout):
+ return self.__write(_lib.libusb_interrupt_transfer,
+ dev_handle,
+ ep,
+ intf,
+ data,
+ timeout)
+
+ @methodtrace(_logger)
+ def intr_read(self, dev_handle, ep, intf, size, timeout):
+ return self.__read(_lib.libusb_interrupt_transfer,
+ dev_handle,
+ ep,
+ intf,
+ size,
+ timeout)
+
+# TODO: implement isochronous
+# @methodtrace(_logger)
+# def iso_write(self, dev_handle, ep, intf, data, timeout):
+# pass
+
+
+# @methodtrace(_logger)
+# def iso_read(self, dev_handle, ep, intf, size, timeout):
+# pass
+
+ @methodtrace(_logger)
+ def ctrl_transfer(self,
+ dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ data_or_wLength,
+ timeout):
+ if usb.util.ctrl_direction(bmRequestType) == usb.util.CTRL_OUT:
+ buff = data_or_wLength
+ else:
+ buff = _interop.as_array((0,) * data_or_wLength)
+
+ addr, length = buff.buffer_info()
+ length *= buff.itemsize
+
+ ret = _check(_lib.libusb_control_transfer(dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ cast(addr,
+ POINTER(c_ubyte)),
+ length,
+ timeout))
+
+ if usb.util.ctrl_direction(bmRequestType) == usb.util.CTRL_OUT:
+ return ret.value
+ else:
+ return buff[:ret.value]
+
+ @methodtrace(_logger)
+ def reset_device(self, dev_handle):
+ _check(_lib.libusb_reset_device(dev_handle))
+
+ @methodtrace(_logger)
+ def is_kernel_driver_active(self, dev_handle, intf):
+ return bool(_check(_lib.libusb_kernel_driver_active(dev_handle, intf)))
+
+ @methodtrace(_logger)
+ def detach_kernel_driver(self, dev_handle, intf):
+ _check(_lib.libusb_detach_kernel_driver(dev_handle, intf))
+
+ @methodtrace(_logger)
+ def attach_kernel_driver(self, dev_handle, intf):
+ _check(_lib.libusb_attach_kernel_driver(dev_handle, intf))
+
+ def __write(self, fn, dev_handle, ep, intf, data, timeout):
+ address, length = data.buffer_info()
+ length *= data.itemsize
+ transferred = c_int()
+ retval = fn(dev_handle,
+ ep,
+ cast(address, POINTER(c_ubyte)),
+ length,
+ byref(transferred),
+ timeout)
+ # do not assume LIBUSB_ERROR_TIMEOUT means no I/O.
+ if not (transferred.value and retval == LIBUSB_ERROR_TIMEOUT):
+ _check(retval)
+
+ return transferred.value
+
+ def __read(self, fn, dev_handle, ep, intf, size, timeout):
+ data = _interop.as_array((0,) * size)
+ address, length = data.buffer_info()
+ length *= data.itemsize
+ transferred = c_int()
+ retval = fn(dev_handle,
+ ep,
+ cast(address, POINTER(c_ubyte)),
+ length,
+ byref(transferred),
+ timeout)
+ # do not assume LIBUSB_ERROR_TIMEOUT means no I/O.
+ if not (transferred.value and retval == LIBUSB_ERROR_TIMEOUT):
+ _check(retval)
+ return data[:transferred.value]
+
+def get_backend():
+ global _lib, _init
+ try:
+ if _lib is None:
+ _lib = _load_library()
+ _setup_prototypes(_lib)
+ _init = _Initializer()
+ return _LibUSB()
+ except Exception:
+ _logger.error('Error loading libusb 1.0 backend', exc_info=True)
+ return None
diff --git a/pybot/usb/backend/openusb.py b/pybot/usb/backend/openusb.py
new file mode 100644
index 0000000..474eecb
--- /dev/null
+++ b/pybot/usb/backend/openusb.py
@@ -0,0 +1,708 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+from ctypes import *
+import ctypes.util
+import usb.util
+from usb._debug import methodtrace
+import logging
+import errno
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = [
+ 'get_backend'
+ 'OPENUSB_SUCCESS'
+ 'OPENUSB_PLATFORM_FAILURE'
+ 'OPENUSB_NO_RESOURCES'
+ 'OPENUSB_NO_BANDWIDTH'
+ 'OPENUSB_NOT_SUPPORTED'
+ 'OPENUSB_HC_HARDWARE_ERROR'
+ 'OPENUSB_INVALID_PERM'
+ 'OPENUSB_BUSY'
+ 'OPENUSB_BADARG'
+ 'OPENUSB_NOACCESS'
+ 'OPENUSB_PARSE_ERROR'
+ 'OPENUSB_UNKNOWN_DEVICE'
+ 'OPENUSB_INVALID_HANDLE'
+ 'OPENUSB_SYS_FUNC_FAILURE'
+ 'OPENUSB_NULL_LIST'
+ 'OPENUSB_CB_CONTINUE'
+ 'OPENUSB_CB_TERMINATE'
+ 'OPENUSB_IO_STALL'
+ 'OPENUSB_IO_CRC_ERROR'
+ 'OPENUSB_IO_DEVICE_HUNG'
+ 'OPENUSB_IO_REQ_TOO_BIG'
+ 'OPENUSB_IO_BIT_STUFFING'
+ 'OPENUSB_IO_UNEXPECTED_PID'
+ 'OPENUSB_IO_DATA_OVERRUN'
+ 'OPENUSB_IO_DATA_UNDERRUN'
+ 'OPENUSB_IO_BUFFER_OVERRUN'
+ 'OPENUSB_IO_BUFFER_UNDERRUN'
+ 'OPENUSB_IO_PID_CHECK_FAILURE'
+ 'OPENUSB_IO_DATA_TOGGLE_MISMATCH'
+ 'OPENUSB_IO_TIMEOUT'
+ 'OPENUSB_IO_CANCELED'
+ ]
+
+_logger = logging.getLogger('usb.backend.openusb')
+
+OPENUSB_SUCCESS = 0
+OPENUSB_PLATFORM_FAILURE = -1
+OPENUSB_NO_RESOURCES = -2
+OPENUSB_NO_BANDWIDTH = -3
+OPENUSB_NOT_SUPPORTED = -4
+OPENUSB_HC_HARDWARE_ERROR = -5
+OPENUSB_INVALID_PERM = -6
+OPENUSB_BUSY = -7
+OPENUSB_BADARG = -8
+OPENUSB_NOACCESS = -9
+OPENUSB_PARSE_ERROR = -10
+OPENUSB_UNKNOWN_DEVICE = -11
+OPENUSB_INVALID_HANDLE = -12
+OPENUSB_SYS_FUNC_FAILURE = -13
+OPENUSB_NULL_LIST = -14
+OPENUSB_CB_CONTINUE = -20
+OPENUSB_CB_TERMINATE = -21
+OPENUSB_IO_STALL = -50
+OPENUSB_IO_CRC_ERROR = -51
+OPENUSB_IO_DEVICE_HUNG = -52
+OPENUSB_IO_REQ_TOO_BIG = -53
+OPENUSB_IO_BIT_STUFFING = -54
+OPENUSB_IO_UNEXPECTED_PID = -55
+OPENUSB_IO_DATA_OVERRUN = -56
+OPENUSB_IO_DATA_UNDERRUN = -57
+OPENUSB_IO_BUFFER_OVERRUN = -58
+OPENUSB_IO_BUFFER_UNDERRUN = -59
+OPENUSB_IO_PID_CHECK_FAILURE = -60
+OPENUSB_IO_DATA_TOGGLE_MISMATCH = -61
+OPENUSB_IO_TIMEOUT = -62
+OPENUSB_IO_CANCELED = -63
+
+_openusb_errno = {
+ OPENUSB_SUCCESS:None,
+ OPENUSB_PLATFORM_FAILURE:None,
+ OPENUSB_NO_RESOURCES:errno.__dict__.get('ENOMEM', None),
+ OPENUSB_NO_BANDWIDTH:None,
+ OPENUSB_NOT_SUPPORTED:errno.__dict__.get('ENOSYS', None),
+ OPENUSB_HC_HARDWARE_ERROR:errno.__dict__.get('EIO', None),
+ OPENUSB_INVALID_PERM:errno.__dict__.get('EBADF', None),
+ OPENUSB_BUSY:errno.__dict__.get('EBUSY', None),
+ OPENUSB_BADARG:errno.__dict__.get('EINVAL', None),
+ OPENUSB_NOACCESS:errno.__dict__.get('EACCES', None),
+ OPENUSB_PARSE_ERROR:None,
+ OPENUSB_UNKNOWN_DEVICE:errno.__dict__.get('ENODEV', None),
+ OPENUSB_INVALID_HANDLE:errno.__dict__.get('EINVAL', None),
+ OPENUSB_SYS_FUNC_FAILURE:None,
+ OPENUSB_NULL_LIST:None,
+ OPENUSB_CB_CONTINUE:None,
+ OPENUSB_CB_TERMINATE:None,
+ OPENUSB_IO_STALL:errno.__dict__.get('EIO', None),
+ OPENUSB_IO_CRC_ERROR:errno.__dict__.get('EIO', None),
+ OPENUSB_IO_DEVICE_HUNG:errno.__dict__.get('EIO', None),
+ OPENUSB_IO_REQ_TOO_BIG:errno.__dict__.get('E2BIG', None),
+ OPENUSB_IO_BIT_STUFFING:None,
+ OPENUSB_IO_UNEXPECTED_PID:errno.__dict__.get('ESRCH', None),
+ OPENUSB_IO_DATA_OVERRUN:errno.__dict__.get('EOVERFLOW', None),
+ OPENUSB_IO_DATA_UNDERRUN:None,
+ OPENUSB_IO_BUFFER_OVERRUN:errno.__dict__.get('EOVERFLOW', None),
+ OPENUSB_IO_BUFFER_UNDERRUN:None,
+ OPENUSB_IO_PID_CHECK_FAILURE:None,
+ OPENUSB_IO_DATA_TOGGLE_MISMATCH:None,
+ OPENUSB_IO_TIMEOUT:errno.__dict__.get('ETIMEDOUT', None),
+ OPENUSB_IO_CANCELED:errno.__dict__.get('EINTR', None)
+}
+
+class _usb_endpoint_desc(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bEndpointAddress', c_uint8),
+ ('bmAttributes', c_uint8),
+ ('wMaxPacketSize', c_uint16),
+ ('bInterval', c_uint8),
+ ('bRefresh', c_uint8),
+ ('bSynchAddress', c_uint8)]
+
+class _usb_interface_desc(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bInterfaceNumber', c_uint8),
+ ('bAlternateSetting', c_uint8),
+ ('bNumEndpoints', c_uint8),
+ ('bInterfaceClass', c_uint8),
+ ('bInterfaceSubClass', c_uint8),
+ ('bInterfaceProtocol', c_uint8),
+ ('iInterface', c_uint8)]
+
+class _usb_config_desc(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('wTotalLength', c_uint16),
+ ('bNumInterfaces', c_uint8),
+ ('bConfigurationValue', c_uint8),
+ ('iConfiguration', c_uint8),
+ ('bmAttributes', c_uint8),
+ ('bMaxPower', c_uint8)]
+
+class _usb_device_desc(Structure):
+ _fields_ = [('bLength', c_uint8),
+ ('bDescriptorType', c_uint8),
+ ('bcdUSB', c_uint16),
+ ('bDeviceClass', c_uint8),
+ ('bDeviceSubClass', c_uint8),
+ ('bDeviceProtocol', c_uint8),
+ ('bMaxPacketSize0', c_uint8),
+ ('idVendor', c_uint16),
+ ('idProduct', c_uint16),
+ ('bcdDevice', c_uint16),
+ ('iManufacturer', c_uint8),
+ ('iProduct', c_uint8),
+ ('iSerialNumber', c_uint8),
+ ('bNumConfigurations', c_uint8)]
+
+class _openusb_request_result(Structure):
+ _fields_ = [('status', c_int32),
+ ('transfered_bytes', c_uint32)]
+
+class _openusb_ctrl_request(Structure):
+ class _openusb_ctrl_setup(Structure):
+ _fields_ = [('bmRequestType', c_uint8),
+ ('bRequest', c_uint8),
+ ('wValue', c_uint16),
+ ('wIndex', c_uint16)]
+ _fields_ = [('payload', POINTER(c_uint8)),
+ ('length', c_uint32),
+ ('timeout', c_uint32),
+ ('flags', c_uint32),
+ ('result', _openusb_request_result),
+ ('next', c_void_p)]
+
+class _openusb_intr_request(Structure):
+ _fields_ = [('interval', c_uint16),
+ ('payload', POINTER(c_uint8)),
+ ('length', c_uint32),
+ ('timeout', c_uint32),
+ ('flags', c_uint32),
+ ('result', _openusb_request_result),
+ ('next', c_void_p)]
+
+class _openusb_bulk_request(Structure):
+ _fields_ = [('payload', POINTER(c_uint8)),
+ ('length', c_uint32),
+ ('timeout', c_uint32),
+ ('flags', c_uint32),
+ ('result', _openusb_request_result),
+ ('next', c_void_p)]
+
+class _openusb_isoc_pkts(Structure):
+ class _openusb_isoc_packet(Structure):
+ _fields_ = [('payload', POINTER(c_uint8)),
+ ('length', c_uint32)]
+ _fields_ = [('num_packets', c_uint32),
+ ('packets', POINTER(_openusb_isoc_packet))]
+
+class _openusb_isoc_request(Structure):
+ _fields_ = [('start_frame', c_uint32),
+ ('flags', c_uint32),
+ ('pkts', _openusb_isoc_pkts),
+ ('isoc_results', POINTER(_openusb_request_result)),
+ ('isoc_status', c_int32),
+ ('next', c_void_p)]
+
+_openusb_devid = c_uint64
+_openusb_busid = c_uint64
+_openusb_handle = c_uint64
+_openusb_dev_handle = c_uint64
+
+_lib = None
+_ctx = None
+
+def _load_library():
+ libname = ctypes.util.find_library('openusb')
+ if libname is None:
+ raise OSError('USB library could not be found')
+ return CDLL(libname)
+
+def _setup_prototypes(lib):
+ # int32_t openusb_init(uint32_t flags , openusb_handle_t *handle);
+ lib.openusb_init.argtypes = [c_uint32, POINTER(_openusb_handle)]
+ lib.openusb_init.restype = c_int32
+
+ # void openusb_fini(openusb_handle_t handle );
+ lib.openusb_fini.argtypes = [_openusb_handle]
+
+ # uint32_t openusb_get_busid_list(openusb_handle_t handle,
+ # openusb_busid_t **busids,
+ # uint32_t *num_busids);
+ lib.openusb_get_busid_list.argtypes = [
+ _openusb_handle,
+ POINTER(POINTER(_openusb_busid)),
+ POINTER(c_uint32)
+ ]
+
+ # void openusb_free_busid_list(openusb_busid_t * busids);
+ lib.openusb_free_busid_list.argtypes = [POINTER(_openusb_busid)]
+
+ # uint32_t openusb_get_devids_by_bus(openusb_handle_t handle,
+ # openusb_busid_t busid,
+ # openusb_devid_t **devids,
+ # uint32_t *num_devids);
+ lib.openusb_get_devids_by_bus.argtypes = [
+ _openusb_handle,
+ _openusb_busid,
+ POINTER(POINTER(_openusb_devid)),
+ POINTER(c_uint32)
+ ]
+
+ lib.openusb_get_devids_by_bus.restype = c_int32
+
+ # void openusb_free_devid_list(openusb_devid_t * devids);
+ lib.openusb_free_devid_list.argtypes = [POINTER(_openusb_devid)]
+
+ # int32_t openusb_open_device(openusb_handle_t handle,
+ # openusb_devid_t devid ,
+ # uint32_t flags,
+ # openusb_dev_handle_t *dev);
+ lib.openusb_open_device.argtypes = [
+ _openusb_handle,
+ _openusb_devid,
+ c_uint32,
+ POINTER(_openusb_dev_handle)
+ ]
+
+ lib.openusb_open_device.restype = c_int32
+
+ # int32_t openusb_close_device(openusb_dev_handle_t dev);
+ lib.openusb_close_device.argtypes = [_openusb_dev_handle]
+ lib.openusb_close_device.restype = c_int32
+
+ # int32_t openusb_set_configuration(openusb_dev_handle_t dev,
+ # uint8_t cfg);
+ lib.openusb_set_configuration.argtypes = [_openusb_dev_handle, c_uint8]
+ lib.openusb_set_configuration.restype = c_int32
+
+ # int32_t openusb_get_configuration(openusb_dev_handle_t dev,
+ # uint8_t *cfg);
+ lib.openusb_get_configuration.argtypes = [_openusb_dev_handle, POINTER(c_uint8)]
+ lib.openusb_get_configuration.restype = c_int32
+
+ # int32_t openusb_claim_interface(openusb_dev_handle_t dev,
+ # uint8_t ifc,
+ # openusb_init_flag_t flags);
+ lib.openusb_claim_interface.argtypes = [
+ _openusb_dev_handle,
+ c_uint8,
+ c_int
+ ]
+
+ lib.openusb_claim_interface.restype = c_int32
+
+ # int32_t openusb_release_interface(openusb_dev_handle_t dev,
+ # uint8_t ifc);
+ lib.openusb_release_interface.argtypes = [
+ _openusb_dev_handle,
+ c_uint8
+ ]
+
+ lib.openusb_release_interface.restype = c_int32
+
+ # int32_topenusb_set_altsetting(openusb_dev_handle_t dev,
+ # uint8_t ifc,
+ # uint8_t alt);
+ lib.openusb_set_altsetting.argtypes = [
+ _openusb_dev_handle,
+ c_uint8,
+ c_uint8
+ ]
+ lib.openusb_set_altsetting.restype = c_int32
+
+ # int32_t openusb_reset(openusb_dev_handle_t dev);
+ lib.openusb_reset.argtypes = [_openusb_dev_handle]
+ lib.openusb_reset.restype = c_int32
+
+ # int32_t openusb_parse_device_desc(openusb_handle_t handle,
+ # openusb_devid_t devid,
+ # uint8_t *buffer,
+ # uint16_t buflen,
+ # usb_device_desc_t *devdesc);
+ lib.openusb_parse_device_desc.argtypes = [
+ _openusb_handle,
+ _openusb_devid,
+ POINTER(c_uint8),
+ c_uint16,
+ POINTER(_usb_device_desc)
+ ]
+
+ lib.openusb_parse_device_desc.restype = c_int32
+
+ # int32_t openusb_parse_config_desc(openusb_handle_t handle,
+ # openusb_devid_t devid,
+ # uint8_t *buffer,
+ # uint16_t buflen,
+ # uint8_t cfgidx,
+ # usb_config_desc_t *cfgdesc);
+ lib.openusb_parse_config_desc.argtypes = [
+ _openusb_handle,
+ _openusb_devid,
+ POINTER(c_uint8),
+ c_uint16,
+ c_uint8,
+ POINTER(_usb_config_desc)
+ ]
+ lib.openusb_parse_config_desc.restype = c_int32
+
+ # int32_t openusb_parse_interface_desc(openusb_handle_t handle,
+ # openusb_devid_t devid,
+ # uint8_t *buffer,
+ # uint16_t buflen,
+ # uint8_t cfgidx,
+ # uint8_t ifcidx,
+ # uint8_t alt,
+ # usb_interface_desc_t *ifcdesc);
+ lib.openusb_parse_interface_desc.argtypes = [
+ _openusb_handle,
+ _openusb_devid,
+ POINTER(c_uint8),
+ c_uint16,
+ c_uint8,
+ c_uint8,
+ c_uint8,
+ POINTER(_usb_interface_desc)
+ ]
+
+ lib.openusb_parse_interface_desc.restype = c_int32
+
+ # int32_t openusb_parse_endpoint_desc(openusb_handle_t handle,
+ # openusb_devid_t devid,
+ # uint8_t *buffer,
+ # uint16_t buflen,
+ # uint8_t cfgidx,
+ # uint8_t ifcidx,
+ # uint8_t alt,
+ # uint8_t eptidx,
+ # usb_endpoint_desc_t *eptdesc);
+ lib.openusb_parse_endpoint_desc.argtypes = [
+ _openusb_handle,
+ _openusb_devid,
+ POINTER(c_uint8),
+ c_uint16,
+ c_uint8,
+ c_uint8,
+ c_uint8,
+ c_uint8,
+ POINTER(_usb_endpoint_desc)
+ ]
+
+ lib.openusb_parse_interface_desc.restype = c_int32
+
+ # const char *openusb_strerror(int32_t error );
+ lib.openusb_strerror.argtypes = [c_int32]
+ lib.openusb_strerror.restype = c_char_p
+
+ # int32_t openusb_ctrl_xfer(openusb_dev_handle_t dev,
+ # uint8_t ifc,
+ # uint8_t ept,
+ # openusb_ctrl_request_t *ctrl);
+ lib.openusb_ctrl_xfer.argtypes = [
+ _openusb_dev_handle,
+ c_uint8,
+ c_uint8,
+ POINTER(_openusb_ctrl_request)
+ ]
+
+ lib.openusb_ctrl_xfer.restype = c_int32
+
+ # int32_t openusb_intr_xfer(openusb_dev_handle_t dev,
+ # uint8_t ifc,
+ # uint8_t ept,
+ # openusb_intr_request_t *intr);
+ lib.openusb_intr_xfer.argtypes = [
+ _openusb_dev_handle,
+ c_uint8,
+ c_uint8,
+ POINTER(_openusb_intr_request)
+ ]
+
+ lib.openusb_bulk_xfer.restype = c_int32
+
+ # int32_t openusb_bulk_xfer(openusb_dev_handle_t dev,
+ # uint8_t ifc,
+ # uint8_t ept,
+ # openusb_bulk_request_t *bulk);
+ lib.openusb_bulk_xfer.argtypes = [
+ _openusb_dev_handle,
+ c_uint8,
+ c_uint8,
+ POINTER(_openusb_bulk_request)
+ ]
+
+ lib.openusb_bulk_xfer.restype = c_int32
+
+ # int32_t openusb_isoc_xfer(openusb_dev_handle_t dev,
+ # uint8_t ifc,
+ # uint8_t ept,
+ # openusb_isoc_request_t *isoc);
+ lib.openusb_isoc_xfer.argtypes = [
+ _openusb_dev_handle,
+ c_uint8,
+ c_uint8,
+ POINTER(_openusb_isoc_request)
+ ]
+
+ lib.openusb_isoc_xfer.restype = c_int32
+
+def _check(retval):
+ ret = retval.value
+ if ret != 0:
+ from usb.core import USBError
+ raise USBError(_lib.openusb_strerror(ret), ret, _openusb_errno[ret])
+ return retval
+
+class _Context(object):
+ def __init__(self):
+ self.handle = _openusb_handle()
+ _check(_lib.openusb_init(0, byref(self.handle)))
+ def __del__(self):
+ _lib.openusb_fini(self.handle)
+
+class _BusIterator(object):
+ def __init__(self):
+ self.buslist = POINTER(openusb_busid)()
+ num_busids = c_uint32()
+ _check(_lib.openusb_get_busid_list(_ctx.handle,
+ byref(self.buslist),
+ byref(num_busids)))
+ self.num_busids = num_busids.value
+ def __iter__(self):
+ for i in range(self.num_busids):
+ yield self.buslist[i]
+ def __del__(self):
+ _lib.openusb_free_busid_list(self.buslist)
+
+class _DevIterator(object):
+ def __init__(self, busid):
+ self.devlist = POINTER(_openusb_devid)()
+ num_devids = c_uint32()
+ _check(_lib.openusb_get_devids_by_bus(_ctx.handle,
+ busid,
+ byref(self.devlist),
+ byref(num_devids)))
+ self.num_devids = num_devids.value
+ def __iter__(self):
+ for i in range(self.num_devids):
+ yield self.devlist[i]
+ def __del__(self):
+ _lib.openusb_free_devid_list(self.devlist)
+
+class _OpenUSB(usb.backend.IBackend):
+ @methodtrace(_logger)
+ def enumerate_devices(self):
+ for bus in _BusIterator():
+ for devid in _DevIterator(bus):
+ yield devid
+
+ @methodtrace(_logger)
+ def get_device_descriptor(self, dev):
+ desc = _usb_device_desc()
+ _check(_lib.openusb_parse_device_desc(_ctx.handle,
+ dev,
+ None,
+ 0,
+ byref(desc)))
+ desc.bus = None
+ desc.address = None
+ desc.port_number = None
+ return desc
+
+ @methodtrace(_logger)
+ def get_configuration_descriptor(self, dev, config):
+ desc = _usb_config_desc()
+ _check(_lib.openusb_parse_config_desc(_ctx.handle,
+ dev,
+ None,
+ 0,
+ config,
+ byref(desc)))
+ return desc
+
+ @methodtrace(_logger)
+ def get_interface_descriptor(self, dev, intf, alt, config):
+ desc = _usb_interface_desc()
+ _check(_lib.openusb_parse_interface_desc(_ctx.handle,
+ dev,
+ None,
+ 0,
+ config,
+ intf,
+ alt,
+ byref(desc)))
+ return desc
+
+ @methodtrace(_logger)
+ def get_endpoint_descriptor(self, dev, ep, intf, alt, config):
+ desc = _usb_endpoint_desc()
+ _check(_lib.openusb_parse_endpoint_desc(_ctx.handle,
+ dev,
+ None,
+ 0,
+ config,
+ intf,
+ alt,
+ ep,
+ byref(desc)))
+ return desc
+
+ @methodtrace(_logger)
+ def open_device(self, dev):
+ handle = _openusb_dev_handle()
+ _check(_lib.openusb_open_device(_ctx.handle, dev, 0, byref(handle)))
+ return handle
+
+ @methodtrace(_logger)
+ def close_device(self, dev_handle):
+ _lib.openusb_close_device(dev_handle)
+
+ @methodtrace(_logger)
+ def set_configuration(self, dev_handle, config_value):
+ _check(_lib.openusb_set_configuration(dev_handle, config_value))
+
+ @methodtrace(_logger)
+ def get_configuration(self, dev_handle):
+ config = c_uint8()
+ _check(_lib.openusb_get_configuration(dev_handle, byref(config)))
+ return config.value
+
+ @methodtrace(_logger)
+ def set_interface_altsetting(self, dev_handle, intf, altsetting):
+ _check(_lib.set_altsetting(dev_handle, intf, altsetting))
+
+ @methodtrace(_logger)
+ def claim_interface(self, dev_handle, intf):
+ _check(_lib.openusb_claim_interface(dev_handle, intf, 0))
+
+ @methodtrace(_logger)
+ def release_interface(self, dev_handle, intf):
+ _lib.openusb_release_interface(dev_handle, intf)
+
+ @methodtrace(_logger)
+ def bulk_write(self, dev_handle, ep, intf, data, timeout):
+ request = _openusb_bulk_request()
+ memset(byref(request), 0, sizeof(request))
+ request.payload, request.length = data.buffer_info()
+ request.timeout = timeout
+ _check(_lib.openusb_bulk_xfer(dev_handle, intf, ep, byref(request)))
+ return request.transfered_bytes.value
+
+ @methodtrace(_logger)
+ def bulk_read(self, dev_handle, ep, intf, size, timeout):
+ request = _openusb_bulk_request()
+ buffer = array.array('B', '\x00' * size)
+ memset(byref(request), 0, sizeof(request))
+ request.payload, request.length = buffer.buffer_info()
+ request.timeout = timeout
+ _check(_lib.openusb_bulk_xfer(dev_handle, intf, ep, byref(request)))
+ return buffer[:request.transfered_bytes.value]
+
+ @methodtrace(_logger)
+ def intr_write(self, dev_handle, ep, intf, data, timeout):
+ request = _openusb_intr_request()
+ memset(byref(request), 0, sizeof(request))
+ payload, request.length = data.buffer_info()
+ request.payload = cast(payload, POINTER(c_uint8))
+ request.timeout = timeout
+ _check(_lib.openusb_intr_xfer(dev_handle, intf, ep, byref(request)))
+ return request.transfered_bytes.value
+
+ @methodtrace(_logger)
+ def intr_read(self, dev_handle, ep, intf, size, timeout):
+ request = _openusb_intr_request()
+ buffer = array.array('B', '\x00' * size)
+ memset(byref(request), 0, sizeof(request))
+ payload, request.length = buffer.buffer_info()
+ request.payload = cast(payload, POINTER(c_uint8))
+ request.timeout = timeout
+ _check(_lib.openusb_intr_xfer(dev_handle, intf, ep, byref(request)))
+ return buffer[:request.transfered_bytes.value]
+
+# TODO: implement isochronous
+# @methodtrace(_logger)
+# def iso_write(self, dev_handle, ep, intf, data, timeout):
+# pass
+
+# @methodtrace(_logger)
+# def iso_read(self, dev_handle, ep, intf, size, timeout):
+# pass
+
+ @methodtrace(_logger)
+ def ctrl_transfer(self,
+ dev_handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ data_or_wLength,
+ timeout):
+ request = _openusb_ctrl_request()
+ request.setup.bmRequestType = bmRequestType
+ request.setup.bRequest = bRequest
+ request.setup.wValue
+ request.setup.wIndex
+ request.timeout = timeout
+
+ direction = usb.util.ctrl_direction(bmRequestType)
+
+ if direction == ENDPOINT_OUT:
+ buffer = data_or_wLength
+ else:
+ buffer = array.array('B', '\x00' * data_or_wLength)
+
+ payload, request.length = buffer.buffer_info()
+ request.payload = cast(payload, POINTER(c_uint8))
+
+ ret = _check(_lib.openusb_ctrl_xfer(dev_handle, 0, 0, byref(request)))
+
+ if direction == ENDPOINT_OUT:
+ ret
+ else:
+ buffer[:ret]
+
+ @methodtrace(_logger)
+ def reset_device(self, dev_handle):
+ _check(_lib.openusb_reset(dev_handle))
+
+def get_backend():
+ try:
+ global _lib, _ctx
+ if _lib is None:
+ _lib = _load_library()
+ _setup_prototypes(_lib)
+ _ctx = _Context()
+ return _OpenUSB()
+ except Exception:
+ _logger.error('Error loading OpenUSB backend', exc_info=True)
+ return None
diff --git a/pybot/usb/control.py b/pybot/usb/control.py
new file mode 100644
index 0000000..8647c14
--- /dev/null
+++ b/pybot/usb/control.py
@@ -0,0 +1,252 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+r"""usb.control - USB standard control requests
+
+This module exports:
+
+get_status - get recipeint status
+clear_feature - clear a recipient feature
+set_feature - set a recipient feature
+get_descriptor - get a device descriptor
+set_descriptor - set a device descriptor
+get_configuration - get a device configuration
+set_configuration - set a device configuration
+get_interface - get a device interface
+set_interface - set a device interface
+"""
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = ['get_status',
+ 'clear_feature',
+ 'set_feature',
+ 'get_descriptor',
+ 'set_descriptor',
+ 'get_configuration',
+ 'set_configuration',
+ 'get_interface',
+ 'set_interface',
+ 'ENDPOINT_HALT',
+ 'FUNCTION_SUSPEND',
+ 'DEVICE_REMOTE_WAKEUP',
+ 'U1_ENABLE',
+ 'U2_ENABLE',
+ 'LTM_ENABLE']
+
+import usb.util as util
+import usb.core as core
+
+def _parse_recipient(recipient, direction):
+ if recipient is None:
+ r = util.CTRL_RECIPIENT_DEVICE
+ wIndex = 0
+ elif isinstance(recipient, core.Interface):
+ r = util.CTRL_RECIPIENT_INTERFACE
+ wIndex = recipient.bInterfaceNumber
+ elif isinstance(recipient, core.Endpoint):
+ r = util.CTRL_RECIPIENT_ENDPOINT
+ wIndex = recipient.bEndpointAddress
+ else:
+ raise ValueError('Invalid recipient.')
+ bmRequestType = util.build_request_type(
+ direction,
+ util.CTRL_TYPE_STANDARD,
+ r
+ )
+ return (bmRequestType, wIndex)
+
+# standard feature selectors from USB 2.0/3.0
+ENDPOINT_HALT = 0
+FUNCTION_SUSPEND = 0
+DEVICE_REMOTE_WAKEUP = 1
+U1_ENABLE = 48
+U2_ENABLE = 49
+LTM_ENABLE = 50
+
+def get_status(dev, recipient = None):
+ r"""Return the status for the specified recipient.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ The recipient can be None (on which the status will be queried
+ on the device), an Interface or Endpoint descriptors.
+
+ The status value is returned as an integer with the lower
+ word being the two bytes status value.
+ """
+ bmRequestType, wIndex = _parse_recipient(recipient, util.CTRL_IN)
+ ret = dev.ctrl_transfer(bmRequestType = bmRequestType,
+ bRequest = 0x00,
+ wIndex = wIndex,
+ data_or_wLength = 2)
+ return ret[0] | (ret[1] << 8)
+
+def clear_feature(dev, feature, recipient = None):
+ r"""Clear/disable a specific feature.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ feature is the feature you want to disable.
+
+ The recipient can be None (on which the status will be queried
+ on the device), an Interface or Endpoint descriptors.
+ """
+ bmRequestType, wIndex = _parse_recipient(recipient, util.CTRL_OUT)
+ dev.ctrl_transfer(bmRequestType = bmRequestType,
+ bRequest = 0x01,
+ wIndex = wIndex,
+ wValue = feature)
+
+def set_feature(dev, feature, recipient = None):
+ r"""Set/enable a specific feature.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ feature is the feature you want to enable.
+
+ The recipient can be None (on which the status will be queried
+ on the device), an Interface or Endpoint descriptors.
+ """
+ bmRequestType, wIndex = _parse_recipient(recipient, util.CTRL_OUT)
+ dev.ctrl_transfer(bmRequestType = bmRequestType,
+ bRequest = 0x03,
+ wIndex = wIndex,
+ wValue = feature)
+
+def get_descriptor(dev, desc_size, desc_type, desc_index, wIndex = 0):
+ r"""Return the specified descriptor.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ desc_size is the descriptor size.
+
+ desc_type and desc_index are the descriptor type and index,
+ respectively. wIndex index is used for string descriptors
+ and represents the Language ID. For other types of descriptors,
+ it is zero.
+ """
+ wValue = desc_index | (desc_type << 8)
+ bmRequestType = util.build_request_type(
+ util.CTRL_IN,
+ util.CTRL_TYPE_STANDARD,
+ util.CTRL_RECIPIENT_DEVICE
+ )
+ return dev.ctrl_transfer(
+ bmRequestType = bmRequestType,
+ bRequest = 0x06,
+ wValue = wValue,
+ wIndex = wIndex,
+ data_or_wLength = desc_size
+ )
+
+def set_descriptor(dev, desc, desc_type, desc_index, wIndex = None):
+ r"""Update an existing descriptor or add a new one.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ The desc parameter is the descriptor to be sent to the device.
+ desc_type and desc_index are the descriptor type and index,
+ respectively. wIndex index is used for string descriptors
+ and represents the Language ID. For other types of descriptors,
+ it is zero.
+ """
+ wValue = desc_index | (desc_type << 8)
+ bmRequestType = util.build_request_type(
+ util.CTRL_OUT,
+ util.CTRL_TYPE_STANDARD,
+ util.CTRL_RECIPIENT_DEVICE
+ )
+ dev.ctrl_transfer(
+ bmRequestType = bmRequestType,
+ bRequest = 0x07,
+ wValue = wValue,
+ wIndex = wIndex,
+ data_or_wLength = desc
+ )
+
+def get_configuration(dev):
+ r"""Get the current active configuration of the device.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ This function differs from the Device.get_active_configuration
+ method because the later may use cached data, while this
+ function always does a device request.
+ """
+ bmRequestType = util.build_request_type(
+ util.CTRL_IN,
+ util.CTRL_TYPE_STANDARD,
+ util.CTRL_RECIPIENT_DEVICE
+ )
+ return dev.ctrl_transfer(
+ bmRequestType,
+ bRequest = 0x08,
+ data_or_wLength = 1
+ )[0]
+
+def set_configuration(dev, bConfigurationNumber):
+ r"""Set the current device configuration.
+
+ dev is the Device object to which the request will be
+ sent to.
+ """
+ dev.set_configuration(bConfigurationNumber)
+
+def get_interface(dev, bInterfaceNumber):
+ r"""Get the current alternate setting of the interface.
+
+ dev is the Device object to which the request will be
+ sent to.
+ """
+ bmRequestType = util.build_request_type(
+ util.CTRL_IN,
+ util.CTRL_TYPE_STANDARD,
+ util.CTRL_RECIPIENT_INTERFACE
+ )
+ return dev.ctrl_transfer(
+ bmRequestType = bmRequestType,
+ bRequest = 0x0a,
+ wIndex = bInterfaceNumber,
+ data_or_wLength = 1
+ )[0]
+
+def set_interface(dev, bInterfaceNumber, bAlternateSetting):
+ r"""Set the alternate setting of the interface.
+
+ dev is the Device object to which the request will be
+ sent to.
+ """
+ dev.set_interface_altsetting(bInterfaceNumber, bAlternateSetting)
+
diff --git a/pybot/usb/core.py b/pybot/usb/core.py
new file mode 100644
index 0000000..597637f
--- /dev/null
+++ b/pybot/usb/core.py
@@ -0,0 +1,871 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+r"""usb.core - Core USB features.
+
+This module exports:
+
+Device - a class representing a USB device.
+Configuration - a class representing a configuration descriptor.
+Interface - a class representing an interface descriptor.
+Endpoint - a class representing an endpoint descriptor.
+find() - a function to find USB devices.
+"""
+
+__author__ = 'Wander Lairson Costa'
+
+__all__ = ['Device', 'Configuration', 'Interface', 'Endpoint', 'find']
+
+import usb.util as util
+import copy
+import operator
+import usb._interop as _interop
+import logging
+
+_logger = logging.getLogger('usb.core')
+
+_DEFAULT_TIMEOUT = 1000
+
+def _set_attr(input, output, fields):
+ for f in fields:
+ setattr(output, f, getattr(input, f))
+
+class _ResourceManager(object):
+ def __init__(self, dev, backend):
+ self.backend = backend
+ self._active_cfg_index = None
+ self.dev = dev
+ self.handle = None
+ self._claimed_intf = _interop._set()
+ self._alt_set = {}
+ self._ep_type_map = {}
+
+ def managed_open(self):
+ if self.handle is None:
+ self.handle = self.backend.open_device(self.dev)
+ return self.handle
+
+ def managed_close(self):
+ if self.handle is not None:
+ self.backend.close_device(self.handle)
+ self.handle = None
+
+ def managed_set_configuration(self, device, config):
+ if config is None:
+ cfg = device[0]
+ elif isinstance(config, Configuration):
+ cfg = config
+ elif config == 0: # unconfigured state
+ class FakeConfiguration(object):
+ def __init__(self):
+ self.index = None
+ self.bConfigurationValue = 0
+ cfg = FakeConfiguration()
+ else:
+ cfg = util.find_descriptor(device, bConfigurationValue=config)
+ self.managed_open()
+ self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
+ # cache the index instead of the object to avoid cyclic references
+ # of the device and Configuration (Device tracks the _ResourceManager,
+ # which tracks the Configuration, which tracks the Device)
+ self._active_cfg_index = cfg.index
+ # after changing configuration, our alternate setting and endpoint type caches
+ # are not valid anymore
+ self._ep_type_map.clear()
+ self._alt_set.clear()
+
+ def managed_claim_interface(self, device, intf):
+ self.managed_open()
+ if intf is None:
+ cfg = self.get_active_configuration(device)
+ i = cfg[(0,0)].bInterfaceNumber
+ elif isinstance(intf, Interface):
+ i = intf.bInterfaceNumber
+ else:
+ i = intf
+ if i not in self._claimed_intf:
+ self.backend.claim_interface(self.handle, i)
+ self._claimed_intf.add(i)
+
+ def managed_release_interface(self, device, intf):
+ if intf is None:
+ cfg = self.get_active_configuration(device)
+ i = cfg[(0,0)].bInterfaceNumber
+ elif isinstance(intf, Interface):
+ i = intf.bInterfaceNumber
+ else:
+ i = intf
+ if i in self._claimed_intf:
+ self.backend.release_interface(self.handle, i)
+ self._claimed_intf.remove(i)
+
+ def managed_set_interface(self, device, intf, alt):
+ if isinstance(intf, Interface):
+ i = intf
+ else:
+ cfg = self.get_active_configuration(device)
+ if intf is None:
+ intf = cfg[(0,0)].bInterfaceNumber
+ if alt is not None:
+ i = util.find_descriptor(cfg, bInterfaceNumber=intf, bAlternateSetting=alt)
+ else:
+ i = util.find_descriptor(cfg, bInterfaceNumber=intf)
+ self.managed_claim_interface(device, i)
+ if alt is None:
+ alt = i.bAlternateSetting
+ self.backend.set_interface_altsetting(self.handle, i.bInterfaceNumber, alt)
+ self._alt_set[i.bInterfaceNumber] = alt
+
+ def get_interface(self, device, intf):
+ # TODO: check the viability of issuing a GET_INTERFACE
+ # request when we don't have a alternate setting cached
+ if isinstance(intf, Interface):
+ return intf
+ else:
+ cfg = self.get_active_configuration(device)
+ if intf is None:
+ intf = cfg[(0,0)].bInterfaceNumber
+ if intf in self._alt_set:
+ return util.find_descriptor(cfg,
+ bInterfaceNumber=intf,
+ bAlternateSetting=self._alt_set[intf])
+ else:
+ return util.find_descriptor(cfg, bInterfaceNumber=intf)
+
+ def get_active_configuration(self, device):
+ if self._active_cfg_index is None:
+ self.managed_open()
+ cfg = util.find_descriptor(
+ device,
+ bConfigurationValue=self.backend.get_configuration(self.handle)
+ )
+ if cfg is None:
+ raise USBError('Configuration not set')
+ self._active_cfg_index = cfg.index
+ return cfg
+ return device[self._active_cfg_index]
+
+ def get_endpoint_type(self, device, address, intf):
+ intf = self.get_interface(device, intf)
+ key = (address, intf.bInterfaceNumber, intf.bAlternateSetting)
+ try:
+ return self._ep_type_map[key]
+ except KeyError:
+ e = util.find_descriptor(intf, bEndpointAddress=address)
+ etype = util.endpoint_type(e.bmAttributes)
+ self._ep_type_map[key] = etype
+ return etype
+
+ def release_all_interfaces(self, device):
+ claimed = copy.copy(self._claimed_intf)
+ for i in claimed:
+ self.managed_release_interface(device, i)
+
+ def dispose(self, device, close_handle = True):
+ self.release_all_interfaces(device)
+ if close_handle:
+ self.managed_close()
+ self._ep_type_map.clear()
+ self._alt_set.clear()
+ self._active_cfg_index = None
+
+class USBError(IOError):
+ r"""Exception class for USB errors.
+
+ Backends must raise this exception when USB related errors occur.
+ The backend specific error code is available through the
+ 'backend_error_code' member variable.
+ """
+
+ def __init__(self, strerror, error_code = None, errno = None):
+ r"""Initialize the object.
+
+ This initializes the USBError object. The strerror and errno are passed
+ to the parent object. The error_code parameter is attributed to the
+ backend_error_code member variable.
+ """
+ IOError.__init__(self, errno, strerror)
+ self.backend_error_code = error_code
+
+class Endpoint(object):
+ r"""Represent an endpoint object.
+
+ This class contains all fields of the Endpoint Descriptor
+ according to the USB Specification. You may access them as class
+ properties. For example, to access the field bEndpointAddress
+ of the endpoint descriptor:
+
+ >>> import usb.core
+ >>> dev = usb.core.find()
+ >>> for cfg in dev:
+ >>> for i in cfg:
+ >>> for e in i:
+ >>> print e.bEndpointAddress
+ """
+
+ def __init__(self, device, endpoint, interface = 0,
+ alternate_setting = 0, configuration = 0):
+ r"""Initialize the Endpoint object.
+
+ The device parameter is the device object returned by the find()
+ function. endpoint is the endpoint logical index (not the endpoint address).
+ The configuration parameter is the logical index of the
+ configuration (not the bConfigurationValue field). The interface
+ parameter is the interface logical index (not the bInterfaceNumber field)
+ and alternate_setting is the alternate setting logical index (not the
+ bAlternateSetting value). Not every interface has more than one alternate
+ setting. In this case, the alternate_setting parameter should be zero.
+ By "logical index" we mean the relative order of the configurations returned by the
+ peripheral as a result of GET_DESCRIPTOR request.
+ """
+ self.device = device
+ intf = Interface(device, interface, alternate_setting, configuration)
+ self.interface = intf.bInterfaceNumber
+ self.index = endpoint
+
+ backend = device._ctx.backend
+
+ desc = backend.get_endpoint_descriptor(
+ device._ctx.dev,
+ endpoint,
+ interface,
+ alternate_setting,
+ configuration
+ )
+
+ _set_attr(
+ desc,
+ self,
+ (
+ 'bLength',
+ 'bDescriptorType',
+ 'bEndpointAddress',
+ 'bmAttributes',
+ 'wMaxPacketSize',
+ 'bInterval',
+ 'bRefresh',
+ 'bSynchAddress'
+ )
+ )
+
+ def write(self, data, timeout = None):
+ r"""Write data to the endpoint.
+
+ The parameter data contains the data to be sent to the endpoint and
+ timeout is the time limit of the operation. The transfer type and
+ endpoint address are automatically inferred.
+
+ The method returns the number of bytes written.
+
+ For details, see the Device.write() method.
+ """
+ return self.device.write(self.bEndpointAddress, data, self.interface, timeout)
+
+ def read(self, size, timeout = None):
+ r"""Read data from the endpoint.
+
+ The parameter size is the number of bytes to read and timeout is the
+ time limit of the operation.The transfer type and endpoint address
+ are automatically inferred.
+
+ The method returns an array.array object with the data read.
+
+ For details, see the Device.read() method.
+ """
+ return self.device.read(self.bEndpointAddress, size, self.interface, timeout)
+
+class Interface(object):
+ r"""Represent an interface object.
+
+ This class contains all fields of the Interface Descriptor
+ according to the USB Specification. You may access them as class
+ properties. For example, to access the field bInterfaceNumber
+ of the interface descriptor:
+
+ >>> import usb.core
+ >>> dev = usb.core.find()
+ >>> for cfg in dev:
+ >>> for i in cfg:
+ >>> print i.bInterfaceNumber
+ """
+
+ def __init__(self, device, interface = 0,
+ alternate_setting = 0, configuration = 0):
+ r"""Initialize the interface object.
+
+ The device parameter is the device object returned by the find()
+ function. The configuration parameter is the logical index of the
+ configuration (not the bConfigurationValue field). The interface
+ parameter is the interface logical index (not the bInterfaceNumber field)
+ and alternate_setting is the alternate setting logical index (not the
+ bAlternateSetting value). Not every interface has more than one alternate
+ setting. In this case, the alternate_setting parameter should be zero.
+ By "logical index" we mean the relative order of the configurations returned by the
+ peripheral as a result of GET_DESCRIPTOR request.
+ """
+ self.device = device
+ self.alternate_index = alternate_setting
+ self.index = interface
+ self.configuration = configuration
+
+ backend = device._ctx.backend
+
+ desc = backend.get_interface_descriptor(
+ self.device._ctx.dev,
+ interface,
+ alternate_setting,
+ configuration
+ )
+
+ _set_attr(
+ desc,
+ self,
+ (
+ 'bLength',
+ 'bDescriptorType',
+ 'bInterfaceNumber',
+ 'bAlternateSetting',
+ 'bNumEndpoints',
+ 'bInterfaceClass',
+ 'bInterfaceSubClass',
+ 'bInterfaceProtocol',
+ 'iInterface',
+ )
+ )
+
+ def set_altsetting(self):
+ r"""Set the interface alternate setting."""
+ self.device.set_interface_altsetting(
+ self.bInterfaceNumber,
+ self.bAlternateSetting
+ )
+
+ def __iter__(self):
+ r"""Iterate over all endpoints of the interface."""
+ for i in range(self.bNumEndpoints):
+ yield Endpoint(
+ self.device,
+ i,
+ self.index,
+ self.alternate_index,
+ self.configuration
+ )
+ def __getitem__(self, index):
+ r"""Return the Endpoint object in the given position."""
+ return Endpoint(
+ self.device,
+ index,
+ self.index,
+ self.alternate_index,
+ self.configuration
+ )
+
+class Configuration(object):
+ r"""Represent a configuration object.
+
+ This class contains all fields of the Configuration Descriptor
+ according to the USB Specification. You may access them as class
+ properties. For example, to access the field bConfigurationValue
+ of the configuration descriptor:
+
+ >>> import usb.core
+ >>> dev = usb.core.find()
+ >>> for cfg in dev:
+ >>> print cfg.bConfigurationValue
+ """
+
+ def __init__(self, device, configuration = 0):
+ r"""Initialize the configuration object.
+
+ The device parameter is the device object returned by the find()
+ function. The configuration parameter is the logical index of the
+ configuration (not the bConfigurationValue field). By "logical index"
+ we mean the relative order of the configurations returned by the
+ peripheral as a result of GET_DESCRIPTOR request.
+ """
+ self.device = device
+ self.index = configuration
+
+ backend = device._ctx.backend
+
+ desc = backend.get_configuration_descriptor(
+ self.device._ctx.dev,
+ configuration
+ )
+
+ _set_attr(
+ desc,
+ self,
+ (
+ 'bLength',
+ 'bDescriptorType',
+ 'wTotalLength',
+ 'bNumInterfaces',
+ 'bConfigurationValue',
+ 'iConfiguration',
+ 'bmAttributes',
+ 'bMaxPower'
+ )
+ )
+
+ def set(self):
+ r"""Set this configuration as the active one."""
+ self.device.set_configuration(self.bConfigurationValue)
+
+ def __iter__(self):
+ r"""Iterate over all interfaces of the configuration."""
+ for i in range(self.bNumInterfaces):
+ alt = 0
+ try:
+ while True:
+ yield Interface(self.device, i, alt, self.index)
+ alt += 1
+ except (USBError, IndexError):
+ pass
+ def __getitem__(self, index):
+ r"""Return the Interface object in the given position.
+
+ index is a tuple of two values with interface index and
+ alternate setting index, respectivally. Example:
+
+ >>> interface = config[(0, 0)]
+ """
+ return Interface(self.device, index[0], index[1], self.index)
+
+
+class Device(object):
+ r"""Device object.
+
+ This class contains all fields of the Device Descriptor according
+ to the USB Specification. You may access them as class properties.
+ For example, to access the field bDescriptorType of the device
+ descriptor:
+
+ >>> import usb.core
+ >>> dev = usb.core.find()
+ >>> dev.bDescriptorType
+
+ Additionally, the class provides methods to communicate with
+ the hardware. Typically, an application will first call the
+ set_configuration() method to put the device in a known configured
+ state, optionally call the set_interface_altsetting() to select the
+ alternate setting (if there is more than one) of the interface used,
+ and call the write() and read() method to send and receive data.
+
+ When working in a new hardware, one first try would be like this:
+
+ >>> import usb.core
+ >>> dev = usb.core.find(idVendor=myVendorId, idProduct=myProductId)
+ >>> dev.set_configuration()
+ >>> dev.write(1, 'test')
+
+ This sample finds the device of interest (myVendorId and myProductId should be
+ replaced by the corresponding values of your device), then configures the device
+ (by default, the configuration value is 1, which is a typical value for most
+ devices) and then writes some data to the endpoint 0x01.
+
+ Timeout values for the write, read and ctrl_transfer methods are specified in
+ miliseconds. If the parameter is omitted, Device.default_timeout value will
+ be used instead. This property can be set by the user at anytime.
+ """
+
+ def __init__(self, dev, backend):
+ r"""Initialize the Device object.
+
+ Library users should normally get a Device instance through
+ the find function. The dev parameter is the identification
+ of a device to the backend and its meaning is opaque outside
+ of it. The backend parameter is a instance of a backend
+ object.
+ """
+ self._ctx = _ResourceManager(dev, backend)
+ self.__default_timeout = _DEFAULT_TIMEOUT
+
+ desc = backend.get_device_descriptor(dev)
+
+ _set_attr(
+ desc,
+ self,
+ (
+ 'bLength',
+ 'bDescriptorType',
+ 'bcdUSB',
+ 'bDeviceClass',
+ 'bDeviceSubClass',
+ 'bDeviceProtocol',
+ 'bMaxPacketSize0',
+ 'idVendor',
+ 'idProduct',
+ 'bcdDevice',
+ 'iManufacturer',
+ 'iProduct',
+ 'iSerialNumber',
+ 'bNumConfigurations',
+ 'address',
+ 'bus',
+ 'port_number'
+ )
+ )
+
+ if desc.bus is not None:
+ self.bus = int(desc.bus)
+ else:
+ self.bus = None
+
+ if desc.address is not None:
+ self.address = int(desc.address)
+ else:
+ self.address = None
+
+ if desc.port_number is not None:
+ self.port_number = int(desc.port_number)
+ else:
+ self.port_number = None
+
+ def set_configuration(self, configuration = None):
+ r"""Set the active configuration.
+
+ The configuration parameter is the bConfigurationValue field of the
+ configuration you want to set as active. If you call this method
+ without parameter, it will use the first configuration found.
+ As a device hardly ever has more than one configuration, calling
+ the method without parameter is enough to get the device ready.
+ """
+ self._ctx.managed_set_configuration(self, configuration)
+
+ def get_active_configuration(self):
+ r"""Return a Configuration object representing the current configuration set."""
+ return self._ctx.get_active_configuration(self)
+
+ def set_interface_altsetting(self, interface = None, alternate_setting = None):
+ r"""Set the alternate setting for an interface.
+
+ When you want to use an interface and it has more than one alternate setting,
+ you should call this method to select the alternate setting you would like
+ to use. If you call the method without one or the two parameters, it will
+ be selected the first one found in the Device in the same way of set_configuration
+ method.
+
+ Commonly, an interface has only one alternate setting and this call is
+ not necessary. For most of the devices, either it has more than one alternate
+ setting or not, it is not harmful to make a call to this method with no arguments,
+ as devices will silently ignore the request when there is only one alternate
+ setting, though the USB Spec allows devices with no additional alternate setting
+ return an error to the Host in response to a SET_INTERFACE request.
+
+ If you are in doubt, you may want to call it with no arguments wrapped by
+ a try/except clause:
+
+ >>> try:
+ >>> dev.set_interface_altsetting()
+ >>> except usb.core.USBError:
+ >>> pass
+ """
+ self._ctx.managed_set_interface(self, interface, alternate_setting)
+
+ def reset(self):
+ r"""Reset the device."""
+ self._ctx.managed_open()
+ self._ctx.dispose(self, False)
+ self._ctx.backend.reset_device(self._ctx.handle)
+ self._ctx.dispose(self, True)
+
+ def write(self, endpoint, data, interface = None, timeout = None):
+ r"""Write data to the endpoint.
+
+ This method is used to send data to the device. The endpoint parameter
+ corresponds to the bEndpointAddress member whose endpoint you want to
+ communicate with. The interface parameter is the bInterfaceNumber field
+ of the interface descriptor which contains the endpoint. If you do not
+ provide one, the first one found will be used, as explained in the
+ set_interface_altsetting() method.
+
+ The data parameter should be a sequence like type convertible to
+ array type (see array module).
+
+ The timeout is specified in miliseconds.
+
+ The method returns the number of bytes written.
+ """
+ backend = self._ctx.backend
+
+ fn_map = {
+ util.ENDPOINT_TYPE_BULK:backend.bulk_write,
+ util.ENDPOINT_TYPE_INTR:backend.intr_write,
+ util.ENDPOINT_TYPE_ISO:backend.iso_write
+ }
+
+ intf = self._ctx.get_interface(self, interface)
+ fn = fn_map[self._ctx.get_endpoint_type(self, endpoint, intf)]
+ self._ctx.managed_claim_interface(self, intf)
+
+ return fn(
+ self._ctx.handle,
+ endpoint,
+ intf.bInterfaceNumber,
+ _interop.as_array(data),
+ self.__get_timeout(timeout)
+ )
+
+ def read(self, endpoint, size, interface = None, timeout = None):
+ r"""Read data from the endpoint.
+
+ This method is used to receive data from the device. The endpoint parameter
+ corresponds to the bEndpointAddress member whose endpoint you want to
+ communicate with. The interface parameter is the bInterfaceNumber field
+ of the interface descriptor which contains the endpoint. If you do not
+ provide one, the first one found will be used, as explained in the
+ set_interface_altsetting() method. The size parameters tells how many
+ bytes you want to read.
+
+ The timeout is specified in miliseconds.
+
+ The method returns an array object with the data read.
+ """
+ backend = self._ctx.backend
+
+ fn_map = {
+ util.ENDPOINT_TYPE_BULK:backend.bulk_read,
+ util.ENDPOINT_TYPE_INTR:backend.intr_read,
+ util.ENDPOINT_TYPE_ISO:backend.iso_read
+ }
+
+ intf = self._ctx.get_interface(self, interface)
+ fn = fn_map[self._ctx.get_endpoint_type(self, endpoint, intf)]
+ self._ctx.managed_claim_interface(self, intf)
+
+ return fn(
+ self._ctx.handle,
+ endpoint,
+ intf.bInterfaceNumber,
+ size,
+ self.__get_timeout(timeout)
+ )
+
+
+ def ctrl_transfer(self, bmRequestType, bRequest, wValue=0, wIndex=0,
+ data_or_wLength = None, timeout = None):
+ r"""Do a control transfer on the endpoint 0.
+
+ This method is used to issue a control transfer over the
+ endpoint 0(endpoint 0 is required to always be a control endpoint).
+
+ The parameters bmRequestType, bRequest, wValue and wIndex are the
+ same of the USB Standard Control Request format.
+
+ Control requests may or may not have a data payload to write/read.
+ In cases which it has, the direction bit of the bmRequestType
+ field is used to infere the desired request direction. For
+ host to device requests (OUT), data_or_wLength parameter is
+ the data payload to send, and it must be a sequence type convertible
+ to an array object. In this case, the return value is the number of data
+ payload written. For device to host requests (IN), data_or_wLength
+ is the wLength parameter of the control request specifying the
+ number of bytes to read in data payload. In this case, the return
+ value is the data payload read, as an array object.
+ """
+ if util.ctrl_direction(bmRequestType) == util.CTRL_OUT:
+ a = _interop.as_array(data_or_wLength)
+ elif data_or_wLength is None:
+ a = 0
+ else:
+ a = data_or_wLength
+
+ self._ctx.managed_open()
+
+ return self._ctx.backend.ctrl_transfer(
+ self._ctx.handle,
+ bmRequestType,
+ bRequest,
+ wValue,
+ wIndex,
+ a,
+ self.__get_timeout(timeout)
+ )
+
+ def is_kernel_driver_active(self, interface):
+ r"""Determine if there is kernel driver associated with the interface.
+
+ If a kernel driver is active, and the object will be unable to perform I/O.
+ """
+ self._ctx.managed_open()
+ return self._ctx.backend.is_kernel_driver_active(self._ctx.handle,
+ self._ctx.get_interface(self, interface).bInterfaceNumber)
+
+ def detach_kernel_driver(self, interface):
+ r"""Detach a kernel driver.
+
+ If successful, you will then be able to perform I/O.
+ """
+ self._ctx.managed_open()
+ self._ctx.backend.detach_kernel_driver(self._ctx.handle,
+ self._ctx.get_interface(self, interface).bInterfaceNumber)
+
+ def attach_kernel_driver(self, interface):
+ r"""Re-attach an interface's kernel driver, which was previously
+ detached using detach_kernel_driver()."""
+ self._ctx.managed_open()
+ self._ctx.backend.attach_kernel_driver(self._ctx.handle,
+ self._ctx.get_interface(self, interface).bInterfaceNumber)
+
+ def __iter__(self):
+ r"""Iterate over all configurations of the device."""
+ for i in range(self.bNumConfigurations):
+ yield Configuration(self, i)
+
+ def __getitem__(self, index):
+ r"""Return the Configuration object in the given position."""
+ return Configuration(self, index)
+
+ def __del__(self):
+ self._ctx.dispose(self)
+
+ def __get_timeout(self, timeout):
+ if timeout is not None:
+ return timeout
+ return self.__default_timeout
+
+ def __set_def_tmo(self, tmo):
+ if tmo < 0:
+ raise ValueError('Timeout cannot be a negative value')
+ self.__default_timeout = tmo
+
+ def __get_def_tmo(self):
+ return self.__default_timeout
+
+ default_timeout = property(
+ __get_def_tmo,
+ __set_def_tmo,
+ doc = 'Default timeout for transfer I/O functions'
+ )
+
+def find(find_all=False, backend = None, custom_match = None, **args):
+ r"""Find an USB device and return it.
+
+ find() is the function used to discover USB devices.
+ You can pass as arguments any combination of the
+ USB Device Descriptor fields to match a device. For example:
+
+ find(idVendor=0x3f4, idProduct=0x2009)
+
+ will return the Device object for the device with
+ idVendor Device descriptor field equals to 0x3f4 and
+ idProduct equals to 0x2009.
+
+ If there is more than one device which matchs the criteria,
+ the first one found will be returned. If a matching device cannot
+ be found the function returns None. If you want to get all
+ devices, you can set the parameter find_all to True, then find
+ will return an list with all matched devices. If no matching device
+ is found, it will return an empty list. Example:
+
+ printers = find(find_all=True, bDeviceClass=7)
+
+ This call will get all the USB printers connected to the system.
+ (actually may be not, because some devices put their class
+ information in the Interface Descriptor).
+
+ You can also use a customized match criteria:
+
+ dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
+
+ A more accurate printer finder using a customized match would be like
+ so:
+
+ def is_printer(dev):
+ import usb.util
+ if dev.bDeviceClass == 7:
+ return True
+ for cfg in dev:
+ if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
+ return True
+
+ printers = find(find_all=True, custom_match = is_printer)
+
+ Now even if the device class code is in the interface descriptor the
+ printer will be found.
+
+ You can combine a customized match with device descriptor fields. In this
+ case, the fields must match and the custom_match must return True. In the our
+ previous example, if we would like to get all printers belonging to the
+ manufacturer 0x3f4, the code would be like so:
+
+ printers = find(find_all=True, idVendor=0x3f4, custom_match=is_printer)
+
+ If you want to use find as a 'list all devices' function, just call
+ it with find_all = True:
+
+ devices = find(find_all=True)
+
+ Finally, you may pass a custom backend to the find function:
+
+ find(backend = MyBackend())
+
+ PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.
+ If you do not supply a backend explicitly, find() function will select
+ one of the predefineds backends according to system availability.
+
+ Backends are explained in the usb.backend module.
+ """
+
+ def device_iter(k, v):
+ for dev in backend.enumerate_devices():
+ d = Device(dev, backend)
+ if _interop._reduce(
+ lambda a, b: a and b,
+ map(
+ operator.eq,
+ v,
+ map(lambda i: getattr(d, i), k)
+ ),
+ True
+ ) and (custom_match is None or custom_match(d)):
+ yield d
+
+ if backend is None:
+ import usb.backend.libusb1 as libusb1
+ import usb.backend.libusb0 as libusb0
+ import usb.backend.openusb as openusb
+
+ for m in (libusb1, openusb, libusb0):
+ backend = m.get_backend()
+ if backend is not None:
+ _logger.info('find(): using backend "%s"', m.__name__)
+ break
+ else:
+ raise ValueError('No backend available')
+
+ k, v = args.keys(), args.values()
+
+ if find_all:
+ return [d for d in device_iter(k, v)]
+ else:
+ try:
+ return _interop._next(device_iter(k, v))
+ except StopIteration:
+ return None
diff --git a/pybot/usb/legacy.py b/pybot/usb/legacy.py
new file mode 100644
index 0000000..9a9fb95
--- /dev/null
+++ b/pybot/usb/legacy.py
@@ -0,0 +1,344 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+import usb.core as core
+import usb.util as util
+import usb._interop as _interop
+import usb.control as control
+
+__author__ = 'Wander Lairson Costa'
+
+USBError = core.USBError
+
+CLASS_AUDIO = 1
+CLASS_COMM = 2
+CLASS_DATA = 10
+CLASS_HID = 3
+CLASS_HUB = 9
+CLASS_MASS_STORAGE = 8
+CLASS_PER_INTERFACE = 0
+CLASS_PRINTER = 7
+CLASS_VENDOR_SPEC = 255
+DT_CONFIG = 2
+DT_CONFIG_SIZE = 9
+DT_DEVICE = 1
+DT_DEVICE_SIZE = 18
+DT_ENDPOINT = 5
+DT_ENDPOINT_AUDIO_SIZE = 9
+DT_ENDPOINT_SIZE = 7
+DT_HID = 33
+DT_HUB = 41
+DT_HUB_NONVAR_SIZE = 7
+DT_INTERFACE = 4
+DT_INTERFACE_SIZE = 9
+DT_PHYSICAL = 35
+DT_REPORT = 34
+DT_STRING = 3
+ENDPOINT_ADDRESS_MASK = 15
+ENDPOINT_DIR_MASK = 128
+ENDPOINT_IN = 128
+ENDPOINT_OUT = 0
+ENDPOINT_TYPE_BULK = 2
+ENDPOINT_TYPE_CONTROL = 0
+ENDPOINT_TYPE_INTERRUPT = 3
+ENDPOINT_TYPE_ISOCHRONOUS = 1
+ENDPOINT_TYPE_MASK = 3
+ERROR_BEGIN = 500000
+MAXALTSETTING = 128
+MAXCONFIG = 8
+MAXENDPOINTS = 32
+MAXINTERFACES = 32
+RECIP_DEVICE = 0
+RECIP_ENDPOINT = 2
+RECIP_INTERFACE = 1
+RECIP_OTHER = 3
+REQ_CLEAR_FEATURE = 1
+REQ_GET_CONFIGURATION = 8
+REQ_GET_DESCRIPTOR = 6
+REQ_GET_INTERFACE = 10
+REQ_GET_STATUS = 0
+REQ_SET_ADDRESS = 5
+REQ_SET_CONFIGURATION = 9
+REQ_SET_DESCRIPTOR = 7
+REQ_SET_FEATURE = 3
+REQ_SET_INTERFACE = 11
+REQ_SYNCH_FRAME = 12
+TYPE_CLASS = 32
+TYPE_RESERVED = 96
+TYPE_STANDARD = 0
+TYPE_VENDOR = 64
+
+class Endpoint(object):
+ r"""Endpoint descriptor object."""
+ def __init__(self, ep):
+ self.address = ep.bEndpointAddress
+ self.interval = ep.bInterval
+ self.maxPacketSize = ep.wMaxPacketSize
+ self.type = util.endpoint_type(ep.bmAttributes)
+
+class Interface(object):
+ r"""Interface descriptor object."""
+ def __init__(self, intf):
+ self.alternateSetting = intf.bAlternateSetting
+ self.interfaceNumber = intf.bInterfaceNumber
+ self.iInterface = intf.iInterface
+ self.interfaceClass = intf.bInterfaceClass
+ self.interfaceSubClass = intf.bInterfaceSubClass
+ self.interfaceProtocol = intf.bInterfaceProtocol
+ self.endpoints = [Endpoint(e) for e in intf]
+
+class Configuration(object):
+ r"""Configuration descriptor object."""
+ def __init__(self, cfg):
+ self.iConfiguration = cfg.iConfiguration
+ self.maxPower = cfg.bMaxPower << 2
+ self.remoteWakeup = (cfg.bmAttributes >> 5) & 1
+ self.selfPowered = (cfg.bmAttributes >> 6) & 1
+ self.totalLength = cfg.wTotalLength
+ self.value = cfg.bConfigurationValue
+ self.interfaces = [
+ list(g) for k, g in _interop._groupby(
+ _interop._sorted(
+ [Interface(i) for i in cfg],
+ key=lambda i: i.interfaceNumber
+ ),
+ lambda i: i.alternateSetting)
+ ]
+
+class DeviceHandle(object):
+ def __init__(self, dev):
+ self.dev = dev
+ self.__claimed_interface = -1
+
+ def bulkWrite(self, endpoint, buffer, timeout = 100):
+ r"""Perform a bulk write request to the endpoint specified.
+
+ Arguments:
+ endpoint: endpoint number.
+ buffer: sequence data buffer to write.
+ This parameter can be any sequence type.
+ timeout: operation timeout in miliseconds. (default: 100)
+ Returns the number of bytes written.
+ """
+ return self.dev.write(endpoint, buffer, self.__claimed_interface, timeout)
+
+ def bulkRead(self, endpoint, size, timeout = 100):
+ r"""Performs a bulk read request to the endpoint specified.
+
+ Arguments:
+ endpoint: endpoint number.
+ size: number of bytes to read.
+ timeout: operation timeout in miliseconds. (default: 100)
+ Return a tuple with the data read.
+ """
+ return self.dev.read(endpoint, size, self.__claimed_interface, timeout)
+
+ def interruptWrite(self, endpoint, buffer, timeout = 100):
+ r"""Perform a interrupt write request to the endpoint specified.
+
+ Arguments:
+ endpoint: endpoint number.
+ buffer: sequence data buffer to write.
+ This parameter can be any sequence type.
+ timeout: operation timeout in miliseconds. (default: 100)
+ Returns the number of bytes written.
+ """
+ return self.dev.write(endpoint, buffer, self.__claimed_interface, timeout)
+
+ def interruptRead(self, endpoint, size, timeout = 100):
+ r"""Performs a interrupt read request to the endpoint specified.
+
+ Arguments:
+ endpoint: endpoint number.
+ size: number of bytes to read.
+ timeout: operation timeout in miliseconds. (default: 100)
+ Return a tuple with the data read.
+ """
+ return self.dev.read(endpoint, size, self.__claimed_interface, timeout)
+
+ def controlMsg(self, requestType, request, buffer, value = 0, index = 0, timeout = 100):
+ r"""Perform a control request to the default control pipe on a device.
+
+ Arguments:
+ requestType: specifies the direction of data flow, the type
+ of request, and the recipient.
+ request: specifies the request.
+ buffer: if the transfer is a write transfer, buffer is a sequence
+ with the transfer data, otherwise, buffer is the number of
+ bytes to read.
+ value: specific information to pass to the device. (default: 0)
+ index: specific information to pass to the device. (default: 0)
+ timeout: operation timeout in miliseconds. (default: 100)
+ Return the number of bytes written.
+ """
+ return self.dev.ctrl_transfer(
+ requestType,
+ request,
+ wValue = value,
+ wIndex = index,
+ data_or_wLength = buffer,
+ timeout = timeout
+ )
+
+ def clearHalt(self, endpoint):
+ r"""Clears any halt status on the specified endpoint.
+
+ Arguments:
+ endpoint: endpoint number.
+ """
+ cfg = self.dev.get_active_configuration()
+ intf = util.find_descriptor(cfg, bInterfaceNumber = self.__claimed_interface)
+ e = util.find_descriptor(intf, bEndpointAddress = endpoint)
+ control.clear_feature(self.dev, control.ENDPOINT_HALT, e)
+
+ def claimInterface(self, interface):
+ r"""Claims the interface with the Operating System.
+
+ Arguments:
+ interface: interface number or an Interface object.
+ """
+ if isinstance(interface, Interface):
+ if_num = interface.interfaceNumber
+ else:
+ if_num = interface
+
+ util.claim_interface(self.dev, if_num)
+ self.__claimed_interface = if_num
+
+ def releaseInterface(self):
+ r"""Release an interface previously claimed with claimInterface."""
+ util.release_interface(self.dev, self.__claimed_interface)
+ self.__claimed_interface = -1
+
+ def reset(self):
+ r"""Reset the specified device by sending a RESET
+ down the port it is connected to."""
+ self.dev.reset()
+
+ def resetEndpoint(self, endpoint):
+ r"""Reset all states for the specified endpoint.
+
+ Arguments:
+ endpoint: endpoint number.
+ """
+ self.clearHalt(endpoint)
+
+ def setConfiguration(self, configuration):
+ r"""Set the active configuration of a device.
+
+ Arguments:
+ configuration: a configuration value or a Configuration object.
+ """
+ self.dev.set_configuration(configuration)
+
+ def setAltInterface(self, alternate):
+ r"""Sets the active alternate setting of the current interface.
+
+ Arguments:
+ alternate: an alternate setting number or an Interface object.
+ """
+ self.dev.set_interface_altsetting(self.__claimed_interface, alternate)
+
+ def getString(self, index, length, langid = None):
+ r"""Retrieve the string descriptor specified by index
+ and langid from a device.
+
+ Arguments:
+ index: index of descriptor in the device.
+ length: number of bytes of the string
+ langid: Language ID. If it is omittedi, will be
+ used the first language.
+ """
+ return util.get_string(self.dev, length, index, langid).encode('ascii')
+
+ def getDescriptor(self, desc_type, desc_index, length, endpoint = -1):
+ r"""Retrieves a descriptor from the device identified by the type
+ and index of the descriptor.
+
+ Arguments:
+ desc_type: descriptor type.
+ desc_index: index of the descriptor.
+ len: descriptor length.
+ endpoint: ignored.
+ """
+ return control.get_descriptor(self.dev, length, desc_type, desc_index)
+
+ def detachKernelDriver(self, interface):
+ r"""Detach a kernel driver from the interface (if one is attached,
+ we have permission and the operation is supported by the OS)
+
+ Arguments:
+ interface: interface number or an Interface object.
+ """
+ self.dev.detach_kernel_driver(interface)
+
+class Device(object):
+ r"""Device descriptor object"""
+ def __init__(self, dev):
+ self.deviceClass = dev.bDeviceClass
+ self.deviceSubClass = dev.bDeviceSubClass
+ self.deviceProtocol = dev.bDeviceProtocol
+ self.deviceVersion = str((dev.bcdDevice >> 12) & 0xf) + \
+ str((dev.bcdDevice >> 8) & 0xf) + \
+ '.' + \
+ str((dev.bcdDevice >> 4) & 0xf) + \
+ str(dev.bcdDevice & 0xf)
+ self.devnum = None
+ self.filename = ''
+ self.iManufacturer = dev.iManufacturer
+ self.iProduct = dev.iProduct
+ self.iSerialNumber = dev.iSerialNumber
+ self.idProduct = dev.idProduct
+ self.idVendor = dev.idVendor
+ self.maxPacketSize = dev.bMaxPacketSize0
+ self.usbVersion = str((dev.bcdUSB >> 12) & 0xf) + \
+ str((dev.bcdUSB >> 8) & 0xf) + \
+ '.' + \
+ str((dev.bcdUSB >> 4) & 0xf) + \
+ str(dev.bcdUSB & 0xf)
+ self.configurations = [Configuration(c) for c in dev]
+ self.dev = dev
+
+ def open(self):
+ r"""Open the device for use.
+
+ Return a DeviceHandle object
+ """
+ return DeviceHandle(self.dev)
+
+class Bus(object):
+ r"""Bus object."""
+ def __init__(self):
+ self.dirname = ''
+ self.location = 0
+ self.devices = [Device(d) for d in core.find(find_all=True)]
+
+def busses():
+ r"""Return a tuple with the usb busses."""
+ return (Bus(),)
+
diff --git a/pybot/usb/util.py b/pybot/usb/util.py
new file mode 100644
index 0000000..da4cb0e
--- /dev/null
+++ b/pybot/usb/util.py
@@ -0,0 +1,260 @@
+# Copyright (C) 2009-2011 Wander Lairson Costa
+#
+# The following terms apply to all files associated
+# with the software unless explicitly disclaimed in individual files.
+#
+# The authors hereby grant permission to use, copy, modify, distribute,
+# and license this software and its documentation for any purpose, provided
+# that existing copyright notices are retained in all copies and that this
+# notice is included verbatim in any distributions. No written agreement,
+# license, or royalty fee is required for any of the authorized uses.
+# Modifications to this software may be copyrighted by their authors
+# and need not follow the licensing terms described here, provided that
+# the new terms are clearly indicated on the first page of each file where
+# they apply.
+#
+# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+# MODIFICATIONS.
+
+r"""usb.util - Utility functions.
+
+This module exports:
+
+endpoint_address - return the endpoint absolute address.
+endpoint_direction - return the endpoint transfer direction.
+endpoint_type - return the endpoint type
+ctrl_direction - return the direction of a control transfer
+build_request_type - build a bmRequestType field of a control transfer.
+find_descriptor - find an inner descriptor.
+claim_interface - explicitly claim an interface.
+release_interface - explicitly release an interface.
+dispose_resources - release internal resources allocated by the object.
+get_string - retrieve a string descriptor from the device.
+"""
+
+__author__ = 'Wander Lairson Costa'
+
+import operator
+import usb._interop as _interop
+
+# descriptor type
+DESC_TYPE_DEVICE = 0x01
+DESC_TYPE_CONFIG = 0x02
+DESC_TYPE_STRING = 0x03
+DESC_TYPE_INTERFACE = 0x04
+DESC_TYPE_ENDPOINT = 0x05
+
+# endpoint direction
+ENDPOINT_IN = 0x80
+ENDPOINT_OUT = 0x00
+
+# endpoint type
+ENDPOINT_TYPE_CTRL = 0x00
+ENDPOINT_TYPE_ISO = 0x01
+ENDPOINT_TYPE_BULK = 0x02
+ENDPOINT_TYPE_INTR = 0x03
+
+# control request type
+CTRL_TYPE_STANDARD = (0 << 5)
+CTRL_TYPE_CLASS = (1 << 5)
+CTRL_TYPE_VENDOR = (2 << 5)
+CTRL_TYPE_RESERVED = (3 << 5)
+
+# control request recipient
+CTRL_RECIPIENT_DEVICE = 0
+CTRL_RECIPIENT_INTERFACE = 1
+CTRL_RECIPIENT_ENDPOINT = 2
+CTRL_RECIPIENT_OTHER = 3
+
+# control request direction
+CTRL_OUT = 0x00
+CTRL_IN = 0x80
+
+_ENDPOINT_ADDR_MASK = 0x0f
+_ENDPOINT_DIR_MASK = 0x80
+_ENDPOINT_TRANSFER_TYPE_MASK = 0x03
+_CTRL_DIR_MASK = 0x80
+
+def endpoint_address(address):
+ r"""Return the endpoint absolute address.
+
+ The address parameter is the bEndpointAddress field
+ of the endpoint descriptor.
+ """
+ return address & _ENDPOINT_ADDR_MASK
+
+def endpoint_direction(address):
+ r"""Return the endpoint direction.
+
+ The address parameter is the bEndpointAddress field
+ of the endpoint descriptor.
+ The possible return values are ENDPOINT_OUT or ENDPOINT_IN.
+ """
+ return address & _ENDPOINT_DIR_MASK
+
+def endpoint_type(bmAttributes):
+ r"""Return the transfer type of the endpoint.
+
+ The bmAttributes parameter is the bmAttributes field
+ of the endpoint descriptor.
+ The possible return values are: ENDPOINT_TYPE_CTRL,
+ ENDPOINT_TYPE_ISO, ENDPOINT_TYPE_BULK or ENDPOINT_TYPE_INTR.
+ """
+ return bmAttributes & _ENDPOINT_TRANSFER_TYPE_MASK
+
+def ctrl_direction(bmRequestType):
+ r"""Return the direction of a control request.
+
+ The bmRequestType parameter is the value of the
+ bmRequestType field of a control transfer.
+ The possible return values are CTRL_OUT or CTRL_IN.
+ """
+ return bmRequestType & _CTRL_DIR_MASK
+
+def build_request_type(direction, type, recipient):
+ r"""Build a bmRequestType field for control requests.
+
+ These is a conventional function to build a bmRequestType
+ for a control request.
+
+ The direction parameter can be CTRL_OUT or CTRL_IN.
+ The type parameter can be CTRL_TYPE_STANDARD, CTRL_TYPE_CLASS,
+ CTRL_TYPE_VENDOR or CTRL_TYPE_RESERVED values.
+ The recipient can be CTRL_RECIPIENT_DEVICE, CTRL_RECIPIENT_INTERFACE,
+ CTRL_RECIPIENT_ENDPOINT or CTRL_RECIPIENT_OTHER.
+
+ Return the bmRequestType value.
+ """
+ return recipient | type | direction
+
+def find_descriptor(desc, find_all=False, custom_match=None, **args):
+ r"""Find an inner descriptor.
+
+ find_descriptor works in the same way the core.find() function does,
+ but it acts on general descriptor objects. For example, suppose you
+ have a Device object called dev and want a Configuration of this
+ object with its bConfigurationValue equals to 1, the code would
+ be like so:
+
+ >>> cfg = util.find_descriptor(dev, bConfigurationValue=1)
+
+ You can use any field of the Descriptor as a match criteria, and you
+ can supply a customized match just like core.find() does. The
+ find_descriptor function also accepts the find_all parameter to get
+ a list of descriptor instead of just one.
+ """
+ def desc_iter(k, v):
+ for d in desc:
+ if (custom_match is None or custom_match(d)) and \
+ _interop._reduce(
+ lambda a, b: a and b,
+ map(
+ operator.eq,
+ v,
+ map(lambda i: getattr(d, i), k)
+ ),
+ True
+ ):
+ yield d
+
+ k, v = args.keys(), args.values()
+
+ if find_all:
+ return [d for d in desc_iter(k, v)]
+ else:
+ try:
+ return _interop._next(desc_iter(k, v))
+ except StopIteration:
+ return None
+
+def claim_interface(device, interface):
+ r"""Explicitly claim an interface.
+
+ PyUSB users normally do not have to worry about interface claiming,
+ as the library takes care of it automatically. But there are situations
+ where you need deterministic interface claiming. For these uncommon
+ cases, you can use claim_interface.
+
+ If the interface is already claimed, either through a previously call
+ to claim_interface or internally by the device object, nothing happens.
+ """
+ device._ctx.managed_claim_interface(device, interface)
+
+def release_interface(device, interface):
+ r"""Explicitly release an interface.
+
+ This function is used to release an interface previously claimed,
+ either through a call to claim_interface or internally by the
+ device object.
+
+ Normally, you do not need to worry about claiming policies, as
+ the device object takes care of it automatically.
+ """
+ device._ctx.managed_release_interface(device, interface)
+
+def dispose_resources(device):
+ r"""Release internal resources allocated by the object.
+
+ Sometimes you need to provide deterministic resources
+ freeing, for example to allow another application to
+ talk to the device. As Python does not provide deterministic
+ destruction, this function releases all internal resources
+ allocated by the device, like device handle and interface
+ policy.
+
+ After calling this function, you can continue using the device
+ object normally. If the resources will be necessary again, it
+ will allocate them automatically.
+ """
+ device._ctx.dispose(device)
+
+def get_string(dev, length, index, langid = None):
+ r"""Retrieve a string descriptor from the device.
+
+ dev is the Device object to which the request will be
+ sent to.
+
+ length is the maximum length of the string in number of characters.
+
+ index is the string descriptor index and langid is the Language
+ ID of the descriptor. If langid is omitted, the string descriptor
+ of the first Language ID will be returned.
+
+ The return value is the unicode string present in the descriptor.
+ """
+ from usb.control import get_descriptor
+ if langid is None:
+ # Asking for the zero'th index is special - it returns a string
+ # descriptor that contains all the language IDs supported by the device.
+ # Typically there aren't many - often only one. The language IDs are 16
+ # bit numbers, and they start at the third byte in the descriptor. See
+ # USB 2.0 specification section 9.6.7 for more information.
+ #
+ # Note from libusb 1.0 sources (descriptor.c)
+ buf = get_descriptor(
+ dev,
+ 254,
+ DESC_TYPE_STRING,
+ 0
+ )
+ assert len(buf) >= 4
+ langid = buf[2] | (buf[3] << 8)
+
+ buf = get_descriptor(
+ dev,
+ length * 2 + 2, # string is utf16 + 2 bytes of the descriptor
+ DESC_TYPE_STRING,
+ index,
+ langid
+ )
+ return buf[2:buf[0]].tostring().decode('utf-16-le')
diff --git a/pybot/usb4butia.py b/pybot/usb4butia.py
new file mode 100755
index 0000000..eb964d7
--- /dev/null
+++ b/pybot/usb4butia.py
@@ -0,0 +1,375 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# USB4Butia main
+#
+# Copyright (c) 2012-2013 Butiá Team butia@fing.edu.uy
+# Butia is a free and open robotic platform
+# www.fing.edu.uy/inco/proyectos/butia
+# Facultad de Ingeniería - Universidad de la República - Uruguay
+#
+# 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 of the License, 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
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+import os
+import imp
+import com_usb
+from baseboard import Baseboard
+from device import Device
+
+ERROR = -1
+
+class USB4Butia():
+
+ def __init__(self, debug=False, get_modules=True):
+ self._debug = debug
+ self._hotplug = []
+ self._openables = []
+ self._drivers_loaded = {}
+ self._bb = []
+ self._modules = []
+ self._get_all_drivers()
+ self.find_butias(get_modules)
+
+ def get_butia_count(self):
+ """
+ Gets the number of boards detected
+ """
+ return len(self._bb)
+
+ def find_butias(self, get_modules=True):
+ """
+ Search for connected USB4Butia boards and open it
+ """
+ devices = com_usb.find()
+ for dev in devices:
+ b = Baseboard(dev)
+ try:
+ b.open_baseboard()
+ self._bb.append(b)
+ except:
+ if self._debug:
+ print 'error open baseboard'
+ if get_modules:
+ self.get_modules_list()
+
+ def get_modules_list(self, normal=True):
+ """
+ Get the list of modules loaded in the board
+ """
+ self._modules = []
+ n_boards = self.get_butia_count()
+
+ if self._debug:
+ print '=Listing Devices'
+
+ for i, b in enumerate(self._bb):
+ try:
+ listi = b.get_listi()
+ s = b.get_handler_size()
+
+ if self._debug:
+ print '===board', i
+
+ for m in range(0, s + 1):
+ module_name = listi[b.get_handler_type(m)]
+ if n_boards > 1:
+ complete_name = module_name + '@' + str(i) + ':' + str(m)
+ else:
+ complete_name = module_name + ':' + str(m)
+
+ if self._debug:
+ print '=====module', module_name, (8 - len(module_name)) * ' ', complete_name
+
+ if not(module_name == 'port'):
+
+ if normal:
+ self._modules.append(complete_name)
+ else:
+ self._modules.append((str(m), module_name, str(i)))
+
+ if not(b.devices.has_key(m) and (b.devices[m].name == module_name)):
+ d = Device(b, module_name, m)
+ d.add_functions(self._drivers_loaded[module_name])
+ b.add_device(m, d)
+
+ if module_name in self._openables:
+ b.add_openable_loaded(module_name)
+ else:
+ if b.devices.has_key(m):
+ b.devices.pop(m)
+
+ except Exception, err:
+ if self._debug:
+ print 'error module list', err
+
+ return self._modules
+
+ def _get_all_drivers(self):
+ """
+ Load the drivers for the differents devices
+ """
+ # current folder
+ path_drivers = os.path.join(os.path.dirname(__file__), 'drivers')
+ if self._debug:
+ print 'Searching drivers in: ', path_drivers
+ # normal drivers
+ tmp = os.listdir(path_drivers)
+ tmp.sort()
+ for d in tmp:
+ if d.endswith('.py'):
+ name = d.replace('.py', '')
+ self._openables.append(name)
+ self._get_driver(path_drivers, name)
+ # hotplug drivers
+ path = os.path.join(path_drivers, 'hotplug')
+ tmp = os.listdir(path)
+ tmp.sort()
+ for d in tmp:
+ if d.endswith('.py'):
+ name = d.replace('.py', '')
+ self._hotplug.append(name)
+ self._get_driver(path, name)
+
+ def _get_driver(self, path, driver):
+ """
+ Get a specify driver
+ """
+ if self._debug:
+ print 'Loading driver %s...' % driver
+ abs_path = os.path.abspath(os.path.join(path, driver + '.py'))
+ f = None
+ try:
+ f = imp.load_source(driver, abs_path)
+ except:
+ if self._debug:
+ print 'Cannot load %s' % driver, abs_path
+ if f and hasattr(f, 'FUNCTIONS'):
+ self._drivers_loaded[driver] = f.FUNCTIONS
+ else:
+ if self._debug:
+ print 'Driver not have FUNCTIONS'
+
+ def callModule(self, modulename, board_number, number, function, params = []):
+ """
+ Call one function: function for module: modulename in board: board_name
+ with handler: number (only if the module is pnp, else, the parameter is
+ None) with parameteres: params
+ """
+ try:
+ board = self._bb[board_number]
+ if board.devices.has_key(number) and (board.devices[number].name == modulename):
+ return board.devices[number].call_function(function, params)
+ else:
+ if modulename in self._openables:
+ if modulename in board.get_openables_loaded():
+ number = board.get_device_handler(modulename)
+ else:
+ board.add_openable_loaded(modulename)
+ dev = Device(board, modulename)
+ number = dev.module_open()
+ dev.add_functions(self._drivers_loaded[modulename])
+ board.add_device(number, dev)
+ return board.devices[number].call_function(function, params)
+ else:
+ if self._debug:
+ print 'no open and no openable'
+ return ERROR
+ except Exception, err:
+ if self._debug:
+ print 'error call module', err
+ return ERROR
+
+ def reconnect(self):
+ """
+ Not implemented
+ """
+ pass
+
+ def refresh(self):
+ """
+ Refresh: if no boards presents, search for them.. else, check if
+ the boards continues present
+ """
+ if self._bb == []:
+ self.find_butias(False)
+ else:
+ for b in self._bb:
+ info = ERROR
+ try:
+ info = b.get_info()
+ except:
+ if self._debug:
+ print 'error refresh getinfo'
+
+ if info == ERROR:
+ self._bb.remove(b)
+ try:
+ b.close_baseboard()
+ except:
+ pass
+
+ def close(self):
+ """
+ Closes all open baseboards
+ """
+ for b in self._bb:
+ try:
+ b.close_baseboard()
+ except:
+ if self._debug:
+ print 'error in close baseboard'
+ self._bb = []
+
+ def isPresent(self, module_name):
+ """
+ Check if module: module_name is present
+ """
+ module_list = self.get_modules_list()
+ return (module_name in module_list)
+
+ def loopBack(self, data, board=0):
+ """
+ LoopBack command: send data to the board and get the result. If all is ok
+ the return must be exactly of the data parameter
+ """
+ return self.callModule('lback', board, 0, 'send', [data])
+
+ ################################ Movement calls ################################
+
+ def set2MotorSpeed(self, leftSense = 0, leftSpeed = 0, rightSense = 0, rightSpeed = 0, board = 0):
+ """
+ Set the speed of 2 motors. The sense is 0 or 1, and the speed is
+ between 0 and 1023
+ """
+ msg = [int(leftSense), int(leftSpeed / 256.0), leftSpeed % 256, int(rightSense), int(rightSpeed / 256.0) , rightSpeed % 256]
+ return self.callModule('motors', board, 0, 'setvel2mtr', msg)
+
+ def setMotorSpeed(self, idMotor = 0, sense = 0, speed = 0, board = 0):
+ """
+ Set the speed of one motor. idMotor = 0 for left motor and 1 for the
+ right motor. The sense is 0 or 1, and the speed is between 0 and 1023
+ """
+ msg = [idMotor, sense, int(speed / 256.0), speed % 256]
+ return self.callModule('motors', board, 0, 'setvelmtr', msg)
+
+ ############################### General calls ###############################
+
+ def getBatteryCharge(self, board=0):
+ """
+ Gets the battery level charge
+ """
+ return self.callModule('butia', board, 0, 'get_volt')
+
+ def getVersion(self, board=0):
+ """
+ Gets the version of Butiá module. 22 for new version
+ """
+ return self.callModule('butia', board, 0, 'read_ver')
+
+ def getFirmwareVersion(self, board=0):
+ """
+ Gets the version of the Firmware
+ """
+ return self.callModule('admin', board, 0, 'getVersion')
+
+ ############################### Sensors calls ###############################
+
+ def getButton(self, number, board=0):
+ """
+ Gets the value of the button connected in port: number
+ """
+ res = self.callModule('button', board, number, 'getValue')
+ if res != ERROR:
+ return (1 - res)
+ else:
+ return res
+
+ def getLight(self, number, board=0):
+ """
+ Gets the value of the light sensor connected in port: number
+ """
+ m = 65535
+ res = self.callModule('light', board, number, 'getValue')
+ if res != ERROR:
+ return (m - res)
+ else:
+ return res
+
+ def getDistance(self, number, board=0):
+ """
+ Gets the value of the distance sensor connected in port: number
+ """
+ return self.callModule('distanc', board, number, 'getValue')
+
+ def getGray(self, number, board=0):
+ """
+ Gets the value of the gray sensor connected in port: number
+ """
+ return self.callModule('grey', board, number, 'getValue')
+
+ def getTemperature(self, number, board=0):
+ """
+ Gets the value of the temperature sensor connected in port: number
+ """
+ return self.callModule('temp', board, number, 'getValue')
+
+ def getResistance(self, number, board=0):
+ """
+ Gets the value of the resistance sensor connected in port: number
+ """
+ vcc = 65535
+ raw = self.callModule('res', board, number, 'getValue')
+ if not(raw == ERROR):
+ return raw * 6800 / (vcc - raw)
+ return raw
+
+ def getVoltage(self, number, board=0):
+ """
+ Gets the value of the voltage sensor connected in port: number
+ """
+ vcc = 65535
+ raw = self.callModule('volt', board, number, 'getValue')
+ if not(raw == ERROR):
+ return raw * 5 / vcc
+ return raw
+
+ def setLed(self, number, on_off, board=0):
+ """
+ Sets on or off the LED connected in port: number (0 is off, 1 is on)
+ """
+ return self.callModule('led', board, number, 'turn', [int(on_off)])
+
+ ################################ Extras ################################
+
+ def modeHack(self, pin, mode, board = 0):
+ """
+ Sets the mode of hack pin. If mode 0 = input, mode 1 = output
+ """
+ msg = [int(pin), int(mode)]
+ return self.callModule('hackp', board, 0, 'setMode', msg)
+
+ def setHack(self, pin, value, board = 0):
+ """
+ Sets the value of hack pin configured as output. Value is 0 or 1
+ """
+ msg = [int(pin), int(value)]
+ return self.callModule('hackp', board, 0, 'write', msg)
+
+ def getHack(self, pin, board = 0):
+ """
+ Gets the value of hack pin configured as input. Returns 0 or 1
+ """
+ return self.callModule('hackp', board, 0, 'read', [int(pin)])
+
diff --git a/robot.py b/robot.py
index ab76693..b422842 100755
--- a/robot.py
+++ b/robot.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# FollowMe Butia - Robot
-# Copyright (C) 2010, 2011, 2012
+# Copyright (C) 2010-2013
# This program was created to use with the robot Butia.
# Butia is a project from Facultad de Ingenieria - Uruguay
# Facultad de Ingenieria web site: <http://www.fing.edu.uy/>
@@ -27,8 +27,7 @@
# Rodrigo Dearmas <piegrande46@hotmail.com>
import time
-import commands
-import butiaAPI
+from pybot import usb4butia
import subprocess
from gettext import gettext as _
@@ -45,19 +44,8 @@ class Robot(object):
def bobot_launch(self):
print 'Initialising butia...'
- output = commands.getoutput('ps -ax | grep lua')
- if 'bobot-server' in output:
- print 'bobot is alive!'
- else:
- try:
- print 'creating bobot'
- self.bobot = subprocess.Popen(['./lua', 'bobot-server.lua'], cwd='./lib/support')
- except:
- print 'ERROR creating bobot'
-
- time.sleep(1)
- self.butia = butiaAPI.robot()
+ self.butia = usb4butia.USB4Butia()
self.modules = self.butia.get_modules_list()
@@ -131,8 +119,8 @@ class Robot(object):
vel_actual = (0, 600, 0, 900)
- self.butia.set2MotorSpeed(str(vel_actual[0]), str(vel_actual[1]), str(vel_actual[2]), str(vel_actual[3]))
+ self.butia.set2MotorSpeed(vel_actual[0], vel_actual[1], vel_actual[2], vel_actual[3])
def stop_robot(self):
- self.butia.set2MotorSpeed('0', '0', '0', '0')
+ self.butia.set2MotorSpeed(0, 0, 0, 0)
diff --git a/lib/sugargame/__init__.py b/sugargame/__init__.py
index 439eb0c..439eb0c 100755
--- a/lib/sugargame/__init__.py
+++ b/sugargame/__init__.py
diff --git a/lib/sugargame/canvas.py b/sugargame/canvas.py
index 1ce0250..1ce0250 100755
--- a/lib/sugargame/canvas.py
+++ b/sugargame/canvas.py
diff --git a/lib/sugargame/event.py b/sugargame/event.py
index 431a600..431a600 100755
--- a/lib/sugargame/event.py
+++ b/sugargame/event.py