#!/usr/bin/python

# Written by Mark Eichin.  Use for whatever you want...

# "version 0" of the missile launcher driver
# works with a local build of pyusb...
import sys
import os
import time
sys.path.append("pyusb-0.3.1/build/lib.linux-i686-2.4/")
import usb

# find all of the USB busses
busses = usb.busses()
print busses

# Find one device
for bus in busses:
    for dev in bus.devices:
        if dev.idVendor == 0x1941 and dev.idProduct == 0x8021:
            rdev = dev

dev = rdev
# bugcheck - make sure we did find the DreamCheeky device
assert dev.idVendor == 0x1941
assert dev.idProduct == 0x8021
print dev, hex(dev.idVendor), hex(dev.idProduct)
# we know that there's one config, one interface, and one endpoint
conf = dev.configurations[0]
iface = conf.interfaces[0][0]
endpoint = iface.endpoints[0]

# open it
handle = dev.open()
handle.detachKernelDriver(0) # Should this be iface.interfaceNumber?
# Note that if you don't run this, you'll actually get messages like
# [222572.952000] usb usb1: usbfs: process 20986 (python) did not claim interface 1 before use
# in dmesg...
handle.setConfiguration(conf)
handle.claimInterface(iface)
handle.setAltInterface(iface)
handle.reset()

# based on /mac/USB Missile Launcher NZ Source Package/USB Missile Launcher NZ v1.4e/Classes/USBMissileControl.m
# we have

reqBuffer = [0] * 8
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
# which is 0x21...
# setconfig is 0x9...
# dt_config is 2...

print "PID:", os.getpid()
reqBuffer[0] = 0
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, value=usb.DT_CONFIG, index=0)
# move and fire...
FIRE = 16
MOVE_LEFT = 4
reqBuffer[0] = MOVE_LEFT | FIRE
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, value=usb.DT_CONFIG, index=0)
time.sleep(0.5)
reqBuffer[0] = 0
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, value=usb.DT_CONFIG, index=0)

# >>> reqBuffer[0] = 4 | 16
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, value=usb.DT_CONFIG, index=0)
# 8
# >>> reqBuffer[0] = 0
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, value=usb.DT_CONFIG, index=0)
# 8
# >>> stop = [0]*8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> pad = [0]* 7
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [11]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [8]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [11]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [5]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [5]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [8]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [16]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [16]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [16]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [16]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [16]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [32]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, [16]+pad, value=usb.DT_CONFIG, index=0)
# 8
# >>> handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, stop, value=usb.DT_CONFIG, index=0)
# 8
# >>> 


# handle.interruptRead(endpoint.address, 8)
# (-128L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)

# from USBMissileControl.m:
# 			//		Thanks to Brandon Heyer for the following:
# 			//      the DreamCheeky Launcher will return the following codes
# 			//	
# 			//		00 04 00 00 00 00 00 00 - All the way left
# 			//		00 08 00 00 00 00 00 00 - All the way right
# 			//		40 00 00 00 00 00 00 00 - All the way down
# 			//		80 00 00 00 00 00 00 00 - All the way up 
